Proper error handling is essential for building robust integrations with the G-Tateth API. This guide covers all error types, status codes, and best practices.
HTTP Status Codes
The G-Tateth API uses standard HTTP status codes to indicate success or failure:
Success Codes
- 200 OK - Request succeeded
- 201 Created - Resource created successfully
- 204 No Content - Request succeeded, no content to return
Client Error Codes
- 400 Bad Request - Invalid request parameters or malformed JSON
- 401 Unauthorized - Missing or invalid authentication
- 403 Forbidden - Insufficient permissions
- 404 Not Found - Resource doesn’t exist
- 409 Conflict - Resource conflict (e.g., duplicate entry)
- 422 Unprocessable Entity - Validation errors
- 429 Too Many Requests - Rate limit exceeded
Server Error Codes
- 500 Internal Server Error - Unexpected server error
- 502 Bad Gateway - Upstream service error
- 503 Service Unavailable - Service temporarily unavailable
- 504 Gateway Timeout - Request timeout
All error responses follow a consistent format:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "Additional error details",
"validation": "Specific validation errors"
},
"requestId": "req_1234567890",
"timestamp": "2024-01-15T10:30:00Z"
}
}
Common Error Codes
Authentication Errors
Always check authentication before making requests.
AUTH_REQUIRED
Status: 401 Unauthorized
{
"success": false,
"error": {
"code": "AUTH_REQUIRED",
"message": "Authentication required",
"details": {
"hint": "Include a valid API key or Bearer token in the Authorization header"
}
}
}
Solution:
// Add Authorization header
headers: {
'Authorization': `Bearer ${apiKey}`
}
AUTH_INVALID
Status: 401 Unauthorized
{
"success": false,
"error": {
"code": "AUTH_INVALID",
"message": "Invalid API key or token"
}
}
Solution: Verify your API key is correct and hasn’t been revoked.
AUTH_EXPIRED
Status: 401 Unauthorized
{
"success": false,
"error": {
"code": "AUTH_EXPIRED",
"message": "Token has expired",
"details": {
"expiredAt": "2024-01-15T10:00:00Z"
}
}
}
Solution: Refresh your token or generate a new API key.
Validation Errors
VALIDATION_ERROR
Status: 422 Unprocessable Entity
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"fields": {
"email": ["Email is required", "Email format is invalid"],
"phone": ["Phone number must be in E.164 format"]
}
}
}
}
Solution: Fix the validation errors and retry the request.
Rate Limiting
RATE_LIMIT_EXCEEDED
Status: 429 Too Many Requests
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded",
"details": {
"limit": 100,
"remaining": 0,
"resetAt": "2024-01-15T11:00:00Z"
}
}
}
Solution: Wait until resetAt or upgrade your plan for higher limits.
Resource Errors
RESOURCE_NOT_FOUND
Status: 404 Not Found
{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Conversation not found",
"details": {
"resource": "conversation",
"id": "conv_123"
}
}
}
Solution: Verify the resource ID exists and you have access to it.
RESOURCE_CONFLICT
Status: 409 Conflict
{
"success": false,
"error": {
"code": "RESOURCE_CONFLICT",
"message": "Resource already exists",
"details": {
"resource": "api_key",
"conflict": "Key with this name already exists"
}
}
}
Solution: Use a different identifier or update the existing resource.
Permission Errors
PERMISSION_DENIED
Status: 403 Forbidden
{
"success": false,
"error": {
"code": "PERMISSION_DENIED",
"message": "Insufficient permissions",
"details": {
"required": "write:conversations",
"granted": ["read:conversations"]
}
}
}
Solution: Use an API key with the required permissions or contact your administrator.
Plan Limits
PLAN_LIMIT_EXCEEDED
Status: 403 Forbidden
{
"success": false,
"error": {
"code": "PLAN_LIMIT_EXCEEDED",
"message": "Plan limit exceeded",
"details": {
"limit": 1000,
"current": 1001,
"resource": "api_calls_per_month"
}
}
}
Solution: Upgrade your plan or wait for the next billing cycle.
Error Handling Examples
JavaScript/TypeScript
async function handleApiRequest(url: string, options: RequestInit) {
try {
const response = await fetch(url, options);
const data = await response.json();
if (!response.ok) {
throw new ApiError(data.error, response.status);
}
return data;
} catch (error) {
if (error instanceof ApiError) {
// Handle API errors
switch (error.code) {
case 'AUTH_REQUIRED':
case 'AUTH_INVALID':
case 'AUTH_EXPIRED':
// Redirect to login or refresh token
await refreshAuth();
break;
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
await waitForRateLimit(error.details.resetAt);
break;
case 'VALIDATION_ERROR':
// Show validation errors to user
showValidationErrors(error.details.fields);
break;
default:
// Show generic error
showError(error.message);
}
} else {
// Handle network errors
showError('Network error. Please check your connection.');
}
throw error;
}
}
class ApiError extends Error {
constructor(
public error: {
code: string;
message: string;
details?: any;
},
public status: number
) {
super(error.message);
this.name = 'ApiError';
}
get code() {
return this.error.code;
}
get details() {
return this.error.details;
}
}
Python
import requests
from typing import Dict, Any
class ApiError(Exception):
def __init__(self, error: Dict[str, Any], status_code: int):
self.code = error.get('code')
self.message = error.get('message')
self.details = error.get('details', {})
self.status_code = status_code
super().__init__(self.message)
def handle_api_request(url: str, method: str = 'GET', **kwargs) -> Dict:
try:
response = requests.request(method, url, **kwargs)
data = response.json()
if not response.ok:
raise ApiError(data.get('error', {}), response.status_code)
return data
except requests.exceptions.RequestException as e:
# Handle network errors
raise Exception(f'Network error: {str(e)}')
# Usage with error handling
try:
result = handle_api_request(
'https://api.g-tateth.com/api/v1/conversations',
headers={'Authorization': f'Bearer {api_key}'}
)
except ApiError as e:
if e.code == 'AUTH_REQUIRED':
# Refresh authentication
refresh_auth()
elif e.code == 'RATE_LIMIT_EXCEEDED':
# Wait and retry
wait_for_rate_limit(e.details.get('resetAt'))
else:
print(f'API Error: {e.message}')
PHP
<?php
class ApiError extends Exception {
public $code;
public $details;
public $statusCode;
public function __construct($error, $statusCode) {
$this->code = $error['code'] ?? 'UNKNOWN_ERROR';
$this->details = $error['details'] ?? [];
$this->statusCode = $statusCode;
parent::__construct($error['message'] ?? 'Unknown error');
}
}
function handleApiRequest($url, $options = []) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $options['headers'] ?? [],
CURLOPT_CUSTOMREQUEST => $options['method'] ?? 'GET',
CURLOPT_POSTFIELDS => isset($options['body']) ? json_encode($options['body']) : null,
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($statusCode >= 400) {
throw new ApiError($data['error'] ?? [], $statusCode);
}
return $data;
}
// Usage
try {
$result = handleApiRequest(
'https://api.g-tateth.com/api/v1/conversations',
[
'headers' => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]
]
);
} catch (ApiError $e) {
switch ($e->code) {
case 'AUTH_REQUIRED':
refreshAuth();
break;
case 'RATE_LIMIT_EXCEEDED':
waitForRateLimit($e->details['resetAt']);
break;
default:
echo "API Error: " . $e->getMessage();
}
}
Retry Logic
Implement exponential backoff for retryable errors:
async function retryRequest(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;
// Only retry on specific errors
const retryableErrors = [
'RATE_LIMIT_EXCEEDED',
'SERVER_ERROR',
'TIMEOUT'
];
if (!retryableErrors.includes(error.code)) {
throw error;
}
// Exponential backoff: 1s, 2s, 4s
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
Best Practices
1. Always Check Response Status
// ❌ Bad
const data = await response.json();
// ✅ Good
if (!response.ok) {
const error = await response.json();
throw new ApiError(error.error, response.status);
}
const data = await response.json();
2. Handle Network Errors
try {
const response = await fetch(url);
} catch (error) {
if (error instanceof TypeError) {
// Network error
console.error('Network error:', error.message);
} else {
// Other error
throw error;
}
}
3. Log Errors for Debugging
catch (error) {
console.error('API Error:', {
code: error.code,
message: error.message,
details: error.details,
requestId: error.requestId,
url: error.url
});
throw error;
}
4. Provide User-Friendly Messages
const errorMessages = {
'AUTH_REQUIRED': 'Please log in to continue',
'RATE_LIMIT_EXCEEDED': 'Too many requests. Please try again later.',
'VALIDATION_ERROR': 'Please check your input and try again.',
'RESOURCE_NOT_FOUND': 'The requested item could not be found.'
};
function getUserMessage(error) {
return errorMessages[error.code] || error.message;
}
5. Use Request IDs for Support
Always include the requestId when contacting support:
catch (error) {
if (error.requestId) {
console.error(`Request ID: ${error.requestId}`);
// Include in support ticket
}
}
Testing Error Handling
Test your error handling with different scenarios:
// Test authentication errors
test('handles invalid API key', async () => {
const response = await apiRequest('/conversations', {
headers: { 'Authorization': 'Bearer invalid' }
});
expect(response.status).toBe(401);
});
// Test validation errors
test('handles validation errors', async () => {
const response = await apiRequest('/conversations', {
method: 'POST',
body: { invalid: 'data' }
});
expect(response.status).toBe(422);
});
// Test rate limiting
test('handles rate limits', async () => {
// Make many requests
for (let i = 0; i < 100; i++) {
await apiRequest('/conversations');
}
const response = await apiRequest('/conversations');
expect(response.status).toBe(429);
});
Support
If you encounter an error that isn’t documented here:
- Check the error
requestId in the response
- Review the error
details for additional context
- Contact support with the
requestId and error details
- Check our status page for service issues
Support Email: support@g-tateth.com