Status codes
HTTP status codes returned by the Thought Industries REST API and how to handle them.
Status codes
The REST API uses standard HTTP status codes to indicate the outcome of each request. Successful operations return 2xx codes, client errors return 4xx, and server errors return 5xx.
Success codes
| Code | Meaning | When returned |
|---|---|---|
200 OK | Request succeeded | GET, PUT, PATCH requests that return data |
201 Created | Resource created | POST requests that create a new resource |
204 No Content | Request succeeded, no body | DELETE requests and updates with no response body |
Redirect codes
| Code | Meaning | When returned |
|---|---|---|
301 Moved Permanently | Resource permanently moved | Follow the Location header |
304 Not Modified | Resource unchanged since last request | Use your cached version |
Client error codes
| Code | Meaning | Action |
|---|---|---|
400 Bad Request | Malformed request body or invalid parameters | Check request syntax and parameter types |
401 Unauthorized | Missing or invalid authentication | Verify your API key in the Authorization header |
403 Forbidden | Valid credentials but insufficient permissions | Check the role assigned to your API key |
404 Not Found | Resource does not exist | Verify the resource ID and endpoint path |
405 Method Not Allowed | HTTP method not supported | Use the correct method for this endpoint |
409 Conflict | Resource state conflict (e.g., duplicate) | Check for existing resources before creating |
422 Unprocessable Entity | Valid syntax but semantic errors | Review field values against validation rules |
429 Too Many Requests | Rate limit exceeded | Implement retry with backoff (see rate limits) |
Server error codes
| Code | Meaning | Action |
|---|---|---|
500 Internal Server Error | Unexpected server failure | Retry after a brief delay; contact support if persistent |
502 Bad Gateway | Upstream service unavailable | Retry with exponential backoff |
503 Service Unavailable | Temporary maintenance or overload | Check the Retry-After header |
504 Gateway Timeout | Upstream server timeout | Retry with exponential backoff |
Error response format
All error responses follow a consistent JSON structure:
Response: 422 Unprocessable Entity
{
"error": "validation_error",
"message": "Request body contains invalid fields.",
"details": [
{
"field": "email",
"code": "invalid_format",
"message": "Must be a valid email address."
},
{
"field": "firstName",
"code": "required",
"message": "This field is required."
}
]
}Error fields
Error response body
| Field | Type | Required | Description |
|---|---|---|---|
error | string | Yes | Machine-readable error code for programmatic handling. |
message | string | Yes | Human-readable summary of the error. |
details | array | No | Field-level validation errors. Present only for 400 and 422 responses. |
Handling errors in code
response=$(curl -s -w "\n%{http_code}" \
-H "Authorization: Bearer ti_live_a1b2c3d4e5f6g7h8i9j0" \
"https://api.thoughtindustries.com/incoming/v2/users/nonexistent")
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$ d')
if [ "$http_code" -ge 400 ]; then
echo "Error $http_code: $body"
ficonst response = await fetch(url, { headers });
if (!response.ok) {
const error = await response.json();
console.error(`[${response.status}] ${error.message}`);
if (error.details) {
error.details.forEach(d => console.error(` ${d.field}: ${d.message}`));
}
}response = requests.get(url, headers=headers)
if not response.ok:
error = response.json()
print(f"[{response.status_code}] {error['message']}")
for detail in error.get("details", []):
print(f" {detail['field']}: {detail['message']}")$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode >= 400) {
$error = json_decode($response, true);
echo "[{$httpCode}] {$error['message']}\n";
foreach ($error['details'] ?? [] as $detail) {
echo " {$detail['field']}: {$detail['message']}\n";
}
}Related
- Authentication — resolve 401 errors
- Rate limits — resolve 429 errors
- Pagination — avoid unnecessary requests