Developer Resources · API Basics
Errors
How the Monime API reports errors, what each status code means, which errors to retry, and how to handle them in your integration.
Every Monime API response says whether the request succeeded. A failed request returns an HTTP status of 400 or above and an error object that says why, so your code can decide whether to fix the request, retry it, or stop.
The error response
A successful response has "success": true and a result. A failed one has "success": false and an error:
{
"success": false,
"messages": [],
"error": {
"code": 409,
"reason": "idempotency_key_in_use",
"message": "Conflict: Idempotency key reused with a non-identical request.",
"details": []
}
}| Field | What it is |
|---|---|
code | The HTTP status code, repeated in the body |
reason | A short, stable name for the error, such as too_many_requests. Branch on this in your code |
message | A sentence for people, which can change: log it, but don't match on it |
details | More about the error, such as the fields at fault, when there is more to say |
Every response also carries a Monime-Request-Id header. Log it with each failure, and include it when you contact Monime support: it identifies the exact request.
Status codes
| Status | What it means | What to do |
|---|---|---|
2xx | The request succeeded | Use the result |
400–499 | The request can't succeed as it is, such as invalid input | Fix the request; sending it again unchanged fails again |
401 | The access token is missing, invalid or expired | Check the Authorization header, or create a new token. See Authentication |
403 | The token is valid, but lacks the permission or Space access the request needs | Check the token's scopes and the Monime-Space-Id header |
404 | The object doesn't exist, in this Space and environment | Check the ID, the Space and whether you used a test or live token |
409 | idempotency_key_in_use: an Idempotency-Key was reused for a different request | Fix how your code chooses keys. See Idempotency |
429 | too_many_requests: a rate limit was reached. Nothing happened | Wait the seconds in Retry-After, then retry. See Rate limiting |
500–599 | Something failed at Monime | Retry with backoff, with the same Idempotency-Key |
Retry or fix?
- Retry network errors,
429and5xxresponses. Wait between attempts, longer each time, and add a little randomness so many clients don't retry at once. On429, wait at leastRetry-Afterseconds. - Send every retry of a create with the same
Idempotency-Key, method, URL and body, so a retry after a timeout can never create a second payout or payment. - Don't retry other
4xxerrors without changing the request: fix what the error names first. - If you can't tell whether a create succeeded, such as after a timeout,
GETthe object before trying again. A404means it was never created.
Handle errors in code
type MonimeError = { code: number; reason: string; message: string; details: unknown[] };
export async function callMonime(path: string, init: RequestInit, attempts = 5): Promise<unknown> {
for (let attempt = 1; ; attempt++) {
let response: Response;
try {
response = await fetch(`https://api.monime.io${path}`, init);
} catch (networkError) {
if (attempt === attempts) throw networkError;
await wait(backoff(attempt));
continue;
}
const payload = await response.json();
if (payload.success) return payload.result;
const error: MonimeError = payload.error;
const requestId = response.headers.get('Monime-Request-Id');
const retryable = response.status === 429 || response.status >= 500;
if (!retryable || attempt === attempts) {
console.error(`Monime ${error.reason} (request ${requestId}): ${error.message}`);
throw Object.assign(new Error(error.message), { reason: error.reason, requestId });
}
// On 429, Retry-After says how long to wait; otherwise back off.
const retryAfter = Number(response.headers.get('Retry-After'));
await wait(retryAfter > 0 ? retryAfter * 1000 : backoff(attempt));
}
}
const backoff = (attempt: number) => 2 ** attempt * 500 + Math.random() * 250;
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));Pass the same init, including its Idempotency-Key header, to every attempt, so each retry is identical.
Errors in webhooks
Webhook deliveries are retried by Monime when your endpoint doesn't answer with a 2xx. See Delivery and retries for how to answer them, and Troubleshoot for common failures.