AI-native errors
Errors are designed to be actionable by an automated client. Instead of an opaque failure, you get a structured message that names the field or condition to fix, so an agent can adjust its input and retry without a human in the loop.
There are two layers: errors that reject the request outright, and errors that happen per account during delivery.
Request level errors
If the request itself is invalid (missing field, text too long, a scheduled time in the past), the call fails synchronously with a JSON body:
{ "detail": "scheduled_at must be at least 60 seconds in the future." }
Nothing is enqueued in this case. Fix the input and send it again.
Per account delivery errors
A request can be accepted (202) and still fail for some accounts during
delivery. Those outcomes live in the publish history, one result per account:
{
"account_id": "acc_8f2c1d",
"provider": "x",
"status": "failed",
"platform_post_id": null,
"error_code": "media_unsupported",
"error_message": "X media upload requires a re-connected account with media.write.",
"raw_response": { }
}
error_code is stable and machine friendly; error_message is human readable;
raw_response carries the untouched provider payload for debugging. When some
accounts succeed and others fail, the job status is partial. See
handling partial failures.
HTTP status codes
| Code | Meaning |
|---|---|
200 / 201 / 202 / 204 | Success (202 means accepted for async delivery). |
400 | Validation error or malformed input. |
401 | Missing or invalid API key or JWT. |
404 | Resource not found. |
409 | Conflict (for example canceling a job already in flight). |
413 | Media file too large. |
415 | Unsupported media type. |
422 | Semantically invalid request. |
429 | Rate limited. |
502 | Upstream provider or storage failure. |