Skip to main content

Error Handling

Learn how to handle errors when working with the Stateless API.

HTTP Status Codes

The Stateless API uses standard HTTP status codes:

Status CodeMeaningDescription
200OKRequest successful
400Bad RequestInvalid request format or validation error
401UnauthorizedMissing or invalid API key
403ForbiddenValid API key but insufficient permissions
404Not FoundEndpoint or resource not found
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side error
503Service UnavailableTemporary service disruption

Error Response Format

All error responses follow a consistent format:

{
"error": "ErrorType",
"message": "Human-readable error description",
"code": "specific_error_code",
"details": {
"field": "field_name",
"reason": "Additional context"
}
}

Fields

  • error: Error type category (e.g., ValidationError, AuthenticationError)
  • message: Human-readable description of the error
  • code: Machine-readable error code for programmatic handling (optional)
  • details: Additional context about the error (optional)

Common Errors

Authentication Errors (401)

{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}

Solution: Verify your API key is correct and included in the Authorization header.

Validation Errors (400)

{
"error": "ValidationError",
"message": "Validation failed",
"code": "form_id_missing",
"details": {
"field": "form_id",
"reason": "The form_id field is required"
}
}

Solution: Check the error code and details to identify which field failed validation.

Rate Limiting (429)

{
"error": "RateLimitExceeded",
"message": "Too many requests. Please try again later.",
"details": {
"retryAfter": 60
}
}

Solution: Implement exponential backoff and respect the retryAfter value.

Error Handling Best Practices

1. Handle Errors Gracefully

async function submitForm(data: any) {
try {
const response = await fetch('https://api.statelessapp.com/api/v1/forms/accept-submission', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.STATELESS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});

if (!response.ok) {
const error = await response.json();
throw new Error(`API Error: ${error.message}`);
}

return await response.json();
} catch (error) {
console.error('Form submission failed:', error);
throw error;
}
}

2. Retry Transient Errors

async function submitFormWithRetry(data: any, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await submitForm(data);
} catch (error: any) {
// Retry on 5xx errors or network issues
if (attempt === maxRetries ||
(error.status >= 400 && error.status < 500)) {
throw error;
}

// Exponential backoff
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

3. Handle Validation Errors

async function submitFormWithValidation(data: any) {
try {
return await submitForm(data);
} catch (error: any) {
if (error.code === 'form_id_missing') {
console.error('Form ID is required');
} else if (error.code === 'consent_missing') {
console.error('At least one consent must be granted');
} else if (error.code?.startsWith('consent_to_general_contact_email')) {
console.error('Email consent error:', error.message);
}
throw error;
}
}

4. Log Errors for Debugging

function logApiError(error: any, context: any) {
console.error('API Error:', {
timestamp: new Date().toISOString(),
error: error.error,
message: error.message,
code: error.code,
details: error.details,
context,
});
}

5. Provide User-Friendly Messages

function getUserFriendlyErrorMessage(error: any): string {
const errorMessages: Record<string, string> = {
'form_id_missing': 'Invalid form configuration. Please contact support.',
'consent_missing': 'Please accept at least one consent option.',
'consent_to_general_contact_email_invalid': 'Please provide a valid email address.',
'consent_to_general_contact_phone_invalid': 'Please provide a valid phone number.',
};

return errorMessages[error.code] || 'An unexpected error occurred. Please try again.';
}

Debugging Tips

Check Request Format

Ensure your request matches the expected format:

  • Headers include Authorization and Content-Type
  • Body is valid JSON
  • Required fields are present

Validate API Key

Test your API key with a simple request:

curl -X POST https://api.statelessapp.com/api/v1/forms/accept-submission \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"form_id": "test"}'

Enable Detailed Logging

Log full request and response details during development:

async function submitFormWithLogging(data: any) {
console.log('Request:', JSON.stringify(data, null, 2));

try {
const response = await submitForm(data);
console.log('Response:', JSON.stringify(response, null, 2));
return response;
} catch (error) {
console.error('Error:', JSON.stringify(error, null, 2));
throw error;
}
}

Getting Help

If you encounter persistent errors:

  1. Check this documentation for error codes and solutions
  2. Review your request format against the API reference
  3. Contact support with:
    • Error message and code
    • Request details (without sensitive data)
    • Timestamp of the error