White-Label Platform API Docs
Backend APIs and branded management for iGaming platform providers—not an operator installation guide.
Download OpenAPI JSON · Download runnable native/embedded example
One-call amount-locked payment links
From your backend, POST /api/platform/v1/payment-links with a production Bearer credential scoped to payments:write and your merchant IDs. Supply merchantId, title, amountCents, currency (USD or ILS), locked:true and a stable idempotencyKey in the JSON body; externalReference optionally identifies your order. No widget bootstrap is required. The response supplies an immutable reference amount and paymentUrl on your published company’s verified primary HTTPS domain. The active primary company domain also serves these collection endpoints. First creation returns 201; identical replay returns 200 with the same ID/URL; changed data with that key returns 409. Open paymentUrl as a standalone page or embed that same URL on an exact company-approved HTTPS casino origin, using an iframe with allow="payment *". Never expose the credential in the customer browser. GET /api/platform/v1/payment-links/{id}, with payments:read, checks the authoritative status and returns your reference; only succeeded is success. Existing operator activation, prepaid gates, method limits, provider availability and certification stay in force. Pricing, withdrawals, wallet administration and broad company link listing are not granted by collection access. Download payment-links.mjs in example.zip for server-only creation/status helpers.
const response = await fetch(apiBase + "/payment-links", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.SURESETTLES_PLATFORM_TOKEN,
"Content-Type": "application/json"
},
body: JSON.stringify({
merchantId, title: "Casino payment",
amountCents: 30000, currency: "ILS", locked: true,
externalReference: "order-123",
idempotencyKey: "order-123-create-v1"
})
});
// Check response.ok and success before using data.paymentUrl.
// Only the returned paymentUrl goes to the customer browser.Company onboarding and standalone access
Only a main SureSettles administrator creates a white-label at /admin → White-labels; new public white-label registration is closed, while ordinary integrator signup and existing accounts remain supported. Creation has a stable idempotency key and does not assign ownership to the main administrator. The intended customer accepts a purpose-bound owner invitation after explicit confirmation. Configure and publish name, PNG/JPEG logo/favicon and colors; domain ownership, edge routing, HTTPS and current hosting capacity are separate checks. A saved hostname is not a serving URL. After activation, an invited member signs in directly at the verified customer URL using a single-use email link, without a backend or parent window. Pending, suspended, expired and signed-out states retain the published brand. Email delivery, domain attachment, migrations and production activation require separate operational approval.
Merchant-paid white-label pricing and earnings
The verified, unbound human company administrator uses the management Pricing & earnings page, not a machine credential, to change one company-wide rate: 0–5% inclusive, at most two decimal places (integer 0–500 basis points). Management PUT /pricing sends {rateBps,expectedRevision}; a stale revision returns 409 PRICING_REVISION_CONFLICT, so refresh and consciously retry. Financial owners explicitly consent through management PUT /operators/{merchantId}/fee-enrollment with {consent:true}, or the independent owner approves at /platform-delegations. Delegated management permission alone never authorizes a debit. Freeze company, canonical merchant, consent, rate and policy at admission, preserving earlier binding quotes; old, zero-rate, sandbox, unenrolled and pre-activation admissions are not backcharged. The fee is based on authoritative merchant proceeds after actual existing deposit charges, not quoted delivery, player credit or wallet cash. At 2%, $100 eligible proceeds incurs $2. Customer charges, player credit, existing SureSettles/provider/affiliate fees and payment-link surcharge policy stay unchanged. Native, widget and customer payment-link crypto/fiat deposits are covered; withdrawals, refuels, internal transfers and prepaid top-ups are excluded. Automatic collection uses the existing approved hot-wallet fee sweep; external mode allocates only actually funded prepaid value. Reserved sends, ambiguous transfers, missing delivery and negative prepaid debt are outstanding, not collected cash. Confirmed refunds have immutable compensation; earnings are not automatically payable or withdrawable.
Complete portfolio, payment filters and wallet evidence
Use /operator-portfolio rather than assuming the first 200 compatibility operators are the full portfolio. /reports and /earnings accept from/to (UTC, end-exclusive; date-only to includes that day), merchantId, status, currency, network and rail=crypto|fiat; /reports additionally accepts type and bucket=day|week|month. The maximum window is 366 days and 400 buckets. Pages use scope-bound keyset cursors (50 rows); changing company, account, operator, environment or filters requires a fresh cursor. Linked fiat orders and canonical deposits count once and operator-funding links do not count as customer deposits. Deposit activity includes recorded attempts; player-credit totals, verified settlement proceeds and observed wallet cash are distinct. Financial totals explicitly disclose missing evidence and unavailable provider-cost detail. Earnings describe current immutable accrual/collection/reversal state for the same canonical-deposit creation cohort, not current-rate recalculation or freely available platform revenue. Wallets report public addresses, chain/token, settlement mode, observation time and gas/readiness warnings; failed observations are null, not zero. Shared addresses are never summed into a purported company cash balance. No keys, signer controls, new refund authority or treasury withdrawals are exposed.
Native, hosted and embedded delivery
Native: build your own interface at your own application URL and call /api/platform/v1 only from your backend. Hosted: open the branded management app in a first-party window and exchange a management launch for a host-only secure cookie. Embedded: put the same app in an iframe and exchange a launch for an in-memory bearer; no third-party cookies are required. Both branded modes use the approved full-page or compact template. Card and bank methods remain in their admitted provider checkout screens: never collect raw card details or remove required provider disclosures.
Platform → operator → player
The existing white-label organization is the platform. Operators use canonical merchantId UUIDs. externalOperatorId is unique within platform and environment; externalPlayerId is unique within platform and merchant. externalSubject is a platform-namespaced management identity. Reusing IDs in unrelated tenants is safe. Supplying an email never attaches a global user. New operators belong to the platform owner. An independent owner signs in at /platform-delegations, explicitly approves a restricted role and optionally approves authoritative callback delegation; either side can revoke access. Signing keys, treasury withdrawal passwords and approval policies stay with the merchant owner. Existing direct-merchant, integrator and referral contracts remain unchanged; white-label organizations do not accrue affiliate shares.
Backend credentials and scopes
In /platform select the exact white-label account, enable integration, approve exact HTTPS application origins and create a sandbox credential. Secrets are displayed once, stored only as hashes, expire within 1–365 days and can be atomically rotated or revoked. Keep SURESETTLES_PLATFORM_TOKEN only in your backend environment. Send Authorization: Bearer with every native request; browser Origin-bearing requests are rejected. scopes are explicit: operators:read/write, reports:read, players:write, payments:read/write, launches:write, branding:write, domains:write and callbacks:write. Domain and credential administration are canonical-owner portal functions in this release, not native endpoints. Restricted merchantIds cannot provision or change portfolio callbacks. A management session intersects its role with the issuing credential’s scopes; a player token, widget key, hostname or launch cannot authorize native APIs or SureSettles administration.
export SURESETTLES_BASE_URL="https://suresettles.com"
# Set SURESETTLES_PLATFORM_TOKEN securely in your backend environment.
curl "$SURESETTLES_BASE_URL/api/platform/v1/operators" \
-H "Authorization: Bearer $SURESETTLES_PLATFORM_TOKEN"Provision and select operators
POST /operators with the same externalOperatorId and identical configuration returns the original merchant. Different configuration under an already-assigned ID returns EXTERNAL_OPERATOR_CONFLICT; edit with PATCH instead. No email field is accepted. The initial limit is 200 operators per platform, including sandbox/retired records. Sandbox operators have no usable live widget API key. Management and report selections always use the exact merchantId; never infer an operator from a player ID or the first account in a list. Only permitted non-financial configuration is exposed.
curl "$SURESETTLES_BASE_URL/api/platform/v1/operators" \
-H "Authorization: Bearer $SURESETTLES_PLATFORM_TOKEN" \
-H "Content-Type: application/json" \
-d '{"externalOperatorId":"casino-42","name":"Aurora Casino","website":"https://casino.example.com","payoutAddress":""}'Player sessions, native quotes and deposits
Issue /operators/{merchantId}/player-sessions with externalPlayerId, purpose (deposit, withdrawal or both), an approved exact origin and 60–900 seconds expiry. This is a checkout credential, not management access. USD deposit amounts are positive decimal strings with at most two decimal places; crypto inputs allow up to eight. The engine’s amountFrom is preserved as a decimal string. Persist nativeQuoteId and expiry from /quotes, then submit /deposits with externalPlayerId, nativeQuoteId, playerToken and a stable Idempotency-Key. Quote IDs are single-use and bound to player, merchant, platform and environment. Retry the identical business request with the same key; refreshing an expired player token does not change the operation fingerprint. GET /requests/{key} reconciles uncertain work. Unknown failures retain a processing claim instead of replaying provider creation. Only verified engine completion is creditable. For admitted fiat methods, launch the existing branded cashier/provider screen rather than treating crypto /quotes as a fiat API.
Branded player cashier
Production player-session responses return playerId, the public widgetApiKey, opaque token and genuine handshakeProof. Send these through the existing widget’s explicit-origin initialization handshake, never a URL, HTML attribute or persistent browser storage. Set platformBranding: true to load the published platform/operator theme; this opt-in avoids additional requests on ordinary SureSettles widgets. Sandbox native requests never enter the live widget or a provider. Financial/provider/security notices remain visible and provider frames are not restyled. External operator/player identifiers must be mapped in your backend, not guessed from email.
// examples/platform-saas/public/demo.js: retrieve player data from your authenticated backend.
// Never place SURESETTLES_PLATFORM_TOKEN in this file.
SureSettles.init({
apiKey: session.widgetApiKey, playerId: session.playerId,
sessionToken: session.token, handshakeProof: session.handshakeProof,
platformBranding: true
});
// Native fiat: /fiat-quotes → /fiat-orders with Idempotency-Key.
// Show the admitted redirectUrl/provider interface, never raw card inputs.
// Read /fiat-orders/{fiatOrderId}; provider webhooks remain authoritative.Withdrawals, authorization and rollback
Create /withdrawal-quotes using externalPlayerId, positive integer amountCents, playerAddress and playerPreferredCoin. Submit /withdrawals with that nativeQuoteId, a withdrawal-purpose playerToken and a stable Idempotency-Key. Existing supported-asset/address, per-transaction limit, KYT, prepaid fee, certification, manual approval, reserve and ambiguous-broadcast guards remain authoritative. These are player payouts, not treasury withdrawals; there is no platform route to bypass an owner’s treasury password or take over a signer. Your credit-check endpoint must durably return the verification identity, debit exactly once, and preserve cancellation tombstones that prevent late authorization after a timeout. Replay rollback with the same verificationId; never retry using a new identity or restore a balance twice. Pending/manual/recovery statuses are not successful payouts.
Multi-operator callbacks: one financial route
Configure one HTTPS webhookUrl and creditCheckUrl on the platform. Owned production operators inherit them; independent operators use them only after explicit callback consent. This changes the existing authoritative route, not a second credit/debit path. Destination validation blocks credentials, query strings, fragments, private/special IPs and redirects; each outbound connection revalidates and pins public DNS. GET callback-credential returns a derived per-platform/operator verification apiSecret and webhookToken; store both server-side. Verify X-Casino-Id, the signed platform.platformId/merchantId/externalOperatorId/environment attribution, HMAC-SHA256 of the exact raw request body against X-Webhook-Signature (hex) and X-Webhook-Token before parsing or changing balances. Signed externalPlayerId identifies the namespaced player. eventId is stable when a transaction/verification reference exists; credit/debit receipts use that reference plus the phase. Persist one receipt and balance mutation in one database transaction. Acknowledge only after commit. Do not re-credit informational/nonterminal events. Delivery retries use stored signed bytes. Endpoint changes invalidate certification and do not rewrite queued destinations; reconcile outstanding work before changing routing.
Secure sign-in handoff
After authenticating your management user in your platform backend, POST /management-launches with externalSubject, permitted role, optional merchantId, mode, approved sourceOrigin and targetOrigin. targetOrigin must be the canonical origin or an activated assigned customer hostname. Receive {launch,url,expiresAt}; the token lasts 60 seconds and is consumed durably once across replicas. Open only the token-free url. Wait for suresettles.platform.ready from that exact window and exact target origin, then post suresettles.platform.launch containing the token, using the exact target origin. The app validates both source window and approved origin, exchanges the token inside its own audience origin, and returns suresettles.platform.opened or suresettles.platform.expired. Hosted mode uses a host-only Secure HttpOnly SameSite=Strict cookie; embedded mode uses a closure-only bearer with credentials:omit and no storage. On reload, embedded users request a new launch. Hosted cookie mutations require the session CSRF token plus same-origin Origin. Replayed, revoked, cross-purpose, cross-platform or wrong-origin launches fail closed. The recovery screen says to reopen from your platform; it never upgrades the launch into a SureSettles login.
// See the runnable examples/platform-saas/public/demo.js.
const response = await fetch("/demo/management-launch", { method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ mode: "embedded" }) });
const { launch, url } = await response.json();
const targetOrigin = new URL(url).origin;
const frame = document.querySelector("#management iframe");
// Attach your origin/source-checked ready listener BEFORE assigning frame.src.
// Keep launch only in memory, then send it once with the exact targetOrigin.
frame.src = url;Draft, preview, publish and inherit
Use /branding for platform defaults and ?merchantId=UUID for operator overrides. Draft edits never affect published pages. Preview the draft in the portal and publish its exact draftRevision; concurrent edits return DRAFT_CHANGED. An unset operator override inherits published platform defaults. DELETE the operator override to restore inheritance. Approved templates are full-page and compact. appName is bounded plain text. Palette values are six-digit hexadecimal colors; text/background and primaryText/primary must each meet WCAG AA 4.5:1 contrast. Upload a single PNG/JPEG (256 KiB; logo ≤1024×1024, favicon ≤512×512) to /assets; server decoding strips metadata/active polyglot tails and persists re-encoded PNG bytes in shared database storage, not a replica’s local filesystem. The initial asset allowance is 32 per platform. Assets use immutable IDs and safe public caching. No remote fonts, arbitrary CSS, HTML, SVG or executable theme code.
Verified customer subdomains on Railway
The canonical-owner Domain screen supports five reserved/active/suspended customer subdomains per platform. No wildcard, apex migration or same-origin reverse proxy. Register an exact customer-owned hostname to receive _suresettles-verification.<hostname> TXT and its unique expiring challenge value. Publish that exact TXT at your DNS provider and press Verify ownership. Reservations expire after seven days. Operations separately attaches the subdomain to the existing Railway web service, reads Railway’s actual required records and reconciles them through the operations-only adapter. Copy those exact CNAME/TXT records from the screen; do not invent a target. Ownership, provider routing and HTTPS certificate readiness are separate. Activate only after app TXT proof and fresh authoritative routing=ready/https=ready. CNAME resolution alone never activates. Removal immediately blocks tenant access; operations separately removes the Railway attachment. Renewal checks suspend missing ownership, failed routing/certificates or stale evidence. Actual Railway plan/domain capacity is displayed only when verified recently; unknown does not mean unlimited. The documented default Pro allowance of 20 domains is NOT a confirmed allowance for this workspace. Attachment requires an actual capacity check and separate production approval.
Errors, limits and retries
Success envelope: {success:true,data:...}. Safe failure envelope: {success:false,error:{code,message},requestId}. 400 INVALID_REQUEST/INVALID_ASSET/INVALID_HOSTNAME: correct input; do not retry unchanged. 401 INVALID_CREDENTIAL, SESSION_EXPIRED or LAUNCH_INVALID: refresh/relaunch from your own backend. 403 SCOPE_REQUIRED, ORIGIN_REJECTED, AUDIENCE_REJECTED, CSRF_REJECTED or TENANT_MISMATCH: do not retry with a more privileged player/widget credential. 404 OPERATOR_NOT_FOUND/TRANSACTION_NOT_FOUND: the reference is unavailable to this principal. 409 IDEMPOTENCY_CONFLICT, QUOTE_INVALID, REQUEST_IN_PROGRESS, DRAFT_CHANGED or DOMAIN_NOT_READY: reconcile or request a fresh quote/draft, never re-key an uncertain financial request. 421 CUSTOMER_HOST_INACTIVE: use the canonical launch URL while operations restores the assigned host. 429 RATE_LIMITED: shared 600 requests/platform/minute and 120 requests/operator/minute per environment, across credentials and replicas; honor Retry-After:60. 503 TEMPORARILY_UNAVAILABLE/PAYMENT_NOT_ADMITTED: inspect durable request/transaction status before any financial retry. Reports return ≤50 rows with opaque keyset cursors; amounts/totals are strings to preserve precision. No unlimited-domain or unlimited-operator claim.
Runnable native and embedded example
Download example.zip, unzip it, and open examples/platform-saas/README.md. Exact files: server.mjs (backend-only native calls and launch issuance), receiver.mjs (raw-body HMAC and transactional receipts), sandbox.mjs (explicit local-only callback simulation), schema.sql (isolated customer ledger), public/demo.html and public/demo.js (native deposit/withdrawal exercise and explicit-origin management embedding). Set SURESETTLES_BASE_URL, SURESETTLES_PLATFORM_TOKEN, SURESETTLES_MANAGEMENT_ORIGIN, DEMO_PUBLIC_ORIGIN, DEMO_PORT and DEMO_DATABASE_URL. The server fetches sandbox operator callback-verification credentials server-side; none are sent to the browser. npm install in the example directory installs pg only. Apply schema.sql explicitly to an isolated PostgreSQL database, then npm start. The API sandbox emits no real webhooks; the example simulates authenticated sandbox outcomes through its own receipt handler and refuses production transactions. The demo binds loopback and uses a fixed demo identity; replace its local-demo authentication gate with your own user/session authorization before exposing it publicly. No production secrets are bundled.
Two-platform sandbox exercises
Create two unrelated white-label platforms and two operators under each using reused externalOperatorId values. Issue the same externalPlayerId in all operators and prove different internal player IDs and balances. Create a sandbox deposit, replay its submission and confirm twice: one ledger credit only. Create a sandbox withdrawal, replay it and rollback twice: one debit and one restoration only. Try foreign merchant/status IDs, viewer mutations, forged callback bytes, wrong/replayed/revoked launches, hostile origins and cross-platform domains/assets. Sandbox confirm/rollback endpoints are credential-scoped synthetic proofs; they cannot send blockchain/provider requests and do not certify a live operator callback endpoint. The runnable receiver’s PostgreSQL suite separately proves duplicate debit/credit, cancellation-before-authorization and late-authorization rejection. Complete the established real endpoint certification before production admission.
Go-live and release checklist
1. Select the exact platform; approve HTTPS customer origins and narrow production scopes. 2. Configure and verify one authoritative callback/debit/rollback route per operator; pass existing financial certification and owner wallet/signer readiness. 3. Verify same-ID isolation, idempotent requests, manual approval and timeout recovery in sandbox. 4. Publish validated branding and check mobile/focus/loading/error/recovery states in both templates. 5. Verify actual Railway plan, occupied domain count and remaining allowance; obtain separate approval for each provider attachment/DNS/certificate operation. 6. Run the release validation gate, inspect the committed migration journal and exact task-branch revision, back up the intended database and obtain approval before applying additive migrations. 7. Verify that exact revision after an approved release. GitHub main pushes trigger production services; task checkpoints are mirrored only to a dedicated task branch. No SDK/package release, shared Neon migration or production deployment is part of development. The release handoff documents configuration, capacity, migration, domain activation/deactivation and rollback.
Implemented native endpoints
GET /api/platform/v1/session— Read this credential’s platform identity, environment and effective permissions. Never a SureSettles user login. (authenticated)POST /api/platform/v1/payment-links— Create an amount-locked, company-branded link for an authorized operator. Production backend only; no pricing or wallet-administration permission needed. Retry the identical body and idempotencyKey after an uncertain response. (payments:write)GET /api/platform/v1/payment-links/{id}— Read the authoritative status of one company-created link within this credential’s current operator access. A browser redirect is not proof of payment. (payments:read)GET /api/platform/v1/operators— List only this credential’s platform/operator portfolio. (operators:read)POST /api/platform/v1/operators— Idempotently provision a new platform-owned operator using externalOperatorId. No email account linking. (operators:write)GET /api/platform/v1/operators/{merchantId}— Read one canonical merchant’s permitted configuration. (operators:read)PATCH /api/platform/v1/operators/{merchantId}— Edit name, website, payment-method allowlist, enablement and per-transaction limits. No signer or approval-policy controls. (operators:write)POST /api/platform/v1/delegations— Request independent-owner consent. Production only; approval happens on the canonical site. (operators:write)DELETE /api/platform/v1/operators/{merchantId}/delegation— Revoke a delegated relationship without transferring merchant ownership. (operators:write)GET /api/platform/v1/operators/{merchantId}/payment-methods— Discover effective methods. Fiat retains admitted provider checkout and mandatory disclosures. (payments:read)GET /api/platform/v1/operators/{merchantId}/assets— Discover assets admitted by the established payment engine. (payments:read)POST /api/platform/v1/operators/{merchantId}/player-sessions— Issue a separate, purpose-bound opaque player token; production returns a genuine widget handshake proof. (players:write)POST /api/platform/v1/operators/{merchantId}/player-sessions/revoke— Revoke an opaque player token for this operator only. (players:write)POST /api/platform/v1/operators/{merchantId}/quotes— Persist a short-lived, player/operator/environment-bound crypto deposit quote. (payments:read)POST /api/platform/v1/operators/{merchantId}/deposits— Consume a native quote using a player token and Idempotency-Key. Executes existing deposit admission. (payments:write)POST /api/platform/v1/operators/{merchantId}/fiat-quotes— Persist admitted fiat checkout input and estimated credit. No raw card data. (payments:read)POST /api/platform/v1/operators/{merchantId}/fiat-orders— Consume a fiat quote through existing player-purpose, provider, limits, fees and payout admission. (payments:write)GET /api/platform/v1/operators/{merchantId}/fiat-orders/{fiatOrderId}— Read webhook-reconciled fiat status by canonical local UUID and merchant ownership. (payments:read)GET /api/platform/v1/operators/{merchantId}/deposits— Keyset-paginated deposit history; optional externalPlayerId filter. (payments:read)GET /api/platform/v1/operators/{merchantId}/deposits/{transactionId}— Read a transaction owned by this operator, not a provider-wide reference. (payments:read)POST /api/platform/v1/operators/{merchantId}/withdrawal-quotes— Quote an integer-cent player withdrawal to a supported address/asset. (payments:read)POST /api/platform/v1/operators/{merchantId}/withdrawals— Submit through the existing authorization, manual-approval, reserve and rollback engine. Not a merchant-treasury withdrawal. (payments:write)GET /api/platform/v1/operators/{merchantId}/withdrawals— Read paginated player withdrawal history. (payments:read)GET /api/platform/v1/operators/{merchantId}/withdrawals/{transactionId}— Read canonical operator-scoped withdrawal status. (payments:read)GET /api/platform/v1/operators/{merchantId}/requests/{key}— Reconcile a durable idempotency claim. Never re-key an uncertain financial request. (payments:read)GET /api/platform/v1/reports— Portfolio or merchantId-filtered totals and 50-row transaction pages. Monetary totals are decimal strings. (reports:read)GET /api/platform/v1/operator-portfolio— Search the complete authorized portfolio using search and a scope-bound keyset cursor. 50 rows per page; total includes operators beyond the compatibility-list cap. (operators:read)GET /api/platform/v1/wallets— Read-only configured settlement addresses and cached observations, with merchantId/cursor filters. Null/unavailable is not zero; no signer or withdrawal authority. (wallets:read)GET /api/platform/v1/pricing— Merchant markup, revision, history and paged financial enrollments. Unrestricted production company access also returns read-only revenueShareBps and all-time USD fee-share, markup and combined earnings, with recorded collections separate. The fee share defaults to 30% of posted processing fees, never payment volume; only central administration can change it. Restricted and sandbox principals never receive company-wide revenue. Machine credentials cannot change pricing or enroll merchants. (pricing:read)GET /api/platform/v1/earnings— Immutable accrued, funded collected, reserved, outstanding and reversed fees with deposit/collection references. Not a withdrawable balance. Same canonical-deposit date and payment filters as reports. (reports:read)POST /api/platform/v1/management-launches— Issue a 60-second, single-use hosted/embedded management handoff. Resulting permissions are intersected with the credential scopes. (launches:write)POST /api/platform/v1/subjects/revoke— Durably revoke a tenant-namespaced external management subject and its outstanding access. (launches:write)GET /api/platform/v1/branding— Read platform defaults or an operator draft/published configuration via merchantId. (operators:read)PUT /api/platform/v1/branding— Save a contrast-validated draft, without publishing it. (branding:write)POST /api/platform/v1/branding/publish— Compare-and-publish the exact draftRevision previewed by your team. (branding:write)DELETE /api/platform/v1/branding— Remove an operator override using merchantId; platform defaults remain. (branding:write)POST /api/platform/v1/assets— Decode/re-encode bounded PNG/JPEG logo or favicon bytes. No SVG, remote fetch, HTML, CSS or scripts. (branding:write)GET /api/platform/v1/callbacks— Read the single platform webhook and credit-check destinations. (callbacks:write)PUT /api/platform/v1/callbacks— Configure public HTTPS destinations. Changes invalidate financial certification; delegated callbacks require owner consent. (callbacks:write)GET /api/platform/v1/operators/{merchantId}/callback-credential— Backend-only verification secret derived for this platform/operator, never the underlying legacy merchant API secret. (callbacks:write)POST /api/platform/v1/operators/{merchantId}/sandbox/{transactionId}/confirm— Sandbox-only duplicate-safe credit proof; no provider traffic or real funds. (payments:write)POST /api/platform/v1/operators/{merchantId}/sandbox/{transactionId}/rollback— Sandbox-only duplicate-safe rollback of a reserved player debit. (payments:write)