Skip to content
Not available yet. Replyz is built and tested, but not deployed: https://api.replyz.io is the planned address and does not answer yet. These pages describe the API as it is built today and may change before launch.

Threads

Conversations: messages of one inbox grouped by their reply headers or, failing that, by subject and participants.

GET /v1/threads/{id}

Auth: API key (Authorization: Bearer rz_live_…)

Returns a conversation and its messages as compact items, oldest first. A thread belongs to one inbox. At most the newest 500 messages are included (truncated is true when there are more; message_count is the total). Does not mark messages as read. Threads of deleted inboxes are not found. Works in every account status.

Problem codes: unauthorized (401), not_found (404).

Name In Type Required Description
id path string yes Thread id (thr_…), from a message’s thread_id. Any other value gets 404 not_found.

The thread.

Content type application/json.

Field Type Required Description
id string yes
inbox_id string yes
subject string or null yes The subject of the oldest message in messages. Untrusted.
message_count integer (1–) yes Number of messages in the thread, counting all of them even when truncated.
last_message_at string or null (date-time) yes When the newest message was received.
truncated boolean yes True when the thread has more than 500 messages; only the newest 500 are in messages.
messages array of CompactMessage (max 500 items) yes Oldest first.
messages[].id string yes
messages[].thread_id string yes
messages[].inbox_id string yes
messages[].from string or null yes The first address in the From header, lowercase. It can be forged unless sender_trust is aligned_pass. Null when there is no usable address or the message could not be parsed.
messages[].to array of string (max 100 items) yes Addresses in the To and Cc headers, lowercase, at most 100. For a message that could not be parsed, the inbox address.
messages[].subject string or null yes The subject without invisible characters, at most 2 KB (UTF-8). Null when empty or missing. Untrusted.
messages[].snippet string (length 0–200) yes The first 200 characters (Unicode code points, so an emoji is never cut in half) of reply_text (or of text when reply_text is empty), with whitespace collapsed. Untrusted.
messages[].received_at string (date-time) yes When Replyz accepted the message.
messages[].sender_trust string: aligned_pass, dkim_pass, unauthenticated yes How far the sender is authenticated. Today every message is unauthenticated: aligned_pass and dkim_pass are planned (docs/features/safety.md). They will be based on Cloudflare’s own authentication results, located by position; ambiguous cases are unauthenticated.

- aligned_pass: Cloudflare reports a DMARC pass for the domain of from. The mail comes from that domain; its content is still untrusted.
• dkim_pass: Cloudflare reports a valid DKIM signature but no DMARC pass. The signature can belong to any domain, so from can still be forged.
• unauthenticated: everything else. from can be forged.

A message that could not be parsed is always unauthenticated.
messages[].injection_risk string: low, medium, high yes Heuristic risk that the content tries to instruct an AI.

- high: instruction-like text hidden from a human reader, Unicode tag characters (invisible text), two or more kinds of instruction-like text, one kind together with hidden content, or instructions in a text/plain part that the HTML does not show.
• medium: one kind of instruction-like text, a hiding signal (hidden_content, zero_width_chars, long_encoded_blob, text_part_differs), or a message that could not be parsed.
• low: none of these. This does not mean the content is safe.
messages[].otp_like boolean yes Heuristic: true when the code finder of POST /v1/messages/{id}/extract finds a likely code in the subject and the new text (reply_text, or text when it is empty). A hint only; get the code itself with extraction.
messages[].has_attachments boolean yes
messages[].returned_before boolean yes True if wait, GET /v1/messages/{id} or POST /v1/messages/{id}/extract had returned this message before this call.
{
"id": "thr_01M6R6JZDERMT2DVG0T8ABTX4J",
"inbox_id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"subject": "Dinner on Friday?",
"message_count": 2,
"last_message_at": "2026-11-06T10:47:40.117Z",
"truncated": false,
"messages": [
{
"id": "msg_01M6R6JZDERMT2DVG0T8ABTX4J",
"thread_id": "thr_01M6R6JZDERMT2DVG0T8ABTX4J",
"inbox_id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"from": "ana@example.com",
"to": [
"atlas-wo7tw5@youreplyz.com"
],
"subject": "Dinner on Friday?",
"snippet": "Hi! Are you free for dinner on Friday at 8? I booked a table at the usual place. The menu is attached. Ana",
"received_at": "2026-11-06T10:31:05.902Z",
"sender_trust": "unauthenticated",
"injection_risk": "low",
"otp_like": false,
"has_attachments": true,
"returned_before": true
},
{
"id": "msg_01M6R7HAANT4D11FHFZPYG0C2V",
"thread_id": "thr_01M6R6JZDERMT2DVG0T8ABTX4J",
"inbox_id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"from": "ana@example.com",
"to": [
"atlas-wo7tw5@youreplyz.com"
],
"subject": "Re: Dinner on Friday?",
"snippet": "Also, can you bring the wine? Thanks!",
"received_at": "2026-11-06T10:47:40.117Z",
"sender_trust": "unauthenticated",
"injection_risk": "low",
"otp_like": false,
"has_attachments": false,
"returned_before": false
}
]
}

unauthorized: the Authorization header is missing, is not Bearer rz_live_…, or holds an unknown or revoked key.

Header Description
WWW-Authenticate Always Bearer realm="replyz".

Problem object (application/problem+json). Codes: unauthorized.

Example: unauthorized: missing or malformed key

{
"type": "https://docs.replyz.io/errors/unauthorized",
"code": "unauthorized",
"status": 401,
"message": "Missing or malformed API key.",
"fix": "Send the header Authorization: Bearer rz_live_… with the api_key from POST /v1/signup.",
"docs": "https://docs.replyz.io/errors/unauthorized.md"
}

not_found: no such thread in this account, or its inbox was deleted.

Problem object (application/problem+json). Codes: not_found.

Example: not_found: thread

{
"type": "https://docs.replyz.io/errors/not_found",
"code": "not_found",
"status": 404,
"message": "Thread not found.",
"fix": "Use a thread_id from a message.",
"docs": "https://docs.replyz.io/errors/not_found.md"
}

internal_error: something failed on Replyz’s side. Retry after a few seconds.

Problem object (application/problem+json). Codes: internal_error.

Example: internal_error

{
"type": "https://docs.replyz.io/errors/internal_error",
"code": "internal_error",
"status": 500,
"message": "Something went wrong on our side.",
"fix": "Retry in a few seconds.",
"docs": "https://docs.replyz.io/errors/internal_error.md"
}