Errors and rate limits
Strent returns JSON errors with a stable code, a human-readable message, and a request ID:
{ "error": { "code": "CUSTOMER_STATE_NOT_READY", "message": "The customer projection is not ready.", "requestId": "req_123" }}The optional details object contains additional diagnostic context.
Status codes
Section titled “Status codes”| Status | Meaning | Retry guidance |
|---|---|---|
400 |
Invalid request data | Fix the request |
401 |
Missing, malformed, or invalid authentication | Fix the credential or header |
403 |
Revoked project key | Rotate the key |
409 |
Required projection is not ready | Refresh or wait for synchronization |
413 |
Request body is too large | Reduce the request |
415 |
Unsupported content type | Send Content-Type: application/json |
429 |
Rate limit exceeded | Honor Retry-After and back off |
500 |
Internal service failure | Retry cautiously within the caller budget |
Readiness conflicts
Section titled “Readiness conflicts”409 preserves an important distinction: Strent does not have enough trustworthy state to answer. It never substitutes false or [] for unknown state.
CUSTOMER_STATE_NOT_READYapplies to customer subscription-derived facts.
Customer refresh failures
Section titled “Customer refresh failures”customers.refresh returns 401 API_KEY_REVOKED for a revoked key; reads retain
403 API_KEY_REVOKED. It has these additional operational errors:
| Status | Code | Meaning |
|---|---|---|
404 |
CUSTOMER_REFRESH_STRIPE_CUSTOMER_NOT_FOUND |
Customer missing in the project’s Stripe mode |
409 |
STRIPE_CONNECTION_REQUIRED / STRIPE_CONNECTION_INVALID |
Configure or repair the Stripe connection |
502 |
CUSTOMER_REFRESH_FAILED |
Customer refresh failed |
503 |
CUSTOMER_REFRESH_UNAVAILABLE |
The refresh could not be requested or observed |
504 |
CUSTOMER_REFRESH_NOT_FINISHED |
The 10-second wait expired; the refresh continues |
Rate limits
Section titled “Rate limits”Public billing routes apply a coarse source-identity admission fuse before token parsing. Authentic tokens then have separate bearer and project fairness limits. These are per-instance, in-memory controls, not a customer entitlement and not complete DDoS protection.
customers.refresh allows 60 calls per minute per project and per bearer, in a
separate scope from checks, lists, and billing-state reads.
A 429 response uses the public RATE_LIMIT_EXCEEDED envelope and may include:
Retry-After: 2Use bounded exponential backoff with jitter. Do not create an unbounded retry loop, and keep all attempts inside the original request’s latency budget.
Request correlation
Section titled “Request correlation”Every response, successful or not, carries the same ID in a Request-Id header:
Request-Id: req_0f8c2d4e-5b1a-4c7e-9d3f-2a6b8e1c4f07Quote it when you contact support about a specific answer, including a 200 you believe is wrong.
Capture the error requestId in server logs and operator-facing diagnostics. Do not return billing payloads, API keys, or internal error details to end users.