Skip to Content
🚀 Sendbox is live — this documentation is a work in progress.
API ReferenceErrors & Rate Limits

Errors & Rate Limits

Error shape

Every failed request returns the same JSON shape:

{ "error": "email: Invalid email", "code": "VALIDATION_ERROR", "details": { "fieldErrors": { "email": ["Invalid email"] }, "formErrors": [] } }
  • error is always a human-readable string. Sendbox gives the real, specific reason (e.g. the exact SMTP error from a failed send) wherever it is knowable.
  • code is stable and machine-readable: VALIDATION_ERROR, BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, NOT_FOUND, CONFLICT, PAYLOAD_TOO_LARGE, RATE_LIMITED, UPSTREAM_ERROR, INTERNAL_ERROR, and so on. Branch on code, not on the text.
  • details is present when there is more to say, e.g. the per-field messages of a validation error.

Some endpoints return extra fields next to the error (for example a failed test send also returns smtpResponseCode).

Status codes

CodeMeaning
400Invalid request body/params
401Missing, invalid, or expired credentials
403Authenticated, but not allowed to do this (e.g. an API key hitting an account-management route, or a non-owner attempting an owner-only action)
404Not found — including when a resource exists but belongs to a different workspace, so existence is never leaked across tenants
409Conflict with current state (e.g. deleting a mailbox with real send history)
413Request body too large
429Rate limited, or an AI-credit limit reached
502An upstream operation failed (e.g. an SMTP send attempt)

Rate limits

  • A request with a valid API key counts against that key’s limit: 300 requests/minute per key. Keys never share a limit, even when your integration calls from a shared IP (Zapier, Make, n8n).
  • A signed-in dashboard session counts against 600 requests/minute per user.
  • Anything else counts against 200 requests/minute per IP.
  • Some routes (login/signup, mailbox test-send) have their own tighter limits on top.

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 also has Retry-After (seconds) and code: "RATE_LIMITED". Over MCP, each tool call counts against the same per-key limit.

Pagination

Most list endpoints return { ..., page, limit, total } and take page and limit query parameters.

These four return a plain JSON array instead, and put the totals in headers: GET /campaigns, GET /mailboxes, GET /domains, GET /crm/pipeline. They also take page and limit.

HeaderMeaning
X-Total-CountRows across all pages
X-PageThe page returned (starts at 1)
X-LimitThe page size used

Without parameters you get the first page, which is large enough for a normal workspace (500 campaigns, 5000 mailboxes, 2000 domains, 200 pipeline rows). Compare X-Total-Count with what you received to know whether there is more.