Skip to main content
AhaSend API errors use an HTTP status and a JSON message; this reference explains status codes and how your application should handle them.

Error Response Format

All API errors return a consistent JSON structure with an HTTP status code and a descriptive message:
The message field is human-readable text, not a stable error code. Use the HTTP status and the operation’s contract for program logic. When Send Campaign or Test Campaign refuses a campaign with issues, the 400 body also holds issues. Each issue has a stable code and a message. See Issues.

HTTP Status Codes

The AhaSend API uses standard HTTP status codes to indicate the success or failure of requests:

2xx Success

  • 200 OK - Request succeeded
  • 201 Created - Resource created successfully
  • 202 Accepted - Message accepted for processing; inspect each recipient’s status. Send Campaign also answers 202, with the campaign in validating

4xx Client Errors

400 Bad Request

Returned when the request is malformed or contains invalid parameters.
Common causes include invalid JSON, missing required fields, or parameters that don’t meet validation requirements.
Example scenarios:
  • Invalid UUID format for account_id or resource IDs
  • Malformed email addresses
  • Invalid time formats (expecting RFC3339)
  • Parameters outside allowed ranges (e.g., limit not between 1-100)
  • Invalid domain names or URLs
  • Malformed request body

401 Unauthorized

Authentication failed or is missing. Common causes:
  • Missing Authorization header
  • Invalid API key format (must be Bearer <api_key>)
  • API key doesn’t exist or has been revoked
  • Sending is paused on the account of the API key
  • API key doesn’t belong to the specified account

403 Forbidden

Authentication succeeded, but you don’t have permission to access the resource.
This typically occurs when your API key doesn’t have the required scopes for the operation you’re trying to perform.
Common causes:
  • API key lacks required scopes (e.g., trying to delete domains without domains:delete:all or domains:delete:{domain} scope)
  • Attempting to access resources outside your API key’s domain restrictions
  • Insufficient permissions for specific operations
  • Sending from the domain is paused. You cannot send from the domain or delete it. See paused domains.

404 Not Found

The requested resource doesn’t exist or you don’t have access to it. Common scenarios:
  • Resource ID doesn’t exist
  • Resource was deleted
  • Resource belongs to a different account

409 Conflict

The request conflicts with the current state of the resource. Common causes:
  • Idempotency conflicts: Another request with the same idempotency key is already in progress
  • Resource conflicts: Trying to create a resource that already exists (e.g., duplicate domain)
  • IP allow list conflicts: Updating your own key would exclude the caller’s current IP
  • Campaign status conflicts: Changing, deleting, testing or sending a campaign that is not a draft, or unscheduling a campaign that is not validating or scheduled or that has queued mail. See Changes only to drafts

422 Unprocessable Entity

The same idempotency key was used with a different method, resolved path, or request body. Use a new key for a new request, or retry the original request unchanged. See idempotency.

429 Too Many Requests

You’ve exceeded the API rate limits.
When you receive this error, wait before making additional requests. Use exponential backoff with jitter. See API rate limits; rate-limit headers are not a documented contract.
Daily test limit: Test Campaign also answers 429 when the addresses of the test would take the day’s total over 50 test emails (UTC). Its message currently reads daily test send limit reached. Backoff does not clear this 429. A test to fewer addresses can still fit the same day; otherwise the limit clears when the UTC day changes. Keep count of the test emails you send each UTC day; a 429 from Test Campaign that stays after backoff is the daily limit. See Test Campaign for the rules of the limit.

5xx Server Errors

500 Internal Server Error

An unexpected server error occurred on our side (these are rare).
These errors indicate a problem on our end. If you consistently receive 500 errors, please contact support.

502 Bad Gateway

Test Campaign answers 502 when the mail server could not take the test. Nothing was sent, and the test does not count toward the daily test limit. Retry the request.

503 Service Unavailable

The service could not finish the request. Retry it later. The transactional template operations answer 503 with a Retry-After header when the template kept changing while the request ran, for example while it was edited in the dashboard. Retry the request after that delay.

Validation Errors

When request validation fails, you’ll receive a 400 Bad Request with a descriptive message:

Request Body Validation

Field-Specific Validation

The API provides specific validation messages for individual fields:

Scope and Permission Errors

When your API key doesn’t have sufficient permissions:

Missing Scopes

Invalid API Key Context

Best Practices

Error Handling

  • Always check the HTTP status code first
  • Show the message field to people; do not branch on its text, which can change
  • Implement appropriate retry logic for 5xx errors
  • Respect rate limits when receiving 429 responses

Common Fixes

  • 400 errors: Validate your request parameters and JSON structure
  • 401 errors: Check your API key and authentication headers
  • 403 errors: Verify your API key has the required scopes
  • 404 errors: Confirm the resource exists and belongs to your account
  • 429 errors: Implement exponential backoff in your retry logic
Error messages are designed to be descriptive and actionable. They provide specific guidance on what needs to be corrected in your request.