Single API for providers: design, version, compatibility
Full article
1) Why "single API" and what it is
A single API is a specification and a set of endpoints/events through which any content provider (RGS, live studio, jackpot, KYC/AML, affiliates) communicates with the platform according to the same rules:- unified resource model (players, sessions, bets, settlements, bonuses, jackpots, payments), common event contracts and identifiers, security and backward compatibility standards, SDK/tools to speed up integrations.
The goal: to reduce time-to-integrate, reduce errors on "money paths" and provide predictable upgrades.
2) Design principles
1. Domain-first. First, the dictionary and invariants (rate, setting, RG limits), then endpoints.
2. Compatibility by default. Any change is compatible by default; breaking changes strictly by process.
3. Idempotency everywhere. All money commands are repeatable without side effects.
4. Events are source of truth. Operations → events to the bus; analytics listens to the bus, not beats OLTP.
5. Least privilege & zero-trust. Tokens, signatures, segmentation by brand/region.
6. Observability. End-to-end 'trace _ id', understandable error model, p95/p99 metrics.
3) Resource model (simplified)
Player: Platform side player pseudo-ID, geo/currency/RG statuses.
Session: a channel between the provider and the platform ('session _ id', TTL, geo/restrictions).
Bet: bet authorization/debit.
Settlement: Round outcome and win credit.
Bonus/Wager: Bonus/vager balance status.
Jackpot: contributions/triggers/payouts.
Event: unchanging domain events (Kafka/analogues).
Identifiers: 'tenant _ id', 'brand _ id', 'region', 'player _ id', 'session _ id', 'round _ id', 'bet _ id', 'settlement _ id'. All - string, globally unique (UUID/KSUID/Snowflake), are included in logs and events.
4) API contracts: requests, responses, errors
4. 1 Authorization and security
OAuth2 Client Credentials or mTLS + Request Body Signature (HMAC/EdDSA).
Скоупы вида: `bets:write`, `settlements:write`, `sessions:read`, `events:publish`.
Headers are required in each request:- `X-Trace-Id`, `X-Brand-Id`, `X-Region`, `X-Idempotency-Key`.
4. 2 Examples of endpoints
Session creation
POST /v1/sessions
{
"player_id":"p_19f3", "game_id":"studio:slot_forge_02", "currency":"EUR", "locale":"de-DE", "constraints":{"max_bet":5,"rg_flags":["self_exclusion":false]}
}
→ 201
{
"session_id":"s_456", "expires_at":"2025-10-23T19:10:00Z"
}
Rate authorization (hold)
POST /v1/bets/authorize
Headers: X-Idempotency-Key: bet_r_8c12_1
{
"session_id":"s_456", "bet_id":"b_001", "round_id":"r_8c12", "amount":{"amount":2. 00,"currency":"EUR"}
}
→ 200 { "status":"authorized","hold_id":"h_zz1" }
Settlement
POST /v1/bets/settle
Headers: X-Idempotency-Key: settle_r_8c12_1
{
"bet_id":"b_001", "round_id":"r_8c12", "win":{"amount":14. 60,"currency":"EUR"}, "bonus_state":{"in_bonus":true,"freespins_left":7}
}
→ 200 { "status":"credited","settlement_id":"st_77" }
4. 3 Errors (single model)
`code`: машинное имя (`RG_BLOCK`, `LIMIT_EXCEEDED`, `DUPLICATE`, `IDEMPOTENCY_MISMATCH`, `INVALID_STATE`, `AUTH_FAILED`).
'message ': brief for the person.
`retryable`: `true/false`.
'trace _ id ': to search the logs.
Example:
409 CONFLICT
{
"code":"DUPLICATE", "message":"Bet already authorized with a different amount", "retryable":false, "trace_id":"tr_a1b2c3"
}
5) Event bus and circuits
5. 1 Basic topics
5. 2 Event Schema (Avro/JSON Schema)
json
{
"event_id":"uuid", "event_type":"bet. settled", "occurred_at":"2025-10-23T16:21:05Z", "tenant_id":"brand-7", "region":"EU", "player_id":"p_19f3", "trace_id":"tr_a1b2c3", "payload":{
"round_id":"r_8c12", "bet":{"amount":1. 00,"currency":"EUR"}, "win":{"amount":14. 60,"currency":"EUR"}, "in_bonus":true
}, "idempotency_key":"bet_r_8c12_1", "schema_version":"1. 2. 0"
}
Rules: backward-compatible evolution of schemes, registry + contract tests.
6) API version: strategies and rules
6. 1 Where to store the version
Path version: '/v1/... '(just cache/route).
Header version: 'Accept: application/vnd. platform. api+json; version=1. 2`.
Events: 'schema _ version' in the event field + registry.
Practice: path for HTTP, schema_version for events, feature flags for point capabilities.
6. 2 SemVer and change types
PATCH (minor) - reverse docking: new optional fields, new endpoints, new types of events.
MAJOR - breaking: renaming fields, changing semantics, deleting. Allowed only through the new '/vN/' and the depletion of the old.
6. 3 Stable contracts (which cannot be broken)
Names and types of key identification fields ('_ id', 'idempotency _ key').
Monetary model ('amount/currency', accuracy).
Status semantics ('authorized', 'credited', 'forfeited', etc.).
Idempotency: repetition behavior is strictly defined.
7) Compatibility and evolution
7. 1 Add (safe)
New optional fields with defaults.
New events/endpoints without changing existing ones.
Enum extension with fallback in 'unknown'.
7. 2 Changes (risky)
Change the field type (number → line).
optional → required.
Reversal of business logic ('settle' before 'authorize').
→ need a new major version and migration guide.
7. 3 Depreccation
The field/endpoint is marked with'deprecated _ since: 1. 7`, `removed_in: 2. 0`.
Communication: release notes, newsletter, deprecation-headers ('Sunset', 'Deprecation').
Tracing the use of "outdated" paths for proactive partner notifications.
8) Idempotency and consistency
The'X-Idempotency-Key 'header is required for all recording operations.
Semantics: repeat with the same key → the same result (200 with the same body).
Keys are bound to a composition of parameters (for example, 'bet _ id + amount').
Sagas on long processes: 'authorize → commit/lock → settle → credit'; compensation - 'rollback' events.
9) Pagination, filters, sorting
Cursor-based pagination (strictly preferred 'page/limit' for large threads).
Unification: '? cursor =... & limit = 200 & order = asc'.
In the answer: 'next _ cursor', 'has _ more'.
Filters: by time ('occurred _ at _ from/to'), 'tenant _ id', 'game _ id', 'status'.
10) Locales, currencies, data residency
Currency in ISO-4217; accuracy is stored in the scheme ('scale'), calculations - in minor-units (cents).
Locali - BCP 47 ('en-GB', 'pt-BR').
In each request - 'region'; PII and cash transactions do not cross regions.
PII and RLS masking in BI showcases.
11) Observability and limits
Required headings: 'X-Trace-Id', 'X-Provider-Id', correlation with events.
Metrics: p50/p95/p99 latency, error rate (by codes), throughput, queue lag (for events).
Rate limits: per provider / per brand; responses from 'Retry-After'.
WORM audit of critical changes (limits, RTP pools, jackpot formulas).
12) Testing and quality of contracts
Contract tests (Pact/others): provider ↔ platform ↔ event consumers.
Load: "storm" of rates/settlements; goals of p95.
Chaos cases: double-delivery, out-of-order, wallet delays.
Sandbox '/sandbox 'with fictitious money and test' player _ id '.
13) SDK, generators and documentation
OpenAPI/AsyncAPI → SDK generation (TypeScript/Java/Kotlin/Go/Rust).
Code examples for'authorize/settle/rollback ', retrays, and error handling.
Live dock with examples of request/response (curl + JSON), Postman/Insomnia collection.
Changelog with change types and compatibility labels.
14) Migration roadmap (example)
1. v1. 6 → v1. 7 (minor) Added the 'bonus _ state' field to 'settle' (optional).
2. v1. x EOL announcement: for 6 months - letter + 'Deprecation' header + dashboard of use.
3. v2. 0 (major): individual'wallet. commit '(formerly implicit), new field' settlement _ id 'is required.
4. Migration guide: field mapping, timeline, fichflag of "double writing" (parallel publication of'v1 '/' v2' events).
5. Sunset v1: blocking new integrations, extending only for SLA exceptions.
15) Checklists
For platform architects
- There is a single dictionary of domain entities and invariants.
- OpenAPI/AsyncAPI + Schema Registry, semver, process of decrements.
- Idempotency on all write operations; keys are documented.
- Single error model and codes.
- Sagas and outbox/CDC on Money Ways.
- Rate-limits, observability, WORM audit.
- Sandbox and contract tests are available to partners.
- Data residency and RLS/masking.
For the provider
- I always send 'X-Trace-Id' and 'X-Idempotency-Key'.
- I process request repetitions safely; I don't create doubles.
- Processing 'Deprecation/Sunset' and reading Changelog.
- I publish/read events according to the registry schemes; I keep a version.
- I have retry/backoff and deduplication on my side.
16) Anti-patterns (red flags)
Manual edits of balances/settlements in the database.
Publishing events "past" outbox/CDC.
No idempotency → duplicate payments/debits.
Mixing PII/money of different regions without marking 'region'.
"Quiet" breaking changes without a new version and decrement.
Generating SDK manually (drift with real specs).
Big-bang migrations without feature flags and double event writing.
A single API is not only a "collection of endpoints," but an ecosystem contract: a consistent dictionary, stable monetary invariants, versioned events, clear compatibility rules, and manageable decrements. Relying on semantic version, idempotency, outbox/CDC, observability and strong security, the platform connects providers quickly and painlessly, and upgrades turn from risk to routine.