White label · Operator handbook

Set up, run, and integrate your white-label picks platform

Everything a white-label tenant needs to launch on the platform: first-day setup, the daily operating routine, and the integration surface for wallets and your own apps. Screenshots are live captures from a demo tenant, every screen shown carries your brand on your own tenant.

Player app…/picks/?tenant={your-slug}
Admin console…/picks/admin
Sport live nowNFL · more per request
1

Set up

A new tenant goes from credentials to a live board in under an hour. Do these once, in order.

1.1What you're running

Appently Picks is a white-label, peer-to-peer player-pick contest platform. Everything players see carries your brand, "TX Picks" in the screenshots is the demo tenant's brand, not the platform's. Your players pick More or Less on stat lines you publish (e.g. C.J. Stroud 210.5 passing yards), build a ticket of 2–6 picks, and choose Power (hit every pick) or Flex (tiered, miss one or two and still cash). Tickets with the same shape, pick count × mode × entry amount, are pooled together. You take a fixed rake off each pool; winners split the rest.

  • You never hold a position against a player. Revenue is the rake, identical whoever wins. If nobody in a pool wins, every ticket is refunded and no rake is taken.
  • Your tenant is isolated. Players, balances, lines, pools, branding, and rake are yours alone, other operators on the platform never see them.
  • Grading is automatic. Schedules, box scores, and final stats flow in from ESPN; picks grade when games go final, and pools pay out on a 5-minute cycle with no operator action.
The money, end to end Ten $5 tickets enter the 2-pick Power · $5 pool → $50 gross. At 10% rake, you keep $5 and the prize pool is $45. Two tickets go 2-for-2 → each is paid $22.50, credited the moment the pool settles. Exactly hitting a line is a push: that pick is voided and the ticket is judged on the rest.

Whose money is what

  • The rake is yours, all of it. It accrues inside your pools and is reported on your Dashboard and Pools pages. The platform never deducts anything from pools, entries, or player balances.
  • Player balances are your liability. In built-in ledger mode you hold the cash (your cashier desk); in bring-your-own-wallet mode it never leaves your system at all.
  • Platform fees are separate. Whatever your agreement is, flat monthly, revenue share, or both, it is invoiced commercially, never taken out of the system automatically. Your books in the console are gross of any platform fee.

1.2Sign in

Your owner account is created for you (email + password supplied separately). Sign in at …/picks/admin/login.php with your tenant owner account, everything in this handbook happens in that console.

appentlygaming.com/picks/admin/login.php
Admin sign-in screen
The admin console. Sessions are per-admin; every action is stamped with the admin who did it.

1.3Brand the player app

Settings → Branding controls what players see: brand name, tagline, operator name (used in FAQ copy), logo, and the five theme colors. Changes apply instantly, reload the player app to check.

Two more panels on the same page finish the identity:

  • Game rules, min/max picks, entry amounts, default rake, pool min/max. These drive both new contest types and the wording of the generated FAQ.
  • Help & FAQ, the player app's Help tab. Sensible answers are generated from your brand and rules; override any answer, hide a question, or add house rules (hours, where to cash out, age policy).
…/admin/settings.php
Settings page with branding, game rules, and FAQ editor
Settings. Branding, game rules, FAQ editor, admin users, and the wallet/funding mode all live here.

Contest Types are the pool shapes players can enter. Generate the grid once, entry amounts × 2–6 picks × Power/Flex, then tune each row:

  • Rake is set in basis points: 1000 bps = 10%, 500 = 5% (max 30%). The page shows the percent next to the field. Changing rake affects new pools only.
  • Scoring reads as correct picks → share weight. Power is all-or-nothing (2/2 → 1 share). Flex pays tiers (5/5 → 1 · 4/5 → 0.25 · 3/5 → 0.05); winners split the prize pool in proportion to shares.
  • Group min / max, a pool needs min entries at lock to run (otherwise everyone is refunded) and closes at max, after which a fresh pool of the same shape opens.
  • Toggle a shape Off to hide it from players.
…/admin/contest_types.php
Contest Types page with rake and scoring per shape
Contest Types. The "How to read this table" panel explains rake, scoring, and group sizes in-page.
Start narrowOpen with a few shapes ($5 / $10 / $20, 2–4 picks) so pools actually fill. A pool that never reaches its minimum refunds everyone and earns nothing. Widen the menu as volume grows.

1.5Publish your first lines

Projections is where you author the board. Games appear automatically from the ESPN schedule, eight days ahead.

  1. Click a game. If the Player dropdown is empty, hit ↻ Load roster from ESPN, it pulls QB / RB / WR / TE for both teams in one click.
  2. Pick player, stat, line. Use .5 lines (62.5, not 62) to avoid pushes. Publish now makes it live instantly; untick to stage drafts and publish them all at once.
  3. Star (★) a line to feature it at the top of the player board. Aim for 8–15 lines per game across positions.
  • Lines are editable until kickoff. Tickets keep the line they were sold at, edits only affect new entries.
  • Void a line if a player is ruled out or a game is postponed, picks on it become pushes, before or after lock.
  • After a game is final, Grade (manual actual value) exists only for official stat corrections; re-settle the pool afterward.
  • Stats available today: Pass Yds, Pass TDs, Rush Yds, Rec Yds, Receptions, Rush+Rec Yds.
…/admin/projections.php
Projections page with a game open and 22 published lines
Projections. One game open: roster loader, the add-line form, and 22 published lines with inline edit, feature, unpublish, and void.

1.6Launch checklist

  1. Branding saved and player app reloaded, name, colors, FAQ read right.
  2. Contest menu generated; shapes you don't want are toggled Off; rake confirmed.
  3. Lines published for every game in the next 48 hours.
  4. Funding decided (Part 3): built-in ledger with your cashier desk, or your own wallet connected and tested.
  5. Cashier staff added as support admins (Settings → Admin users).
  6. Dashboard shows Ledger integrity OK ✓, you're live.
2

Operate

The daily rhythm: publish lines in the morning, run the counter all day, let settlement run itself overnight.

2.1Dashboard

Your morning glance. Entries and handle today, rake today and all-time, open/locked pools, and two health signals worth checking daily:

  • Player balances (liability), the total you owe players. It should track cash taken in minus cash paid out, minus rake, plus bonuses.
  • Ledger integrity, must read OK ✓. Anything else: stop posting and contact platform support.
…/admin/dashboard.php
Admin dashboard with KPIs and upcoming games
Dashboard. The cashier quick-find sits at the top; the games table shows projection coverage so a bare slate is obvious before kickoff.

2.2Cashier, the counter workflow

Built for a brick-and-mortar desk: find, tap, post. Search by any part of a name, email, or player number, a single match opens straight to the player card.

…/admin/cashier.php
Cashier landing with day totals and player search
Cashier home. Day totals for the drawer, one big search box, and recent cashier activity below.
…/admin/cashier.php?p=8
Cashier player card with deposit, withdraw, bonus
Player card. Live balance, then Deposit / Withdraw / Bonus with quick-amount buttons and an optional receipt note.
  • Over-withdrawals are refused. The balance shown is spendable cash, money on a locked ticket is already debited, so it can never be withdrawn.
  • Bonus is house promo credit. It counts toward liability and is tagged separately in the ledger for reporting.
  • New walk-ups: Create player on the same page, name, email, optional opening deposit. They can log into the app with that email immediately.
  • No deletes, ever. Correct a mistake by posting the opposite transaction with a memo. Every posting carries the admin's ID into the audit log.

2.3Pools & payouts

The Pools page lists every pool with entries, gross, rake, and prize; click through for its tickets. Lifecycle: openlocked at first kickoff → settled once every pick is graded, or void (refunded).

  • Settle forces settlement when all picks are graded (normally automatic). Run cycle now triggers lock → grade → settle immediately instead of waiting for the 5-minute job.
  • Void refunds every ticket, for an abandoned game, a bad line you sold, or any integrity call. Reasons are logged.
  • Payouts are pari-mutuel: prize pool ÷ total winning shares × ticket's shares, rounded down to the cent; leftover pennies go to the first winner so pools always balance exactly.
…/admin/pools.php
Pools list
Pools. After a game day, yesterday's pools should all read settled or void by morning, if one is stuck, see Troubleshooting.

2.4Entries & disputes

Every ticket has a ref code (FPRS-KAJ7) printed in the player's app. When someone questions a result, search the ref on the Entries page: each leg shows the line sold, the actual stat, and its result, won / lost / push / void, so you can walk through the ticket at the counter.

  • Wrong stat? Correct it on Projections (Grade with the official value), then re-settle the pool. Ledger corrections are appended, never edited, the trail stays intact.
  • Players can't cancel a placed ticket. As a courtesy before lock: void the pool (refunds everyone) or post a manual refund on the player's page, noting the ref code.

2.5Players

Search, then open a profile: balance, lifetime handle, won/net, full ledger, and every ticket. From here you can post any ledger type (including corrections) and set account status, suspended (can log in, can't enter) or closed.

…/admin/players.php
Players list
Players. Signups happen in the app or at the cashier; there's no approval queue.

2.6Ledger & reconciliation

The ledger is append-only, every balance is the sum of its rows, and the platform re-checks that invariant continuously (that's the Dashboard's integrity light). Row types: deposit, withdrawal, bonus, adjustment, entry, payout, refund.

  • End of day: filter deposits/withdrawals for today and compare against the drawer. The Cashier page shows the same totals at the top all day.
  • Rake: per pool on the Pools page; today and all-time on the Dashboard.
…/admin/ledger.php
Ledger page
Ledger. Entry debits carry the ticket ref; cashier rows carry the admin and memo.

2.7What players see

The player app is a mobile-first web app, no install, no store. Players sign up with email + password (or you create them at the cashier), browse the board, tap More/Less, set an entry amount, and submit. Their Entries tab tracks live tickets leg by leg; Help shows your FAQ.

lobby
Player app lobby
picks + lineup slip
Player app board with a pick selected and lineup slip
help / faq
Player app help tab
The player app, themed with your branding. Share it as …/picks/?tenant=your-slug or point a domain at it.
In-console versionA condensed, printable version of Parts 1–2 ships inside the console under Guide in the nav, useful for training cashier staff without handing them this document.
3

Integrate

Two integration surfaces: bring your own wallet so balances live in your system, and a JSON API if you want to embed the game in your own app.

3.1Funding modes

Built-in ledger (default)Bring your own wallet
Balances live inThe platformYour system
Players fund viaYour cashier desk (cash/card at the counter)Your existing cashier / payment rails
Entry debits & payoutsPosted to the internal ledgerPosted to your wallet API in real time
Admin cashier pageFull deposit / withdraw / bonusStill works, forwards postings to your wallet
Best forCard rooms, clubs, standalone launchesPoker sites and operators with player accounts already

Switch modes in Settings → Wallet / funding mode: enter your API base URL and key, press Test (it performs a live balance call), then save. In remote mode the internal ledger keeps a mirror of every posting with your transaction IDs, so both systems hold a complete audit trail.

Switching with player balances outstandingMoving between modes while player liability is non-zero requires a balance-migration plan. Do it with platform support, not mid-week.

3.2Wallet API contract

To bring your own wallet, expose three JSON endpoints. All calls arrive with Authorization: Bearer <your api key> and JSON bodies; respond in JSON.

CallRequestSuccess response
GET /balance?user={id}-{"ok":true,"balance_cents":12345}
POST /debit{"user":"…","amount_cents":1000,"ref":"ENTRY-123","memo":"…"}{"ok":true,"balance_cents":11345,"txn_id":"…"}
POST /credit{"user":"…","amount_cents":1350,"ref":"POOL-7","memo":"…"}{"ok":true,"balance_cents":12695,"txn_id":"…"}

Rules your implementation must follow:

  • ref is an idempotency key. The same ref must never post twice, on a repeat, return the original result. This makes network retries safe.
  • Refuse debits that overdraw with {"ok":false,"error":"INSUFFICIENT_FUNDS"}, the player sees a clean "insufficient balance" message.
  • user is the player's ID in your system (their sso_subject), falling back to the platform player ID if none is set.
  • Any other failure: {"ok":false,"error":"YOUR_CODE"}. Timeouts and non-JSON responses surface to staff as wallet errors and nothing is posted.

What gets posted when: ENTRY-{id} debits when a ticket is placed, POOL-{id} credits on wins, refund refs credit on voided pools/lines, and cashier/bonus postings carry admin refs. Optionally set a cashier_url in the wallet config, the player app's "Add funds" button sends players there.

3.3Player API

The player app itself runs on a public JSON API, anything it does, your own app can do. Base: …/picks/api.php?a={action}&tenant={slug}. Authenticated calls take Authorization: Bearer <token> from login.

ActionMethodAuthReturns
configGET-Branding, rules, FAQ, funding mode
register / login / logoutPOST-Player + bearer token
meGETProfile + live balance
boardGET-Open projections with athlete, game, line
previewPOSTEntry preview: pool, prize math, validation
entryPOSTPlaces a ticket (debits wallet)
entries · entry&id=GETTicket list / one ticket with per-leg results
ledgerGETPlayer's transaction history
# place a 2-pick Power ticket for $10
curl -X POST '…/picks/api.php?a=entry&tenant={your-slug}' \
  -H 'Authorization: Bearer <token>' -H 'Content-Type: application/json' \
  -d '{"picks":[{"projection_id":1,"side":"more"},
              {"projection_id":4,"side":"less"}],
       "play_mode":"power","entry_cents":1000}'
# → {"ok":true,"entry":{"ref_code":"FPRS-KAJ7", …}}

For single sign-on from an existing poker site, player accounts carry an sso_subject field that maps to your user IDs, the same key the wallet API uses. Full SSO token exchange is wired per integration; talk to the platform.

3.4Automation, what runs by itself

A platform job runs every 5 minutes, in order: sync the ESPN schedule (8 days out) and pull rosters for teams that need them → lock pools whose first game kicked off → ingest box scores → grade finished projections → settle ready pools. Players who never took the field are auto-voided (DNP) two hours after a game goes final, so pools don't hang on inactive players.

Nothing in the cycle needs operator action; Run cycle now on the Pools page exists only for impatience and stat corrections.

3.5Admin roles & audit

RoleCanCan't
ownerEverything in the tenant, incl. admins, wallet mode, settingsSee other tenants
managerLines, pools, entries, players, cashier, contest typesManage admins, switch wallet mode
supportCashier, players, entriesTouch lines, pools, or settings
superPlatform staff, all tenants(not a tenant role)

Every state change, postings, voids, line edits, grades, status flips, lands in the audit log with the acting admin's ID and a payload of what changed.

3.6Troubleshooting

SymptomCause & fix
No games in ProjectionsSchedule syncs every 5 min. Still empty after 10, contact support (feed issue).
Player dropdown emptyClick ↻ Load roster from ESPN on that game.
Pool stuck locked after games endedAn ungraded pick, usually a DNP. It auto-voids 2 h after final; or void the projection yourself and hit Run cycle now.
Player disputes balanceTheir profile's ledger lists every movement with time, type, memo, and ticket refs. Walk it at the counter.
"Wallet error" at the cashierRemote mode: your wallet API is unreachable or errored. Nothing was posted. Retry; verify with Settings → Test.
Ledger integrity ⚠Stop posting. Contact platform support before any further transactions.

3.7Reference

WhatWhere
Player apphttps://appentlygaming.com/picks/?tenant={slug}
Admin consolehttps://appentlygaming.com/picks/admin/login.php
Player APIhttps://appentlygaming.com/picks/api.php?a=…&tenant={slug}
Your admin loginTenant owner account, supplied at onboarding (add your staff under Settings → Admin users)
Your rake100% yours, reported per pool and on the Dashboard; platform fees are invoiced separately per your agreement
Settlement cadenceEvery 5 minutes: schedule → lock → box scores → grade → settle
SportsNFL live; NBA/MLB/NHL on request (ESPN-fed, same pipeline)
Appently Picks · Operator handbook · screenshots from a demo tenant · updated Aug 20, 2026