Skip to content

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 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

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_READY applies to customer subscription-derived facts.

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

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: 2

Use bounded exponential backoff with jitter. Do not create an unbounded retry loop, and keep all attempts inside the original request’s latency budget.

Every response, successful or not, carries the same ID in a Request-Id header:

Request-Id: req_0f8c2d4e-5b1a-4c7e-9d3f-2a6b8e1c4f07

Quote 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.