Every error has the same shape and a stable code. Branch on the code, not on the message.
Every error answers with the same envelope:
{ "error": { "code": "VALIDATION_FAILED", "message": "Postcode can't be blank", "details": { "postcode": ["can't be blank"] } } }
code is stable and machine-readable. Branch on it.message is plain English for people. It may change.details is keyed by field for VALIDATION_FAILED, and empty otherwise.| Code | HTTP | What it means |
|---|---|---|
UNAUTHENTICATED |
401 | No valid session or API key. Sign in again or check the key. |
API_KEY_INVALID |
401 | The API key is not recognised. |
API_KEY_REVOKED |
401 | The API key was revoked in the product. |
SESSION_EXPIRED |
401 | The session has expired. Sign in again. |
CONTEXT_REQUIRED |
409 | Choose a workspace: send X-Abide-Rent-Context and X-Abide-Rent-Context-Id. |
CONTEXT_FORBIDDEN |
403 | This call is not available in the workspace you chose (for example a tenant calling an agency endpoint). |
CONTEXT_EXPIRED |
403 | That access has ended — the role or invitation behind the workspace is gone. |
ACCOUNT_REQUIRED |
403 | The call needs an agency or landlord workspace. |
PERSON_REQUIRED |
403 | Only a signed-in person can do this. An API key cannot — for example signing or recording service. |
SEAT_FORBIDDEN |
403 | The caller’s seat or the key’s scope does not allow this action. |
SCOPE_INSUFFICIENT |
403 | The API key’s scopes do not include this action. |
PLAN_RESTRICTED |
403 | The plan does not include this (for example Solo’s 1-property limit). Reading and export keep working. |
FORBIDDEN |
403 | Not allowed, or blocked by a legal hold or the instruction on the property. |
NOT_FOUND |
404 | No such record in the workspace you chose. Records in other workspaces are never visible. |
CONFLICT |
409 | A unique rule refused the write — usually a duplicate or two requests at once. Retry once. |
VALIDATION_FAILED |
422 | A field is missing or invalid. details is keyed by field. |
DUPLICATE_PRN |
422 | That Property Registration Number is already on another property. |
TENANCY_CURRENT |
422 | The property already has a current tenancy. End it before starting the next. |
ADVANCE_RENT_BLOCKED |
422 | Rent in advance above one rental period is not allowed (Renters’ Rights Act). |
RELET_RESTRICTED |
422 | The property cannot be re-let yet after a possession ground that restricts reletting. |
ALREADY_SERVED |
422 | Service is already recorded on this notice. |
IMMUTABLE_RECORD |
422 | The record is part of the evidence trail and cannot be changed. |
NOTICE_ALREADY_RESPONDED |
422 | The tenant has already accepted, queried or referred this notice. |
NOTICE_VOID |
422 | The notice is void and cannot be responded to. |
SECTION_8_NOT_REFERRABLE |
422 | A Section 8 notice cannot be referred to the rent tribunal. |
SOLICITOR_REVIEW_REQUIRED |
422 | This notice kind needs the solicitor-reviewed flag before it can be generated. |
PACK_INCLUDED_ON_MANAGE |
422 | The pack is already included on this plan; no purchase is needed. |
LEGAL_HOLD_PREVENTS_DELETE |
422 | A legal hold keeps this record. It cannot be deleted while the case is live. |
LEGAL_HOLD_SUBJECT_LIVE |
422 | The record is under a live legal hold. |
SERVE_NOT_AVAILABLE_OVER_API |
403 | Serving a notice is never an API call. A person records service in the product. |
RATE_LIMITED |
429 | Too many requests. Wait for the number of seconds in Retry-After. |
NOT_AVAILABLE |
501 | The feature is not built yet. The API says so rather than pretending. |
429 after the Retry-After seconds, and 409 CONFLICT once.4xx validation or permission errors unchanged — they will fail the same way.5xx errors are on us. Retry with backoff and open a ticket if they persist.