Errors
Every refusal is JSON, every refusal names itself in an error field, and every way of missing answers the same way.
Statuses
- 200 — A data object, or a data array with a meta object carrying the page, the page size, the total count and the number of pages.
- 201 — A listing was created, and comes back in the shape the index returns.
- 202 — The work was queued. It happens in the background, so the reply describes what was asked for rather than what it found.
- 401 invalid_token — The key is missing, unreadable or revoked.
- 403 insufficient_scope — The key is valid but does not carry the capability this endpoint needs.
- 404 not_found — The directory is not the one this key was issued for, the record is not in it, or you are no longer a member of the account that owns it. We answer the same way in every case, on purpose.
- 409 conflict — You sent an expected_updated_at that no longer matches. Nothing was written, and the record as it now stands comes back with the refusal.
- 422 invalid — A validation refused the write. errors names every message.
- 422 limit_exceeded — Your plan's limit for this directory is already reached. The body names the limit, what you are using and what you are allowed.
- 422 plan_not_permitted — Your plan does not allow the value you sent. The body names the setting and what is permitted.
- 429 throttled — The same action was asked for again too soon. retry_at names the moment you can ask again.
- 503 unavailable — A Domain Rating fetch could not be asked for at all — the listing has no host, or our own credential is paused. Neither is fixed by sending the same request a second later.
The body
An error body always carries error. A validation refusal carries errors as well — every message, in full — and a plan refusal carries the numbers behind it, so you can tell a caller what to do about it.
{
"error": "invalid",
"errors": [
"Name can't be blank"
]
}
{
"error": "limit_exceeded",
"limit": "listings",
"usage": 500,
"allowed": 500
}Conditional writes
Two integrations on one listing is the normal case. Echo back the updated_at you last read and the write is refused if the record has moved since. Leave it out and the write is unconditional.
Body parameters
| Parameter | Type | Description |
|---|---|---|
| expected_updated_at | string | The updated_at you last read, echoed back. If the record has moved since, nothing is written and you get 409 with the record as it now stands. Leave it out to write unconditionally. |
A conflict is 409, not 422 — nothing about the request was invalid, the record simply moved underneath it — and the record as it now stands travels with the refusal, so you can re-read without a second request.
Retrying
429 names the moment you may ask again in retry_at; wait for it rather than backing off blindly. 503 is our own dependency rather than your request, and sending the same thing a second later will not help. Nothing else here is worth an automatic retry — a 4xx refuses the same way every time.