Troubleshooting
Error handling
HTTP status codes, the flat `_error` format and recommended retry strategies.
The QUiCK API answers with predictable HTTP status codes and a simple, flat error object.
Error response shape
Every error response uses the same shape — a single _error text field:
{
"_error": "Authentication credentials were not provided."
}There is no error-code field and no per-field error list. The message is meant for humans: always branch your code on the HTTP status code, never on the contents of the text.
Status codes
| Code | Meaning | What to do |
|---|---|---|
400 | Bad request or validation error | Fix the parameters or the body — do not retry unchanged |
401 | Missing or invalid token | Check the Authorization: Token <token> header |
403 | No permission, or Quick-Company-Id is not the token's company | Verify permissions and company scope |
404 | Resource not found | Check the identifier and the trailing / in the URL |
429 | Too many requests | Wait, then retry with exponential backoff |
5xx | Server-side error | Exponential backoff, a few attempts at most |
Common pitfalls
401 with a token that looks right
The most frequent cause is the wrong prefix: QUiCK expects Token (Authorization: Token abc123), not Bearer. A quote or newline left over from an .env loader at the end of the token is the second most common cause.
404 for a resource that exists
Endpoints are valid with a trailing slash: /1/expenses/, not /1/expenses. The slash-less form may redirect or return 404, and on a POST the request body can be lost in the process.
If you get a 403 on a call that used to work, check whether you are sending a Quick-Company-Id header unnecessarily: if its value is not the token's company, the API rejects the request.
Recommended strategy
- On 4xx errors, fix the request — retrying it unchanged produces the same result.
- On 429, slow down: use exponential backoff, and honour the
Retry-Afterheader if the response carries one. Persistent 429s call for less frequent polling and a largerpage_size, not more retries. - On 5xx, retry with exponential backoff and an upper bound.
- Log the status code, the endpoint and the
_errortext on every failure — it is the fastest route to support.
Handling errors in the client
Convert the response into a typed error in one place:
export class QuickApiError extends Error {
constructor(public status: number, message: string) {
super(message);
this.name = "QuickApiError";
}
}
export async function quickFetch(path: string, init: RequestInit = {}) {
const res = await fetch(`https://api.quick.riport.co.hu${path}`, {
...init,
headers: {
...init.headers,
Authorization: `Token ${process.env.QUICK_API_TOKEN}`,
},
});
if (!res.ok) {
const body = await res.json().catch(() => ({}));
throw new QuickApiError(res.status, body._error ?? res.statusText);
}
return res.json();
}For a step-by-step version, see the Handling error responses recipe.