Documentation Index Fetch the complete documentation index at: https://docs.humanly.io/llms.txt
Use this file to discover all available pages before exploring further.
Overview
This guide covers how to handle errors and edge cases when using the Gather API. Proper error handling ensures your integration is robust and provides a good user experience.
All errors follow a consistent format:
{
"error" : {
"code" : "ERROR_CODE" ,
"message" : "Human-readable error message" ,
"details" : {
// Additional error details
}
},
"meta" : {
"requestId" : "uuid" ,
"timestamp" : "2024-01-01T00:00:00Z"
}
}
HTTP Status Codes
400 Bad Request
Invalid request parameters or malformed request body.
{
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "Invalid request parameters" ,
"details" : {
"field" : "email" ,
"reason" : "Invalid email format"
}
}
}
Action : Review the error details and fix the request parameters.
401 Unauthorized
Invalid or missing authentication credentials.
{
"error" : {
"code" : "UNAUTHORIZED" ,
"message" : "Invalid or missing authentication credentials"
}
}
Action : Verify your API credentials are correct and properly formatted.
404 Not Found
Resource not found.
{
"error" : {
"code" : "NOT_FOUND" ,
"message" : "Resource not found" ,
"details" : {
"resource" : "interview" ,
"id" : "uuid"
}
}
}
Action : Verify the resource ID exists and you have access to it.
429 Too Many Requests
Rate limit exceeded.
{
"error" : {
"code" : "RATE_LIMIT_EXCEEDED" ,
"message" : "Rate limit exceeded. Please try again later." ,
"details" : {
"limit" : 1000 ,
"remaining" : 0 ,
"resetAt" : "2024-01-01T01:00:00Z"
}
}
}
Action : Implement exponential backoff and retry after the reset time.
500 Internal Server Error
Server error.
{
"error" : {
"code" : "INTERNAL_ERROR" ,
"message" : "An internal error occurred"
}
}
Action : Retry the request with exponential backoff. If the error persists, contact support.
Error Handling Patterns
Retry Logic
Implement retry logic for transient errors (429, 500):
async function makeRequestWithRetry ( url , options , maxRetries = 3 ) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
const response = await fetch ( url , options );
if ( response . status === 429 ) {
const resetTime = parseInt ( response . headers . get ( 'X-RateLimit-Reset' ));
const waitTime = Math . max (( resetTime * 1000 ) - Date . now (), 0 );
if ( i < maxRetries - 1 ) {
await new Promise ( resolve => setTimeout ( resolve , waitTime ));
continue ;
}
}
if ( ! response . ok && response . status >= 500 && i < maxRetries - 1 ) {
await new Promise ( resolve => setTimeout ( resolve , Math . pow ( 2 , i ) * 1000 ));
continue ;
}
return response ;
} catch ( error ) {
if ( i === maxRetries - 1 ) throw error ;
await new Promise ( resolve => setTimeout ( resolve , Math . pow ( 2 , i ) * 1000 ));
}
}
}
import time
import requests
def make_request_with_retry ( url , headers , max_retries = 3 ):
for i in range (max_retries):
try :
response = requests.get(url, headers = headers)
if response.status_code == 429 :
reset_time = int (response.headers.get( 'X-RateLimit-Reset' , 0 ))
wait_time = max (reset_time - int (time.time()), 0 )
if i < max_retries - 1 :
time.sleep(wait_time)
continue
if response.status_code >= 500 and i < max_retries - 1 :
time.sleep( 2 ** i)
continue
return response
except Exception as e:
if i == max_retries - 1 :
raise
time.sleep( 2 ** i)
Validation Error Handling
Handle validation errors gracefully:
async function createQuestion ( questionData ) {
try {
const response = await fetch ( 'https://api.prod.qualifi.hr/qsi/gather/questions' , {
method: 'POST' ,
headers: {
'x-api-key' : apiKey ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( questionData )
});
if ( ! response . ok ) {
const error = await response . json ();
if ( response . status === 400 ) {
// Handle validation errors
console . error ( 'Validation error:' , error . error . details );
// Show user-friendly error messages
return { error: error . error . message };
}
throw new Error ( error . error . message );
}
return await response . json ();
} catch ( error ) {
console . error ( 'Request failed:' , error );
throw error ;
}
}
Common Error Scenarios
Invalid Credentials
Symptom : 401 Unauthorized
Solution :
Verify credentials are correct
Check that your API key is correctly formatted and prefixed with qapi_
Ensure using organizationId:apiKey (not reversed)
Resource Not Found
Symptom : 404 Not Found
Solution :
Verify resource ID exists
Check you have access to the resource
Ensure using correct endpoint path
Rate Limit Exceeded
Symptom : 429 Too Many Requests
Solution :
Implement exponential backoff
Monitor rate limit headers
Cache responses when possible
Reduce request frequency
Network Errors
Symptom : Connection timeout or network errors
Solution :
Implement retry logic
Use connection pooling
Set appropriate timeouts
Handle network failures gracefully
Best Practices
Always Check Status Codes : Don’t assume requests succeed
Log Errors : Log errors with request IDs for debugging
User-Friendly Messages : Translate technical errors to user-friendly messages
Retry Strategically : Retry transient errors, not client errors
Handle Edge Cases : Plan for network failures, timeouts, and partial failures
Monitor Error Rates : Track error rates and types to identify issues
Rate Limits Learn about rate limits and throttling
Best Practices Review API best practices