Error Handling
Understanding and handling API errors in your SuperSend integration.
SuperSend uses conventional HTTP response codes and returns detailed error information to help you handle issues gracefully.
V2 Standardized Errors
HTTP Status Codes
200201400401403404409422429500503Note: V2 uses 400 for all validation errors. V1 may use 422 in some endpoints.
V2 Error Response Format
All V2 errors follow this structure:
{
"error": {
"type": "invalid_request_error",
"code": "missing_required_parameter",
"message": "TeamId is required",
"param": "TeamId",
"doc_url": "https://docs.supersend.io/docs/error-handling#missing_required_parameter"
},
"request_id": "req_a1b2c3d4e5f6789012345678"
}typecodemessageparamdoc_urlrequest_idV1 Error Response Format
V1 responses vary but typically follow:
{
"success": false,
"error": "CampaignId is required"
}Or in some endpoints:
{
"error": "Not found"
}Error Types (V2)
invalid_request_errorauthentication_errorauthorization_errornot_found_errorconflict_errorrate_limit_errorapi_errorCommon Error Codes
Authentication Errors
invalid_api_key or missing_api_key
Your API key is missing or invalid.
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "Invalid API key provided"
}
}Fix: Include a valid Authorization: Bearer YOUR_API_KEY header.
team_access_denied
You don't have access to the requested team.
{
"error": {
"type": "authorization_error",
"code": "team_access_denied",
"message": "You do not have access to this team"
}
}Fix: Verify you're accessing a team your API key has access to.
Validation Errors
missing_required_parameter
A required parameter was not provided.
{
"error": {
"type": "invalid_request_error",
"code": "missing_required_parameter",
"message": "TeamId is required",
"param": "TeamId"
}
}Fix: Include the missing parameter in your request.
validation_error
Request data failed validation.
{
"error": {
"type": "invalid_request_error",
"code": "validation_error",
"message": "email must be a valid email address",
"param": "email"
}
}Fix: Ensure the parameter matches the expected format.
invalid_parameter_type
Parameter has wrong data type.
{
"error": {
"type": "invalid_request_error",
"code": "invalid_parameter_type",
"message": "limit must be a number",
"param": "limit"
}
}Resource Errors
resource_not_found
The requested resource doesn't exist.
{
"error": {
"type": "not_found_error",
"code": "resource_not_found",
"message": "Resource not found"
}
}Fix: Verify the resource ID is correct.
campaign_not_found
Campaign doesn't exist or you don't have access.
{
"error": {
"type": "not_found_error",
"code": "campaign_not_found",
"message": "Campaign not found"
}
}contact_not_found
Contact doesn't exist.
{
"error": {
"type": "not_found_error",
"code": "contact_not_found",
"message": "Contact not found"
}
}Business Logic Errors
insufficient_permissions
A usage limit has been exceeded or you don't have permission for this action.
{
"error": {
"type": "authorization_error",
"code": "insufficient_permissions",
"message": "Contact limit reached"
}
}Fix: Upgrade your plan or reduce usage to stay within limits.
duplicate_resource
Resource already exists.
{
"error": {
"type": "conflict_error",
"code": "duplicate_resource",
"message": "Contact with this email already exists in this campaign"
}
}Handling Errors
JavaScript/Node.js
async function makeApiRequest(url, options) {
try {
const response = await fetch(url, {
...options,
headers: {
'Authorization': Bearer ${process.env.SUPERSEND_API_KEY},
'Content-Type': 'application/json',
...options.headers
}
});
const data = await response.json();
if (!response.ok) {
// V2 error format
const error = data.error || {};
console.error(API Error [${error.code}]: ${error.message});
console.error(Request ID: ${data.request_id});
switch (error.type) {
case 'authentication_error':
throw new Error('Check your API key');
case 'not_found_error':
throw new Error('Resource not found');
case 'invalid_request_error':
throw new Error(Validation error: ${error.param});
default:
throw new Error(error.message || 'Unknown error');
}
}
return data;
} catch (err) {
console.error('Request failed:', err.message);
throw err;
}
}Python
import requestsdef make_api_request(url, method='GET', kwargs):
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json',
kwargs.get('headers', {})
}
response = requests.request(method, url, headers=headers, kwargs)
data = response.json()
if not response.ok:
error = data.get('error', {})
print(fclass="text-green-700 dark:text-green-400">"API Error [{error.get('code')}]: {error.get('message')}")
print(fclass="text-green-700 dark:text-green-400">"Request ID: {data.get('request_id')}")
if error.get('type') == 'authentication_error':
raise Exception('Check your API key')
elif error.get('type') == 'not_found_error':
raise Exception('Resource not found')
else:
raise Exception(error.get('message', 'Unknown error'))
return data
Request ID for Debugging
Every response includes a unique request_id:
"request_id": "req_a1b2c3d4e5f6789012345678"X-Request-Id: req_a1b2c3d4e5f6789012345678When contacting support, always include the request ID for faster debugging.
Best Practices
1. Check Error Types Programmatically
if (error.type === 'authentication_error') {
// Refresh token or re-authenticate
} else if (error.type === 'not_found_error') {
// Resource doesn't exist
} else if (error.type === 'invalid_request_error') {
// Fix request parameters
}2. Log Request IDs
Always log request IDs for troubleshooting:
console.log(Request ${data.request_id}: ${response.status});3. Handle Retries for Server Errors
Retry 5xx errors with exponential backoff:
async function retryRequest(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (err.status >= 500 && i < maxRetries - 1) {
await sleep(Math.pow(2, i) * 1000);
continue;
}
throw err;
}
}
}4. Don't Retry Client Errors
4xx errors indicate problems with your request. Fix the issue rather than retrying.