Errors and rate limits
Error shape
Section titled “Error shape”All 4xx/5xx responses return a JSON envelope:
{ "message": "user payment method not found", "status_code": 404, "details": "payment method 00000000-0000-0000-0000-000000000010 not found for user 00000000-0000-0000-0000-000000000001"}message is always present. status_code appears on flights and offer error paths but is omitted on profile and passenger handlers — trust the HTTP status, not the body field. details carries a validation error or provider-forwarded string.
Validation failures return a ValidationError shape with a fields map; see the OpenAPI spec.
Status code semantics
Section titled “Status code semantics”| Code | Meaning |
|---|---|
400 | Validation failed or malformed body. |
401 | Missing or invalid bearer token. Refresh and retry. |
403 | Token valid but RBAC denies. Do not retry. |
404 | Resource does not exist or is soft-deleted. |
409 | Conflict — usually idempotency-key collision or stale offer. |
429 | Rate limited. Back off. |
500 | Server error. Retry idempotent reads after backoff. |
502 | Upstream provider error. Retry only if idempotent. |
Retry guidance
Section titled “Retry guidance”- Idempotent reads (
GET) — retry freely with exponential backoff (1s, 2s, 4s, 8s) plus jitter. - Other writes — treat 5xx as ambiguous; read the resource back before retrying.
- 429 — does not carry
Retry-After. Use the same backoff schedule.
Booking failure playbook
Section titled “Booking failure playbook”The booking POST is the highest-stakes call. Always send an idempotency_key. Treat outcomes as:
- 2xx — success; persist
booking.id. - 4xx with
status_code— terminal; surface to user, do not retry. - 5xx, network error, or timeout — ambiguous; replay with the same
idempotency_key. Movmo deduplicates and returns the original booking. - 409 on replay — the original request succeeded; the body is the original booking.
Rate limits
Section titled “Rate limits”API Gateway throttles partner traffic per usage plan. Today’s commercial tier is 200 requests/second sustained, 400 burst, 5,000,000 requests/month. Exact numbers are confirmed at onboarding and may be tuned per partner.
MCP routes are throttled to 0 RPS for keyed clients. API key usage plans (Public Website, Customer, Aviare) explicitly block /v1/mcp/* so a request carrying x-api-key against MCP returns 429. This is intentional — MCP requests authenticate via Authorization: Bearer only and must not include the API key. Send the key on REST, the Bearer on MCP, never both on the same request.
WAF additionally enforces stricter IP-level caps on auth-sensitive endpoints, evaluated per source IP over a five-minute window:
| Endpoint | Limit per IP / 5 min |
|---|---|
/v1/users/me/contact/* | 20 |
/v1/users/me/phone/verify/* | 20 |
/v1/oauth/register | 10 |
/v1/mcp | 100 |
Aggregate behavior server-side. Contact us before pushing traffic that may exceed these.