Error Handling
Comprehensive guide to handling errors and troubleshooting issues with the Magnetite API.
Error Response Format
All error responses follow this consistent structure:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": {
// Additional context when available
}
}
}success
Always false for error responses
error.code
Machine-readable error identifier for programmatic handling
error.message
Human-readable description suitable for display
HTTP Status Codes
Common Error Codes
Possible Causes
- API key is incorrect or malformed
- API key has been revoked or expired
- API key is not properly formatted in the Authorization header
Resolution
Verify your API key in the dashboard and ensure it's properly formatted in the Authorization header as 'Bearer sk_...'
Example Response
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid API key provided"
}
}Possible Causes
- Authorization header is missing from the request
- Header name is misspelled
- API key is missing from the header value
Resolution
Include the Authorization header with your API key: 'Authorization: Bearer sk_your_api_key'
Example Response
{
"success": false,
"error": {
"code": "MISSING_AUTHORIZATION",
"message": "Authorization header is required"
}
}Possible Causes
- Required fields are missing (companyName, contactName, or email)
- Field values are in the wrong format
- JSON structure is malformed
- Email address is invalid
Resolution
Check the API documentation for required fields and ensure all data is properly formatted
Example Response
{
"success": false,
"error": {
"code": "INVALID_REQUEST",
"message": "Missing required field: email",
"details": {
"field": "email",
"expected": "string",
"received": "undefined"
}
}
}Possible Causes
- Sending requests too frequently
- Multiple API clients using the same key
- Bulk operations exceeding rate limits
Resolution
Implement exponential backoff and respect the rate limit headers. Consider batching requests with appropriate delays.
Example Response
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Maximum 10 requests per 60 seconds allowed.",
"retryAfter": 45
}
}Possible Causes
- Campaign ID is incorrect or malformed
- Campaign has been deleted or deactivated
- API key doesn't have access to the campaign
Resolution
Verify the campaign ID in your dashboard and ensure your API key has the correct permissions
Example Response
{
"success": false,
"error": {
"code": "CAMPAIGN_NOT_FOUND",
"message": "Campaign not found: abc123def456ghi789jkl012mno345pq"
}
}Possible Causes
- Prospect ID is incorrect or malformed
- Prospect was not created successfully
- API key doesn't have access to the prospect
Resolution
Verify the prospect ID from the add lead response and ensure it was created successfully
Example Response
{
"success": false,
"error": {
"code": "PROSPECT_NOT_FOUND",
"message": "Prospect not found: prospect_xyz789"
}
}Possible Causes
- Email address already added to this campaign
- Lead was previously submitted via API or dashboard
- Duplicate submission in batch processing
Resolution
Check if the lead already exists before submitting, or handle the duplicate response gracefully
Example Response
{
"success": false,
"error": {
"code": "DUPLICATE_LEAD",
"message": "A lead with email john@acme.com already exists in this campaign",
"existingProspectId": "prospect_abc123"
}
}Possible Causes
- Campaign is paused or archived
- Campaign setup is incomplete
- Campaign has reached its lead limit
Resolution
Ensure the campaign is active in your dashboard before adding leads
Example Response
{
"success": false,
"error": {
"code": "CAMPAIGN_INACTIVE",
"message": "Campaign is not active. Current status: paused"
}
}Possible Causes
- Temporary server issue
- Database connectivity problem
- Unexpected system error
Resolution
This is usually temporary. Wait a moment and try again. If the issue persists, contact support.
Example Response
{
"success": false,
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred. Please try again later."
}
}Error Handling Best Practices
Don't rely solely on the response body. HTTP status codes provide important context:
async function handleApiResponse(response) {
if (!response.ok) {
const errorData = await response.json();
switch (response.status) {
case 401:
throw new AuthenticationError(errorData.error.message);
case 404:
throw new NotFoundError(errorData.error.message);
case 409:
throw new DuplicateLeadError(errorData.error.message);
case 429:
throw new RateLimitError(errorData.error.message, errorData.error.retryAfter);
case 500:
throw new ServerError(errorData.error.message);
default:
throw new ApiError(errorData.error.message, response.status);
}
}
return response.json();
}Some errors are transient and should be retried with exponential backoff:
async function makeRequestWithRetry(url, options, maxRetries = 3) {
const retryableStatuses = [429, 500, 502, 503, 504];
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.ok) {
return await response.json();
}
if (!retryableStatuses.includes(response.status)) {
throw new Error('Non-retryable error: ' + response.status);
}
if (attempt === maxRetries - 1) {
throw new Error('Max retries exceeded');
}
const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
console.log(`Retrying in ${delay}ms (attempt ${attempt + 1})`);
await new Promise(resolve => setTimeout(resolve, delay));
} catch (error) {
if (attempt === maxRetries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt)));
}
}
}Different error types require different logging levels:
function logApiError(error, context) {
const logData = {
timestamp: new Date().toISOString(),
context,
error: {
code: error.code,
message: error.message,
status: error.status
}
};
switch (error.status) {
case 401:
// Authentication issues - warn level
console.warn('API authentication error:', logData);
break;
case 429:
// Rate limiting - info level (expected during high usage)
console.info('API rate limit hit:', logData);
break;
case 500:
case 502:
case 503:
case 504:
// Server errors - error level
console.error('API server error:', logData);
break;
default:
// Client errors - debug level
console.debug('API client error:', logData);
}
}Convert technical error messages into user-friendly ones:
function getUserFriendlyMessage(error) {
const friendlyMessages = {
INVALID_API_KEY: 'There was an authentication issue. Please check your API configuration.',
CAMPAIGN_NOT_FOUND: 'The specified campaign could not be found. Please verify the campaign ID.',
DUPLICATE_LEAD: 'This contact has already been added to the campaign.',
RATE_LIMIT_EXCEEDED: 'You\'re sending requests too quickly. Please wait a moment before trying again.',
CAMPAIGN_INACTIVE: 'The campaign is not currently accepting new leads.',
INTERNAL_SERVER_ERROR: 'Something went wrong on our end. Please try again in a few moments.'
};
return friendlyMessages[error.code] || 'An unexpected error occurred. Please try again or contact support if the issue persists.';
}When importing leads in bulk, handle duplicates without failing the entire batch:
async function importLeadsWithDuplicateHandling(leads, campaignId, apiKey) {
const results = {
added: [],
duplicates: [],
errors: []
};
for (const lead of leads) {
try {
const response = await fetch(
`https://magnetite.ai/api/campaigns/${campaignId}/leads`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(lead)
}
);
const data = await response.json();
if (response.ok) {
results.added.push({ lead, prospectId: data.prospectId });
} else if (data.error?.code === 'DUPLICATE_LEAD') {
// Handle duplicate gracefully
results.duplicates.push({
lead,
existingProspectId: data.error.existingProspectId
});
} else {
results.errors.push({ lead, error: data.error });
}
} catch (error) {
results.errors.push({ lead, error: error.message });
}
// Respect rate limits
await new Promise(resolve => setTimeout(resolve, 1000));
}
return results;
}Need More Help?
If you're experiencing errors not covered here or need additional assistance: