Overview
Response Codes
HTTP status codes returned by the TournamentSuite API and how to handle them.
The TournamentSuite API uses standard HTTP status codes to indicate whether a request succeeded or failed.
Success codes
| Code | Meaning | When it occurs |
|---|---|---|
200 OK | Request succeeded | GET, PATCH, DELETE |
201 Created | Resource created | POST that creates a new resource |
204 No Content | Request succeeded, no body | DELETE operations |
Client error codes
| Code | Meaning | Common causes |
|---|---|---|
400 Bad Request | Invalid request body or parameters | Missing required fields, type errors |
401 Unauthorized | Authentication failed | Missing or invalid API key / expired token |
403 Forbidden | Authenticated but not authorized | Insufficient scope, accessing another project's data |
404 Not Found | Resource does not exist | Wrong ID, deleted resource |
409 Conflict | State conflict | Duplicate registration, resource already in that state |
422 Unprocessable Entity | Validation failed | Business rule violation (e.g. tournament already started) |
429 Too Many Requests | Rate limit exceeded | Check X-RateLimit-* headers and back off |
Server error codes
| Code | Meaning | What to do |
|---|---|---|
500 Internal Server Error | Unexpected server error | Retry with exponential backoff; contact support if persistent |
503 Service Unavailable | Temporary outage or maintenance | Retry after the Retry-After header value |
Error response format
All error responses follow a consistent JSON envelope:
{
"success": false,
"error": {
"code": "TOURNAMENT_NOT_FOUND",
"message": "Tournament with ID '550e8400' was not found.",
"timestamp": "2026-06-01T10:00:00.000Z",
"path": "/api/v1/tournaments/550e8400"
}
}Handling rate limits
When you receive a 429, inspect the rate limit headers before retrying:
const response = await fetch(url, { headers });
if (response.status === 429) {
const resetAt = response.headers.get('X-RateLimit-Reset');
const waitMs = (Number(resetAt) * 1000) - Date.now();
await new Promise(resolve => setTimeout(resolve, waitMs));
// retry
}