Download OpenAPI specification:
API for accessing poker providers, clubs, and tables data
Returns a one-time URL to change password; user is redirected back to appUrl/#/settings
| appUrl required | string App origin (no trailing slash), e.g. https://app.lobbyscanner.com |
{- "appUrl": "string"
}{- "url": "string"
}Paid users: subscription is canceled at period end and the account is scheduled for deletion then. Free users: deleted immediately. Agents must resolve blockers first and choose dependentHandling (cancel_subs | delete_accounts) for their managed players / team members.
| dependentHandling | string Enum: "cancel_subs" "delete_accounts" |
{- "dependentHandling": "cancel_subs"
}| level required | integer Enum: 1 2 1 = direct commission (will auto-cascade L2 to the upline). 2 = raw L2 entry, no cascade. |
| period required | string |
| amountCents required | integer |
| sourceAgentId | integer or null |
| referredUserId | string or null |
| sourceAmountCents | integer or null |
| note | string or null |
| cascadeL2 | boolean Default: true When booking L1, set false to suppress the automatic Level-2 cascade. |
{- "level": 1,
- "period": "2026-05",
- "amountCents": 0,
- "sourceAgentId": 0,
- "referredUserId": "string",
- "sourceAmountCents": 0,
- "note": "string",
- "cascadeL2": true
}| status | string Enum: "pending" "approved" "rejected" "cancelled" |
| reveal | integer Payout request id to return with FULL (unmasked) bank/tax details. The list itself is always masked; revealing is a deliberate, per-request, logged action for the operator executing the transfer. |
Copies the MGC source admin's DEFAULT club list onto the target agent as a linked clone, then promotes that clone to the target agent's default. Future mutations on the source list are hard-mirrored to every clone (the target agent cannot edit the clone). Idempotent – calling again refreshes items without creating a duplicate.
Restricted to the caller whose email matches MGC_SOURCE_AGENT_EMAIL (defaults to nmmediationltd@gmail.com).
| agentId required | integer |
Per-provider residential-proxy byte usage, read from the .netmeter.json snapshots the bots write when their meter is enabled. Evomi bills one shared account for every bot, so this is the only per-provider breakdown that exists. complete is false whenever a provider has no usable or no recent snapshot, in which case the totals are a floor rather than a sum.
| providerId required | string |
| clubId required | string |
| customDisplayName | string |
| isVisible | boolean |
| sortOrder | integer |
{- "customDisplayName": "string",
- "isVisible": true,
- "sortOrder": 0
}| email required | string |
| password required | string |
| name | string |
| plan | string Enum: "grinder" "high-stakes" "agent-pro" |
| paymentMethod | string Enum: "balance" "card" "free" |
| compTerm | string Enum: "1m" "3m" "6m" "unlimited" How long a free (comped) subscription lasts, measured from now. Only valid with paymentMethod "free"; omitted means unlimited, the historic behaviour. |
| appUrl | string |
{- "email": "string",
- "password": "string",
- "name": "string",
- "plan": "grinder",
- "paymentMethod": "balance",
- "compTerm": "1m",
- "appUrl": "string"
}Always best-effort cancels any active Stripe subscription for the
player first, then deletes the membership. If the Stripe cancel
partially fails (orphaned customer/network), the player is still
removed and a stripeWarning is returned so the agent can verify
in the Stripe Dashboard.
| playerUserId required | string URL-encoded Auth0 user id |
{- "success": true,
- "stripeWarning": "string"
}Cancels any active Stripe subscription for the player immediately.
The player keeps their account and roster membership; only billing is
ended. If the Stripe cancel partially fails (orphaned customer/network),
a warning is returned so the agent can verify in Stripe.
| playerUserId required | string URL-encoded Auth0 user id |
{- "success": true,
- "warning": "string"
}Changes the end date of an admin-granted free subscription to 1, 3 or 6 months from NOW, or to unlimited. Only free accounts have a comp term — a player paying through Stripe or Apple is rejected. Requires the same authorization as granting a free subscription in the first place.
The term is always measured from today, so re-picking one extends it; it never shortens retroactively. Shortening takes effect immediately.
| playerUserId required | string URL-encoded Auth0 user id |
| compTerm required | string Enum: "1m" "3m" "6m" "unlimited" |
{- "compTerm": "1m"
}{- "success": true,
- "compTerm": "string",
- "compEndsAt": "string"
}| id required | integer Agent numeric id |
| amountCents required | integer |
| description | string |
{- "amountCents": 0,
- "description": "string"
}| name | string |
| providerId | string |
| clubId | string |
| listId | integer |
| rakeStructure | string |
| dealPct | number Rakeback as a fraction (0.5 = 50%) |
| rebatePct | number Rebate as a fraction |
| clubName | string |
| isPublished | boolean |
| assignToAll | boolean |
| userIds | Array of strings |
{- "name": "string",
- "providerId": "string",
- "clubId": "string",
- "listId": 0,
- "rakeStructure": "string",
- "dealPct": 0,
- "rebatePct": 0,
- "clubName": "string",
- "isPublished": true,
- "assignToAll": true,
- "userIds": [
- "string"
]
}Idempotent. Returns the list's existing publicSlug, or mints a unique one from the agent's display name so the Share button in the Club List works without a trip to Agent Tools.
| listId required | integer |
| listId required | integer |
| providerId required | string |
| clubId required | string |
| customDisplayName | string |
| customPlayerClubId | string |
| listVisible | boolean |
| publicVisible | boolean |
| sortOrder | integer |
| isPrivate | boolean Manual (agent-added) items only. True keeps the club out of the public lobby once we scan it — visible only to this agent and their players. Turning it on is refused with 409 if we already track the club publicly. |
{- "customDisplayName": "string",
- "customPlayerClubId": "string",
- "listVisible": true,
- "publicVisible": true,
- "sortOrder": 0,
- "isPrivate": true
}| listId required | integer |
| mode required | string Enum: "changes" "sync" |
| added | Array of arrays |
| removed | Array of arrays |
{- "mode": "changes",
- "added": [ ],
- "removed": [ ]
}| listId | integer Optional source club list |
| app required | string Platform / provider (may be one we don't scan yet) |
| clubName required | string |
| unionName | string |
| clubId required | string |
| playerClubId | string The club id the agent hands to players |
| refId | string |
| region | string |
| currency | string |
| games | Array of strings |
| dealPct | number |
| rebatePct | number |
| stakesUrl | string |
| rakeStructure | string |
| rules | string |
| note | string |
{- "listId": 0,
- "app": "string",
- "clubName": "string",
- "unionName": "string",
- "clubId": "string",
- "playerClubId": "string",
- "refId": "string",
- "region": "string",
- "currency": "string",
- "games": [
- "string"
], - "dealPct": 0,
- "rebatePct": 0,
- "stakesUrl": "string",
- "rakeStructure": "string",
- "rules": "string",
- "note": "string"
}Powers the lobby's club-info panel. A player following two agents can be offered the same club by both on different rakeback, so this returns one entry per agent rather than resolving a winner — picking one for them is the Directory's job, not the lobby's.
Retrieves a paginated list of all poker clubs with optional sorting and filtering
| sortBy | string Enum: "clubId" "clubName" "providerId" Column name to sort by |
| sortOrder | string Default: "asc" Enum: "asc" "desc" Sort order (ascending or descending) |
| q | string Keyword to search for in club names or IDs |
| providerId | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Filter clubs by provider ID |
| page | integer >= 1 Default: 1 Page number (1-based) |
| limit | integer [ 1 .. 5000 ] Default: 50 Number of items per page (max 5000) |
| debug | string When set (e.g. 1, true, or empty), each club includes |
{- "data": [
- {
- "clubId": "string",
- "clubName": "string",
- "providerId": "PokerBros",
- "originalRecord": { },
- "lastActivity": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "page": 0,
- "limit": 0,
- "totalPages": 0
}
}Uploads or replaces a club in the database using INSERT ... ON DUPLICATE KEY UPDATE. Updates the provider's lastParsed timestamp.
| clubId required | string Unique identifier for the club (scoped to provider) |
| clubName required | string Name of the club |
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Provider this club belongs to |
| originalRecord | object or null Original JSON payload from the provider |
{- "clubId": "string",
- "clubName": "string",
- "providerId": "PokerBros",
- "originalRecord": { }
}{- "clubId": "string",
- "clubName": "string",
- "providerId": "PokerBros",
- "originalRecord": { }
}Writes a manual union override for the club. Manual overrides are never touched by the Google Sheet sync, so this is the way to fix a club the sheet doesn't list yet. An empty or null unionName removes the override, returning the club to Privat and to sheet control.
| clubId required | string |
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" |
| unionName | string or null |
{- "unionName": "string"
}Deletes a club by ID and provider ID
| clubId required | string Club ID to delete |
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Provider ID of the club |
{- "message": "string"
}Checks if the provider's lastParsed timestamp is within the stale window (30 minutes, or 90 for PokerBros)
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Provider ID to check |
{- "healthy": true
}Returns tracked bot servers (hostnames) with lastParsed and healthy flag. A server is healthy if lastParsed is within 30 minutes (90 for PokerBros). Optional query serverName filters to one host (exact match). When both providerId and serverName are set, the response also includes root-level healthy and lastParsed for that target (easy for monitors).
| providerId | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Filter by provider (optional) |
| serverName | string Exact hostname filter (optional). Combine with providerId to query one machine. |
{- "data": [
- {
- "providerId": "string",
- "serverName": "string",
- "lastParsed": "2019-08-24T14:15:22Z",
- "healthy": true
}
], - "healthy": true,
- "lastParsed": "2019-08-24T14:15:22Z"
}Returns tracked bot accounts with lastParsed and healthy flag. Same stale window as servers. When both providerId and accountName are set, the response also includes root-level healthy and lastParsed.
| providerId | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Filter by provider (optional) |
| accountName | string Exact account name filter (optional). Combine with providerId to query one account. |
| emailMode | string Enum: "instant" "smart" "digest" |
| digestWindowMinutes | integer |
| dailyEmailCap | integer |
| quietHoursStart | integer or null |
| quietHoursEnd | integer or null |
| timezone | string or null |
{- "emailMode": "instant",
- "digestWindowMinutes": 0,
- "dailyEmailCap": 0,
- "quietHoursStart": 0,
- "quietHoursEnd": 0,
- "timezone": "string"
}| clubId required | string |
| tableId required | string |
| notifyStartMinutes | integer |
| notifyRegCloseMinutes | integer |
{- "notifyStartMinutes": 0,
- "notifyRegCloseMinutes": 0
}Retrieves a list of all poker providers with optional sorting and filtering
| sortBy | string Enum: "providerId" "lastParsed" Column name to sort by |
| sortOrder | string Default: "asc" Enum: "asc" "desc" Sort order (ascending or descending) |
| q | string Keyword to search for in provider names |
[- {
- "providerId": "PokerBros",
- "lastParsed": "2019-08-24T14:15:22Z"
}
]Creates a new saved search for the authenticated user
| name required | string Name for the saved search |
| filters required | object Filter criteria |
{- "name": "string",
- "filters": { }
}Updates the name and filters of an existing saved search for the authenticated user
| id required | integer |
| name required | string |
| filters required | object |
| purpose | string |
{- "name": "string",
- "filters": { },
- "purpose": "string"
}Registers or validates device fingerprint; returns X-Session-Token value for API calls.
| fingerprint required | string |
| deviceUuid required | string |
| deviceName | string |
{- "fingerprint": "string",
- "deviceUuid": "string",
- "deviceName": "string"
}| removeDeviceId required | integer |
| fingerprint required | string |
| deviceUuid required | string |
| deviceName | string |
{- "removeDeviceId": 0,
- "fingerprint": "string",
- "deviceUuid": "string",
- "deviceName": "string"
}| priceId required | string Stripe price ID (monthly or yearly, must match server-configured STRIPE_PRICE_* / *_YEARLY) |
| appUrl | string Optional app base URL for success/cancel redirects |
{- "priceId": "string",
- "appUrl": "string"
}{- "url": "string"
}Called after redirect from Checkout; loads session from Stripe and updates DB.
| sessionId required | string |
{- "sessionId": "string"
}| appUrl | string Return URL base (default app.lobbyscanner.com) |
{- "appUrl": "string"
}{- "url": "string"
}Upgrade (more expensive annualized, or switch to yearly billing): immediate switch with proration. Downgrade or switching from yearly back to monthly: scheduled for end of current billing period.
| priceId required | string |
{- "priceId": "string"
}Public endpoint hit by Stripe. Verifies the Stripe-Signature header
against STRIPE_WEBHOOK_SECRET and books affiliate commissions on
paid invoices. Idempotent across retries via a UNIQUE index on
agent_referral_earnings.stripeEventId.
Registers a push token and email for the authenticated user
| pushToken required | string |
| language | string Default: "en" Enum: "en" "de" |
| type | string Default: "Web" Enum: "Web" "Android" "iOS" "Desktop" |
{- "pushToken": "string",
- "language": "en",
- "type": "Web"
}Register or update email address for email notifications
| email required | string |
| language | string Default: "en" Enum: "en" "de" |
{- "email": "string",
- "language": "en"
}Sends the in-app support contact form to the LobbyScanner support inbox.
| category | string |
| subject required | string |
| message required | string |
string |
{- "category": "string",
- "subject": "string",
- "message": "string",
- "email": "string"
}Retrieves a paginated list of all poker tables with optional sorting and filtering
| sortBy | string Enum: "id" "clubId" "tableName" "gameVariant" "gameMode" "blinds" "blindsNum" "buyIn" "prize" "jackpot" "playersSeated" "playersRemaining" "playersRegistered" "tableMaxSeats" "waitingListCount" "startTime" "registrationClosesAt" "status" Column name to sort by |
| sortOrder | string Default: "asc" Enum: "asc" "desc" Sort order (ascending or descending) |
| q | string Keyword to search for in table names, game variants, or game modes |
| clubId | string Filter tables by club ID |
| providerId | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Filter tables by provider ID |
| gameMode | string Enum: "CG" "MTT" "SNG" "TrueSpinGo" Filter tables by game mode |
| gameVariant | string Enum: "NLH" "PLO4" "PLO5" "PLO6" "OFC" "AoF" "Flash" "Mixed" "HiLo" "Joker" "StandUp" "ShortDeck" "NLH31" Filter tables by game variant |
| status | string Filter tables by status (comma-separated). Valid values: Announced, Late Registration, Late Registration Closed |
| page | integer >= 1 Default: 1 Page number (1-based) |
| limit | integer [ 1 .. 100 ] Default: 50 Number of items per page (max 100) |
| debug | string When set (e.g. 1, true, or empty), each table and nested |
{- "data": [
- {
- "id": "string",
- "clubId": "string",
- "providerId": "PokerBros",
- "tableName": "string",
- "gameVariant": "NLH",
- "gameMode": "CG",
- "blinds": "string",
- "blindsNum": 0,
- "buyIn": 0,
- "prize": 0,
- "jackpot": 0,
- "playersSeated": 0,
- "playersRemaining": 0,
- "playersRegistered": 0,
- "tableMaxSeats": 0,
- "waitingListCount": 0,
- "tableTags": [
- "string"
], - "startTime": "2019-08-24T14:15:22Z",
- "registrationClosesAt": "2019-08-24T14:15:22Z",
- "blindLevelDuration": 0,
- "status": "Announced",
- "originalRecord": { },
- "club": {
- "clubId": "string",
- "clubName": "string",
- "providerId": "PokerBros",
- "originalRecord": { }
}
}
], - "pagination": {
- "total": 0,
- "page": 0,
- "limit": 0,
- "totalPages": 0
}
}Uploads or replaces a table in the database using REPLACE INTO. Updates the provider's lastParsed timestamp.
| id required | string Unique identifier for the table |
| clubId required | string ID of the club this table belongs to |
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Provider this table belongs to |
| tableName required | string Name of the table |
| gameVariant required | string Enum: "NLH" "PLO4" "PLO5" "PLO6" "OFC" "AoF" "Flash" "Mixed" "HiLo" "Joker" "StandUp" "ShortDeck" "NLH31" Variant of poker being played |
| gameMode required | string Enum: "CG" "MTT" "SNG" "TrueSpinGo" Game mode/type |
| blinds | string or null Blind structure (e.g., "1/2") |
| blindsNum | integer or null Numeric blind value for sorting purposes |
| buyIn | number or null Buy-in amount |
| prize | number or null Prize pool |
| jackpot | number or null Jackpot amount |
| playersSeated | integer Default: 0 Number of players currently seated |
| playersRemaining | integer Default: 0 Number of players remaining |
| playersRegistered | integer Default: 0 Number of players registered |
| tableMaxSeats | integer Default: 0 Maximum number of seats at the table |
| waitingListCount | integer Default: 0 Number of players on the waiting list |
| tableTags | Array of strings or null Array of table tags/features |
| startTime | string or null <date-time> Table start time |
| registrationClosesAt | string or null <date-time> Registration closing time |
| blindLevelDuration | integer or null Duration of blind levels in seconds |
| status required | string Enum: "Announced" "Late Registration" "Late Registration Closed" Current status of the table |
| originalRecord | object or null Original JSON payload from the provider |
{- "id": "string",
- "clubId": "string",
- "providerId": "PokerBros",
- "tableName": "string",
- "gameVariant": "NLH",
- "gameMode": "CG",
- "blinds": "string",
- "blindsNum": 0,
- "buyIn": 0,
- "prize": 0,
- "jackpot": 0,
- "playersSeated": 0,
- "playersRemaining": 0,
- "playersRegistered": 0,
- "tableMaxSeats": 0,
- "waitingListCount": 0,
- "tableTags": [
- "string"
], - "startTime": "2019-08-24T14:15:22Z",
- "registrationClosesAt": "2019-08-24T14:15:22Z",
- "blindLevelDuration": 0,
- "status": "Announced",
- "originalRecord": { }
}{- "id": "string",
- "clubId": "string",
- "providerId": "PokerBros",
- "tableName": "string",
- "gameVariant": "string",
- "gameMode": "string",
- "status": "string"
}Retrieves a specific table by its Club ID and Table ID
| clubId required | string The ID of the club |
| tableId required | string The unique identifier of the table |
{- "id": "string",
- "clubId": "string",
- "providerId": "PokerBros",
- "tableName": "string",
- "gameVariant": "NLH",
- "gameMode": "CG",
- "blinds": "string",
- "blindsNum": 0,
- "buyIn": 0,
- "prize": 0,
- "jackpot": 0,
- "playersSeated": 0,
- "playersRemaining": 0,
- "playersRegistered": 0,
- "tableMaxSeats": 0,
- "waitingListCount": 0,
- "tableTags": [
- "string"
], - "startTime": "2019-08-24T14:15:22Z",
- "registrationClosesAt": "2019-08-24T14:15:22Z",
- "blindLevelDuration": 0,
- "status": "Announced",
- "originalRecord": { },
- "club": {
- "clubId": "string",
- "clubName": "string",
- "providerId": "PokerBros",
- "originalRecord": { }
}
}Uploads or replaces multiple tables in the database using REPLACE INTO in a batch operation. Updates the provider's lastParsed timestamp.
| id required | string Unique identifier for the table |
| clubId required | string ID of the club this table belongs to |
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Provider this table belongs to |
| tableName required | string Name of the table |
| gameVariant required | string Enum: "NLH" "PLO4" "PLO5" "PLO6" "OFC" "AoF" "Flash" "Mixed" "HiLo" "Joker" "StandUp" "ShortDeck" "NLH31" Variant of poker being played |
| gameMode required | string Enum: "CG" "MTT" "SNG" "TrueSpinGo" Game mode/type |
| blinds | string or null Blind structure (e.g., "1/2") |
| blindsNum | integer or null Numeric blind value for sorting purposes |
| buyIn | number or null Buy-in amount |
| prize | number or null Prize pool |
| jackpot | number or null Jackpot amount |
| playersSeated | integer Default: 0 |
| playersRemaining | integer Default: 0 |
| playersRegistered | integer Default: 0 |
| tableMaxSeats | integer Default: 0 |
| waitingListCount | integer Default: 0 |
| tableTags | Array of strings or null |
| startTime | string or null <date-time> |
| registrationClosesAt | string or null <date-time> |
| blindLevelDuration | integer or null |
| status required | string Enum: "Announced" "Late Registration" "Late Registration Closed" |
| originalRecord | object or null |
[- {
- "id": "string",
- "clubId": "string",
- "providerId": "PokerBros",
- "tableName": "string",
- "gameVariant": "NLH",
- "gameMode": "CG",
- "blinds": "string",
- "blindsNum": 0,
- "buyIn": 0,
- "prize": 0,
- "jackpot": 0,
- "playersSeated": 0,
- "playersRemaining": 0,
- "playersRegistered": 0,
- "tableMaxSeats": 0,
- "waitingListCount": 0,
- "tableTags": [
- "string"
], - "startTime": "2019-08-24T14:15:22Z",
- "registrationClosesAt": "2019-08-24T14:15:22Z",
- "blindLevelDuration": 0,
- "status": "Announced",
- "originalRecord": { }
}
]{- "count": 0,
- "message": "string"
}Soft-deletes a table (isDeleted); the row is kept and excluded from list/detail API responses. Updates the club's lastActivity.
| clubId required | string Club ID the table belongs to |
| id required | string Table ID to delete |
{- "message": "string"
}Soft-deletes tables (isDeleted) for a provider with updatedAt older than the cutoff. Optionally filter by clubId. Affected clubs get lastActivity updated.
| providerId required | string Enum: "PokerBros" "ClubGG" "PPPoker" "XPoker" "SupremaPoker" "QQPK" "PokerBoss" "Revolution" "WPTGlobal" "Pokerrrr2" "KingsHomeGames" Provider to cleanup tables for |
| timestamp required | string <date-time> Cutoff timestamp (ISO 8601). Tables with updatedAt older than this will be soft-deleted. |
| clubId | string Optional club ID to filter cleanup to a specific club |
{- "count": 0,
- "message": "string"
}