Generations API
Generate and retrieve game thumbnails, banners and promotional images using a game name. You do not need to supply a game ID. Include the provider name when you know it to help distinguish similar titles.
Unmatched games stay in the original asynchronous request while Lobby Magic resolves them. Once a match is confirmed and the game is ready, generation continues automatically. You do not need to submit those items again.
Existing integrations using mapped game IDs can continue as before.
Authentication and base URL
Send requests from your server to:
https://api.lobbymagic.comUse your team's API key in every request:
Authorization: Bearer YOUR_API_KEYTeam admins can create or rotate the key on the API documentation page when signed in. Keep it server-side. Rotating a key replaces the previous one, so update every integration that uses it. Requests without a valid key receive HTTP 401. Generation and request records are scoped to your team.
The public API host is separate from the application's internal /api routes.
Quick start: generate by name
1. Submit your games
Each item needs a game name and a preset_id from your team's templates. provider_name is recommended but optional. The template ID below is an example; replace it with one available to your team.
Use matching_mode: "async" for the request-tracking flow shown throughout this guide. Send an Idempotency-Key so you can safely retry the same request if the response is lost.
curl -X POST "https://api.lobbymagic.com/v1/generations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: autumn-campaign-001" \
-d '{
"matching_mode": "async",
"request_id": "autumn-campaign",
"generations": [
{
"game_name": "Gold Blitz™ Ultimate",
"provider_name": "Games Global",
"preset_id": 502
}
],
"webhook_url": "https://your-server.com/lobby-magic/callback"
}'webhook_url is optional. Omit it if you will retrieve results by polling.
2. Keep the request reference
HTTP 202 Accepted means the request has been stored. Matching and rendering can still be in progress. An initial response looks like this:
{
"source": "api",
"generation_request_id": "11111111-1111-4111-8111-111111111111",
"batch_id": 9300,
"matching_status": "matching",
"status_url": "/v1/generation-requests/11111111-1111-4111-8111-111111111111",
"request_id": "autumn-campaign",
"generations": [
{
"item_index": 0,
"preset_id": 502,
"matching_status": "pending"
}
]
}Store generation_request_id, status_url, batch_id and your original item order. A generation_id appears only after a game is matched and accepted for generation. Its absence during matching or review is expected.
Examples use illustrative IDs and omit some optional or null fields. Handle both omitted and null optional values.
3. Follow the original request
Poll the returned status_url under the API base URL, using the same team's API key:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.lobbymagic.com/v1/generation-requests/11111111-1111-4111-8111-111111111111"Inspect every item. Matched games can proceed while other games wait for review. Keep polling the same request while unmatched games are being resolved; do not submit replacement requests.
4. Retrieve the asset
Once an item has a generation_id, retrieve its generation detail or use its completion webhook:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.lobbymagic.com/v1/generations/51700"Use the returned asset URL when status is complete. Request-status polling shows rendering progress but does not return the final URL. Continue checking the original request for items that have not yet received a generation ID, even if you use webhooks for completed assets.
Identifying games
Generation requests, match-only checks and asset lookups accept these identity fields:
| Field | Type | Requirement and meaning |
|---|---|---|
game_name | string | Required when game_id is omitted. Maximum 500 characters. |
provider_name | string | Optional; recommended when known. Maximum 200 characters. |
game_id | string | Optional external game ID from your system. An approved team mapping is checked first. |
Supply a nonblank game_name or game_id. A provider name alone is insufficient. Names use the same matching system as game-list uploads in Lobby Magic.
If an external ID has an approved mapping, that mapping takes precedence even when the submitted name or provider differs. Sending a name does not create or change an external-ID mapping. An unknown external ID needs a game name for name matching.
resolved_game_id and candidate game_id values in matching results identify games in Lobby Magic's catalogue. They are not external IDs. To generate after checking a name, submit that name and provider, or an external ID already mapped for your team.
Existing external-ID mappings can be managed through Lists and ID Sync. Name-based requests do not require an ID Sync setup.
POST /v1/generations
Request one or more assets. Every generation item pairs a game identity with a template. Items are processed independently; an invalid preset or an unresolved game does not prevent other valid items from proceeding.
Request body
| Field | Type | Description |
|---|---|---|
generations | array | Required game/template items. Asynchronous requests accept up to 1,000 items. |
generations[].game_name | string | Required if the item has no game_id. |
generations[].provider_name | string | Optional provider name to help matching. |
generations[].game_id | string | Optional external ID. Existing mapped IDs remain supported. |
generations[].preset_id | integer | Required template ID belonging to your team. |
generations[].output_mode | string | Optional: composite_and_layers (default) or layers_only. Layer modes apply to presets configured for layer exports. |
matching_mode | string | Optional: async or sync. See the mode table below. |
request_id | string | Optional label echoed for correlation. It does not prevent duplicate work. |
webhook_url | string | Optional URL receiving generation completion/failure notifications after a generation exists. |
For asynchronous items eligible for automatic review, external IDs and the request's request_id must each be no more than 200 characters. Keep new integration identifiers within this limit.
Matching modes and response shapes
| Mode | Behaviour |
|---|---|
async | Returns generation_request_id and status_url. Use this for consistent request tracking, automatic review of unmatched games, and idempotent retries, including mapped-ID batches. |
| Omitted, with any name-only item | Uses the asynchronous request response for the whole batch, including any mapped-ID items. |
| Omitted, with external IDs on every item | Keeps the existing synchronous matching response, including requests with both an ID and a fallback name. |
sync | Matches within the HTTP request and returns the existing creation response. Intended for small requests. Unresolved items do not enter automatic review. |
Synchronous here describes matching and acceptance into generation. Rendering still runs asynchronously.
The asynchronous response is shown in the quick start. It does not include the legacy response's trace_id. Use generation_request_id for tracking and support, and item_index to associate results with their zero-based input position. Duplicate names and missing or repeated external IDs are supported; each generation item remains separate work.
Multiple games, including an existing mapped ID
{
"matching_mode": "async",
"generations": [
{ "game_name": "Gold Blitz™ Ultimate", "provider_name": "Games Global", "preset_id": 502 },
{ "game_name": "Starburst", "provider_name": "NetEnt", "preset_id": 502 },
{ "game_id": "your-game-123", "preset_id": 503 }
]
}Existing ID-based integrations
An integration using approved external IDs can keep its current request, generation polling and webhooks:
{
"generations": [
{ "game_id": "your-game-123", "preset_id": 502 }
]
}Its existing HTTP 202 response includes generation IDs directly:
{
"batch_id": 9300,
"generations": [
{
"generation_id": 51700,
"game_id": "your-game-123",
"preset_id": 502,
"status": "pending"
}
],
"trace_id": "33333333-3333-4333-8333-333333333333"
}Synchronous matching can return an individual item with no generation ID and an error when a game cannot be resolved. Check every result. If an unmapped ID has a fallback name, the shared matcher now makes that fallback decision; its result can differ from the earlier matcher.
Adding name-only items or setting matching_mode: "async" changes the creation response. Update your integration to store and poll the generation request before adopting that flow.
Safe retries with Idempotency-Key
For asynchronous generation requests, send the Idempotency-Key header with a stable value of 1–128 characters. Keys are scoped to your team.
- The same key and parsed request body return the original request and its current progress, including after completion.
- Reusing a key with a changed body returns HTTP 409 Conflict. Changes to item order, presets, matching mode,
request_idorwebhook_urlcan change the body. - After a timeout or lost response, retry using the original key and body. Once you have
status_url, use polling to follow progress. - A new key, or a submission without a key, can create new work. Use a new key only when you intend a new request.
request_id is a correlation label, not an idempotency key. This retry guarantee applies to the asynchronous request path. Set matching_mode: "async" explicitly if you need it for mapped-ID-only batches too.
GET /v1/generation-requests/{generation_request_id}
Follow matching, review and generation progress for the original asynchronous request. Returns HTTP 200 OK with the same response shape as asynchronous creation, in the original item order.
Request matching status
matching_status | Meaning | Action |
|---|---|---|
matching | One or more items are matching, being sent for review or being rematched. | Keep polling. Inspect all items for progress or errors. |
waiting_review | No automatic matching remains in progress; at least one item awaits a review decision. | Keep the original request. Other items may already be complete. |
matched | Every item has a generation ID. | Check each item's rendering status; assets may not be ready yet. |
needs_attention | No matching or open review is currently pending, and at least one item was not accepted for generation. | Inspect each result. A blocked review can recover after correction. |
Item matching status
generations[].matching_status | Meaning and next step |
|---|---|
pending | Initial matching or a scheduled retry is pending. Keep polling. |
review_pending | The item is being sent for review. Keep the original request. |
awaiting_review | Waiting for a review decision. Do not resubmit. |
rematching | Another matching attempt has been requested during review. Keep polling. |
review_blocked | A review decision could not be applied. Contact support with the request, item and review references. A corrected decision can resume this item. |
admitted | A generation ID exists. Follow the separate rendering status. |
needs_review | No safe match was selected and the item has not entered automatic review. Correct the input or contact support. |
no_match | No accepted match was found and the item has not entered automatic review. Correct the input or contact support. |
failed | Matching or generation acceptance failed, such as an invalid preset or exhausted matching retries. Inspect error. |
For example, this item has been matched but is still waiting to render:
{
"item_index": 0,
"preset_id": 502,
"generation_id": 51700,
"matching_status": "admitted",
"status": "pending",
"match": {
"status": "matched",
"resolved_game_id": 6315,
"resolved_game_name": "Gold Blitz™ Ultimate",
"effective_provider_id": 6318,
"effective_provider_name": "Games Global",
"staging": false,
"candidates_truncated": false,
"retryable": false,
"candidates": []
}
}The match object records the matching result. Fields such as staging describe that recorded result; use the current rendering status to determine readiness. Fetch final URLs and current rendering error details from GET /v1/generations/{generation_id}.
Which identifier to keep
| Identifier | Purpose |
|---|---|
request_id | Your optional correlation label. |
generation_request_id | The API's UUID for matching, review and request tracking. |
item_index | Zero-based position in the original submitted array. |
batch_id | Batch shared by the generations created from the request. |
generation_id | One generation and its asset or rendering error. |
review.review_id | A review reference for support, when present. |
Unmatched games continue from the same request
Asynchronous items containing a game name are sent to Lobby Magic for review when a completed matching search cannot select a game. Your integration keeps the original request while the team confirms the match or requests the game for preparation.
After a successful decision, a generation is created for the original item. The request, batch, item position, preset, output mode and webhook setting are retained. Other items proceed independently.
An item awaiting a decision can look like this:
{
"item_index": 0,
"preset_id": 502,
"matching_status": "awaiting_review",
"review": {
"review_id": "22222222-2222-4222-8222-222222222222",
"state": "open"
}
}The review object may appear before a review_id is assigned. Its state can be publishing, open, decision_ready, processing, closed or blocked, with an optional diagnostic reason_code. A closed review does not mean an asset is complete. Follow the item's matching and rendering statuses.
If the confirmed game or its production templates are not ready, the generation has status: "queued". It starts automatically when ready, using the same generation ID. You do not need to resend it.
Which requests continue automatically
Automatic review applies to asynchronous generation requests containing a game name. Match-only checks, GET asset lookups, explicit sync requests and unmapped ID-only items do not enter this flow. Previously finished unresolved requests are not automatically reopened.
If an item reports needs_review or no_match without entering review, inspect its diagnostics and contact support or correct its input. Submit only corrected terminal items as a new request with a new idempotency key; avoid resubmitting successful items. For an active or blocked review, retain the original request and use support to resolve it.
An unknown title does not automatically create a catalogue game; that requires a review decision. There is no fixed completion time for matching, review or asset preparation. Back off polling while an item is waiting. Temporary matching-service errors are retried separately and do not mean the game is missing.
POST /v1/games/resolve
Check game identities before requesting generation. Send 1–100 games; no preset is required. Returns HTTP 200 OK with one result per input position.
{
"request_id": "catalogue-check-001",
"games": [
{ "game_name": "Gold Blitz™ Ultimate", "provider_name": "Games Global" },
{ "game_name": "Starburst" },
{ "game_id": "your-game-123" }
]
}An abridged response showing the first result:
{
"trace_id": "33333333-3333-4333-8333-333333333333",
"request_id": "catalogue-check-001",
"games": [
{
"item_index": 0,
"status": "matched",
"resolved_game_id": 6315,
"resolved_game_name": "Gold Blitz™ Ultimate",
"effective_provider_id": 6318,
"effective_provider_name": "Games Global",
"staging": false,
"candidates_truncated": false,
"retryable": false,
"candidates": []
}
]
}Matching fields appear directly on each result here, rather than nested inside match as in generation-request results. The external game_id is included when supplied.
Result status | Meaning |
|---|---|
matched | An identity was accepted. Templates and assets may still be unavailable. |
needs_review | No safe automatic selection was made. Suggestions may help clarify your input; this check does not create a review. |
no_match | No accepted match was found. Check the name/provider or contact support. |
error | Matching could not complete. Inspect reason_code and retryable. |
Inspect each result even when HTTP status is 200. Retry affected items for retryable errors, keeping your own association to the original list: item_index always refers to the array submitted in that particular request.
Matching details may include method, reason_code, matcher_version, provider information and candidates. Each candidate has a canonical game_id, name and provider_name; numerical confidence is optional. candidates_truncated: true means there are more suggestions than returned. Suggestions are not confirmed selections. Diagnostic strings and optional descriptive fields should not drive your integration's primary status handling.
This endpoint creates no generation, review or external-ID mapping. A successful check does not reserve a match; identity and access are checked again when generation is requested.
GET /v1/generations
Retrieve the latest generated assets for a game using its name or an existing mapped external ID. The result contains the most recent asset per preset and animation type. This lookup does not create generations or reviews.
curl -G "https://api.lobbymagic.com/v1/generations" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-urlencode "game_name=Gold Blitz™ Ultimate" \
--data-urlencode "provider_name=Games Global" \
--data-urlencode "preset_id=502"Query parameters
| Parameter | Type | Description |
|---|---|---|
game_name | string | Required if game_id is omitted. Maximum 500 characters. |
provider_name | string | Optional provider name. Maximum 200 characters. |
game_id | string | Optional external game ID. Approved team mappings take precedence. |
preset_id | integer | Optional filter to one preset. |
animation | boolean | Optional: true for animated assets, false for static assets. |
include_candidates | boolean | Optional; defaults to false. Set true for suggestions on an ambiguous lookup. |
request_id | string | Optional correlation label echoed in the response. |
Response
{
"status": "ready",
"reliability": "medium",
"trace_id": "33333333-3333-4333-8333-333333333333",
"match": {
"status": "matched",
"resolved_game_id": 6315,
"resolved_game_name": "Gold Blitz™ Ultimate",
"effective_provider_name": "Games Global",
"candidates_truncated": false,
"retryable": false,
"candidates": []
},
"generations": [
{
"generation_id": 51700,
"asset_version": 1,
"preset_id": 502,
"url": "https://api.lobbymagic.com/v1/assets/51700/...",
"updated_at": "2026-10-31T12:00:00Z",
"animation": false,
"format": "webp",
"scale": 2,
"dimensions": { "width": 300, "height": 300 }
}
]
}A successful name-only lookup also includes a match object describing the selected identity. Do not require it on every lookup response. Approved mappings return reliability: "high"; successful name matching returns "medium"; unresolved lookups return "none".
Lookup status | Meaning and action |
|---|---|
ready | Assets are available. Use generations. |
resolved_no_generations | The game was resolved but has no assets for the lookup. Submit a generation request if needed. |
ambiguous | No safe selection was made among possible matches. Add or correct the provider, request candidates, or submit an asynchronous generation request with the game name for automatic review. |
not_mapped | No accepted game identity was found. Supply a name for an unmapped ID, check the input, or submit an asynchronous generation request with the game name for automatic review. |
These lookup statuses differ from match-only and generation-request statuses. A matching-service failure returns HTTP 503 with a structured detail containing code, retryable and trace_id, rather than a not-found result.
Filtering
Combine preset_id and animation with either form of game identity. For example, to retrieve static assets for a named game, add --data-urlencode "animation=false" to the name-based lookup above. Existing ID-based filters still work:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.lobbymagic.com/v1/generations?game_id=your-game-123&preset_id=502&animation=true"GET /v1/generations/{generation_id}
Retrieve one generation's current rendering status, asset URL and error details. Use this after a generation_id exists.
{
"generation_id": 51700,
"asset_version": 1,
"status": "complete",
"preset_id": 502,
"url": "https://api.lobbymagic.com/v1/assets/51700/...",
"animation": false,
"format": "webp",
"scale": 2,
"dimensions": { "width": 300, "height": 300 },
"created_at": "2026-10-31T11:59:00Z",
"updated_at": "2026-10-31T12:00:00Z"
}Use the returned URL instead of constructing one from an ID. Layer-enabled presets also return output_mode, layers_status and layers. A layers_only result omits the composite URL.
A failed generation includes an error message:
{
"generation_id": 51700,
"status": "failed",
"preset_id": 502,
"error_message": "Generation failed. Contact support with the generation_id for details."
}Rendering statuses
status | Meaning | Action |
|---|---|---|
queued | The game or its production templates are not ready. | Keep the generation; processing resumes automatically when ready. |
pending | The generation has been accepted and is waiting to start. | Poll again later. |
processing | The asset is being composed and rendered. | Wait for the webhook or poll every 10–30 seconds. |
complete | The requested output is ready. | Use url, or layers for a layers-only request. |
failed | Rendering failed. | Inspect error_message before deciding whether to create a new request. |
Rendering status is separate from item matching_status. Matching can fail before a generation ID exists. A request-level status of matched does not guarantee that rendering succeeded.
GET /v1/generations/batch/{batch_id}
Retrieve the status and details of generations already created in a batch. The response includes batch_id, total, counts for queued, pending, processing, complete and failed, and a generations array using the generation-detail contract.
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.lobbymagic.com/v1/generations/batch/9300"Batch polling covers created generations only. It does not include unmatched items that have no generation ID and can return HTTP 404 before the first generation is created. For asynchronous requests, continue using status_url while any items have not been accepted for generation.
Layer exports
Layer exports are available only for presets configured to produce them. Presets without layer exports keep their existing response contract.
output_mode | Result |
|---|---|
composite_and_layers | Default. Returns the composite URL and, for layer-enabled presets, exported layers. |
layers_only | Returns layer images without a composite URL in detail, list, batch or webhook responses. Requires at least one exportable layer to succeed. |
For example:
{
"matching_mode": "async",
"generations": [
{
"game_name": "Gold Blitz™ Ultimate",
"provider_name": "Games Global",
"preset_id": 502,
"output_mode": "layers_only"
}
]
}GET /v1/generations/{generation_id}/layers
Retrieve only a generation's layer-export result. Optionally repeat kind to filter by background, logo, asset or logo_assets:
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.lobbymagic.com/v1/generations/51700/layers?kind=background&kind=logo"{
"generation_id": 51700,
"status": "complete",
"output_mode": "layers_only",
"layers_status": "ready",
"layers": [
{
"layer_export_id": "48123",
"layer_id": "background",
"kind": "background",
"url": "https://api.lobbymagic.com/v1/assets/51700/layers/48123/...",
"format": "webp",
"dimensions": { "width": 300, "height": 300 },
"export_mode": "thumbnail",
"padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 }
}
]
}| Layer field | Meaning |
|---|---|
layer_export_id | Stable identifier for the exported layer image. |
layer_id | Source layer identifier in the preset. |
kind | background, logo, asset or logo_assets. |
url | Signed Lobby Magic API URL for the exported image. |
format | Exported image format, such as webp or png. |
dimensions | Exported width and height in pixels. |
export_mode | original, thumbnail or specific. |
padding | Top, right, bottom and left padding applied to the export. |
layers_status | Meaning and action |
|---|---|
pending | Layer export is not finished. Poll later or wait for the webhook. |
ready | Use the returned layer images. |
failed | Inspect the generation's error details. |
not_configured | The preset snapshot did not enable layer exports. Use a layer-enabled preset. |
Composite and layer URLs use the Lobby Magic API. Raw storage and source-file URLs are not exposed. A layers-only request does not expose its composite URL through the public API.
Your templates
When signed in, the API documentation page lists the preset_id values available to your team. Use these in generation requests and asset filters. Layer output fields appear only for templates configured for layer exports.
Webhooks
Generation webhooks work with name-based requests. The optional webhook_url is retained through matching, review and queued readiness, and receives completion/failure notifications after a generation exists.
There are no matching-complete, awaiting-review or review-decision webhooks in this release. An item that never receives a generation ID does not produce a generation completion/failure notification. Poll request status to detect unresolved or blocked items even when you use webhooks for assets.
Team subscription
Use a team subscription for signed generation.complete, generation.failed and generation.updated events. The per-request webhook_url continues to support complete/failed events but does not receive update events.
curl -X PUT "https://api.lobbymagic.com/v1/webhooks/subscription" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/lobby-magic/webhooks",
"enabled": true,
"events": ["generation.complete", "generation.failed", "generation.updated"]
}'The signing secret is returned only on creation and rotation. Store it securely.
| Endpoint | Purpose |
|---|---|
GET /v1/webhooks/subscription | Read configuration and health. |
POST /v1/webhooks/subscription/test | Enqueue a signed test event. |
POST /v1/webhooks/subscription/rotate-secret | Rotate the signing secret. |
DELETE /v1/webhooks/subscription | Disable the subscription while retaining delivery history. |
GET /v1/webhooks/deliveries | Inspect delivery history. |
POST /v1/webhooks/deliveries/{delivery_id}/retry | Retry a terminal delivery. |
Completion event
{
"schema_version": 1,
"event_id": "f0515e4a-3f3f-4e32-aa36-8823a8a3698a",
"event": "generation.complete",
"occurred_at": "2026-10-31T12:00:00Z",
"generation_id": 51700,
"asset_version": 1,
"layout_revision": 0,
"status": "complete",
"canonical_game_id": 6315,
"external_game_ids": [],
"preset_id": 502,
"url": "https://api.lobbymagic.com/v1/assets/51700/...",
"batch_id": 9300
}Do not require an external game ID to correlate the event. A game requested by name may have no external-ID mapping. Store generation IDs as they become available and associate them with the original request items.
Updated event
{
"schema_version": 1,
"event_id": "0d8b8da1-a1ee-4bd5-a3eb-d67c390d844f",
"event": "generation.updated",
"occurred_at": "2026-10-31T13:00:00Z",
"generation_id": 51700,
"asset_version": 3,
"layout_revision": 4,
"status": "complete",
"canonical_game_id": 6315,
"external_game_ids": [],
"preset_id": 502,
"batch_id": 9300,
"url": "https://api.lobbymagic.com/v1/assets/51700/...",
"format": "webp",
"updated_at": "2026-10-31T13:00:00Z"
}Failed event
{
"event": "generation.failed",
"generation_id": 51700,
"status": "failed",
"error_message": "Generation failed. Contact support with the generation_id for details.",
"batch_id": 9300
}For layer-enabled presets, events also carry the applicable layer output fields. A layers_only completion event includes output_mode, layers_status and layers, with no composite url.
Signature verification and delivery
For signed subscription events, verify the exact raw request body using:
HMAC-SHA256(secret, timestamp + "." + rawBody)Headers are X-Lobby-Magic-Event-Id, X-Lobby-Magic-Timestamp and X-Lobby-Magic-Signature. The signature uses the v1= prefix. Compare digests using a constant-time comparison after validating their format and length.
Subscription delivery is at least once. Deduplicate by event_id, and apply asset updates only when asset_version is newer than your stored version. Network failures and non-2xx responses retry with exponential backoff and jitter for up to 24 hours. Redirects are not followed; bounded Retry-After is honoured. HTTP 410 disables the subscription. Delivery history is retained for 90 days.
If a notification is missing, read the generation detail and check your endpoint logs. Do not create another generation solely because a webhook was missed.
Errors and recovery
| Situation | Result | Action |
|---|---|---|
| Missing or invalid API key | HTTP 401 | Correct authentication. |
| Unknown request, generation or batch, or wrong team's credentials | HTTP 404 | Check the identifier and team. Batch polling may also return 404 before any generation is created. |
| Same asynchronous idempotency key with a different body | HTTP 409 | Retry the original body, or deliberately create a new request with a new key. |
| Missing game identity, invalid mode or field length, or exceeded batch limit | HTTP 422 | Correct the request. |
| Invalid or unavailable preset in an asynchronous item | Item matching_status: "failed" with an error | Correct that item; other items may proceed. |
| Matching unavailable during request acceptance | HTTP 503 may be returned | A rejected request is not evidence of an unmatched game. Retry appropriately using the original key and body. |
| Retryable matching error after acceptance | Background retry; exhausted retries can become an item failure | Continue polling the original request. |
| Waiting for review or readiness | Review status or rendering queued | Keep the original request; back off polling. |
| Review decision could not be applied | review_blocked | Contact support; a corrected decision can continue the original item. |
A synchronous item can also return an error without a generation ID. Inspect every result rather than treating HTTP 202 as proof that every item succeeded.
For support, include generation_request_id and item_index, plus review.review_id when present. For rendering problems include generation_id; for lookup, match-only or legacy creation responses include trace_id. Never include your API key.