ThreadPage
All docs

Errors

Every refusal has a stable code you can branch on.

View as Markdown

On this page
  1. Error shape
  2. Diagnostic ID
  3. How to handle
  4. Errors every call can get
  5. All codes
  6. Next

Error shape

Integration API

JSON
{
  "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 [email protected].

Contact support

How to handle

How to handle
StatusMeansWhat to do
400The request is malformed: bad JSON, content in no supported form, a token in the query string, or lossy_markdown.Fix the request. Sending it unchanged fails again.
401The token is missing, wrong, revoked, replaced or retired, or its term ended.For token_expired, ask the owner to choose Renew. Otherwise ask the owner for a new token.
403The level, the plan or the owner’s settings don’t allow it.Read code. For a level refusal, give the owner details.manage_url.
404Not found within the connection’s scope.Don’t guess other IDs. Ask the owner whether the item is in scope.
409A conflict with the current state.Read code: some need a fresh read, some a confirmation, some the owner.
410A pull feed cursor expired.Continue from details.resync_cursor.
413The content or the body is too large, or the workspace’s storage is full.Split the note, or send a smaller image. For attachment_quota_exceeded, tell the person.
415Not sent as JSON (or, for an image, as multipart/form-data).Fix the Content-Type.
422A parameter or header has an unsupported value, or a write has no Operation-Id.Fix what the message names.
429A rate limit or the monthly Free quota.Wait Retry-After seconds and retry with the same Operation-Id. quota_exhausted has no Retry-After: stop until details.resets_at.
503ThreadPage is busy or the call took too long.Wait Retry-After seconds and retry with the same Operation-Id.

Errors every call can get

Any call with a token can answer these, whatever it does. Each operation lists its own codes under its block.

Errors every call can get
CodeHTTPWhenWhat to doRetryable
authentication_required401No token was sent.Send Authorization: Bearer tp_….No
invalid_token401The 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_expired401, 409The 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
invalid_request400, 422A 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
rate_limited429A 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
timed_out503The 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_busy503ThreadPage is busy.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
CodeHTTPWhenWhat to doRetryable
authentication_required401No token was sent.Send Authorization: Bearer tp_….No
invalid_token401The 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_expired401, 409The 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_required403A 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_required403, 409An 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
CodeHTTPWhenWhat to doRetryable
read_not_allowed403Reading, or subscribing to events, on Add only or Add to Inbox.Tell the person and give them details.manage_url.No
write_not_allowed403, 409Adding on Read only, or receiving requests below Read and add (details.needs and details.manage_url); 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_allowed403Changing 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_allowed403Threads, folders, pin or Done below Edit and organize.Give the person details.manage_url.No
unavailable404Not found within this connection's scope.Don't guess other IDs; ask the person whether the item is in scope.No
not_found404No such request, subscription, delivery, endpoint, reminder or operation for this connection.Check the ID; it may have expired or been deleted.No
connection_unavailable409The connection can't act now: its token is not current, or its state stops it.Tell the owner.No
connection_paused409, 503The 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
CodeHTTPWhenWhat to doRetryable
invalid_request400, 422A 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_json400The body is not a JSON object, or it nests too deep.Send a JSON object.No
invalid_content400Markdown or text the converter can't take, such as too many lines.Fix the content or split it into several notes.No
invalid_document400A document that breaks the RichDocument v4 schema.Fix the document; the formatting guide lists every element.No
invalid_rule400A reminder rule ThreadPage can't take, or a one-time reminder already past.Fix the rule as the reminder routes describe it.No
lossy_markdown400Markdown or text would drop formatting the note holds.Read the note and send its document with your change.No
content_too_large413A 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_content413, 422A 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_type415Not sent as JSON (an image: not multipart/form-data).Fix the Content-Type.No

Conflicts

Errors
CodeHTTPWhenWhat to doRetryable
stale_block409Someone changed the same part of the note since your read.Read the note again and apply your change again.No
reread_required409The 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_changed409A 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_changed409The note changed since the read a version restore is based on.Read the note again, then restore.No
operation_id_reused409The 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_locked409A note written for a request: it never changes.Add a new note instead.No
request_open409The 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_write409A 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_required409Moving 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
declinedMCP onlyThe person did not accept the confirmation question.Don't repeat the call; ask the person.No
reminder_exists409The 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
CodeHTTPWhenWhat to doRetryable
thread_archived409The thread is archived, so it takes no new notes.Unarchive it first, or ask the owner.No
entity_deleted409The item is in Trash.Restore it first, or ask the owner.No
parent_deleted409Its thread or folder is in Trash.Restore the thread or folder first.No
target_deleted409The destination is in Trash.Restore it, or choose another destination.No
folder_cycle409A folder can't move inside itself.Choose another destination.No
folder_name_conflict409A folder next to it already has this name.Choose another name.No

Images and files

Errors
CodeHTTPWhenWhat to doRetryable
image_unavailable409The note names an image this connection may not use there.Upload the image to that thread first.No
invalid_attachment422Not a PNG, JPEG or WebP image within 5 MB, 20 megapixels and 300 frames.Send a supported image.No
attachment_quota_exceeded413The workspace's storage is full.Tell the person.No
attachment_blocked403The operator blocked this file.Tell the person.No
attachment_checksum_mismatch409The stored original does not match its checksum.Tell the person; quote the diagnostic_id to support.No
attachment_unavailable503A 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_unavailable503File storage is unavailable for a moment.Wait Retry-After seconds and send the same request again.Yes
image_busy503Another image is being processed.Wait Retry-After seconds and send the same request again.Yes

Plan and quota

Errors
CodeHTTPWhenWhat to doRetryable
pro_required403It 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_required403It needs the owner's cloud copy: Pro without Sync.Tell the owner to turn on Sync; adding to the Inbox works meanwhile.No
entitlement_required403The owner's Pro ended while the call ran.Tell the owner; adding to the Inbox works on Free.No
quota_exhausted429Free's 3,000 connection notes this month are used.Stop until details.resets_at. There is no Retry-After.No
inbox_full4091,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
CodeHTTPWhenWhat to doRetryable
rate_limited429A 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_limit422The thread, or the person, has as many reminders as they may (details.scope).Tell the person.No
timed_out503The 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_busy503ThreadPage is busy.Wait Retry-After seconds and send the identical request.Yes

Subscriptions

Errors
CodeHTTPWhenWhat to doRetryable
webhooks_not_allowed403The 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_allowed403A 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_endpoint422The webhook URL may not receive deliveries.Use a public https URL.No
subscription_limit409The connection already has 10 webhooks and pull feeds.Delete one first.No
webhook_limit409The account already has 50 live webhooks.Delete one first, or ask the owner.No
subscription_paused409The subscription is paused.Resume it first.No
subscription_expired409The webhook's endpoint answered 410, so it stopped.Create a new subscription.No
paused_by_owner409The owner paused it, so only the owner resumes it.Ask the owner.No
not_retryable409Only the latest failed delivery of an event can be sent again.Retry that delivery instead.No
content_removed409The event's content is no longer kept, so its delivery can't be sent again.Read the note through the API instead.No
delivery_limit409Resuming while the account's deliveries for the day are used.Wait until after midnight UTC.No
cursor_expired410A 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
CodeHTTPWhenWhat to doRetryable
not_receiving403Receiving requests is off for this connection.Ask the owner to switch on Receive requests.No
already_claimed409Another run claimed the request with a different claim_id.Don't start the work.No
not_claimed409A report or result before the request was claimed.Claim it first.No
cancellation_requested409The owner asked to stop.Send status cancelled (or outcome_unknown), or the result if the work is done.No
request_closed409The request has ended: completed, cancelled, failed, expired or with an unknown outcome.Stop; nothing more is accepted.No

Endpoint URLs

Errors
CodeHTTPWhenWhat to doRetryable
invalid_signature401The 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_unavailable401The endpoint can no longer check signatures.Ask the owner to add the endpoint again.No
method_not_allowed405Not sent with POST.Send POST.No
endpoint_paused503The owner paused the endpoint; the event is not kept.Ask the owner to resume it, then send the event again.Yes
missing_field422The event lacks a field the template needs.Send the field, or mark it optional with ? in the template.No
empty_note422The event makes an empty note.Send text or markdown.No

Next