Every Makini API answers an error the same way: a stable code you can branch on, a message for your logs, and the HTTP status that matches the code. The /v4 API and the Management API share one set of codes, so one error handler covers both.Read the error body#
Any non-2xx answer has this body:| Field | Meaning |
|---|
code | The error code, always MAKINI_ plus upper-case words. Branch on this. |
message | A human-readable explanation for a developer reading logs. |
details | Optional extra information, such as the fields a validation error found. |
Never parse message, and don't show it to your end users as is. details may be absent and its shape can vary, so treat it as a hint for logs and debugging.
Look up a code#
Rate limits#
Makini never bills API calls, but it limits how fast one application can make them. Limits are counted per application, over one-minute windows.| Surface | Requests per minute |
|---|
/v4 data API | 600 |
| MCP | 300 |
| Management API | 120 |
POST /oauth/token | 60, per IP address |
Every response from these surfaces says where you stand:| Header | Meaning |
|---|
X-RateLimit-Limit | The limit for this surface. |
X-RateLimit-Remaining | Requests left in the current window. |
X-RateLimit-Reset | Seconds until the window resets. |
Over the limit, the answer is 429 with the code MAKINI_RATE_LIMITED and a Retry-After header holding the same number of seconds. Nothing was done with the request: wait, then send it again.An MCP plan's tool-call allowance is a different limit. It answers 429 with MAKINI_MCP_QUOTA_EXCEEDED, and waiting a minute doesn't help: it resets with the billing period.
Retry the right errors#
Retry only the codes marked Yes, with exponential backoff and jitter: for example 1, 2, 4 and 8 seconds, then give up and report the failure.
Honor Retry-After when it's present, and wait at least that long.
Don't retry any other 4xx. The same request gets the same answer. Fix the request, the token or the data first. The one exception is 429 MAKINI_RATE_LIMITED: wait for Retry-After, then retry.
Make writes safe to retry. Send an Idempotency-Key with every /v4 write and every connection create. A retry with the same key returns the original result instead of doing the work twice.
On a 401, renew the token, then retry once. Use your refresh token, or request a new client_credentials token. See Access tokens.
A 502 or 504 on a write means the outcome is unknown, so retry it with the same key, or poll the write record.
Handle OAuth errors#
POST /oauth/token and POST /oauth/revoke follow the OAuth 2.0 standard instead, with a body of {error, error_description}:{
"error": "invalid_grant",
"error_description": "The authorization grant is invalid, expired or revoked."
}
Branch on error. The common values are invalid_request, invalid_client (401), invalid_grant, invalid_scope and unsupported_grant_type. A 503 with server_error is temporary: retry it with backoff.Next steps#
Writing data
Poll a write record and read its error.
Access tokens
Renew a token after a 401.