Errors, pagination, and rate limits
Handle Monument REST API status codes and error bodies, page through list endpoints, and stay within rate limits.
This guide covers the three things every integration has to handle: how errors come back, how to page through lists, and how the rate limiter behaves.
Status codes
200 OKand201 Createdreturn a record.204 No Contentis returned by deletes and has an empty body.400 Bad Requestmeans the query or JSON body failed validation.401 Unauthorizedmeans the key is missing, invalid, revoked, or expired.403 Forbiddenmeans your key does not have permission for the operation. Check the permissions of the person who created the key.404 Not Foundmeans the record does not exist or is not visible to your key.409 Conflictmeans the operation conflicts with the current record state. Read the error message and resolve the conflict before retrying.429 Too Many Requestsmeans you hit the rate limit.
Error shape
Errors return an error label and a human-readable message. Validation failures also include a details object describing which fields were rejected.
{
"error": "Bad Request",
"message": "Invalid request body",
"details": {
"fieldErrors": { "name": ["Required"] },
"formErrors": []
}
}code and a requestId alongside those fields. Log the message and, when present, the requestId to make support requests faster.Paginate list endpoints
List endpoints return a pagination object with total, limit, and offset. Walk offset-based pages until you have collected total records.
const headers = { 'X-API-Key': 'monument_your_api_key' };
const limit = 100;
let offset = 0;
const all = [];
for (;;) {
const res = await fetch(
`https://api.monument.so/api/v1/projects?limit=${limit}&offset=${offset}`,
{ headers },
);
const { data, pagination } = await res.json();
all.push(...data);
offset += limit;
if (offset >= pagination.total) break;
}Rate limits
Keys default to 60 requests per minute and may be given a custom per-minute limit. Every response carries the current window on three headers:
X-RateLimit-Limitis the ceiling for this window.X-RateLimit-Remainingis how many requests are left.X-RateLimit-Resetis the Unix timestamp, in seconds, when the window resets.
When you exceed the limit, the request returns 429 with a Retry-After header (seconds to wait) and this body:
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"code": "RATE_LIMITED",
"retryAfter": 12
}Retry safely
Honour the Retry-After header before retrying a 429, and watch X-RateLimit-Remaining to slow down before reaching the limit. Use increasing delays between retries. For reads, retry temporary 5xx failures. After a write fails or times out, check whether it succeeded before sending it again; a blind retry can create duplicates. Resolve other 4xx errors before retrying.