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.

Inboxes

Inboxes are the email addresses of the account.

Addresses look like <name>-<6 random characters>@youreplyz.com, all lowercase. <name> is made from the name given to POST /v1/inboxes, or else from the account’s agent_name: accents are removed, letters are lowercased, every run of characters other than a-z and 0-9 becomes a hyphen, leading and trailing hyphens are dropped, and the result is cut to 20 characters. A result shorter than 3 characters becomes agent-<result> (or just agent). Names are refused with name_reserved when they contain a high-risk role word (for example postmaster, abuse, admin, support, noreply, or the phrase no-reply) as the whole name or as one of its hyphen-separated words (support-bot), when they are a broader role word as a whole (for example info, mail, help), or when they contain a brand name or a look-alike of one (brand names of 6 or more letters anywhere, 5 letters at the start of a hyphen-separated word, shorter ones only as a whole hyphen-separated word, so startups is allowed). The 6 random characters are lowercase letters and digits.

An address is never reused. Once an inbox is deleted, its address is retired for good and is never issued again, to anyone, so nobody can receive mail (such as password resets) meant for its former owner.

GET /v1/inboxes

Auth: API key (Authorization: Bearer rz_live_…)

Returns the account’s live inboxes, oldest first. Deleted inboxes are not listed. There is no pagination. Works in every account status.

Problem codes: unauthorized (401).

The live inboxes.

Content type application/json.

Field Type Required Description
inboxes array of Inbox yes Live inboxes, oldest first.
inboxes[].id string yes
inboxes[].address string (email) yes The inbox address, lowercase: <name>-<6 random characters>@youreplyz.com. Permanent, and never issued again after the inbox is deleted.
inboxes[].display_name string or null (length 0–64) yes A label for your own use, or null.
inboxes[].created_at string (date-time) yes
{
"inboxes": [
{
"id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"address": "atlas-wo7tw5@youreplyz.com",
"display_name": null,
"created_at": "2026-11-06T10:00:00.000Z"
}
]
}

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"
}

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"
}

POST /v1/inboxes

Auth: API key (Authorization: Bearer rz_live_…)

Creates an inbox with a new address <name>-<6 random characters>@youreplyz.com (see the Inboxes tag). name (optional) sets the start of the address; without it, the account’s agent_name is used. display_name (optional) is a label for your own use; it does not change the address. The body is optional.

  • Needs an active account (sandbox before its expires_at, or claimed).
  • An account can have at most limits.inboxes live inboxes (1 in sandbox) and can create at most 3 inboxes per day (UTC) in sandbox (10 for a claimed account; claiming is not available yet). The inbox made at signup counts toward the daily limit of its signup day. Deleting an inbox does not give back a creation for that day; a refused request does not use one. The limit holds for requests sent in parallel too.
  • Idempotency: send Idempotency-Key (for example a UUID) to make retries safe. For 24 hours, a request with the same key gets the first successful response again (same status and body) with the header idempotent-replayed: true, and no second inbox is created. The body of the repeated request is not compared with the first one. A request that failed frees its key. While the first request is still running, or if it stopped before it could answer, the same key gets 409 idempotency_in_progress (for up to 24 hours): check GET /v1/inboxes, and use a new key for a new request. The body is validated before the key is looked at.

Problem codes: unauthorized (401), org_not_active (403), payload_too_large (413), invalid_json (400), invalid_request (400), name_reserved (400), not_found (404), idempotency_in_progress (409), inbox_limit (409), inbox_create_limit (429), address_unavailable (503).

Name In Type Required Description
Idempotency-Key header string (length 1–255) no Any unique string of 1 to 255 printable ASCII characters without spaces, for example a UUID. A repeat with the same key within 24 hours returns the first successful response instead of creating another inbox. Keys are per account.

Content type application/json.

Field Type Required Description
name string or null (length 0–64) no Start of the new address (see the Inboxes tag), at most 64 characters. Default: the account’s agent_name. A reserved name is refused with name_reserved.
display_name string or null (length 0–64) no A label for your own use, at most 64 characters (after control characters are removed and the value is trimmed).
{
"name": "travel",
"display_name": "Travel bookings"
}

The inbox was created (or, with idempotent-replayed: true, this is the response to an earlier request with the same Idempotency-Key).

Header Description
idempotent-replayed Present, with the value true, only when this response repeats the first response to an earlier request with the same Idempotency-Key.

Content type application/json.

Field Type Required Description
id string yes
address string (email) yes The inbox address, lowercase: <name>-<6 random characters>@youreplyz.com. Permanent, and never issued again after the inbox is deleted.
display_name string or null (length 0–64) yes A label for your own use, or null.
created_at string (date-time) yes
{
"id": "ibx_01M6R9CGR0FEEBEMY4258G1T72",
"address": "travel-clsqjq@youreplyz.com",
"display_name": "Travel bookings",
"created_at": "2026-11-06T11:20:00.000Z"
}

The request was refused.

  • invalid_json: the body is not a JSON object.
  • invalid_request: name or display_name is not a string or is longer than 64 characters, or Idempotency-Key is not 1 to 255 printable ASCII characters.
  • name_reserved: the name (from name, or else from agent_name) is reserved.

Problem object (application/problem+json). Codes: invalid_json, invalid_request, name_reserved.

Example: invalid_json

{
"type": "https://docs.replyz.io/errors/invalid_json",
"code": "invalid_json",
"status": 400,
"message": "Body must be a JSON object.",
"fix": "Send Content-Type: application/json with a JSON object.",
"docs": "https://docs.replyz.io/errors/invalid_json.md"
}

Example: invalid_request: display_name too long

{
"type": "https://docs.replyz.io/errors/invalid_request",
"code": "invalid_request",
"status": 400,
"message": "\"display_name\" is longer than 64 characters.",
"fix": "Shorten \"display_name\".",
"docs": "https://docs.replyz.io/errors/invalid_request.md"
}

Example: invalid_request: bad Idempotency-Key

{
"type": "https://docs.replyz.io/errors/invalid_request",
"code": "invalid_request",
"status": 400,
"message": "Idempotency-Key must be 1–255 printable ASCII characters.",
"fix": "Use a UUID.",
"docs": "https://docs.replyz.io/errors/invalid_request.md"
}

Example: name_reserved: reserved inbox name

{
"type": "https://docs.replyz.io/errors/name_reserved",
"code": "name_reserved",
"status": 400,
"message": "That name is reserved.",
"fix": "Send a different \"name\" (it becomes the start of the address).",
"docs": "https://docs.replyz.io/errors/name_reserved.md"
}

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"
}

org_not_active: the account is suspended or expired (a sandbox account past its expires_at counts as expired), so it cannot create or change inboxes. The fix depends on the status (for expired, sign up again).

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

Example: org_not_active: the account is suspended

{
"type": "https://docs.replyz.io/errors/org_not_active",
"code": "org_not_active",
"status": 403,
"message": "This account is suspended.",
"fix": "Contact abuse@replyz.io if you think this is a mistake.",
"docs": "https://docs.replyz.io/errors/org_not_active.md"
}

not_found: the account no longer exists.

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

Example: not_found: account

{
"type": "https://docs.replyz.io/errors/not_found",
"code": "not_found",
"status": 404,
"message": "Account not found.",
"fix": "Sign up again with POST /v1/signup.",
"docs": "https://docs.replyz.io/errors/not_found.md"
}
  • inbox_limit: the account already has limits.inboxes live inboxes. The message and the fix depend on the account status.
  • idempotency_in_progress: a request with this Idempotency-Key is still running, or stopped before it could answer.

Problem object (application/problem+json). Codes: inbox_limit, idempotency_in_progress.

Example: inbox_limit (claimed account)

{
"type": "https://docs.replyz.io/errors/inbox_limit",
"code": "inbox_limit",
"status": 409,
"message": "This account already has 3 inboxes (the limit for claimed).",
"fix": "Delete an inbox you no longer need with DELETE /v1/inboxes/{id}.",
"docs": "https://docs.replyz.io/errors/inbox_limit.md"
}

Example: idempotency_in_progress

{
"type": "https://docs.replyz.io/errors/idempotency_in_progress",
"code": "idempotency_in_progress",
"status": 409,
"message": "A request with this Idempotency-Key is still running, or it stopped before it could answer.",
"fix": "Check the result with GET /v1/inboxes before retrying; use a new Idempotency-Key for a new request.",
"docs": "https://docs.replyz.io/errors/idempotency_in_progress.md"
}

payload_too_large: the body is larger than 16,384 bytes.

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

Example: payload_too_large

{
"type": "https://docs.replyz.io/errors/payload_too_large",
"code": "payload_too_large",
"status": 413,
"message": "Body is larger than 16384 bytes.",
"fix": "Send a smaller JSON body.",
"docs": "https://docs.replyz.io/errors/payload_too_large.md"
}

inbox_create_limit: the account already created its maximum number of inboxes today (UTC), the inbox made at signup included.

Header Description
Retry-After The seconds until the next UTC day.

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

Example: inbox_create_limit (sandbox account)

{
"type": "https://docs.replyz.io/errors/inbox_create_limit",
"code": "inbox_create_limit",
"status": 429,
"message": "This account already created 3 inboxes today.",
"fix": "Keep using your current inbox, or try again tomorrow (UTC).",
"docs": "https://docs.replyz.io/errors/inbox_create_limit.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"
}

address_unavailable: no free address was found (rare). Retry the request.

Header Description
Retry-After 1, only when the address step lost 3 insert races in a row. Not sent when all 5 address candidates were taken.

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

Example: address_unavailable (inbox)

{
"type": "https://docs.replyz.io/errors/address_unavailable",
"code": "address_unavailable",
"status": 503,
"message": "Could not find a free address.",
"fix": "Retry the request.",
"docs": "https://docs.replyz.io/errors/address_unavailable.md"
}

GET /v1/inboxes/{id}

Auth: API key (Authorization: Bearer rz_live_…)

Returns one live inbox of the account. A deleted inbox, or an inbox of another account, is not found. Works in every account status.

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

Name In Type Required Description
id path string yes Inbox id (ibx_…). Any other value gets 404 not_found.

The inbox.

Content type application/json.

Field Type Required Description
id string yes
address string (email) yes The inbox address, lowercase: <name>-<6 random characters>@youreplyz.com. Permanent, and never issued again after the inbox is deleted.
display_name string or null (length 0–64) yes A label for your own use, or null.
created_at string (date-time) yes
{
"id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"address": "atlas-wo7tw5@youreplyz.com",
"display_name": null,
"created_at": "2026-11-06T10:00:00.000Z"
}

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 live inbox with this id in this account.

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

Example: not_found: inbox

{
"type": "https://docs.replyz.io/errors/not_found",
"code": "not_found",
"status": 404,
"message": "Inbox not found.",
"fix": "List your inboxes with GET /v1/inboxes.",
"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"
}

PATCH /v1/inboxes/{id}

Auth: API key (Authorization: Bearer rz_live_…)

Sets or clears display_name, the only field that can change. The address can never change. The body must contain display_name; null or an empty string clears it. Other fields are ignored. Needs an active account (sandbox or claimed).

Problem codes: unauthorized (401), org_not_active (403), not_found (404), payload_too_large (413), invalid_json (400), invalid_request (400).

Name In Type Required Description
id path string yes Inbox id (ibx_…). Any other value gets 404 not_found.

Content type application/json (required).

Field Type Required Description
display_name string or null (length 0–64) yes New label, at most 64 characters. null or an empty string clears it.
{
"display_name": "Travel bookings"
}

The updated inbox.

Content type application/json.

Field Type Required Description
id string yes
address string (email) yes The inbox address, lowercase: <name>-<6 random characters>@youreplyz.com. Permanent, and never issued again after the inbox is deleted.
display_name string or null (length 0–64) yes A label for your own use, or null.
created_at string (date-time) yes
{
"id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"address": "atlas-wo7tw5@youreplyz.com",
"display_name": "Travel bookings",
"created_at": "2026-11-06T10:00:00.000Z"
}

The request was refused.

  • invalid_json: the body is not a JSON object.
  • invalid_request: the body has no display_name, or it is not a string or null, or it is longer than 64 characters.

Problem object (application/problem+json). Codes: invalid_json, invalid_request.

Example: invalid_json

{
"type": "https://docs.replyz.io/errors/invalid_json",
"code": "invalid_json",
"status": 400,
"message": "Body must be a JSON object.",
"fix": "Send Content-Type: application/json with a JSON object.",
"docs": "https://docs.replyz.io/errors/invalid_json.md"
}

Example: invalid_request: no display_name in the body

{
"type": "https://docs.replyz.io/errors/invalid_request",
"code": "invalid_request",
"status": 400,
"message": "Nothing to update.",
"fix": "Send {\"display_name\": \"…\"} (or null to clear it).",
"docs": "https://docs.replyz.io/errors/invalid_request.md"
}

Example: invalid_request: display_name too long

{
"type": "https://docs.replyz.io/errors/invalid_request",
"code": "invalid_request",
"status": 400,
"message": "\"display_name\" is longer than 64 characters.",
"fix": "Shorten \"display_name\".",
"docs": "https://docs.replyz.io/errors/invalid_request.md"
}

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"
}

org_not_active: the account is suspended or expired (a sandbox account past its expires_at counts as expired), so it cannot create or change inboxes. The fix depends on the status (for expired, sign up again).

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

Example: org_not_active: the account is suspended

{
"type": "https://docs.replyz.io/errors/org_not_active",
"code": "org_not_active",
"status": 403,
"message": "This account is suspended.",
"fix": "Contact abuse@replyz.io if you think this is a mistake.",
"docs": "https://docs.replyz.io/errors/org_not_active.md"
}

not_found: no live inbox with this id in this account.

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

Example: not_found: inbox

{
"type": "https://docs.replyz.io/errors/not_found",
"code": "not_found",
"status": 404,
"message": "Inbox not found.",
"fix": "List your inboxes with GET /v1/inboxes.",
"docs": "https://docs.replyz.io/errors/not_found.md"
}

payload_too_large: the body is larger than 16,384 bytes.

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

Example: payload_too_large

{
"type": "https://docs.replyz.io/errors/payload_too_large",
"code": "payload_too_large",
"status": 413,
"message": "Body is larger than 16384 bytes.",
"fix": "Send a smaller JSON body.",
"docs": "https://docs.replyz.io/errors/payload_too_large.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"
}

DELETE /v1/inboxes/{id}

Auth: API key (Authorization: Bearer rz_live_…)

Deletes the inbox for good:

  • Its address is retired and never issued again, to anyone. Mail sent to it is refused like mail to an unknown address.
  • Its messages, threads, attachments and events disappear from every route at once. (The stored mail is not erased yet: the scheduled job that erases it is not built.)
  • It does not give back an inbox creation for the day.

Works in every account status. Deleting an inbox that is already deleted returns 404 not_found. If the deletion fails part-way, the inbox stays live with its mail visible and the call returns 500 internal_error: repeat it.

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

Name In Type Required Description
id path string yes Inbox id (ibx_…). Any other value gets 404 not_found.

The inbox was deleted.

Content type application/json.

Field Type Required Description
id string yes
address string (email) yes The retired address. It will never be issued again.
deleted boolean true yes
deleted_at string (date-time) yes
{
"id": "ibx_01M6R4T180ZADNV1160NS1SRNP",
"address": "atlas-wo7tw5@youreplyz.com",
"deleted": true,
"deleted_at": "2026-11-06T12:00:00.000Z"
}

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 live inbox with this id in this account.

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

Example: not_found: inbox

{
"type": "https://docs.replyz.io/errors/not_found",
"code": "not_found",
"status": 404,
"message": "Inbox not found.",
"fix": "List your inboxes with GET /v1/inboxes.",
"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"
}