Complete reference for all Developer API endpoints. Every endpoint follows a consistent format for machine parseability.
Base URL: https://your-poker-platform.com/api/v1
Authentication: Unless marked as "Public", all endpoints require HMAC-signed authentication headers. See Authentication.
Registration
POST /developer/register
Register as a new developer partner.
Authentication: Public (no authentication required)
Rate Limit: 5 requests per hour per IP
Required Scopes: None
Prerequisite: Self-registration must be enabled in platform settings.
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Content-Type | string | Yes | application/json |
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| name | string | Yes | 3-100 characters | Partner organization name (must be unique) |
| contactEmail | string | Yes | Valid email | Contact email address |
| websiteUrl | string | No | Valid URL | Partner website |
| description | string | No | Max 500 characters | Description of integration purpose |
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/developer/register \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Gaming",
"contactEmail": "dev@acme.com",
"websiteUrl": "https://acme.com",
"description": "Online gaming platform integration"
}'
Response (201 Created — Auto-Approved):
{
"message": "Partner registration approved. Store your API credentials securely — the secret will not be shown again.",
"partner": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Gaming",
"status": "approved"
},
"apiKey": {
"rawKey": "pk_live_YOUR_KEY_HERE",
"rawSecret": "sk_live_YOUR_SECRET_HERE"
}
}
The auto-approved key gets the platform’s default scopes and rate limit. Default scopes are empty until an admin configures them, so the key may need scopes added before it can call anything.
Response (201 Created — Pending Approval):
{
"message": "Partner registration submitted. An administrator will review your application.",
"partner": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Acme Gaming",
"status": "pending_approval"
}
}
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | A body field failed validation |
| 403 | SELF_REGISTRATION_DISABLED | Self-registration is turned off |
| 409 | NAME_CONFLICT | Partner name already taken |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit exceeded |
GET /developer/status
Check the registration status of a partner by email.
Authentication: Public (no authentication required)
Rate Limit: 3 requests per minute per IP
Required Scopes: None
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | Contact email to look up |
Example Request:
curl "https://your-poker-platform.com/api/v1/developer/status?email=dev@acme.com"
Response (200 OK):
{
"status": "approved"
}
Possible status values: approved, pending, not_found. A suspended partner also returns not_found.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | MISSING_EMAIL | email query parameter is missing |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit exceeded |
Users
POST /developer/users
Provision a new user or retrieve an existing one by external user ID.
Authentication: HMAC-signed
Required Scopes: user:create
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Content-Type | string | Yes | application/json |
| X-API-Key | string | Yes | Your API key |
| X-Signature | string | Yes | HMAC-SHA256 signature |
| X-Timestamp | string | Yes | Unix timestamp in milliseconds |
| X-Request-Id | string | Yes | Unique request ID for deduplication and signature nonce |
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| externalUserId | string | Yes | 1-255 characters | Your platform’s user identifier |
| username | string | No | 3-30 chars, alphanumeric + underscore | Poker username (required if username policy is require) |
| string | No | Valid email | User’s email address | |
| firstName | string | No | Max 100 characters | First name |
| lastName | string | No | Max 100 characters | Last name |
| country | string | No | Max 100 characters | Country |
| avatar | string | No | Valid URL | Avatar image URL |
| metadata | object | No | JSON object | Arbitrary metadata stored with the mapping |
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/developer/users \
-H "Content-Type: application/json" \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID" \
-d '{
"externalUserId": "user_42",
"username": "john_doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe"
}'
Response (201 Created — New User):
{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"externalUserId": "user_42",
"username": "john_doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"balance": "0",
"virtualBalance": "0",
"createdAt": "2026-02-18T12:00:00.000Z"
},
"isNew": true
}
Response (200 OK — Existing User):
Same shape as above, with isNew: false. This endpoint is idempotent — calling it again with the same externalUserId returns the existing user without modification.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | A body field failed validation |
| 400 | MISSING_USERNAME | Policy needs a value that wasn’t sent: username under require, username or email under generate_from_email |
| 409 | EMAIL_CONFLICT | Email already in use by unlinked account |
| 409 | USERNAME_CONFLICT | Requested username already taken |
GET /developer/users/:externalUserId
Retrieve a provisioned user by their external user ID.
Authentication: HMAC-signed
Required Scopes: user:read
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| externalUserId | string | URL-encoded external user ID |
Example Request:
curl https://your-poker-platform.com/api/v1/developer/users/user_42 \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID"
Response (200 OK):
{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"externalUserId": "user_42",
"username": "john_doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"balance": "100",
"virtualBalance": "0",
"createdAt": "2026-02-18T12:00:00.000Z"
}
}
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 404 | USER_NOT_FOUND | No mapping exists for this partner + external user ID |
PUT /developer/users/:externalUserId
Update a provisioned user’s profile fields. Cannot change username or email; other fields in the body are ignored. The response does not include country or avatar.
Authentication: HMAC-signed
Required Scopes: user:create
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| externalUserId | string | URL-encoded external user ID |
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| firstName | string | No | Max 100 characters | First name |
| lastName | string | No | Max 100 characters | Last name |
| country | string | No | Max 100 characters | Country |
| avatar | string | No | Valid URL | Avatar image URL |
Example Request:
curl -X PUT https://your-poker-platform.com/api/v1/developer/users/user_42 \
-H "Content-Type: application/json" \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID" \
-d '{
"firstName": "Jonathan",
"country": "Canada"
}'
Response (200 OK):
Same shape as GET response with updated fields.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 404 | USER_NOT_FOUND | No mapping exists for this partner + external user ID |
Authentication
POST /developer/auth/code
Generate a single-use login code for a user. The code can be exchanged by the user’s browser for a full session.
Authentication: HMAC-signed
Required Scopes: auth:code
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| externalUserId | string | Yes | 1-255 characters | External user ID |
| mode | string | No | cookie or token (default: cookie) | Authentication mode |
| username | string | No | 3-30 chars, alphanumeric + underscore | Username (for auto-provisioning) |
| string | No | Valid email | Email (for auto-provisioning) | |
| firstName | string | No | Max 100 characters | First name (for auto-provisioning) |
| lastName | string | No | Max 100 characters | Last name (for auto-provisioning) |
If the user does not yet have an account, they will be auto-provisioned using the provided fields.
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/developer/auth/code \
-H "Content-Type: application/json" \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID" \
-d '{
"externalUserId": "user_42",
"mode": "cookie",
"email": "john@example.com"
}'
Response (201 Created):
{
"code": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"expiresIn": 60,
"mode": "cookie"
}
The code is a 64-character hex string. It expires in 60 seconds and can only be used once.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | A body field failed validation |
| 400 | MODE_NOT_ALLOWED | Requested mode is disabled in settings |
| 400 | MISSING_USERNAME | Auto-provisioning a new user needs a value that wasn’t sent (see POST /developer/users) |
| 409 | EMAIL_CONFLICT | Auto-provisioning: email already in use by unlinked account |
| 409 | USERNAME_CONFLICT | Auto-provisioning: requested username already taken |
POST /auth/exchange
Exchange a login code for a full authenticated session. This endpoint is called by the user’s browser, not the partner’s backend.
Authentication: Public (the code is the credential)
Feature Toggle: Requires developerApi to be enabled
Rate Limit: 10 requests per minute per IP
Required Scopes: None
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Content-Type | string | Yes | application/json |
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| code | string | Yes | Exactly 64 lowercase hex characters | The login code from POST /developer/auth/code |
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/auth/exchange \
-H "Content-Type: application/json" \
-d '{
"code": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
}'
The response depends on the mode the code was generated with. In both, user is the user’s profile record without credential fields, plus their group; the examples are abridged.
Response (200 OK — Cookie Mode):
Sets access_token and refresh_token as HttpOnly, SameSite=Strict cookies.
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "john_doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"balance": "100",
"virtualBalance": "0"
},
"expiresIn": 900
}
}
Response (200 OK — Token Mode):
No cookies are set. Tokens are returned in the response body.
{
"success": true,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "john_doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"balance": "100",
"virtualBalance": "0"
}
}
}
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | Code is not 64 lowercase hex characters |
| 401 | INVALID_CODE | Code does not exist |
| 401 | CODE_EXPIRED | Code has expired (60-second lifetime) |
| 401 | CODE_ALREADY_USED | Code has already been exchanged |
| 403 | ACCOUNT_BLOCKED | User’s account is blocked |
| 403 | ACCOUNT_FROZEN | User’s account is frozen |
| 403 | AUTHORIZATION_ERROR | developerApi feature toggle is disabled |
| 403 | FEATURE_TIER_RESTRICTED | License tier does not include the Developer API |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit exceeded |
All errors from this endpoint use the nested format: { "success": false, "error": { "code": "...", "message": "..." } }.
Balance
GET /developer/users/:externalUserId/balance
Read a user’s current balance.
Authentication: HMAC-signed
Required Scopes: balance:read
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| externalUserId | string | URL-encoded external user ID |
Example Request:
curl https://your-poker-platform.com/api/v1/developer/users/user_42/balance \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID"
Response (200 OK):
{
"balance": "150",
"virtualBalance": "0",
"tournamentTickets": "0"
}
All values are strings. Trailing zeros are not kept, so 150.00 is returned as "150". tournamentTickets is a count.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 404 | USER_NOT_FOUND | No mapping exists for this partner + external user ID |
POST /developer/users/:externalUserId/balance/credit
Add funds to a user’s balance.
Authentication: HMAC-signed
Required Scopes: balance:write
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| externalUserId | string | URL-encoded external user ID |
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| amount | string | Yes | Positive decimal, max 2 decimal places (^\d+(\.\d{1,2})?$) | Amount to credit |
| currency | string | No | Max 10 characters | Accepted but not used or stored |
| reference | string | No | Max 255 characters | Idempotency key — same reference returns original transaction |
| description | string | No | Max 500 characters | Transaction description (default: Developer API credit) |
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/developer/users/user_42/balance/credit \
-H "Content-Type: application/json" \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID" \
-d '{
"amount": "50.00",
"reference": "purchase_12345",
"description": "Chip purchase from Acme Gaming"
}'
Response (201 Created — New Transaction):
{
"transaction": {
"id": "txn_abc123",
"type": "DEPOSIT",
"amount": "50",
"balanceBefore": "100",
"balanceAfter": "150",
"reference": "purchase_12345",
"description": "Chip purchase from Acme Gaming",
"createdAt": "2026-02-18T12:00:00.000Z"
},
"isNew": true
}
Response (200 OK — Idempotent Match):
Same shape as above with isNew: false. Returned when a transaction with the same reference and partner ID already exists for the same user, amount and operation.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | amount is missing or malformed, or another field is too long |
| 400 | INVALID_AMOUNT | Amount is zero |
| 403 | ACCOUNT_BLOCKED | User’s account is blocked |
| 403 | ACCOUNT_FROZEN | User’s account is frozen |
| 404 | USER_NOT_FOUND | No mapping exists for this partner + external user ID |
| 409 | IDEMPOTENCY_CONFLICT | reference was already used for a different user, amount, or operation |
POST /developer/users/:externalUserId/balance/debit
Remove funds from a user’s balance.
Authentication: HMAC-signed
Required Scopes: balance:write
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| externalUserId | string | URL-encoded external user ID |
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| amount | string | Yes | Positive decimal, max 2 decimal places (^\d+(\.\d{1,2})?$) | Amount to debit |
| currency | string | No | Max 10 characters | Accepted but not used or stored |
| reference | string | No | Max 255 characters | Idempotency key — same reference returns original transaction |
| description | string | No | Max 500 characters | Transaction description (default: Developer API debit) |
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/developer/users/user_42/balance/debit \
-H "Content-Type: application/json" \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID" \
-d '{
"amount": "25.00",
"reference": "cashout_789",
"description": "Cashout to Acme Gaming"
}'
Response (201 Created — New Transaction):
{
"transaction": {
"id": "txn_def456",
"type": "WITHDRAWAL",
"amount": "25",
"balanceBefore": "150",
"balanceAfter": "125",
"reference": "cashout_789",
"description": "Cashout to Acme Gaming",
"createdAt": "2026-02-18T12:00:00.000Z"
},
"isNew": true
}
Response (200 OK — Idempotent Match):
Same shape as above with isNew: false.
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | amount is missing or malformed, or another field is too long |
| 400 | INVALID_AMOUNT | Amount is zero |
| 400 | INSUFFICIENT_BALANCE | User balance is less than the debit amount |
| 403 | ACCOUNT_BLOCKED | User’s account is blocked |
| 403 | ACCOUNT_FROZEN | User’s account is frozen |
| 404 | USER_NOT_FOUND | No mapping exists for this partner + external user ID |
| 409 | IDEMPOTENCY_CONFLICT | reference was already used for a different user, amount, or operation |
Webhooks
POST /developer/webhooks
Subscribe to a webhook event type. One subscription per event type per partner (upserts if subscription already exists).
Authentication: HMAC-signed
Required Scopes: webhooks:manage
Request Body:
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
| eventType | string | Yes | Must be a supported event type | Event type to subscribe to |
| url | string | Yes | Valid URL. In production: HTTPS, no embedded credentials, no local hostnames or private IPs | Endpoint to receive webhook deliveries |
Supported event types: user.created, user.updated, deposit.confirmed, deposit.failed, withdrawal.completed, withdrawal.failed, balance.credited, balance.debited
Example Request:
curl -X POST https://your-poker-platform.com/api/v1/developer/webhooks \
-H "Content-Type: application/json" \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID" \
-d '{
"eventType": "balance.credited",
"url": "https://your-platform.com/webhooks/poker"
}'
Response (201 Created):
{
"subscription": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"partnerId": "6fa459ea-ee8a-3ca4-894e-db77e160355e",
"eventType": "balance.credited",
"url": "https://your-platform.com/webhooks/poker",
"isActive": true,
"createdAt": "2026-02-18T12:00:00.000Z"
}
}
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 400 | VALIDATION_ERROR | eventType is missing, or url is not a valid URL |
| 400 | INVALID_EVENT_TYPE | Event type not in supported list |
| 400 | INVALID_URL | URL breaks one of the rules above |
GET /developer/webhooks
List all webhook subscriptions for this partner.
Authentication: HMAC-signed
Required Scopes: webhooks:manage
Example Request:
curl https://your-poker-platform.com/api/v1/developer/webhooks \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID"
Response (200 OK):
{
"subscriptions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "balance.credited",
"url": "https://your-platform.com/webhooks/poker",
"isActive": true,
"createdAt": "2026-02-18T12:00:00.000Z",
"stats": {
"totalDeliveries": 142,
"failedDeliveries": 3,
"lastDelivery": "2026-02-18T11:55:00.000Z"
}
}
]
}
DELETE /developer/webhooks/:subscriptionId
Delete a webhook subscription.
Authentication: HMAC-signed
Required Scopes: webhooks:manage
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| subscriptionId | string | UUID of the subscription to delete |
Example Request:
curl -X DELETE https://your-poker-platform.com/api/v1/developer/webhooks/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: pk_live_YOUR_KEY_HERE" \
-H "X-Signature: COMPUTED_HMAC_SIGNATURE" \
-H "X-Timestamp: 1708272000000" \
-H "X-Request-Id: UNIQUE_UUID"
Response: 204 No Content
Error Responses:
| Status | Error Code | Condition |
|---|---|---|
| 403 | FORBIDDEN | Subscription belongs to a different partner |
| 404 | SUBSCRIPTION_NOT_FOUND | Subscription not found |
Documentation
These endpoints are public and stay available when the developerApi feature toggle is off.
| Endpoint | Returns |
|---|---|
GET /developer/docs | Documentation home as HTML. Add ?format=json for { title, content, pages } |
GET /developer/docs/:page | A page as HTML or, with ?format=json, JSON. Pages: quickstart, authentication, sso, users, balance, webhooks, errors, security, api-reference |
GET /developer/docs/openapi.yaml | OpenAPI specification as YAML |
GET /developer/docs/openapi.json | OpenAPI specification as JSON |
Common Request Headers
All HMAC-authenticated requests require these headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Content-Type | string | With a body | application/json |
| X-API-Key | string | Yes | Your API key (starts with pk_live_) |
| X-Signature | string | Yes | HMAC-SHA256 of the canonical signing string using your API secret |
| X-Timestamp | string | Yes | Current Unix timestamp in milliseconds |
| X-Request-Id | string | Yes | Unique UUID for request deduplication and signature nonce |
Signature computation:
canonical_path_query = request path as sent, with any query parameters sorted by key, then value, and URL-encoded
signing_string = [
"v1",
HTTP_METHOD_UPPERCASE,
canonical_path_query,
X-Timestamp,
X-Request-Id,
raw_request_body
].join("\n")
signature = HMAC-SHA256(signing_string, api_secret)
X-Signature = hex(signature)
For GET and DELETE requests with no body, use an empty string for the final raw body field, so the signing string ends with a newline. X-Request-Id is still required.
Common Response Format
Successful responses return the requested data directly:
{
"user": { ... },
"isNew": true
}
Most error responses follow this format:
{
"error": "ERROR_CODE",
"message": "Human-readable description"
}
POST /auth/exchange wraps its responses, success or error. Body validation and feature-toggle errors on any endpoint use the same nested error format. See Errors.
{
"success": true,
"data": { ... }
}
{
"success": false,
"error": { "code": "ERROR_CODE", "message": "Human-readable description" }
}
Rate Limits
| Endpoint | Limit | Window | Scope |
|---|---|---|---|
| All authenticated endpoints | Configurable per key (default: 100) | 1 minute | Per API key |
| POST /developer/register | 5 | 1 hour | Per IP |
| GET /developer/status | 3 | 1 minute | Per IP |
| POST /auth/exchange | 10 | 1 minute | Per IP |
Responses to the per-key limit include a Retry-After header with seconds to wait. Every request made with a valid key counts toward it, including rejected ones.
Related Guides
- Quickstart — Get started in 5 minutes
- Authentication — HMAC signing details and code examples
- SSO — Single sign-on integration guide
- Users — User provisioning guide
- Balance — Balance operations guide
- Webhooks — Webhook integration guide
- Errors — Complete error code reference
- Security — Security best practices