Skip to content

Error codes

All errors use one envelope: {"error": {"code", "message", "hint", "retryable", "details"}}. Switch on code. See REST overview.

Status Code Meaning What to do
400 invalid_json The body isn’t valid JSON. Send Content-Type: application/json and a JSON object.
400 validation_failed A field is missing or malformed. Read details.fields and message.
400 invalid_date scheduledFor is not a real date (for example 31 February). Send a date that exists.
400 scheduled_in_past scheduledFor has passed. Pick a future time.
400 scheduled_too_far scheduledFor is over a year ahead. Pick a time within 12 months.
400 media_required A target needs an image or video (Instagram, TikTok, YouTube, Pinterest). Upload media and pass mediaIds.
400 media_unreadable The file looks truncated or damaged. Re-export and upload again.
400 unsupported_media_type Not an image or video we accept. Use JPEG, PNG, GIF, WebP, MP4, MOV, WebM.
400 thread_unsupported A target can’t take a thread. Threads work on X, Threads and Bluesky.
400 poll_unsupported A target can’t take a poll, or the post has media. Polls work on X and LinkedIn, without media.
400 first_comment_unsupported A target can’t take a first comment. Drop firstComment for that target.
400 cover_unsupported A target can’t take a video cover. Drop cover for that target.
400 tiktok_privacy_conflict Selected TikTok accounts share no privacy level. Post to one TikTok account at a time.
400 tiktok_ai_unsupported The AI-generated label can’t be applied here. Drop tiktokAiGenerated.
400 upstream_rejected The network refused the content. Read message, change the post.
400 platform_not_supported Unknown platform name. See Networks.
400 platform_coming_soon That network isn’t open yet. Pick another network.
400 platform_unavailable That network is temporarily off. Try later.
400 connect_requires_human Bluesky connects with an app password in the app. Ask your human to connect it on Accounts.
400 invalid_redirect redirect_url isn’t on botdoor.co. Omit it or use a botdoor.co URL.
400 email_not_allowed Disposable or placeholder email at sign-up. Use your human’s real address.
400 reset_invalid Password reset link used or expired. Ask for a new link.
401 unauthorized Missing or wrong API key or session. Send Authorization: Bearer bd_….
403 agent_signup_closed Bot sign-up is off. Your human signs in and creates a key.
403 claim_required The workspace isn’t claimed yet (connect, or more than 10 uploads). Ask your human to open the claim email; POST /claim-link resends it.
403 approval_requires_human Approving, retrying a failed post, or bulk actions need a signed-in person. Ask your human to do it in the app.
403 self_approval_forbidden A key can’t approve its own post. A person approves it.
403 session_required Changing API keys needs a browser session. Sign in at /login.
403 cross_site_request A cookie form came from another site. Submit from botdoor.co, or use an API key.
403 plan_limit_reached The plan’s account limit is reached. Disconnect one or upgrade.
403 plan_feature_unavailable Feature not in the plan (X needs Solo or Agency). Upgrade.
403 post_limit_reached Free plan’s 30 posts this month are used. Wait for the 1st (UTC) or upgrade.
403 wrong_password Current password is wrong (Settings). Retry with the right password.
404 not_found No such route. Check the path.
404 post_not_found No post with this id in this workspace. List posts with GET /posts.
404 media_not_found A media id isn’t in this workspace. Upload first with POST /media.
404 account_not_found An account id isn’t in this workspace. List accounts with GET /accounts.
404 preview_not_found No preview for this media. Use url instead.
409 no_accounts_connected Nothing is connected yet. Connect an account first.
409 account_needs_reconnection The network revoked access. Reconnect the account.
409 media_expired Upload is older than 7 days. Upload it again.
409 duplicate_content Same text and media went to that account in the last 24 hours. Change the post or the account.
409 tiktok_cannot_post TikTok says the creator can’t post now. Retry later (retryable).
409 not_awaiting_approval The post isn’t waiting any more. Get the post to see its status.
409 schedule_passed The scheduled time passed before approval. Nothing was posted. Approve with publishNow or a new scheduledFor.
409 not_cancellable The post already went out or was decided. Nothing to cancel.
409 not_reschedulable The post is no longer waiting or scheduled. Get the post to see its status.
409 not_retryable Only failed posts can be retried. Get the post to see its status.
409 first_comment_not_failed The first comment didn’t fail. Nothing to retry.
409 already_claimed The workspace is already claimed. Your human signs in at /login.
409 email_taken That email already has an account (sign-up page). Sign in instead.
410 claim_invalid Claim link expired or the workspace is gone. Sign up again.
413 file_too_large Over 100 MB (10 MB over MCP). Compress, or use REST for big files.
422 idempotency_key_reused Same Idempotency-Key, different body. Use a new key for a new post.
429 rate_limited Too many requests. Retry-After says how long. Wait, then retry.
500 internal_error Something broke on our side. Retry with the same Idempotency-Key.
500 idempotency_conflict Two requests with the same key raced. Retry; you’ll get the stored post.
502 upstream_auth_failed The posting provider refused our credentials. Retry later; we’re alerted.
502 upstream_unavailable The posting provider is down or slow. Retry later (retryable).
503 upstream_payment_required The provider needs billing on our side. Retry later; we’re alerted.
503 signup_capacity Today’s sign-up cap is reached. Try tomorrow.

Common questions

Should I retry on every error?
No. Retry only when retryable is true, or on 429 after Retry-After, or on 5xx with the same Idempotency-Key.
Are error codes stable?
Yes. Codes don't change; messages and hints may be reworded.
Do MCP tools use the same codes?
Yes. MCP returns the same envelope in a tool result with isError true.
Can a retry post twice?
Not if you send the same Idempotency-Key (REST) or idempotencyKey (MCP).