Errors
Error codes and how to handle them
The Micro API uses standard HTTP status codes. Every /v2 error returns the same JSON envelope, with the details nested under an error key.
{ "error": { "code": "invalid_request", "message": "Invalid filter: unknown property slug 'emial'", "request_id": "eeaac41f-c240-4c12-9ee8-7d3a30d59413" }}code is a stable machine-readable string — prefer it over string-matching message. request_id is also returned as an x-request-id response header; quote it when contacting support. Validation failures add an errors array with per-field entries (message, field, code).
:::caution
API key validation and rate limiting happen at the gateway, before a request reaches the API. Those rejections return a bare { "message": "Forbidden" } instead of the envelope above, so read error?.code defensively rather than assuming error is always present.
:::
Status codes
Section titled “Status codes”| Status | code | When it happens |
|---|---|---|
400 | invalid_request | Malformed request body, invalid filter operator, unknown property slug, missing required field |
401 | unauthenticated | Missing x-api-key header |
403 | permission_denied | API key is invalid, revoked, or doesn’t have access to the requested team |
404 | not_found | Object ID doesn’t exist or isn’t accessible |
405 | method_not_allowed | Wrong HTTP method for the route |
409 | conflict | Write conflicts with current state — see Idempotency |
412 | precondition_failed | If-Match ETag no longer matches the record |
415 | unsupported_media_type | Missing or non-JSON Content-Type |
422 | unprocessable_entity | Well-formed request that fails a semantic check |
429 | rate_limited | Rate limit exceeded — see Rate Limits |
500 | internal_error | Something went wrong on our end |
503 | service_unavailable | Temporary outage — retry with backoff |
504 | timeout | Request exceeded the server time budget |
Handling errors
Section titled “Handling errors”const res = await fetch(`https://developers.micro.so/v2/prism/${teamId}/contact/query`, { method: 'POST', headers: { 'x-api-key': apiKey, 'Content-Type': 'application/json' }, body: JSON.stringify({ query: { select: ['full_name'] } }),});
if (!res.ok) { const body = await res.json().catch(() => ({})); const code = body.error?.code ?? 'error'; const message = body.error?.message ?? body.message ?? res.statusText; throw new Error(`Micro API ${code} (${res.status}): ${message}`);}Common 400 errors
Section titled “Common 400 errors”- Unknown property slug — check the slug against the Objects reference
- Invalid operator — filter operators are case-sensitive (
=not==) - Missing
select— every query requires at least one property inselect - Invalid
objectType— must be one ofcontact,organization,identity,deal,action,event,document