Errors & Rate Limits
The Platform API reports failures using the standard tRPC error envelope. This page describes its shape, the mapping to HTTP statuses, validation errors, and the rate limits that apply to specific features.
The error envelope
Errors follow the standard tRPC error shape and, like successful responses, are
superjson-wrapped: the error object sits under error.json. The useful fields are:
message: a human-readable message. Messages can be in French or English, so do not parse them: branch ondata.code.data.code: a machine-readable error code (e.g.UNAUTHORIZED,NOT_FOUND).data.httpStatus: the corresponding HTTP status, also used as the response status. In a batch (httpBatchLink), each call keeps its owndata.httpStatus; when the calls in a batch do not all share the same status, the HTTP response is 207.data.path: the<router>.<procedure>that failed.
{
"error": {
"json": {
"message": "Please log in to access this feature. Your session may have expired.",
"code": -32001,
"data": {
"code": "UNAUTHORIZED",
"httpStatus": 401,
"path": "auth.getSession",
"zodError": null
}
}
}
}
Code and HTTP status
data.code |
httpStatus |
|---|---|
BAD_REQUEST |
400 |
UNAUTHORIZED |
401 |
FORBIDDEN |
403 |
NOT_FOUND |
404 |
CONFLICT |
409 |
PRECONDITION_FAILED |
412 |
TOO_MANY_REQUESTS |
429 |
INTERNAL_SERVER_ERROR |
500 |
NOT_IMPLEMENTED |
501 |
PRECONDITION_FAILED means the action is refused in the current state of the object or the
configuration (for example an invoice that is already paid, or online payment that is not
configured): fix the state before retrying (repeating the same call will not help).
UNAUTHORIZED means no valid credential was recognised, or no tenant and site could be
resolved for the call. FORBIDDEN means you are authenticated but lack the required
permission or role, your account cannot act in the requested tenant/site scope, or the
tenant's subscription does not include the module you called. See
Sessions & Tokens.
Validation errors (zodError)
When input fails validation, the call fails with BAD_REQUEST (HTTP 400) and
data.zodError describes the problem: fieldErrors maps each field name to a list of
messages, and formErrors lists errors that do not belong to one field. For every other
error, zodError is null.
{
"error": {
"json": {
"message": "…",
"code": -32600,
"data": {
"code": "BAD_REQUEST",
"httpStatus": 400,
"path": "clients.create",
"zodError": {
"formErrors": [],
"fieldErrors": {
"email": ["Invalid email address"]
}
}
}
}
}
}
Read zodError to show per-field messages to the user.
Rate limits
The API does not publish a general request quota. These features have their own limits:
| Scope | Limit |
|---|---|
| Feed key | The key's rateLimit, in requests per hour (1,000 by default, 0 for unlimited). Not every feed that accepts keys counts requests against it. Where a feed does, the one-hour window starts with the first request; past the limit, the key is no longer accepted until that window ends. |
OIDC token endpoint (auth.1clic.pro/oauth2/token, POST) |
20 requests per minute for a given client and IP address pair, and 30 requests per minute per IP address. |
OIDC device authorization (auth.1clic.pro/oauth2/device) |
5 requests per minute per IP address. |
On the identity provider, a request over the limit gets HTTP 429 with a Retry-After header
(in seconds). The body usually carries the OAuth error slow_down, but not always: rely on
the status and Retry-After. Some API procedures can also answer TOO_MANY_REQUESTS: wait
before retrying.
A feed key's hourly limit is set on the key itself: see the Data Model.