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.

invalid_request

HTTP 400 · A field, header or query parameter is missing or invalid.

Endpoints: Several

When Message (as returned) Fix (as returned)
POST /v1/signup: challenge or nonce is missing or not a string. Body needs "challenge" and "nonce". GET /v1/signup/challenge, find a nonce so that sha256(challenge + ':' + nonce) starts with `difficulty` zero bits, then POST both. The Replyz CLI and scripts/signup.mjs do this for you.
agent_name (signup), name or display_name (inboxes) is not a string (null is allowed). "{field}" must be a string. Send "{field}" as a JSON string.
The same fields are longer than 64 characters after control characters are removed and the value is trimmed. "{field}" is longer than 64 characters. Shorten "{field}".
POST /v1/inboxes: Idempotency-Key is not 1–255 printable ASCII characters (no spaces). Idempotency-Key must be 1–255 printable ASCII characters. Use a UUID.
PATCH /v1/inboxes/{id}: the body has no display_name. Nothing to update. Send {"display_name": "…"} (or null to clear it).
Read routes: a query parameter is invalid. The fix names the accepted format (table below). Invalid query parameter "{name}". Depends on the parameter (table below).
  • Fix the field or parameter named in message, as the fix says. Branch on code, never on the message text.
Parameter Endpoint Valid values Fix (as returned)
limit GET /v1/inboxes/{id}/messages Integer 1–100 (default 20) “Use an integer from 1 to 100.”
limit GET /v1/inboxes/{id}/wait Integer 1–50 (default 10) “Use an integer from 1 to 50.”
limit GET /v1/events Integer 1–100 (default 100) “Use an integer from 1 to 100.”
timeout GET /v1/inboxes/{id}/wait Integer 0–60 (default 25) “Use an integer from 0 to 60.”
wait GET /v1/events Integer 0–60 (default 0) “Use an integer from 0 to 60.”
after GET /v1/events Integer 0–9007199254740991 (default 0) “Use an integer from 0 to 9007199254740991.”
unread GET /v1/inboxes/{id}/messages true/1/yes, false/0/no (any case); empty = false “Use true or false.”
exclude_returned GET /v1/inboxes/{id}/wait Same as unread “Use true or false.”
since GET /v1/inboxes/{id}/messages, GET /v1/inboxes/{id}/wait ISO 8601 date or date-time, e.g. 2026-11-06T10:00:00Z; a time without an offset is UTC “Use an ISO 8601 time, e.g. 2026-11-06T10:00:00Z (encode ‘+’ as %2B).”
from GET /v1/inboxes/{id}/messages, GET /v1/inboxes/{id}/wait At most 200 characters “Use at most 200 characters.”
subject GET /v1/inboxes/{id}/wait At most 200 characters “Use at most 200 characters.”
before GET /v1/inboxes/{id}/messages A message id (msg_…), from next_before “Use next_before from the previous page.”
thread_id GET /v1/inboxes/{id}/wait A thread id (thr_…) “Use a thread id (thr_…).”
extract GET /v1/inboxes/{id}/wait otp, link or otp,link (any case). An empty value is invalid “Use extract=otp, extract=link or extract=otp,link.”
include GET /v1/messages/{id} html, raw or html,raw “Use include=html, include=raw or include=html,raw.”

For suspended and expired accounts, timeout (wait) and wait (events) are validated as for any account; the request then answers at once and never holds.

{
"type": "https://docs.replyz.io/errors/invalid_request",
"code": "invalid_request",
"status": 400,
"message": "Body needs \"challenge\" and \"nonce\".",
"fix": "GET /v1/signup/challenge, find a nonce so that sha256(challenge + ':' + nonce) starts with `difficulty` zero bits, then POST both. The Replyz CLI and scripts/signup.mjs do this for you.",
"docs": "https://docs.replyz.io/errors/invalid_request.md"
}

All codes: Errors.