Errors and retries
Errors use application/problem+json (RFC 9457). Branch on code. Quote traceId when contacting support.
{ "type": "https://docs.smartcast.media/errors/screen-unavailable", "title": "Some screens cannot take this campaign", "status": 409, "code": "SCREEN_UNAVAILABLE", "detail": "1 of 2 screens is full on 2026-12-03.", "errors": [{ "pointer": "/screenIds/1", "code": "NO_CAPACITY", "date": "2026-12-03" }], "traceId": "7f3c9a1e2b"}| Code | Status | What to do |
|---|---|---|
UNAUTHORIZED |
401 | Get a new token and retry |
FORBIDDEN |
403 | The application lacks the scope. Do not retry |
NOT_FOUND |
404 | Check the id. Other partners’ records also return this |
VALIDATION_FAILED |
422 | Fix the fields listed in errors |
IDEMPOTENCY_KEY_REUSED |
422 | Use a new key for a different request |
INVALID_STATE |
409 | Read the resource, then decide |
NOT_READY_TO_SUBMIT |
409 | Complete what errors lists |
SCREEN_UNAVAILABLE |
409 | Choose other screens or dates |
DUPLICATE_EXTERNAL_REF |
409 | Find the existing record by externalRef |
PRECONDITION_FAILED |
412 | Read again for a new ETag, then retry |
PAYLOAD_TOO_LARGE |
413 | Send a smaller body. Creatives are limited to 100 MB, other bodies to 10 MB |
RATE_LIMITED |
429 | Wait for Retry-After |
INTERNAL_ERROR |
500 | Retry with backoff |
SERVICE_UNAVAILABLE |
503 | The API is briefly unavailable. Wait for Retry-After |
PROVIDER_UNAVAILABLE |
503 | A screen provider could not answer. Wait for Retry-After |
Idempotency
Section titled “Idempotency”POST requests that create something require an Idempotency-Key. Generate one per operation and reuse it when retrying. For 24 hours, the same key and body return the original response instead of creating a duplicate.
Submit, withdraw, cancel and upload-complete are safe to retry without a key: if the resource is already in the target state, you get it back as it stands.
Editing safely
Section titled “Editing safely”Reads of a campaign return an ETag. Send it as If-Match on PATCH. If someone changed the campaign in between, you get 412 rather than overwriting their change.
Rate limits
Section titled “Rate limits”Limits are per application. Responses carry RateLimit-Policy and RateLimit headers. Over the limit you get 429 with Retry-After.
Pagination
Section titled “Pagination”Lists return { "data": [...], "nextCursor": "..." }. Pass nextCursor as cursor until it is null. Treat cursors as opaque.