API overview

Maillayer REST API basics: base URL, API key authentication, JSON requests, errors, status codes and idempotency.

Using an AI agent? Just ask:“Send a test email to me from [email protected].”Connect your agent →

Base URL#

URL
https://agent.maillayer.com/api/v1

All requests and responses are JSON. Send Content-Type: application/json with a body.

Authentication#

Create an API key under API keys in the dashboard and send it as a bearer token. Keys belong to one workspace and can do everything in it, so keep them on your server.

HTTP
Authorization: Bearer ml_...

Errors#

Errors use standard HTTP status codes and always have the same shape:

JSON
{
  "error": {
    "code": "domain_not_verified",
    "message": "mail.acme.com is not a verified domain in this workspace. Add and verify it under Domains."
  }
}
StatusMeaningExample codes
400The body is not valid JSON or a field is wrong.invalid_request
401Missing or invalid API key.unauthorized
402Out of credits.payment_required
403Sending is paused for the workspace.workspace_paused
404Not found.not_found, template_not_found, list_not_found
409The campaign is not a draft anymore.not_draft
422Valid request, but it can't be done.domain_not_verified, recipient_suppressed, not_ready
429Daily limit reached or sending is busy.daily_limit_reached, rate_limited
5xxSomething went wrong on our side. Retry.internal_error, send_failed

Idempotency#

POST /emails accepts an Idempotency-Key header. Retrying with the same key returns the original email (status 200) instead of sending it again. Use it for anything you might retry.

Endpoints#

Endpoint
POST /emailsSend a transactional email
GET /emails/:idGet an email and its events
POST /contactsCreate or update a contact
DELETE /contacts/:emailDelete a contact
GET /listsList contact lists
GET /templatesList templates
POST /templatesCreate or update a template
GET /campaignsList campaigns
POST /campaignsCreate a campaign draft
GET /campaigns/:idGet a campaign and its stats
POST /campaigns/:id/sendSend or schedule a campaign
GET /domainsList sending domains