Errors & rate limits

How the API signals problems, and the limits that keep it healthy.

Error responses

A failed request returns the matching HTTP status and a JSON body with an error field (a string, or an array of messages for validation failures).

  • 200 / 201: success.
  • 401: the API key is missing or invalid.
  • 403: authenticated, but the action needs an account admin.
  • 404: no such resource.
  • 422: validation failed; the body lists what went wrong.
  • 429: rate limited (see below).
  • 503: a feature isn’t configured on this deployment (for example billing without Stripe keys).
json
{ "error": "Unauthorized: API key is missing or invalid" }

// validation error (422)
{ "error": ["Subject can't be blank", "To is invalid"] }

Rate limits

Sensitive endpoints are throttled per IP. Going over returns 429; back off and retry.

  • Magic-link request: 10 per 5 minutes
  • Magic-link validation: 30 per 5 minutes
  • Signup: 5 per hour
  • Chat widget: 60 per minute
These limits apply to the hosted cloud. On a self-hosted deployment you control them (Messy uses Rack::Attack), so tune them to your traffic.