{
"code": "stale_block",
"message": "Someone changed the same part of the note. Read it again.",
"retryable": false,
"diagnostic_id": "9d2e6c41-3b7a-4f05-8e1d-6a0c2f9b5e73",
"details": {
"content_revision": 8,
"current": [{"type": "paragraph", "content": [{"type": "text", "text": "Ship on Monday."}]}]
}
}
details.current holds the current content of each part that both you and someone else changed.
code: stable and machine-readable. Branch on it, never on message.
message: a short explanation for a person. Its wording can change.
retryable: true when the same request may succeed later. Never a reason to repeat a write with a new Operation-Id.
diagnostic_id: quote it to support.
details: more about some codes, listed with each code below.
429 and 503 also carry a Retry-After header in seconds.
MCP server
A refused tool call answers a result with isError: true and the same codes, as JSON in its text content:
JSON
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"isError": true,
"content": [
{
"type": "text",
"text": "{\"status\": \"rejected\", \"code\": \"stale_block\", \"message\": \"Someone changed the same part of the note. Read it again.\", \"details\": {\"content_revision\": 8, \"current\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"text\", \"text\": \"Ship on Monday.\"}]}]}}"
}
]
}
}
The JSON is {"status": "rejected", "code", "message", "details"}: it has no retryable and no diagnostic_id. A rate limit carries details.retry_after. A scope miss is unavailable on MCP, where the API answers 404.
Endpoint URLs
POST /in/{capability} answers with outcome (accepted, duplicate, ignored, blocked, failed or rejected) and a diagnostic_id, which is also the X-Request-ID header. A refusal adds code and message. See Endpoint URLs.
Diagnostic ID
Every API and endpoint URL error carries a diagnostic_id. Quote it when you contact support at https://thread.page/contact or support@thread.page.
The token is wrong, revoked or replaced, or it was retired: the owner changed their password, or reset or restored the workspace. /mcp also answers it for a token that only answers its connection's requests.
The token's term ended, or it went 90 days without a call: details.reason is term or inactivity, details.expired_at when. An endpoint URL answers 409 with outcome blocked.
Ask the owner to renew it in Settings → Connections; the same token then works again.
Wait Retry-After seconds and send the identical request.
Yes
All codes
Each code has its own anchor, #error-<code>, so you can link to it.
Authentication
Errors
Code
HTTP
When
What to do
Retryable
authentication_required
401
No token was sent.
Send Authorization: Bearer tp_….
No
invalid_token
401
The token is wrong, revoked or replaced, or it was retired: the owner changed their password, or reset or restored the workspace. /mcp also answers it for a token that only answers its connection's requests.
Ask the owner for a new token.
No
token_expired
401, 409
The token's term ended, or it went 90 days without a call: details.reason is term or inactivity, details.expired_at when. An endpoint URL answers 409 with outcome blocked.
Ask the owner to renew it in Settings → Connections; the same token then works again.
No
oauth_required
403
A token on Edit and organize was sent to /mcp, which takes that level only through OAuth; /mcp answers it before any method, the Integration API keeps the level.
Connect the assistant to /mcp and sign in instead of using the token, or ask the owner to lower the token's level in Settings → Connections.
No
reconnect_required
403, 409
An assistant's sign-in ended or was retired (the owner changed their password, or reset or restored the workspace); at an endpoint URL, its connection's token was retired (409 with outcome blocked).
The owner reconnects the assistant, or replaces the custom connection's token.
No
Access
Errors
Code
HTTP
When
What to do
Retryable
read_not_allowed
403
Reading, or subscribing to events, on Add only or Add to Inbox.
Tell the person and give them details.manage_url.
No
write_not_allowed
403, 409
Adding on Read only, adding to a thread on Add to Inbox, a new thread or a reminder on Add only, or receiving requests below Read and add (details.needs and details.manage_url; the message names the level); an assistant whose sign-in holds no write scope; a connection whose access leaves out the Inbox thread. An endpoint URL answers 409 with outcome blocked.
Give the person details.manage_url where there is one; otherwise tell them.
No
edit_not_allowed
403
Changing a note this connection did not add, or a reminder it did not set, on Read and add; any change below Read and add.
Add a new note instead, or give the person details.manage_url.
No
organize_not_allowed
403
Threads, folders, pin or Done below Edit and organize.
Give the person details.manage_url.
No
unavailable
404
Not found within this connection's scope.
Don't guess other IDs; ask the person whether the item is in scope.
No
not_found
404
No such request, subscription, delivery, endpoint, reminder or operation for this connection.
Check the ID; it may have expired or been deleted.
No
connection_unavailable
409
The connection can't act now: its token is not current, or its state stops it.
Tell the owner.
No
connection_paused
409, 503
The owner paused this connection: every call but GET /connection (get_access) and GET /operations/{id} (get_operation) waits for Resume, which keeps its token. An endpoint URL answers 503 and keeps the event's receipt.
Tell the person they can resume it in Settings → Connections (details.manage_url); don't retry until then. An endpoint's sender retries.
No
A level refusal carries details.needs, the level value the call needs, and details.manage_url, where the owner changes only the level.
Content
Errors
Code
HTTP
When
What to do
Retryable
invalid_request
400, 422
A parameter, field or header is missing or has an unsupported value (a write without Operation-Id too), or the token was sent in the query string.
Fix what the message names. Sending it unchanged fails again.
No
invalid_json
400
The body is not a JSON object, or it nests too deep.
Send a JSON object.
No
invalid_content
400
Markdown or text the converter can't take, such as too many lines.
Fix the content or split it into several notes.
No
invalid_document
400
A document that breaks the RichDocument v4 schema.
Fix the document; the formatting guide lists every element.
No
invalid_link
400
A thread description link without href, or with a label that is not text or null.
Send {href, label}.
No
invalid_rule
400
A reminder rule ThreadPage can't take, or a one-time reminder already past.
Fix the rule as the reminder routes describe it.
No
lossy_markdown
400
Markdown or text would drop formatting the note holds.
Read the note and send its document with your change.
No
content_too_large
413
A note over 256 KiB, Markdown over 32 KiB, an image or an MCP file over 5 MB, or a body over 1 MiB.
Split the note, or send a smaller image.
No
unsupported_content
413, 422
A document over 256 KiB, or a file or image with no preview or text.
Split the note; for a file, tell the person.
No
unsupported_media_type
415
Not sent as JSON (an image: not multipart/form-data).
Fix the Content-Type.
No
Conflicts
Errors
Code
HTTP
When
What to do
Retryable
stale_block
409
Someone changed the same part of the note since your read.
Read the note again and apply your change again.
No
reread_required
409
The read your edit is based on is out of date, or belongs to another connection.
Read the note again and apply your change again.
No
context_changed
409
A list cursor is older than an hour, or the owner changed the connection's access since.
Start the list again without a cursor.
No
preview_changed
409
The note changed since the read a version restore is based on.
Read the note again, then restore.
No
operation_id_reused
409
The Operation-Id (MCP: operation_id) was already used with another body.
If you are repeating a lost write, read GET /operations/{id} first. Otherwise use a new ID.
No
request_note_locked
409
A note written for a request: it never changes.
Add a new note instead.
No
request_open
409
The note, or a note in the thread or folder, is with a recipient.
Wait until its request ends, or ask the owner.
No
shared_place_write
409
A thread or folder shared with people where the owner has not allowed this connection to write; a request there ends with it before its run.
Tell the owner: they choose Allow here in ThreadPage.
No
confirmation_required
409
Moving a folder, moving it to Trash or deleting it alone when it holds threads.
Show the counts to the person, then send the same call with details.confirm within 10 minutes.
No
declined
MCP only
The person did not accept the confirmation question.
Don't repeat the call; ask the person.
No
reminder_exists
409
The person already has a reminder there and replace was not set.
Send replace true only when the person asked to change it.
No
State
Errors
Code
HTTP
When
What to do
Retryable
thread_archived
409
The thread is archived, so it takes no new notes.
Unarchive it first, or ask the owner.
No
entity_deleted
409
The item is in Trash.
Restore it first, or ask the owner.
No
parent_deleted
409
Its thread or folder is in Trash.
Restore the thread or folder first.
No
target_deleted
409
The destination is in Trash.
Restore it, or choose another destination.
No
folder_cycle
409
A folder can't move inside itself.
Choose another destination.
No
folder_name_conflict
409
A folder next to it already has this name.
Choose another name.
No
Images and files
Errors
Code
HTTP
When
What to do
Retryable
image_unavailable
409
The note names an image or a file this connection may not use there: another connection's, one it uploaded for another thread or note, or one whose upload did not finish. An upload with note_id is for that note, one without it for a new note, and each stays with the thread it was made for, even after the note moves.
Place one this connection uploaded for the note's thread, with note_id for a note that already exists and without it for a new note. If its upload has not finished, finish it; if the note moved since, upload it again for the thread it is in now.
No
attachment_upload_in_progress
503
The note names a file this connection uploaded that ThreadPage is still checking.
Wait Retry-After seconds and send the same write again.
Yes
invalid_attachment
422
Not a PNG, JPEG or WebP image within 5 MB, 20 megapixels and 300 frames.
Send a supported image.
No
attachment_quota_exceeded
413
The workspace's storage is full.
Tell the person.
No
attachment_blocked
403
The operator blocked this file.
Tell the person.
No
attachment_checksum_mismatch
409
The stored original does not match its checksum.
Tell the person; quote the diagnostic_id to support.
No
attachment_unavailable
503
A file's bytes can't be read now.
Wait Retry-After seconds and send the same request again; if it stays, tell the person.
Yes
attachments_unavailable
503
File storage is unavailable for a moment.
Wait Retry-After seconds and send the same request again.
Yes
image_busy
503
Another image is being processed.
Wait Retry-After seconds and send the same request again.
Yes
Plan and quota
Errors
Code
HTTP
When
What to do
Retryable
pro_required
403
It needs Pro: on Free a connection adds notes only to the Inbox.
Use POST /inbox/notes (MCP: create_note without thread_id), or tell the owner.
No
cloud_required
403
It needs the owner's cloud copy: Pro without Sync.
Tell the owner to turn on Sync; adding to the Inbox works meanwhile.
No
entitlement_required
403
The owner's Pro ended while the call ran.
Tell the owner; adding to the Inbox works on Free.
No
quota_exhausted
429
Free's 3,000 connection notes this month are used.
Stop until details.resets_at. There is no Retry-After.
No
inbox_full
409
1,000 notes or 20 MB wait for the owner's browser to collect them.
Ask the owner to open ThreadPage, then retry later with the same Operation-Id.
No
Limits
Errors
Code
HTTP
When
What to do
Retryable
rate_limited
429
A technical limit or a change limit; details.reason names it and details.scope whose it is.
Wait Retry-After seconds (MCP: details.retry_after) and send the identical request.
Yes
reminders_limit
422
The thread, or the person, has as many reminders as they may (details.scope).
Tell the person.
No
timed_out
503
The call took longer than 10 seconds, or a file's text or preview is still being made.
Wait Retry-After seconds and send the identical request.
Yes
database_busy
503
ThreadPage is busy.
Wait Retry-After seconds and send the identical request.
Yes
Subscriptions
Errors
Code
HTTP
When
What to do
Retryable
webhooks_not_allowed
403
The owner has not turned on Let the script add note-update URLs through the API.
Use a pull feed, or ask the owner.
No
content_not_allowed
403
A token asked for payload_mode content, or for origins other than human, for a subscription or a sample.
Read note text by ID, or ask the owner to add the webhook in ThreadPage.
No
invalid_endpoint
422
The webhook URL may not receive deliveries.
Use a public https URL.
No
subscription_limit
409
The connection already has 10 webhooks and pull feeds.
Delete one first.
No
webhook_limit
409
The account already has 50 live webhooks.
Delete one first, or ask the owner.
No
subscription_paused
409
The subscription is paused.
Resume it first.
No
subscription_expired
409
The webhook's endpoint answered 410, so it stopped.
Create a new subscription.
No
paused_by_owner
409
The owner paused it, so only the owner resumes it.
Ask the owner.
No
not_retryable
409
Only the latest failed delivery of an event can be sent again.
Retry that delivery instead.
No
content_removed
409
The event's content is no longer kept, so its delivery can't be sent again.
Read the note through the API instead.
No
delivery_limit
409
Resuming while the account's deliveries for the day are used.
Wait until after midnight UTC.
No
cursor_expired
410
A pull feed cursor older than 7 days, or from another feed.
Continue from details.resync_cursor and read current notes through the API.
No
Requests
Errors
Code
HTTP
When
What to do
Retryable
not_receiving
403
Receiving requests is off for this connection.
Ask the owner to switch on Receive requests.
No
already_claimed
409
Another run claimed the request with a different claim_id.
Don't start the work.
No
not_claimed
409
A report or result before the request was claimed.
Claim it first.
No
cancellation_requested
409
The owner asked to stop.
Send status cancelled (or outcome_unknown), or the result if the work is done.
No
request_closed
409
The request has ended: completed, cancelled, failed, expired or with an unknown outcome.
Stop; nothing more is accepted.
No
Endpoint URLs
Errors
Code
HTTP
When
What to do
Retryable
invalid_signature
401
The signature or its webhook-id is missing, wrong or older than 5 minutes.
Sign the raw body with the endpoint's secret, with a fresh timestamp.
No
secret_unavailable
401
The endpoint can no longer check signatures.
Ask the owner to add the endpoint again.
No
method_not_allowed
405
Not sent with POST.
Send POST.
No
endpoint_paused
503
The owner paused the endpoint; the event is not kept.
Ask the owner to resume it, then send the event again.
Yes
missing_field
422
The event lacks a field the template needs.
Send the field, or mark it optional with ? in the template.