Errors
Failures use a small JSON object: an error message and usually a machine-readable code. HTTP status is the first thing to branch on.
Body
{ "error": "Invalid API key", "code": "PARTNER_UNAUTHORIZED" }
Common codes
| HTTP | Code | Meaning |
|---|
| 400 | PARTNER_HTTPS_REQUIRED | Production request was not HTTPS. |
| 401 | PARTNER_UNAUTHORIZED | Missing or invalid secret. |
| 403 | PARTNER_API_DISABLED | Admin turned the Partner API off for this company. |
| 403 | PARTNER_IP_FORBIDDEN | Client IP is not on the key allowlist. |
| 403 | PARTNER_SCOPE_FORBIDDEN | Key is missing the route’s scope. |
| 403 | COMPANY_NOT_VERIFIED | The company must be verified for this write. |
| 403 | FORBIDDEN | Actor is not allowed to perform the action. |
| 404 | COMPANY_NOT_FOUND | Company missing or archived. |
| 422 | INVALID_PHONE | Phone did not normalize to a valid number. |
| 422 | USER_NOT_REGISTERED | Member invite: no Safra user with that phone. |
| 429 | — | Rate limited. Read Retry-After. |
Validation errors from Laravel may return 422 with a message and no code. Domain errors such as “Trip not found” use 404.