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.404 Not Foundmeans the record does not exist or is not visible to your key.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
Honor the Retry-After header before retrying a 429, and watch X-RateLimit-Remaining to slow down before you hit the wall. Retry 429 and 5xx responses with exponential backoff. Do not retry other 4xx responses; the request itself needs to change first.