Skip to main content

Errors

The Benchmark Email API uses standard HTTP status codes and returns structured error responses to help you diagnose and handle problems.

Error Response Format

All errors return a JSON body with an errors array:
{
  "errors": [
    {
      "errorType": "ForbiddenError",
      "message": "API key missing required scope: contacts:write"
    }
  ]
}
Each error object contains:
FieldTypeDescription
errorTypestringThe error class name (e.g., UnauthorizedError, ForbiddenError, ValidationError)
messagestringA human-readable description of what went wrong
The errors array typically contains a single error object. Validation errors may include additional fields like field or fieldId to identify the problematic input.

HTTP Status Codes

StatusMeaningWhen It Happens
400Bad RequestInvalid request body, missing required fields, validation failures, duplicate values
401UnauthorizedInvalid, expired, or inactive API key
403ForbiddenValid key but missing required scope, or account not in good standing
404Not FoundRequested resource does not exist
429Too Many RequestsHourly rate limit or monthly quota exceeded, or IP temporarily blocked

Common Error Scenarios

Invalid API Key (401)

Returned when the API key is malformed, does not exist, or has been deleted.
curl -H "X-API-Key: bme_invalid_key_value" \
  https://api-us1-1.benchmarkemail.com/api/contact
HTTP/1.1 401 Unauthorized
{
  "errors": [
    {
      "errorType": "UnauthorizedError",
      "message": "Invalid API key"
    }
  ]
}
For security reasons, the error message does not distinguish between a malformed key, a nonexistent key, or a deleted key.

Expired API Key (401)

Returned when the API key’s expiration date has passed.
HTTP/1.1 401 Unauthorized
{
  "errors": [
    {
      "errorType": "UnauthorizedError",
      "message": "API key expired"
    }
  ]
}
To resolve this, create a new API key or regenerate the expired one from the API Keys page.

Inactive API Key (401)

Returned when the API key has been deactivated by the account owner.
HTTP/1.1 401 Unauthorized
{
  "errors": [
    {
      "errorType": "UnauthorizedError",
      "message": "Invalid API key"
    }
  ]
}
Inactive keys return the same generic message as invalid keys. Reactivate the key from the API Keys page to restore access.

Missing Required Scope (403)

Returned when the API key is valid but does not have the scope required for the requested operation. The error message tells you which scope is needed.
# Attempting to create a contact with a read-only key
curl -X POST \
  -H "X-API-Key: bme_abc123def456ghi789jkl012mno345pqr678stu90v" \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com"}' \
  https://api-us1-1.benchmarkemail.com/api/contact
HTTP/1.1 403 Forbidden
{
  "errors": [
    {
      "errorType": "ForbiddenError",
      "message": "API key missing required scope: contacts:write"
    }
  ]
}
To resolve this, either:
  • Edit the key’s scopes from the API Keys page to add the required permission.
  • Create a new key with the appropriate scopes.

Endpoint Not Accessible via API Key (403)

Returned when the endpoint is not available for API key access (e.g., billing, user management, or admin endpoints).
HTTP/1.1 403 Forbidden
{
  "errors": [
    {
      "errorType": "ForbiddenError",
      "message": "This endpoint is not accessible via API key"
    }
  ]
}
Only endpoints listed in the API Reference and OpenAPI spec are accessible via API key.

Account Not in Good Standing (403)

Returned when the API key is valid but the account status does not allow API access (e.g., suspended, past due, or terminated accounts).
HTTP/1.1 403 Forbidden
{
  "errors": [
    {
      "errorType": "ForbiddenError",
      "message": "Account does not have API access"
    }
  ]
}
API keys work when the account status is open or pending_cancel. See Authentication for details.

Resource Not Found (404)

Returned when the requested resource does not exist.
curl -H "X-API-Key: bme_abc123def456ghi789jkl012mno345pqr678stu90v" \
  https://api-us1-1.benchmarkemail.com/api/contact/000000000000000000000000
HTTP/1.1 404 Not Found
{
  "errors": [
    {
      "errorType": "RecordNotFound",
      "message": "Contact not found"
    }
  ]
}

Validation Error (400)

Returned when the request body fails validation (e.g., missing required fields, invalid field values).
curl -X POST \
  -H "X-API-Key: bme_abc123def456ghi789jkl012mno345pqr678stu90v" \
  -H "Content-Type: application/json" \
  -d '{"key": "test@example.com"}' \
  https://api-us1-1.benchmarkemail.com/api/contact
HTTP/1.1 400 Bad Request
{
  "errors": [
    {
      "errorType": "ValidationError",
      "message": "contactStructureId is required",
      "field": "contactStructureId"
    }
  ]
}

Duplicate Field (400)

Returned when the operation conflicts with existing data (e.g., creating an API key with a name that already exists).
HTTP/1.1 400 Bad Request
{
  "errors": [
    {
      "errorType": "DuplicateFieldError",
      "message": "API key name is already in use"
    }
  ]
}

Rate Limit Exceeded (429)

Returned when the hourly rate limit or monthly quota is exceeded. See Rate Limits for full details. Hourly limit exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 3600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711828800
{
  "errors": [
    {
      "errorType": "TooManyRequestsError",
      "message": "Rate limit exceeded. Retry after 45 seconds."
    }
  ]
}
Monthly quota exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 86400
{
  "errors": [
    {
      "errorType": "TooManyRequestsError",
      "message": "Monthly API quota exceeded."
    }
  ]
}
The Retry-After header indicates the number of seconds to wait before retrying. For hourly limits, this is the time until the current window resets. For monthly quotas, this is the time until the billing period resets.

IP Temporarily Blocked (429)

Returned when your IP address has been temporarily blocked due to too many failed authentication attempts.
HTTP/1.1 429 Too Many Requests
Retry-After: 900
{
  "errors": [
    {
      "errorType": "TooManyRequestsError",
      "message": "Too many failed authentication attempts. Please try again later."
    }
  ]
}
Stop retrying and verify your API key is correct. The block will automatically expire after the time indicated in Retry-After.

Error Handling Best Practices

  1. Always check the status code first. Use the HTTP status to determine the category of error before parsing the response body.
  2. Retry on 429 only. Use the Retry-After header to determine when to retry. Do not retry 401 or 403 errors — they will not resolve without configuration changes.
  3. Log the full error response. Include the errorType and message in your logs for debugging.
  4. Handle scope errors proactively. If you receive a 403 with a scope message, update your API key’s permissions in Settings rather than retrying the request.
  5. Use exponential backoff for rate limits. See the Rate Limits guide for retry strategies.

Next Steps