Errors and retries
What errors look like, what to do about each one, and how to retry safely.
What an error looks like
Every error has the same shape:
{
"error": {
"code": "content_too_long",
"message": "X (Twitter) allows 280 characters — this one is 300",
"field": "channels[1].blocks[0].content",
"requestId": "req_a8b0c1d2-3e4f-5678-9abc-def012345678"
}
}| Field | What to do with it |
|---|---|
code | Use this in your code (in if / switch). It never changes. |
message | A clear sentence you can show to users. The wording may change, so don't check it in code. |
field | Which part of your request is wrong. |
details | When several fields are wrong, all of them are listed here, so you can fix everything at once. |
requestId | Send this to support when you need help. It is also in the x-request-id header. |
New error codes can be added at any time. If you get a code you don't know, handle it by its HTTP status.
Status codes
| Status | What it means | What to do |
|---|---|---|
400 | Your request is wrong (invalid_request, content_too_long, …). | Fix it using field and message. Nothing was saved. |
401 | No key, or the key is wrong, revoked or expired. | Check your key. |
402 | quota_exceeded — your plan's limit for this month is used up. | Do not retry. Wait for the reset, or upgrade. See Limits. |
403 | forbidden — your key is read only. | Use a read and write key. |
404 | Not found. | Check the id. |
409 | Conflict, for example post_publishing, post_changed or request_in_progress. | Wait a moment, then check the post. |
413 | The request or file is too large. | Send a smaller one. |
415 | File type not supported. | See allowed files. |
422 | Same Idempotency-Key used with a different body, or platform_refused: the social network said no. | Use a new key for a new request. For platform_refused, read message; retrying won't help. |
429 | rate_limited — too many requests. | Wait Retry-After seconds, then retry. |
500 | Something broke on our side. | Retry with the same Idempotency-Key. |
502 | platform_error: the social network failed. message has its reason. | Retry later. |
503 | A service we need was not reachable. Nothing was done. | Retry with the same Idempotency-Key. |
Common error codes
| Code | Meaning |
|---|---|
content_too_long | Text is longer than the platform allows. |
content_empty | A block has no text and no media. |
media_required | This platform needs at least one image or video. |
too_many_attachments | Too many files on one block. |
attachment_type_unsupported | This platform does not accept this file type. |
too_many_blocks / threads_not_supported | Too many blocks for a thread, or no threads on this platform. |
title_required / title_not_supported | The platform needs a title, or has none. |
option_required / option_invalid | A platform option is missing or wrong. |
schedule_required / schedule_in_past | scheduledAt is missing, or in the past. |
schedule_too_far | scheduledAt is more than 5 years away. |
channel_not_connected | The channel id is not a connected account in this workspace. |
duplicate_channel | The same channel appears twice in one post. |
post_already_published | This action is not allowed on a published post. |
post_not_published | Revise only works on a post that is already live. |
post_changed | The post changed while you were editing it. Load it again and resend. |
revision_structure_changed | A revise request added or removed channels or blocks. |
edit_not_supported | The platform does not allow this edit. |
comments_not_supported | Comments on this platform can't be read through Bulkit. |
comments_not_granted | Reconnect the account to allow reading and replying to comments. |
comment_not_found | The comment isn't on this post, or was deleted. |
platform_refused | The social network refused, for example comments are turned off on the post. |
webhook_url_invalid | The webhook URL is not a public https:// URL. |
The interactive reference lists every code.
Idempotency: safe retries
Networks fail. If your request times out, you don't know if Bulkit got it. If you just retry, you might publish the same post twice.
To stop this, send an Idempotency-Key header on every request that changes
something (POST, PUT):
curl -X POST "$BULKIT_URL/posts" \
-H "x-api-key: $BULKIT_API_KEY" \
-H "Idempotency-Key: 5f1c7e0a-3b2d-4c8e-9a61-2e7d4b9f0c13" \
...How it works:
- Use a new unique value (a UUID is perfect) for each new action.
- When you retry the same action, send the same key. Bulkit returns the first answer and does not do the work twice.
- Keys are kept for 24 hours, and can be up to 255 characters.
What happens after an error:
4xxerror → nothing was saved. Fix the request and retry — you can keep the same key.5xxerror → part of the work may be done. Retrying with the same key returns the same error. Check what exists withGET /posts/{id}orGET /posts, then continue with a new key.
Getting help
Include the requestId from the error (or the x-request-id response header)
when you contact support. It lets us find your request right away.