Skip to main content

Error Handling

All urelay API errors follow a consistent format, making it straightforward to handle failures in your application.

Error format

{
"error": {
"code": "error_code",
"message": "Human-readable description",
"details": {}
}
}

The details field is optional and provides additional context for specific error types.

Error codes

CodeHTTP StatusDescriptionRetryable
unauthorized401Invalid or missing API credentialsNo -- check your API key and secret
forbidden403Access denied to the requested resourceNo -- check permissions
not_found404Resource does not existNo
invalid_request400Malformed request body or parametersNo -- fix the request
rate_limit_exceeded429Daily new contact limit reachedYes -- wait until resets_at
phone_offline503The phone line is not availableYes -- retry after a delay
send_failed502Message could not be dispatchedYes -- retry once
internal_error500Unexpected server errorYes -- retry with backoff

Retry guidance

Safe to retry

  • 429 -- Wait until details.resets_at, or use a different phone line
  • 503 -- Phone line may come back online. Retry after 10-30 seconds.
  • 502 -- Transient failure. Retry once after 5 seconds.
  • 500 -- Retry with exponential backoff (1s, 2s, 4s, max 3 attempts)

Do not retry

  • 400 -- Fix the request payload
  • 401 -- Check API credentials
  • 403 -- Check resource access
  • 404 -- Resource does not exist

Example error handling

Node.js

const response = await fetch('https://app.urelay.ai/api/v1/messages/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey,
'X-API-Secret': apiSecret,
},
body: JSON.stringify({ to, text }),
});

if (!response.ok) {
const { error } = await response.json();

switch (error.code) {
case 'rate_limit_exceeded':
console.log(`Rate limited. Resets at: ${error.details.resets_at}`);
break;
case 'phone_offline':
console.log('Phone offline, retrying in 30s...');
break;
default:
console.error(`API error: ${error.code} - ${error.message}`);
}
}

Python

response = requests.post(
'https://app.urelay.ai/api/v1/messages/send',
headers={'X-API-Key': api_key, 'X-API-Secret': api_secret},
json={'to': to, 'text': text},
)

if response.status_code != 200:
error = response.json()['error']
if error['code'] == 'rate_limit_exceeded':
print(f"Rate limited until {error['details']['resets_at']}")
elif error['code'] == 'phone_offline':
print("Phone offline, will retry...")
else:
raise Exception(f"API error: {error['code']}: {error['message']}")