Errors
All errors follow a uniform format with a standard HTTP code and a stable business code for easy programmatic handling.
Error format
Section titled “Error format”{ "code": "CUSTOMER_NOT_FOUND", "message": "Client non trouvé", "details": { /* optional */ }}code: stable identifier — branch your logic on this, not onmessagemessage: user-facing French phrase (may change across versions)details: optional object with extra info (e.g. validation errors per field)
Example — validation error
Section titled “Example — validation error”{ "code": "VALIDATION_ERROR", "message": "Requête invalide", "details": { "email": ["Requis pour la création"], "name": ["Requis pour la création"] }}Error codes by domain
Section titled “Error codes by domain”Authentication
Section titled “Authentication”| HTTP code | Business code | When? |
|---|---|---|
401 | AUTH_API_KEY_MISSING | X-API-Key header missing |
401 | AUTH_API_KEY_INVALID | Malformed key or no matching app |
403 | AUTH_API_KEY_FORBIDDEN | Public key (pk_live_) used on a server-only route |
Validation
Section titled “Validation”| HTTP code | Business code | When? |
|---|---|---|
400 | VALIDATION_ERROR | Invalid body — see details for per-field breakdown |
Customers
Section titled “Customers”| HTTP code | Business code | When? |
|---|---|---|
404 | CUSTOMER_NOT_FOUND | Unknown externalId in your app |
409 | CUSTOMER_EMAIL_EXISTS | Email already taken by another customer in your app |
Tickets
Section titled “Tickets”| HTTP code | Business code | When? |
|---|---|---|
403 | PLAN_LIMIT_REACHED | Monthly ticket quota reached |
404 | TICKET_NOT_FOUND | Unknown ticket ID (read routes) |
Generic
Section titled “Generic”| HTTP code | Business code | When? |
|---|---|---|
429 | TOO_MANY_REQUESTS | Global rate limit exceeded (3 req/s, 20 req/10s, 100 req/min) |
500 | INTERNAL_ERROR | Server error — report to support if persistent |
Client-side best practices
Section titled “Client-side best practices”- Retry only on
5xxand429. On a4xx, fix the request rather than retry. - Exponential backoff on
429: 1s, 2s, 4s, 8s… - Branch on the business
code, not on the Frenchmessagewhich may evolve. - Log
code+detailsfor your internal traces.
Node.js handler example
Section titled “Node.js handler example”async function callSupportDesk(path, body) { const res = await fetch(`https://supportdesk.innovartx.com/api/v1${path}`, { method: 'POST', headers: { 'X-API-Key': process.env.SUPPORTDESK_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify(body), });
if (!res.ok) { const err = await res.json().catch(() => null); const code = err?.code ?? 'UNKNOWN';
if (code === 'CUSTOMER_NOT_FOUND') { // custom business logic } throw new Error(`SupportDesk ${res.status} ${code}`); }
return res.json();}