API Overview
REST API basics, base URL, request format, rate limiting, pagination, and error codes for PlayableLabs
Base URL
All API requests use the following base URL:
https://api.playablelabs.ai/apiRequest Format
The API accepts and returns JSON. Include these headers in every request:
Content-Type: application/json
Authorization: Bearer YOUR_TOKENAuthentication
Every request must include a valid token. PlayableLabs supports two authentication methods:
- JWT session tokens -- Obtained via the web app login flow (NextAuth v5)
- API tokens -- Created in Developers > Tokens for programmatic access
See the Authentication guide for details.
Rate Limiting
The API enforces rate limits to ensure fair usage:
| Tier | Limit | Window | Strategy |
|---|---|---|---|
| Standard | 100 requests | 1 minute | Fixed window |
| Sensitive endpoints | 20 requests | 1 minute | Sliding window |
| Export | 10 requests | 5 minutes | Fixed window |
When rate-limited, the API returns 429 Too Many Requests with these headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1700000000
Retry-After: 30Response Shape
Every successful response wraps the payload in a single data key. Nothing else is added to the body: there is no timestamp, path or method field.
{ "data": { "id": "a1", "name": "Merge Blitz" } }List endpoints add a meta block next to data (see Pagination).
Pagination
List endpoints return paginated results. Use query parameters to control pagination:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://api.playablelabs.ai/api/games?page=1&limit=20&sort=createdAt&order=desc"| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (1-based) |
limit | number | 20 | Items per page (max 100) |
sort | string | createdAt | Field to sort by |
order | string | desc | Sort direction: asc or desc |
Paginated responses return the items in data and the paging details in meta. Some endpoints add counters beside the four standard fields (for example nonDemoCount on the games list). Endpoints addressed by offset (activity and audit logs) still accept offset; meta.page is floor(offset / limit) + 1 and meta.offset echoes the requested offset.
{
"data": [...],
"meta": {
"page": 1,
"limit": 20,
"total": 54,
"totalPages": 3
}
}Multi-Tenant Scoping
All data is scoped by organization. Pass the organizationId as a query parameter or in the request body where required. You can only access data belonging to organizations you are a member of.
Error Codes
The API uses standard HTTP status codes and returns structured error responses:
{
"statusCode": 400,
"error": "Bad Request",
"message": "Name is required",
"requestId": "6f1c0a52-8d0e-4c1b-9a43-0d4f6a1b2c3d"
}requestId is the same value the API returns in the X-Request-ID response header (omitted if the error happens before the request is assigned an id). Quote it when reporting a failed request. Errors may also carry errorCode, code, suggestedName, retryAfter, param or details next to these keys; they are never nested.
| Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body or parameters |
| 401 | AUTHENTICATION_REQUIRED | Missing or invalid token |
| 403 | INSUFFICIENT_PERMISSIONS | Token lacks required scope |
| 404 | RESOURCE_NOT_FOUND | Requested resource does not exist |
| 409 | DUPLICATE_RESOURCE | Resource already exists |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests |
| 500 | INTERNAL_SERVER_ERROR | Unexpected server error |
Key Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/games | List games |
| POST | /api/games | Create a game |
| GET | /api/assets | List assets |
| POST | /api/storage/urls | Get upload URLs |
| POST | /api/export | Trigger an export |
| GET | /api/tokens | List API tokens |
Next Steps
- Authentication -- JWT and API token details
- SDKs and examples -- Client libraries and code samples