The GetBill API uses conventional HTTP response codes to indicate the success or failure of an API request. All error responses follow a consistent JSON format:
{
"error" : true ,
"message" : "A human-readable error message" ,
"code" : 400 ,
"details" : {
"field_name" : [ "Specific field error message" ]
}
}
Always true for error responses
A human-readable description of the error
Additional error details, often including field-specific validation errors
HTTP Status Codes
200 OK : The request was successful
201 Created : A new resource was successfully created
400 Bad Request : The request was invalid or malformed
401 Unauthorized : Authentication credentials are missing or invalid
403 Forbidden : The authenticated user doesn’t have permission to access the resource
404 Not Found : The requested resource doesn’t exist
422 Unprocessable Entity : The request is valid but contains semantic errors
429 Too Many Requests : Rate limit exceeded
500 Internal Server Error : An unexpected error occurred on the server
502 Bad Gateway : The server received an invalid response from an upstream server
503 Service Unavailable : The service is temporarily unavailable
504 Gateway Timeout : The server didn’t receive a response from an upstream server in time
Common Error Scenarios
Authentication Errors
{
"error" : true ,
"message" : "Authentication credentials are missing or invalid" ,
"code" : 401
}
Solution : Ensure you’re including a valid access token in the Authorization header.
Authorization Errors
{
"error" : true ,
"message" : "Required scope \" debts:write \" not found in token" ,
"code" : 403
}
Solution : Request the appropriate scopes when obtaining your access token.
Validation Errors
{
"error" : true ,
"message" : "Validation failed" ,
"code" : 400 ,
"details" : {
"firstname" : [ "First name is required" ],
"amount" : [ "Valid amount is required" ],
"phone" : [ "Phone number is required" ]
}
}
Solution : Check the details object for field-specific errors and correct your request data.
Resource Not Found
{
"error" : true ,
"message" : "Debt not found or invalid ID" ,
"code" : 404
}
Solution : Verify the resource ID exists and you have permission to access it.
Rate Limiting
{
"error" : true ,
"message" : "Rate limit exceeded. Please try again later." ,
"code" : 429 ,
"details" : {
"retry_after" : 60 ,
"limit" : 100 ,
"reset_time" : "2024-01-15T10:30:00Z"
}
}
Solution : Implement exponential backoff and respect the retry_after value.
Error Handling Best Practices
1. Implement Proper Error Handling
async function createDebt ( debtData ) {
try {
const response = await fetch ( '/external-api/v1/debts' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( debtData )
});
if ( ! response . ok ) {
const error = await response . json ();
if ( response . status === 401 ) {
// Handle authentication error
await refreshToken ();
return createDebt ( debtData ); // Retry
}
if ( response . status === 400 && error . details ) {
// Handle validation errors
handleValidationErrors ( error . details );
return ;
}
throw new Error ( error . message );
}
return await response . json ();
} catch ( error ) {
console . error ( 'Failed to create debt:' , error );
throw error ;
}
}
2. Implement Retry Logic
async function apiRequestWithRetry ( url , options , maxRetries = 3 ) {
let retries = 0 ;
while ( retries < maxRetries ) {
try {
const response = await fetch ( url , options );
if ( response . status === 429 ) {
// Rate limited - wait and retry
const retryAfter = response . headers . get ( 'Retry-After' ) || 1 ;
await sleep ( retryAfter * 1000 );
retries ++ ;
continue ;
}
if ( response . status >= 500 ) {
// Server error - exponential backoff
await sleep ( Math . pow ( 2 , retries ) * 1000 );
retries ++ ;
continue ;
}
return response ;
} catch ( error ) {
if ( retries === maxRetries - 1 ) throw error ;
await sleep ( Math . pow ( 2 , retries ) * 1000 );
retries ++ ;
}
}
}
3. Log Errors for Debugging
function logApiError ( endpoint , error , requestData = null ) {
console . error ( 'API Error:' , {
endpoint ,
status: error . code ,
message: error . message ,
details: error . details ,
requestData ,
timestamp: new Date (). toISOString ()
});
}
4. Handle Specific Error Types
Network Errors
Timeout Errors
Token Expiry
catch ( error ) {
if ( error instanceof TypeError && error . message . includes ( 'fetch' )) {
// Network connectivity issue
showNetworkErrorMessage ();
return ;
}
throw error ;
}
const controller = new AbortController ();
const timeoutId = setTimeout (() => controller . abort (), 10000 );
try {
const response = await fetch ( url , {
... options ,
signal: controller . signal
});
clearTimeout ( timeoutId );
return response ;
} catch ( error ) {
if ( error . name === 'AbortError' ) {
throw new Error ( 'Request timeout' );
}
throw error ;
}
async function makeAuthenticatedRequest ( url , options ) {
let response = await fetch ( url , {
... options ,
headers: {
... options . headers ,
'Authorization' : `Bearer ${ getAccessToken () } `
}
});
if ( response . status === 401 ) {
// Token expired, refresh and retry
await refreshAccessToken ();
response = await fetch ( url , {
... options ,
headers: {
... options . headers ,
'Authorization' : `Bearer ${ getAccessToken () } `
}
});
}
return response ;
}
Debugging Tips
Important headers to examine:
X-RateLimit-Remaining: Number of requests remaining in the current window
X-RateLimit-Reset: When the rate limit window resets
Retry-After: How long to wait before retrying (for 429 responses)
Common issues:
Missing or incorrect Content-Type header
Malformed JSON in request body
Invalid field values or types
Missing required fields
Test your requests using tools like:
Postman
curl
Insomnia
HTTPie
4. Enable Debug Logging
Include request/response logging in your application to track API interactions and identify patterns in errors.
Support
If you encounter persistent errors or need help with error handling:
Check our Status Page for ongoing incidents
Review the specific endpoint documentation
Contact support at contact@getbill.io with:
The specific error message
Your request details (without sensitive data)
Steps to reproduce the issue