AutoRelay
FeaturesPricingAPI DocsTemplatesHelp Center
AutoRelay

The best way to reach humans instead of spam folders. Email infrastructure for developers and marketers.

Product

  • Features
  • Pricing
  • API Docs
  • Email Templates

Resources

  • Help Center
  • Contact
  • About Us

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • GDPR

© 2026 AutoRelay. A product of HLP Technologies. All rights reserved.

v1.0 REST
Getting Started
Concepts
API Reference
Guides
SDKs & Tools
REST API Reference

AutoRelay REST API

Welcome to the AutoRelay REST API. Our developer platform delivers the same intuitive, one-line send shape as Resend and Postmark, while integrating first-class email campaigns, lists, contact management, and real-time outbound webhooks.

The API conforms to the REST standard, using secure Bearer tokens for authentication and returning predictable, JSON-structured responses. A machine-readable contract is available for code generation in the SDKs section: openapi.yaml.

Quickstart

Get up and running with AutoRelay in less than 60 seconds.

1

Get your API Key

Go to **Project Settings → API keys** in your dashboard. Click **Generate new key** and copy it once. Plain keys are hashed at rest.

2

Authenticate Header

Include your API key as a Bearer token in the header of every HTTP request:Authorization: Bearer ak_live_...

3

Send Your First Email

Make a POST request to the `/emails` endpoint. Check the code panel on the right side of this section to test.

Sending a test request

You can copy the code snippet on the right to trigger your first email. By default, you can send emails from the domain hello@autorelay.net, which is a shared sandbox sender (free, capped at 100 emails/day per project). To send using your own verified domain, configure a domain under .

POST /api/v1/emails
curl -X POST https://autorelay.net/api/v1/emails \
  -H "Authorization: Bearer ak_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "you@example.com",
    "from": "AutoRelay <hello@autorelay.net>",
    "subject": "Hello from AutoRelay",
    "html": "<p>It works.</p>"
  }'
{
  "id": "em_abc123",
  "success": true,
  "messageId": "0100018f-7c6f-a0e0-..."
}

Authentication

All requests directed to the AutoRelay endpoints must authorize using the header format below. Access keys are project-scoped, meaning they isolate lists, templates, and logs safely between separate environments.

Warning: Plaintext keys are shown only once at creation and are encrypted at rest with AES-256-GCM. Never store them inside client-side code, repositories, or frontend bundles. If compromised, revoke them immediately in settings. Keys stop validating within 30 seconds of revocation.
  • Format: ak_live_<64-character-hex> or ak_test_<64-character-hex> for testing.
  • Auditing: Each active request logs the IP and User-Agent signature of the caller to settings.
# Header format
Authorization: Bearer ak_live_your_key_here

# Base API Endpoint
https://autorelay.net/api/v1

Errors

AutoRelay uses standard HTTP response codes to indicate the success or failure of an API request. In general, `2xx` codes indicate success, `4xx` codes indicate caller validation errors, and `5xx` codes indicate server-side infrastructure issues.

StatusMeaningRecommended Mitigation
400Validation error (e.g. invalid email syntax, missing body parameter)Inspect error body detail, format correctly, and retry.
401Unauthorized (invalid or expired API key)Validate the Authorization header structure. Verify the key isn't revoked.
402Quota exceededYour monthly email limits or active plan quota was met. Upgrade in billing settings.
403Account flagged or suspended for reputation issuesAll mail outbound is paused. Contact support immediately to recover reputation credentials.
404Resource not foundVerify the request URL path variable (e.g. listId, emailId) is typed correctly.
429Rate limit exceededSlow down request volume. Respect the `Retry-After` response header.
500Internal Server ErrorFailure on our side. Retry with exponential backoff. Monitor **status.autorelay.net**.

Error Response Format

All error payloads return JSON with a single `"error"` key detailing the response. For 403 blocks triggered by reputation locks, the payload also returns `"accountStatus"`.

{
  "error": "Account is flagged for review due to high bounce rate. Contact support@autorelay.net.",
  "accountStatus": "flagged"
}

Rate Limits

Rate limits are evaluated in a sliding window, counted per the scope shown for each endpoint (usually your project API key). If you exceed a limit, you will receive a `429 Rate Limit Exceeded` response. The limits below are the exact values currently enforced.

Emails

MethodEndpointScopeLimit
POST/api/v1/emailsSend a single emailper project key100 / min
POST/api/v1/emails/batchSend a batch (up to 100)per project key10 / min

Contacts

MethodEndpointScopeLimit
GET/api/v1/contactsList contactsper project key60 / min
POST/api/v1/contactsCreate a contactper project key30 / min
GET/api/v1/contacts/:idRead a contactper project key60 / min
PUT/api/v1/contacts/:idUpdate a contactper project key30 / min
DELETE/api/v1/contacts/:idDelete a contactper project key30 / min
POST/api/v1/contacts/importBulk import contactsper project key5 / hour

Lists

MethodEndpointScopeLimit
GET/api/v1/listsList listsper project key60 / min
POST/api/v1/listsCreate a listper project key20 / hour

Campaigns

MethodEndpointScopeLimit
GET/api/v1/campaignsList campaignsper project key60 / min
POST/api/v1/campaignsCreate a campaignper project key20 / hour
GET/api/v1/campaigns/:idRead a campaignper project key60 / min
PUT/api/v1/campaigns/:idUpdate a campaignper project key30 / min
DELETE/api/v1/campaigns/:idDelete a campaignper project key30 / min
POST/api/v1/campaigns/:id/launchLaunch a campaignper project key5 / hour

Templates

MethodEndpointScopeLimit
GET/api/v1/templatesList templatesper project key60 / min

Assets

MethodEndpointScopeLimit
GET/api/v1/assetsList assetsper project key60 / min
POST/api/v1/assetsUpload an assetper project key30 / min

Domains

MethodEndpointScopeLimit
POST/api/v1/domainsAdd a sending domainper project key10 / hour

Webhooks

MethodEndpointScopeLimit
POST/api/v1/webhooksRegister a webhookper project key20 / hour

Stats

MethodEndpointScopeLimit
GET/api/v1/statsRead aggregate statsper project key30 / min

OTP & Utilities

MethodEndpointScopeLimit
POST/api/v1/otp/sendSend an OTP codeper project key20 / hour
POST/api/v1/otp/sendOTP codes to one recipientper recipient5 / hour
POST/api/v1/otp/verifyVerify an OTP codeper project key10 / min
POST/api/v1/unsubscribeProcess an unsubscribe (public)per IP60 / min

Three Core Send Patterns

Choose the best mechanism for your use-case.

Pattern A: Transactional (Direct Send)

Best for password resets, order confirmations, and notifications. Sends immediately without needing a pre-configured contact list. Can support key-value `tags` which are echoed back to webhook payloads. Supports batch send calls up to 100 recipients.

POST /api/v1/emails

Pattern B: Campaign / Broadcast Sending

Best for product updates and newsletter broadcasts. Requires a target contact list. The send operation executes asynchronously as a background queue runner, safeguarding reputation limits and pacing delivery.

1. Create a subscriber list: POST /api/v1/lists
2. Populate contacts: POST /api/v1/contacts (or bulk import)
3. Draft the campaign layout: POST /api/v1/campaigns
4. Launch delivery process: POST /api/v1/campaigns/:id/launch

Pattern C: Double Opt-in (Consent Flow)

Enforces strict CAN-SPAM and GDPR alignment. Automatically dispatches verification pins to incoming subscribers to prevent spam sign-ups.

1. Request confirmation code: POST /api/v1/otp/send { purpose: 'subscribe' }
2. Validate code: POST /api/v1/otp/verify { code: '123456' }
3. Create contact after verified=true: POST /api/v1/contacts

Pagination

AutoRelay supports two modes of pagination depending on the dataset characteristics.

Page-based Offset Pagination

Used by list resources like `/contacts`. Straightforward navigation parameters that let you jump to specific index pages.

GET /api/v1/contacts?page=2&pageSize=50

Cursor-based Pagination

Used by active log resources like `/emails`. High-performance streaming that mitigates item duplication when new data is inserted while scanning.

GET /api/v1/emails?limit=100&startingAfter=em_abc123

Idempotency

To prevent duplicate actions caused by network latency or transient connection timeouts, you can pass an `Idempotency-Key` header with any state-changing POST or PATCH request.

If a request with an existing key is received, AutoRelay returns the cached response of the original call without executing the operation again.

  • Keys are kept on cache for exactly 24 hours.
  • We recommend using a UUID v4 string for the key format.
  • Requests without this header are processed immediately and are not protected from duplicates.
# Header parameter
Idempotency-Key: 7c9e3e58-a0b4-4f4c-...

Account Status & Reputation

AutoRelay proactively protects sending IP reputability by monitoring bounce and complaint rates. If rates cross safety thresholds within a 24-hour window, mutating endpoints will return `403 Forbidden` with an explanation.

StatusDefinitionRecovery Process
activeHealthy account state. Normal sending capabilities.Maintain low bounce rate (<2%) and clean list opt-in lists.
flaggedBounce rate ≥ 2% OR Complaint rate ≥ 0.05% in the last 24h. Outbound sends paused.Email **support@autorelay.net**. We will review list opt-ins and restore access within 24h.
suspendedCritical reputation hit (e.g. spamtrap match). Manual audit required.Requires compliance review. Contact support to schedule an evaluation.
deactivatedRepeated abuse or compliance violation. Terminal state.None. Account is permanently closed.

Emails API

Endpoints to dispatch single or batch emails, retrieve delivery states, and view stats.

POST/api/v1/emails

Send a single transactional email. You must supply either `html` content or a `template_id` saved in the dashboard. If both are passed, `template_id` wins and `html` is ignored.

ParameterTypeRequiredDescription
tostringrequiredRecipient email address.
fromstringrequiredSender name and email (e.g. 'Jane <jane@domain.com>').
subjectstringrequiredEmail subject line.
htmlstringoptionalRaw inline HTML. Required if template_id is absent.
template_idstringoptionalID of saved template. Required if html is absent.
dataobjectoptionalFlat key-value map for template variable interpolation.
tagsobjectoptionalMetadata returned in webhook events.
Send Email Sample
curl -X POST https://autorelay.net/api/v1/emails \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "user@example.com",
    "from": "Acme <noreply@yourdomain.com>",
    "subject": "Reset Password",
    "html": "<p>Click <a href=\"https://...\">here</a></p>",
    "tags": { "type": "password-reset", "userId": "u_123" }
  }'
{
  "id": "em_abc123",
  "success": true,
  "messageId": "0100018f-..."
}
POST/api/v1/emails/batch

Send up to 100 emails in a single API call. Each row evaluates independently and can mix template and inline HTML formats.

ParameterTypeRequiredDescription
emailsarrayrequiredList of up to 100 email objects structured exactly like single send API.
Send Batch
curl -X POST https://autorelay.net/api/v1/emails/batch \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      {
        "to": "alice@example.com",
        "from": "Acme <noreply@yourdomain.com>",
        "subject": "Hi Alice",
        "html": "<p>Hello</p>"
      },
      {
        "to": "bob@example.com",
        "from": "Acme <noreply@yourdomain.com>",
        "subject": "Hi Bob",
        "template_id": "tpl_123",
        "data": { "name": "Bob" }
      }
    ]
  }'
{
  "object": "batch",
  "batch_id": "batch_xyz",
  "total": 2,
  "sent": 2,
  "failed": 0,
  "data": [
    { "id": "em_a1", "to": "alice@example.com", "status": "sent", "error": null },
    { "id": "em_b2", "to": "bob@example.com", "status": "sent", "error": null }
  ]
}
GET/api/v1/emails

Read list of emails sent through the account, with cursor-based pagination.

ParameterTypeRequiredDescription
limitnumberoptionalResults count returned. Max 100, default 20.
startingAfterstringoptionalCursor ID representing index after last item.
statusstringoptionalFilter by status: queued, sent, failed, opened, clicked.
orderstringoptionalSorting order: asc, desc. Defaults to asc.
List Emails
curl "https://autorelay.net/api/v1/emails?limit=2" \
  -H "Authorization: Bearer ak_live_..."
{
  "emails": [
    { "id": "em_1", "to": "alice@domain.com", "status": "sent", "opens": 1 },
    { "id": "em_2", "to": "bob@domain.com", "status": "failed", "opens": 0 }
  ],
  "total": 120
}
GET/api/v1/emails/:emailId

Lookup delivery logs, active open/click count stats, and chronologically mapped tracking events for a single email.

ParameterTypeRequiredDescription
emailIdstringrequiredUnique target email identifier.
Get Email Details
curl https://autorelay.net/api/v1/emails/em_abc123 \
  -H "Authorization: Bearer ak_live_..."
{
  "email": {
    "id": "em_abc123",
    "to": "alice@example.com",
    "status": "sent",
    "opens": 1,
    "clicks": 0
  },
  "events": [
    { "type": "queued", "createdAt": "2026-05-25T10:00:00Z" },
    { "type": "sent", "createdAt": "2026-05-25T10:00:02Z" },
    { "type": "opened", "createdAt": "2026-05-25T10:15:30Z" }
  ]
}
GET/api/v1/stats

Returns project-scoped counters mapping bounce rates, complaint metrics, domain quantities, and monthly usage spikes.

Useful for plotting dashboard charts or dynamically tracking plan health on admin frameworks.

Get Stats
curl https://autorelay.net/api/v1/stats \
  -H "Authorization: Bearer ak_live_..."
{
  "contacts": 1500,
  "campaigns": {
    "total": 45,
    "sending": 1,
    "completed": 40
  },
  "emailsThisMonth": 12500,
  "domains": 2
}

Contacts API

Endpoints to construct custom subscriber entries, read paginated listings, or trigger bulk uploads.

POST/api/v1/contacts

Create a new subscriber inside an active list.

ParameterTypeRequiredDescription
emailstringrequiredSubscriber email address.
namestringoptionalFull name parameter.
listIdstringrequiredTarget list ID to insert contact.
Create Contact
curl -X POST https://autorelay.net/api/v1/contacts \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@example.com",
    "name": "Alice Smith",
    "listId": "lst_xyz"
  }'
{
  "id": "con_123",
  "email": "alice@example.com",
  "name": "Alice Smith",
  "status": "subscribed",
  "listId": "lst_xyz"
}
GET/api/v1/contacts

List contacts with offset pagination, filtering, and search criteria.

ParameterTypeRequiredDescription
listIdstringrequiredFilter contacts belonging to this list.
pagenumberoptionalIndex page. Defaults to 1.
pageSizenumberoptionalItem quantity. Max 200, defaults to 50.
searchstringoptionalWildcard search key matching name or email.
statusstringoptionalStatus filter: subscribed, unsubscribed, bounced.
List Contacts
curl "https://autorelay.net/api/v1/contacts?listId=lst_xyz&page=1&pageSize=2" \
  -H "Authorization: Bearer ak_live_..."
{
  "contacts": [
    { "id": "con_1", "email": "a@example.com", "status": "subscribed" },
    { "id": "con_2", "email": "b@example.com", "status": "unsubscribed" }
  ],
  "pagination": {
    "total": 450,
    "page": 1,
    "pageSize": 2
  }
}
POST/api/v1/contacts/import

Import up to 10,000 contacts at once in a single request. Skips existing emails.

ParameterTypeRequiredDescription
listIdstringrequiredTarget subscriber list ID.
contactsarrayrequiredArray of subscriber objects (each with email and optional name).
Bulk Import
curl -X POST https://autorelay.net/api/v1/contacts/import \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "listId": "lst_xyz",
    "contacts": [
      { "email": "joe@example.com", "name": "Joe" },
      { "email": "kim@example.com", "name": "Kim" }
    ]
  }'
{
  "success": true,
  "importedCount": 2,
  "skippedCount": 0
}
GET/api/v1/contacts/:contactId

Read a single contact by ID.

Returns the contact's profile fields and current subscription `status`.

Get Contact
curl https://autorelay.net/api/v1/contacts/con_123 \
  -H "Authorization: Bearer ak_live_..."
{
  "success": true,
  "data": {
    "id": "con_123",
    "email": "alice@example.com",
    "name": "Alice Smith",
    "company": null,
    "listId": "lst_xyz",
    "status": "subscribed",
    "createdAt": "2026-05-25T10:00:00.000Z"
  }
}
PUT/api/v1/contacts/:contactId

Update a contact. Send any subset of the fields below.

ParameterTypeRequiredDescription
namestringoptionalFull name.
emailstringoptionalSubscriber email address.
statusstringoptionalOnly 'subscribed' or 'unsubscribed' — bounce/complaint states are platform-managed.
companystringoptionalCompany name.
listIdstringoptionalMove the contact to a different list.
Update Contact
curl -X PUT https://autorelay.net/api/v1/contacts/con_123 \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "Jane Doe", "status": "unsubscribed" }'
{
  "success": true
}
DELETE/api/v1/contacts/:contactId

Permanently remove a contact from your project.

This is irreversible. To stop emailing a contact without losing their record, set `status` to `unsubscribed` via the update endpoint instead.

Delete Contact
curl -X DELETE https://autorelay.net/api/v1/contacts/con_123 \
  -H "Authorization: Bearer ak_live_..."
{
  "success": true
}

Lists API

Endpoints to isolate subscriber groups for newsletter broadcasts and campaigns.

POST/api/v1/lists

Create a new contact mailing list.

ParameterTypeRequiredDescription
namestringrequiredHuman readable list label.
Create List
curl -X POST https://autorelay.net/api/v1/lists \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "Subscribers" }'
{
  "id": "lst_xyz",
  "name": "Subscribers",
  "createdAt": "2026-05-25T10:00:00Z"
}
GET/api/v1/lists

Retrieve every contact list in the project, each with its live contact count.

Use the returned `id` values as the `listId` parameter when creating contacts, importing in bulk, or launching campaigns.

List Lists
curl https://autorelay.net/api/v1/lists \
  -H "Authorization: Bearer ak_live_..."
{
  "success": true,
  "data": [
    { "id": "lst_xyz", "name": "Subscribers", "contactCount": 1240 }
  ]
}

Campaigns API

Endpoints to draft broadcasts, review progress, verify templates, and initiate launches.

POST/api/v1/campaigns

Initialize a draft campaign targeted at a contact list.

ParameterTypeRequiredDescription
namestringrequiredInternal campaign label.
subjectstringrequiredBroadcast subject line.
fromEmailstringrequiredSender domain email (e.g. news@domain.com).
listIdstringrequiredTarget recipient list identifier.
contentstringrequiredHTML template body markup.
Create Campaign
curl -X POST https://autorelay.net/api/v1/campaigns \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring Sale",
    "subject": "Discount!",
    "fromEmail": "sales@yourdomain.com",
    "listId": "lst_xyz",
    "content": "<h1>Save 20%</h1>"
  }'
{
  "id": "cmp_123",
  "name": "Spring Sale",
  "status": "draft",
  "listId": "lst_xyz"
}
GET/api/v1/campaigns

List campaigns with offset pagination, optionally filtered by status.

ParameterTypeRequiredDescription
pagenumberoptionalIndex page. Defaults to 1.
pageSizenumberoptionalItems per page. Defaults to 20.
statusstringoptionalFilter: draft, sending, or completed.
List Campaigns
curl "https://autorelay.net/api/v1/campaigns?page=1&pageSize=20&status=completed" \
  -H "Authorization: Bearer ak_live_..."
{
  "success": true,
  "data": [
    { "id": "cmp_123", "name": "Spring Sale", "status": "completed", "sentCount": 1240 }
  ],
  "pagination": { "total": 12, "page": 1, "pageSize": 20 }
}
POST/api/v1/campaigns/:campaignId/launch

Trigger campaign delivery. Spawns an isolated background runner job that processes the recipient list. Updates the campaign status from `draft` to `sending`.

Once launched, updating the draft layout content or recipient list is blocked. Querying the campaign metadata status (`GET /api/v1/campaigns/:id`) details active queue percentages.

Launch Campaign
curl -X POST https://autorelay.net/api/v1/campaigns/cmp_123/launch \
  -H "Authorization: Bearer ak_live_..."
{
  "success": true,
  "jobId": "job_camp_123",
  "status": "sending"
}
GET/api/v1/campaigns/:campaignId

Read campaign metadata and live send statistics. Poll this while a launch is in progress to track delivery.

`status` moves `draft` → `sending` → `completed`. The `stats` object is populated as delivery, open, and click events arrive.

Get Campaign
curl https://autorelay.net/api/v1/campaigns/cmp_123 \
  -H "Authorization: Bearer ak_live_..."
{
  "success": true,
  "data": {
    "id": "cmp_123",
    "status": "completed",
    "sentCount": 1240,
    "stats": { "delivered": 1198, "opened": 524, "clicked": 87 }
  }
}
PUT/api/v1/campaigns/:campaignId

Edit a draft campaign. Once a campaign is launched its content and recipient list are locked.

ParameterTypeRequiredDescription
namestringoptionalInternal campaign label.
subjectstringoptionalBroadcast subject line.
fromEmailstringoptionalSender domain email.
listIdstringoptionalTarget recipient list identifier.
contentstringoptionalHTML template body markup.
Update Campaign
curl -X PUT https://autorelay.net/api/v1/campaigns/cmp_123 \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "subject": "Updated subject line" }'
{
  "success": true,
  "data": {
    "id": "cmp_123",
    "status": "draft",
    "subject": "Updated subject line"
  }
}
DELETE/api/v1/campaigns/:campaignId

Delete a campaign. Only drafts can be deleted — a launched campaign owns delivery logs and analytics that are preserved.

Attempting to delete a campaign that has already been launched returns `409 Conflict` with the message `Only draft campaigns can be deleted`.

Delete Campaign
curl -X DELETE https://autorelay.net/api/v1/campaigns/cmp_123 \
  -H "Authorization: Bearer ak_live_..."
{
  "id": "cmp_123",
  "deleted": true
}

Templates API

Read layouts built inside the visual dashboard editor.

GET/api/v1/templates

List saved templates for use with the Send API (`template_id` parameter).

Templates are designed visually in the dashboard at **/app/templates**. Use the returned ID values to send transactional emails via our SDKs or HTTP requests.

List Templates
curl https://autorelay.net/api/v1/templates \
  -H "Authorization: Bearer ak_live_..."
{
  "templates": [
    {
      "id": "tpl_abc123",
      "name": "Welcome Email",
      "subject": "Welcome!",
      "createdAt": "2026-05-20T12:00:00Z"
    }
  ]
}

Assets API

Upload and host files (images, PDFs, any type up to 2MB) and reuse the public link in emails, templates and campaigns.

POST/api/v1/assets

Upload a file as `multipart/form-data` (field name `file`, scope `assets.write`). Returns the hosted asset with a public `url`. Max size 2MB.

The returned `url` is permanent and public — drop it into an image block, a button link, or a transactional email.

Upload Asset
curl -X POST https://autorelay.net/api/v1/assets \
  -H "Authorization: Bearer ak_live_..." \
  -F "file=@/path/to/logo.png"
{
  "object": "asset",
  "id": "...",
  "name": "logo.png",
  "url": "https://storage.googleapis.com/.../logo.png",
  "content_type": "image/png",
  "category": "image",
  "size": 20480,
  "created_at": "2026-06-19T12:00:00Z"
}
GET/api/v1/assets

List uploaded assets (scope `assets.read`). Filter by `category` (`image`, `pdf`, `document`, `video`, `audio`, `other`) and paginate with `cursor`.

Results are ordered newest-first and follow the standard list envelope with `has_more` and `next_cursor`.

List Assets
curl "https://autorelay.net/api/v1/assets?category=image" \
  -H "Authorization: Bearer ak_live_..."
{
  "object": "list",
  "data": [
    { "object": "asset", "id": "...", "name": "logo.png", "url": "https://..." }
  ],
  "has_more": false,
  "next_cursor": null
}

Domains API

Endpoints to register domains, retrieve DKIM/CNAME records, and trigger verification checks.

POST/api/v1/domains

Add a new sending domain. Returns DKIM tokens to publish as DNS CNAME records.

ParameterTypeRequiredDescription
domainstringrequiredApex domain or subdomain (e.g. mail.domain.com).
Add Domain
curl -X POST https://autorelay.net/api/v1/domains \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "domain": "yourdomain.com" }'
{
  "id": "dom_abc",
  "domain": "yourdomain.com",
  "status": "pending",
  "dkimTokens": [
    "token1_val",
    "token2_val",
    "token3_val"
  ]
}
GET/api/v1/domains

List every sending domain in the project with its verification status.

`status` is one of `pending` or `verified`. Fetch a single domain to get the full DKIM/CNAME record set.

List Domains
curl https://autorelay.net/api/v1/domains \
  -H "Authorization: Bearer ak_live_..."
{
  "object": "list",
  "data": [
    {
      "id": "dom_abc",
      "object": "domain",
      "domain": "yourdomain.com",
      "status": "verified",
      "dkim_tokens": ["token1_val", "token2_val", "token3_val"],
      "verified_at": "2026-05-25T10:00:00.000Z",
      "created_at": "2026-05-25T09:00:00.000Z"
    }
  ]
}
POST/api/v1/domains/:domainId/verify

Trigger immediate verification check for registered DKIM, SPF, and DMARC records.

Check out the **Domain Setup** guide in the section below for details on required DNS records.

Verify Domain
curl -X POST https://autorelay.net/api/v1/domains/dom_abc/verify \
  -H "Authorization: Bearer ak_live_..."
{
  "status": "verified",
  "domain": "yourdomain.com"
}
GET/api/v1/domains/:domainId

Fetch a single domain with its DKIM tokens and the exact CNAME records to publish on your DNS.

The `dns_records` array gives you ready-to-paste CNAME entries. Once they propagate, call the verify endpoint to flip `status` to `verified`.

Get Domain
curl https://autorelay.net/api/v1/domains/dom_abc \
  -H "Authorization: Bearer ak_live_..."
{
  "id": "dom_abc",
  "object": "domain",
  "domain": "yourdomain.com",
  "status": "verified",
  "dkim_tokens": ["token1_val", "token2_val", "token3_val"],
  "dns_records": [
    {
      "type": "CNAME",
      "name": "token1_val._domainkey.yourdomain.com",
      "value": "token1_val.dkim.amazonses.com"
    }
  ],
  "verified_at": "2026-05-25T10:00:00.000Z",
  "created_at": "2026-05-25T09:00:00.000Z"
}
DELETE/api/v1/domains/:domainId

Remove a sending domain. This also removes its verified sending identity.

After deletion you can no longer send from addresses on this domain until it is re-added and re-verified.

Delete Domain
curl -X DELETE https://autorelay.net/api/v1/domains/dom_abc \
  -H "Authorization: Bearer ak_live_..."
{
  "id": "dom_abc",
  "deleted": true
}

Webhooks API

Endpoints to register URLs and subscribe to real-time events.

POST/api/v1/webhooks

Register a new webhook endpoint and event subscriptions.

ParameterTypeRequiredDescription
urlstringrequiredDestination HTTPS target URL endpoint on your server.
eventsarrayrequiredList of events. Supported values: email.sent, email.opened, email.clicked, email.bounced, email.complained, email.failed.
Register Webhook
curl -X POST https://autorelay.net/api/v1/webhooks \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/hooks/autorelay",
    "events": ["email.opened", "email.clicked"]
  }'
{
  "id": "whk_123",
  "url": "https://yourapp.com/hooks/autorelay",
  "secret": "whsec_abcd123...",
  "events": ["email.opened", "email.clicked"],
  "isActive": true
}
GET/api/v1/webhooks

List all webhook endpoints registered for the project.

The signing `secret` is only returned once at creation time, so it is omitted from list and read responses.

List Webhooks
curl https://autorelay.net/api/v1/webhooks \
  -H "Authorization: Bearer ak_live_..."
{
  "object": "list",
  "data": [
    {
      "id": "whk_123",
      "object": "webhook",
      "url": "https://yourapp.com/hooks/autorelay",
      "events": ["email.opened", "email.clicked"],
      "active": true,
      "created_at": "2026-05-25T10:00:00.000Z"
    }
  ]
}
GET/api/v1/webhooks/:webhookId

Read a single webhook endpoint.

Returns the current `url`, subscribed `events`, and whether the endpoint is `active`.

Get Webhook
curl https://autorelay.net/api/v1/webhooks/whk_123 \
  -H "Authorization: Bearer ak_live_..."
{
  "id": "whk_123",
  "object": "webhook",
  "url": "https://yourapp.com/hooks/autorelay",
  "events": ["email.opened", "email.clicked"],
  "active": true,
  "created_at": "2026-05-25T10:00:00.000Z"
}
PATCH/api/v1/webhooks/:webhookId

Update a webhook's URL, event subscriptions, or active state. Send any subset of the fields.

ParameterTypeRequiredDescription
urlstringoptionalNew destination HTTPS endpoint.
eventsarrayoptionalReplacement list of subscribed events (non-empty).
activebooleanoptionalPause or resume deliveries without deleting the webhook.
Update Webhook
curl -X PATCH https://autorelay.net/api/v1/webhooks/whk_123 \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "events": ["email.failed"], "active": false }'
{
  "id": "whk_123",
  "object": "webhook",
  "url": "https://yourapp.com/hooks/autorelay",
  "events": ["email.failed"],
  "active": false,
  "created_at": "2026-05-25T10:00:00.000Z"
}
GET/api/v1/webhooks/:webhookId/deliveries

List failed delivery attempts for a webhook so you can debug endpoint outages.

ParameterTypeRequiredDescription
limitnumberoptionalMax rows to return. 1–100, defaults to 50.
List Deliveries
curl "https://autorelay.net/api/v1/webhooks/whk_123/deliveries?limit=20" \
  -H "Authorization: Bearer ak_live_..."
{
  "object": "list",
  "webhook_id": "whk_123",
  "has_more": false,
  "data": [
    {
      "id": "whd_1",
      "object": "webhook_delivery",
      "event_id": "evt_abc",
      "event_type": "email.opened",
      "status": "failed",
      "error": "connect ETIMEDOUT",
      "attempts": 3,
      "replay_count": 0,
      "last_attempt_at": "2026-05-25T10:05:00.000Z",
      "created_at": "2026-05-25T10:00:00.000Z",
      "resolved_at": null
    }
  ]
}
DELETE/api/v1/webhooks/:webhookId

Remove a webhook endpoint. Deliveries stop immediately.

To temporarily stop deliveries without losing the endpoint config, PATCH `active` to `false` instead.

Delete Webhook
curl -X DELETE https://autorelay.net/api/v1/webhooks/whk_123 \
  -H "Authorization: Bearer ak_live_..."
{
  "id": "whk_123",
  "deleted": true
}

OTP & Public Utilities

The **unsubscribe** endpoints are public — they authenticate with a signed token carried in the email link, so no API key is needed. The **OTP** endpoints **do require your API key** (scope `emails.send`) and send real email, so call them from your backend — never the browser.

POST/api/v1/otp/send

Generate and dispatch a 6-digit confirmation pin to an email address.

ParameterTypeRequiredDescription
emailstringrequiredDestination email address.
purposestringrequiredOTP objective. Set to 'subscribe' for list signups.
Send OTP
curl -X POST https://autorelay.net/api/v1/otp/send \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "email": "user@domain.com" }'
{
  "ok": true,
  "expiresAt": "2026-05-25T10:10:00.000Z"
}
POST/api/v1/otp/verify

Verify a dispatched OTP code.

ParameterTypeRequiredDescription
emailstringrequiredSubscriber email.
codestringrequired6-digit OTP string.
purposestringrequiredMatches code generation purpose.
Verify OTP
curl -X POST https://autorelay.net/api/v1/otp/verify \
  -H "Authorization: Bearer ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "email": "user@domain.com", "code": "123456" }'
{
  "ok": true
}
POST/api/v1/unsubscribe

Mark subscriber status unsubscribed from the corresponding list using a secure link token.

ParameterTypeRequiredDescription
tokenstringrequiredCryptographic unsubscribe token generated server-side.
Unsubscribe Link Call
curl -X POST https://autorelay.net/api/v1/unsubscribe \
  -H "Content-Type: application/json" \
  -d '{ "token": "tok_unsub_abc123" }'
{
  "ok": true
}
GET/api/v1/unsubscribe

The destination behind the `{{unsubscribe_url}}` merge field. Opening it applies the token and returns a browser-ready confirmation page.

ParameterTypeRequiredDescription
tokenstringrequiredSigned unsubscribe token, passed as a query parameter.
Unsubscribe Landing
# Users click this link directly from the email footer —
# no API call needed. It renders an HTML confirmation page.
https://autorelay.net/api/v1/unsubscribe?token=tok_unsub_abc123
<!-- 200 text/html -->
<!-- A "You've been unsubscribed" confirmation page. -->

Guide: Add Sending Domain

Verify domain ownership via DNS records to remove limits and send from your custom email addresses.

Required DNS records

Add the following five records to your DNS provider. While DKIM is technically sufficient for email authorization, most email clients (e.g. Gmail, Outlook) will filter your messages as spam if SPF and DMARC records are absent.

TypeHost / NameValuePurpose
CNAME<token1>._domainkey<token1>.dkim.amazonses.comDKIM verification (1/3)
CNAME<token2>._domainkey<token2>.dkim.amazonses.comDKIM verification (2/3)
CNAME<token3>._domainkey<token3>.dkim.amazonses.comDKIM verification (3/3)
TXT@ (apex)"v=spf1 include:amazonses.com ~all"SPF validation policy
TXT_dmarc"v=DMARC1; p=none; rua=mailto:postmaster@domain.com"DMARC delivery reports
Tip: Keep DMARC policy set to `p=none` on setup. Switch to `p=quarantine` or `p=reject` after verification yields a week of healthy, compliant logs.

Provider Setup Guide

  • Log in to **Cloudflare** → Select your Domain → Open **DNS Settings**.
  • Click **Add Record** → Type: CNAME, Name: <token1>._domainkey, Target: <token1>.dkim.amazonses.com.
  • Important: Set **Proxy status** to **DNS Only** (grey cloud icon). Orange-cloud proxying blocks CNAME validation.
  • Repeat CNAME records for token 2 and token 3.
  • Click **Add Record** → Type: `TXT`, Name: `@` or blank, Content: `v=spf1 include:amazonses.com ~all`.
  • Click **Add Record** → Type: `TXT`, Name: `_dmarc`, Content: `v=DMARC1; p=none; rua=mailto:postmaster@yourdomain.com`.

Guide: Webhook Verification

Cryptographically verify incoming payloads to ensure they originate from AutoRelay.

Every webhook request sent to your server includes three signature headers:

HeaderValue
X-Webhook-SignatureHex HMAC-SHA256 signature calculated from the raw payload body.
X-Webhook-IdUnique event uuid. Recommended for deduplication tracking.
X-Webhook-EventPayload event category type (e.g. email.opened).

Three rules for webhook processing:

  1. Compute signature over raw body bytes: JSON parsing alters whitespace, breaking signature calculation.
  2. Use timing-safe comparisons: Mitigate vulnerability to timing attacks by avoiding standard string comparisons (use `crypto.timingSafeEqual`).
  3. Acknowledge immediately: Return a 2xx status code first, then queue parsing operations. If a webhook returns a 5xx, AutoRelay retries up to three times with exponential backoff (1s, 5s, 15s).
Verify Signature Sample
# Webhook Header Verification
X-Webhook-Signature: <computed-hmac-sha256>
X-Webhook-Id: evt_abc123
X-Webhook-Event: email.opened

Official SDKs & Libraries

Integrate AutoRelay with ready-made SDK packages.

LanguagePackage ManagerSource / Import
OpenAPI 3.1 SpecSwagger / Redoc generatorDownload openapi.yaml

Testing in Development

For local integration and sandbox development, you can route calls directly to your local instance.

Local Base URL:

http://localhost:3000/api/v1

To avoid burning through your email quota during development, generate a **Test Mode Key** (`ak_test_...`) in your dashboard. Outbound emails dispatched with a test key are logged in your developer dashboard for verification, but are not actually delivered.

# Local testing headers
Authorization: Bearer ak_test_sandbox_key
Content-Type: application/json

Support & Service Status

Status Panel

Track system uptime, incident history, and current operational efficiency:

status.autorelay.net

Email Support

Direct contact line to our developer relations team for assistance:

support@autorelay.net

Github Issues

Report bugs, request features, or contribute to our SDK repositories:

Github Profile

Ready to Integrate AutoRelay?

Generate an API key in your project settings and start sending emails in minutes.

Get Started