# Handle errors and rate limits

Failed API requests include an HTTP status and an `error` message. The status identifies the category of failure; the message describes the affected field, credential or operation. Endpoint guides list the corresponding fixes.

## Error shape

Application API errors use a flat JSON object:

```json
{ "error": "Requested LOA LOA-4 exceeds RP maximum LOA-2" }
```

OpenID Connect (OIDC) exchanges use protocol fields such as `error` and `error_description`. Log the endpoint, timestamp, HTTP status and message to help trace a failed request.

| Status | How you handle it |
|---|---|
| `400` | Correct the required field or request format named in `error`. |
| `401` | Refresh an expired user token or start sign-in again. For Basic authentication, check the RP client ID and OIDC client secret. |
| `403` | Check your granted scope, RP approval, permitted origin or operation ownership against the message. |
| `404` | Check the identifier and the account or RP that created the item. For an unavailable capture result, retry after its upload completes. |
| `408` | Read the current operation state before retrying a request that may have completed. |
| `409` | Read the current state and continue from it, or correct the identifier conflict named in the error. |
| `410` | Create a fresh operation and collect a new approval within its expiry window. |
| `413` | Reduce the body below the endpoint's limit, including base64 expansion. |
| `415` | Send the content type specified by the endpoint. |
| `422` | Correct the invalid field named in `error`. |
| `429` | Wait for the request window or daily allowance to reset. |
| `5xx` | Read the operation state if available, then retry with backoff. Contact support if the failure persists. |

## Common error messages

| Message | Status | Your recovery action |
|---|---|---|
| `Missing Authorization header` | `401` | Supply the signed-in user's token in `Authorization: Bearer …`. |
| `Invalid or expired token` | `401` | Refresh the token or start sign-in in the same environment as the API. |
| `Token missing subject claim` | `401` | Ask SecurySign to check your client's `basic` scope so access tokens include `sub`. |
| `CSRF token validation failed` | `403` | Check that your backend supplies the required Authorization header and that its credential environment variables are populated. |
| `invalid_client` | `401` | Supply your approved RP's client ID and current OIDC client secret for the KYC request. |
| `Passkey signature verification failed` | `403` | Collect a fresh assertion using the passkey assigned to the operation. |
| `Daily signing limit exceeded (…)` | `429` | Wait until 00:00 UTC or change the RP's plan. |

## Rate limits

Exceeding a per-minute limit returns `429` with `Rate limit exceeded. Please try again later.` Wait for the 60-second window before retrying. Daily signing-limit messages include the used allowance, maximum and reset time. The daily counter resets at 00:00 UTC.

The default RP allowance is 60 requests per minute, 100 signatures per day and 10 documents per batch. A subscription sets the plan's allowance. Call `GET /rp/rate-limits/{clientId}` with the contact account's access token to read the current limits and consumption. See [Pricing and limits](#/docs/limits) for subscriptions.

| Endpoint | Limit | Counter |
|---|---|---|
| `POST /ssc/token` | Your signing allowance. | RP client ID. |
| `POST /ssc/challenge`, registered mode | Your signing allowance. | RP client ID. |
| `POST /ssc/challenge`, anonymous mode | 10 per minute. | IP address. |
| `POST /ssc/finalize` | 5 per minute. | Operation and IP address. |
| `POST /v2/sign/single`, `/v2/sign/batch` | Signing allowance. | Signed-in user. |
| `POST /v2/webhooks/register` | 10 per minute. | User. |
| `GET /v2/webhooks` | 30 per minute. | User. |
| `DELETE /v2/webhooks/{id}` | 20 per minute. | User. |
| `POST /decrypt` | 30 per minute. | User. |
| `POST /decrypt/asymmetric` | 20 per minute. | User. |
| KYC start, document, session, face, comparison and handoff | 20 per minute. | IP address. |
| KYC capture relay and phone handoff | 120 per minute. | IP address. |
| KYC selfie and video | 60 per minute. | IP address. |
| `POST /enrolment/request` | 60 per minute. | IP address. |

For allowance changes beyond the available plans, contact [support@tenda.world](mailto:support@tenda.world).
