Error codes
All error responses share the same JSON shape:
{ "detail": "Human-readable description of the error."}For validation errors (422), detail is an array of field-level messages:
{ "detail": [ { "loc": ["body", "nominee_email"], "msg": "value is not a valid email address", "type": "value_error.email" } ]}Status codes
Section titled “Status codes”| Code | Meaning | Common causes |
|---|---|---|
200 OK | Request succeeded | — |
201 Created | Resource created | POST endpoints that create records |
400 Bad Request | Invalid input | Missing required field, malformed body, invalid OTP |
401 Unauthorized | Authentication failed | Expired token, invalid API key |
403 Forbidden | Access denied | Wrong tenant, request origin not in allowed domains, token mismatch |
404 Not Found | Resource not found | Unknown userId, bannerId, collection_point_id |
409 Conflict | State conflict | Consent already completed, nominee limit reached |
410 Gone | Resource expired | Consent link already used or expired |
422 Unprocessable Entity | Validation error | Request body fails schema validation |
429 Too Many Requests | Rate limit exceeded | Too many SDK requests from the same IP + org within the window. See Rate limits. |
500 Internal Server Error | Server error | Unexpected failure — contact support if persistent |
503 Service Unavailable | Dependency failure | OTP provider (MSG91), JWT service, or S3 temporarily unavailable |
Handling 429
Section titled “Handling 429”When the rate limit is exceeded the response includes headers to help you back off:
HTTP/1.1 429 Too Many RequestsRetry-After: 42X-RateLimit-Limit: 200X-RateLimit-Window: 60Wait for Retry-After seconds before retrying. See Rate limits for the full policy.
Handling 403 on SDK requests
Section titled “Handling 403 on SDK requests”A 403 Forbidden with detail: "Origin not allowed" means the domain or bundle ID making the request is not listed under Settings → API Settings → Allowed Domains. Add the origin and retry.