Error Codes
Complete list of API error codes and their meanings. All errors follow a consistent format to help you handle them programmatically.
Error Response Format
All API errors return a consistent JSON structure:
{
"statusCode": 400,
"code": "ERR_LIMIT_001",
"message": "PDF generation exceeded maximum page limit",
"timestamp": "2025-12-09T10:30:00.000Z",
"path": "/api/attachments/generate",
"relatedInfo": {
"actualPages": 45,
"maxPages": 30,
"message": "PDF generation exceeded 30 page limit. Your PDF has 45 pages."
}
}| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP status code (400, 401, 403, 404, 429, 500) |
code | string | Unique error code for programmatic handling |
message | string | Human-readable error message |
timestamp | string | ISO 8601 timestamp when error occurred |
path | string | API endpoint that generated the error |
relatedInfo | object | Additional context (varies by error type) |
Attachment Limit Errors
These errors occur when attachment generation exceeds “Safe Harbor” limits. All return 400 Bad Request.
See Limits & Quotas for complete limit documentation.
| Code | Error | Description |
|---|---|---|
ERR_LIMIT_001 | PDF Page Limit | PDF generation exceeded 30 page limit |
ERR_LIMIT_002 | PDF Image Limit | PDF contains more than 50 images |
ERR_LIMIT_003 | Excel Row Limit | Excel data exceeded 10,000 row limit |
ERR_LIMIT_004 | Excel Sheet Limit | Workbook exceeded 10 sheet limit |
ERR_LIMIT_005 | Excel Column Limit | Sheet exceeded 50 column limit |
ERR_LIMIT_006 | File Size Limit | Generated file exceeds 7 MB |
ERR_LIMIT_007 | Loop Iteration Limit | Loop exceeded 1,000 iteration limit |
ERR_LIMIT_008 | Nesting Depth | Template exceeded 10 level nesting depth |
ERR_LIMIT_009 | Component Count | Template exceeded 500 component limit |
Example: PDF Page Limit Error
{
"statusCode": 400,
"code": "ERR_LIMIT_001",
"message": "PDF generation exceeded maximum page limit",
"relatedInfo": {
"actualPages": 45,
"maxPages": 30,
"message": "PDF generation exceeded 30 page limit. Your PDF has 45 pages."
}
}Example: Loop Iteration Error
{
"statusCode": 400,
"code": "ERR_LIMIT_007",
"message": "Loop exceeded maximum iteration limit",
"relatedInfo": {
"actualIterations": 2500,
"maxIterations": 1000,
"loopId": "items",
"message": "Loop \"items\" has 2,500 items but maximum is 1,000. Consider pagination or splitting data."
}
}Authentication Errors
| Code | HTTP | Description |
|---|---|---|
ERR_AUTH_001 | 401 | Invalid credentials |
ERR_AUTH_002 | 401 | Missing authentication |
ERR_AUTH_003 | 401 | Invalid API key |
ERR_AUTH_004 | 401 | Token expired |
ERR_AUTH_005 | 403 | Insufficient permissions |
ERR_AUTH_006 | 401 | Invalid refresh token |
ERR_AUTH_007 | 429 | Too many login attempts |
Template Errors
| Code | HTTP | Description |
|---|---|---|
ERR_TMPL_001 | 404 | Template not found |
ERR_TMPL_002 | 404 | Template version not found |
ERR_TMPL_003 | 400 | Invalid template schema |
ERR_TMPL_004 | 400 | Variable validation failed |
ERR_TMPL_005 | 400 | Invalid component type |
ERR_TMPL_006 | 400 | Duplicate component ID |
ERR_TMPL_007 | 400 | Invalid slug format |
ERR_TMPL_008 | 409 | Slug already exists |
Email Errors
| Code | HTTP | Description |
|---|---|---|
ERR_EMAIL_001 | 400 | Invalid recipient email |
ERR_EMAIL_002 | 400 | Missing required variable |
ERR_EMAIL_003 | 400 | Invalid sender address |
ERR_EMAIL_004 | 402 | Insufficient email credits |
ERR_EMAIL_005 | 404 | Email log not found |
ERR_EMAIL_006 | 400 | Recipient on suppression list |
ERR_EMAIL_007 | 400 | Batch size exceeded |
Rate Limit Errors
| Code | HTTP | Description |
|---|---|---|
ERR_QUOTA_001 | 429 | Rate limit exceeded |
ERR_QUOTA_002 | 402 | Monthly quota exceeded |
ERR_QUOTA_003 | 429 | Concurrent request limit |
Example: Rate Limit Error
{
"statusCode": 429,
"code": "ERR_QUOTA_001",
"message": "Rate limit exceeded. Please retry after 45 seconds.",
"retryAfter": 45
}Validation Errors
| Code | HTTP | Description |
|---|---|---|
ERR_VALID_001 | 400 | Missing required field |
ERR_VALID_002 | 400 | Invalid field type |
ERR_VALID_003 | 400 | Field exceeds max length |
ERR_VALID_004 | 400 | Invalid enum value |
ERR_VALID_005 | 400 | Invalid date format |
OAuth Errors
| Code | HTTP | Description |
|---|---|---|
ERR_OAUTH_001 | 400 | Invalid client ID |
ERR_OAUTH_002 | 400 | Invalid redirect URI |
ERR_OAUTH_003 | 400 | Invalid scope |
ERR_OAUTH_004 | 400 | Invalid authorization code |
ERR_OAUTH_005 | 401 | Client authentication failed |
ERR_OAUTH_006 | 400 | Invalid grant type |
ERR_OAUTH_007 | 403 | Insufficient scope |
System Errors
| Code | HTTP | Description |
|---|---|---|
ERR_SYS_001 | 500 | Internal server error |
ERR_SYS_002 | 503 | Service temporarily unavailable |
ERR_SYS_003 | 504 | Request timeout |
ERR_SYS_004 | 500 | Database connection error |
Handling Errors
JavaScript/TypeScript
try {
const response = await formamail.emails.send(payload);
} catch (error) {
if (error.code === 'ERR_LIMIT_007') {
// Handle loop iteration limit
console.log(`Loop "${error.relatedInfo.loopId}" has too many items`);
// Consider pagination or splitting data
} else if (error.code === 'ERR_QUOTA_001') {
// Handle rate limit
await sleep(error.retryAfter * 1000);
// Retry the request
} else if (error.statusCode === 400) {
// Handle validation errors
console.log('Validation error:', error.message);
}
}Best Practices
- Check error codes programmatically - Don’t rely on error messages, they may change
- Handle rate limits gracefully - Implement exponential backoff
- Validate data client-side - Check array sizes before calling API
- Log relatedInfo - Contains valuable debugging context
Back to API Reference