Errors use the RFC 7807 application/problem+json format, so they are consistent and machine-readable:
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
{
"type": "https://docs.grem.capital/api/errors/validation",
"title": "validation",
"status": 400,
"detail": "totalArea (m2) is required",
"requestId": "req_…"
}
Always log the requestId — quote it in support requests to trace a call.
Status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Validation error | Fix the request body/params per detail. |
401 | Invalid or missing key | Check the Authorization header. |
402 | Insufficient funds or quota | Top up or upgrade the plan. |
403 | Missing scope | The key isn't scoped for this tool. |
404 | Not found | Wrong path, or the resource doesn't exist. |
409 | Idempotency conflict | A request with this Idempotency-Key is still in flight. |
422 | Business rule | The request is valid but can't be processed as-is. |
429 | Rate limited | Back off and retry — see Rate limits. |
5xx | Service error | Transient; retry with backoff. |
A rejected request (4xx) is not billed — the per-call charge is only captured on success.
Handling errors
- Branch on the numeric HTTP
status, not on the human-readabledetailtext. - Retry
429and5xxwith exponential backoff; do not retry4xx(except409, after the in-flight request finishes). - Provider details are never leaked in errors — a failure surfaces as a generic
provider_error.