Errors
Error format, status codes, pre-flight issues and what to do about each.
Errors come back as JSON with a stable code, a sentence you can show to a person, and sometimes details:
{ "error": { "code": "VALIDATION", "message": "Some posts need changes before they can be scheduled", "details": { "preflight": [ { "socialAccountId": "acc_th", "issues": [{ "severity": "error", "code": "caption_length", "message": "Caption is 612 characters; the limit is 500." }] } ] } }}| HTTP | code |
Meaning and what to do |
|---|---|---|
| 400 | VALIDATION |
The request needs fixing. details is either field errors ({ "scheduledAt": ["Required"] }) or preflight issues per account. |
| 401 | UNAUTHENTICATED |
Missing, malformed, expired or deleted key or token. OAuth clients refresh the token. |
| 402 | SUBSCRIPTION_EXPIRED, SUBSCRIPTION_GRACE |
The subscription isn’t active. Reading still works; renew in the app to write. |
| 402 | PLAN_LIMIT |
A plan quota is used up: posts a month, accounts or storage. The message says which. |
| 403 | FORBIDDEN |
A read-only credential, an owner-only action, or a workspace that needs the owner’s approval. |
| 404 | NOT_FOUND |
Not in this workspace (or deleted). |
| 409 | CONFLICT |
The post is publishing right now, it changed since you read it (expectedVersion), nothing to retry, or the platform refused an action (the message explains). |
| 429 | RATE_LIMITED |
Too many requests. Wait Retry-After seconds. |
| 500 | INTERNAL |
Something broke on our side. Retry later; tell us if it keeps happening. |
Retry 429, 500 and network errors with backoff. Don’t retry 400, 401, 402, 403 or 404 unchanged.
Pre-flight issues
Section titled “Pre-flight issues”When a post is scheduled, published or validated, each target is checked against its content type’s rules. Errors block scheduling; warnings don’t. Drafts aren’t checked.
| Code | Severity | Means |
|---|---|---|
empty_post |
error | No caption and no media. |
caption_length |
error | Caption over the platform’s limit. |
caption_hashtags, caption_mentions |
error | Too many hashtags or @mentions (Instagram: 30 and 20). |
media_count |
error | Too few or too many files for the format. |
media_kind |
error | Photos where a video is needed, or the reverse. |
media_format |
error | File type not accepted (e.g. PNG for an Instagram photo, which must be JPEG). |
media_size |
error | File too large. |
media_aspect |
error | Width ÷ height outside the allowed range. |
media_duration |
error | Video too short or too long. |
follow_up_length |
error | A follow-up comment is too long. |
youtube_title, youtube_tags, youtube_thumbnail, youtube_angle_brackets |
error | YouTube metadata limits. |
media_aspect_recommended |
warning | Allowed, but not the shape the platform recommends. |
media_dimensions_unknown, media_duration_unknown |
warning | PostFlow couldn’t measure a video; send width, height and durationMs when importing. |
caption_unsupported, first_comment_unsupported, follow_up_unsupported |
warning | The format ignores it (e.g. captions on Stories). |
youtube_long |
warning | Long videos need a phone-verified YouTube channel. |
After scheduling
Section titled “After scheduling”Errors from the platform at publishing time don’t fail your request; they show up on the post’s target with status: "failed",
errorCode and a plain errorMessage, and as a post.failed webhook. See Post statuses.