An email forwarding API is the HTTP interface that lets you create, list, toggle, and revoke email aliases programmatically — without ever opening the alias provider’s dashboard. The shape is familiar to anyone who’s used Stripe or Twilio: REST over HTTPS, scoped API keys, JSON in and out, predictable rate limits, idempotent retries. The shape matters because the use cases all live in places dashboards can’t reach: per-customer aliases for a multi-tenant SaaS, secret-scanner integrations that revoke leaked addresses on the next CI run, audit logs streamed into a SIEM. This guide walks through what an email forwarding API actually is, when you reach for it, the design properties that separate good ones from bad, and the integration patterns we’ve watched survive real production loads.

What is an email forwarding API?

An email forwarding API is a REST interface that exposes the same alias-management primitives the alias provider’s dashboard exposes — create alias, list aliases, toggle on/off, delete, fetch forwarding logs — as authenticated HTTP endpoints over JSON. Behind the API, the forwarding behavior itself is identical to what the UI produces: inbound mail at <alias>@yourdomain is delivered to a real inbox you’ve configured as the destination, and outbound replies (where supported) appear to come from the alias. The API doesn’t change the forwarding semantics; it just removes the human from the loop for the operations the dashboard treats as click events.

The resource model is small and consistent across the major hosted providers. Aliases are the central resource — they have a local-part, a destination, an active/inactive state, optional metadata (label, tag, color), and a creation timestamp. Destinations are the real inboxes aliases forward to; most accounts have one or two. Domains represent custom domains attached to the account, with their own verification state (covered in detail in our custom domain email alias guide). Logs are the per-message forwarding history. Most endpoints map cleanly onto one of those four nouns and one of the standard HTTP verbs.

The same shape can be built from scratch on top of AWS SES, Cloudflare Email Routing, or a self-hosted MTA — but you write the forwarding logic, the alias-routing table, and the auth/quota layer yourself. A hosted email forwarding API hands you all three. The trade-off is the standard build-vs-buy one; we touch on it in the comparison table below. For the underlying OpenAPI specification that drives the EmailAlias.io variant, our OpenAPI for email aliases walkthrough covers the spec file itself, the codegen workflow, and the contract-testing patterns we use against it.

When you need an email forwarding API instead of the dashboard

The default path is the dashboard. It’s the right tool for the everyday case of a privacy-conscious user creating fifteen aliases a year, one at a time, each labelled with the service they’re handing it to. The dashboard breaks down when the unit of work shifts from individuals to systems. Five patterns drive nearly every email forwarding API integration we’ve seen in production.

Bulk creation at deploy time. A new customer-success team rolls out and needs an alias per agent, all sharing the same forwarding rules and the same label pattern. The CLI runs once at deploy, calls POST /aliases in a loop with the appropriate tags, and emits a CSV of (agent_name, alias_email) for the team’s spreadsheet. The dashboard alternative is twenty minutes of clicking and a subtle typo on alias number 27.

Per-customer aliases in a multi-tenant SaaS. A B2B product that needs a unique transactional address per tenant — for support routing, branded reply-from, or compliance scoping — calls the API at tenant onboarding to provision support-{tenant_id}@yourbrand.com and stores the resulting alias ID alongside the tenant row. The address survives the tenant; the kill-switch fires at offboarding via DELETE /aliases/{id}.

Secret-scanner remediation. A CI job runs TruffleHog or GitGuardian against every push, and when an alias address appears in a leaked file, the next job-step calls the email forwarding API to disable that alias and create a replacement labelled with the leak source. The remediation lands before the developer has finished writing the post-mortem.

Audit log streaming. Security teams want every forwarding event in their SIEM. A small consumer polls GET /aliases/{id}/logs?since=<cursor> (or subscribes to a webhook), maps each row into the SIEM’s schema, and ships it. The same pipeline can also drive anomaly detection on the per-alias volume — useful for catching the alias whose recipient just got breached.

Per-environment isolation. Staging, QA, and production each need their own alias set so the verification mail for a staging tenant doesn’t accidentally arrive at the production-tenant address. The dashboard’s manual labelling falls over at the third environment. An email forwarding API lets the IaC layer create the per-environment alias inventory at terraform apply time, tagged with the environment ID for easy cleanup.

How we evaluated the API design

The recommendations below come from integrating an email forwarding API into three internal systems over the last year. The properties that survived contact with reality and made it into the table are the ones that map onto the operational concerns of someone running the integration at scale: HTTPS-only transport (TLS 1.2+ enforced), scoped API keys (read-only vs full vs admin), predictable rate limits with X-RateLimit-* response headers, idempotency keys on every state-changing endpoint, cursor-based pagination on list endpoints, webhook deliveries with HMAC signatures, and a published OpenAPI specification so the integration can be code-generated and contract-tested.

The non-criteria we explicitly excluded: GraphQL endpoints (overkill for the small resource set; adds a dependency without paying for itself), session-cookie auth (wrong for machine clients — API keys are simpler and easier to rotate), and SOAP wrappers (we hope you weren’t considering this in 2026). The goal is a small surface that does CRUD on four nouns, plus webhooks, plus enough operational guarantees that the integration is boring once it’s deployed.

Email forwarding API options compared

Four options sit in the space, and the gaps between them are operational rather than feature-set: every option can create and revoke an alias; the differences are in scoping, webhook support, custom-domain handling, and whether you’d put it in front of a paying customer’s compliance review.

OptionOpenAPI specWebhooksCustom-domain via APIFree tier
EmailAlias.io APIYes — published, code-gen-ableYes — HMAC-signedYes (Premium)10 aliases, full API access
SimpleLogin API (OSS-hosted)Partial — Swagger UI, no maintained spec fileNo first-class webhook layerYes (paid tiers)Yes, with caps
Addy.io APIYes — well-documentedYes — with verificationYes (paid tiers)Yes, with caps
DIY on AWS SES receipt rulesNo — you write the specBuild via SNS → LambdaYes — you handle every recordSES has its own free tier

For most integrations, a hosted email forwarding API (any of the first three rows) is the right call. The DIY-on-SES path is only worth it when you specifically need the alias service to live inside your own AWS account for compliance reasons — and even then, you usually want a hosted forwarding API for the operator-facing CRUD and a thin SES-backed forwarding pipeline beneath it. Our best email alias service for developers comparison covers the developer-facing tradeoffs across the same providers in more depth.

Authentication and rate limits

Every production email forwarding API authenticates with API keys passed in a request header — either as Authorization: Bearer <key> (the more conventional shape) or as X-API-Key: <key>. Both work; the Bearer form is friendlier to standard HTTP libraries. The key itself should be a high-entropy random string (32 bytes minimum) with no embedded user data — the API stores a hash, the client stores the raw value, and the user only sees the raw value once at creation time.

Scoping. Keys should support at least two scopes — read-only and read-write — so a leaked monitoring-script key can’t be used to revoke aliases. Some APIs add an admin scope for billing-tier operations; that’s nice to have, not essential. The OWASP API Security Top 10 covers the broader principles, but the key one for an email forwarding API is least-privilege scoping. A read-only key on a SIEM log shipper is a real risk reduction.

Rate limits. Predictable rate limits make integrations boring. The right pattern is a per-key token-bucket exposed in X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset response headers on every response. Clients that respect those headers — back off when remaining hits zero, retry after reset — never hit hard 429s. Clients that don’t read them eventually trip a per-IP block. Burst limits of 30 requests per second and sustained limits of 1000 per minute cover almost every legitimate integration we’ve watched run; the exception is the secret-scanner bulk-disable case, which is rare and can be batched.

Idempotency keys. Every POST that creates a resource should accept an Idempotency-Key header (a UUID generated client-side). The API stores the key for ~24 hours; the second request with the same key returns the original response without re-creating. This makes safe retries trivial for the client. Stripe popularized the pattern; their idempotency-key documentation remains the canonical reference.

The core endpoints

The endpoint set for an email forwarding API is small — usually fewer than twenty paths once you exclude the auxiliary destination/domain CRUD. The diagram below traces the lifecycle of a single alias from creation through revocation, with the corresponding request shown alongside each step. The same shape works against EmailAlias.io’s API, Addy.io’s, and SimpleLogin’s, modulo the path naming.

The five endpoints worth knowing by heart cover 90% of integration code.

email forwarding api request lifecycle showing POST create, GET list, PATCH toggle, DELETE revoke flowing into a single alias state
An email forwarding API exposes the alias lifecycle — create, list, toggle, log, revoke — as five HTTP endpoints, each calling back to the same alias state the dashboard reads from.
  • POST /aliases — create an alias. Body carries the local-part (or omitted for auto-generated), label, destination, and optional metadata. Response is the full alias object including the assigned address. Idempotent with Idempotency-Key header.
  • GET /aliases — list aliases. Supports filter parameters (label prefix, active state, destination), cursor-based pagination via cursor and limit, and response includes next_cursor when more pages exist. Returns at most a page (often 100) per call regardless of how many aliases the account holds.
  • PATCH /aliases/{id} — partial update. The two most common use cases are toggling active: false (kill-switch) and updating label for organisation. Status changes propagate to forwarding within seconds.
  • DELETE /aliases/{id} — permanent removal. Inbound mail to a deleted alias starts bouncing immediately. Most providers retain the forwarding logs for a configurable window after deletion so audit trails survive.
  • GET /aliases/{id}/logs — forwarding history. Each row captures a forwarded message: sender, timestamp, status (delivered, bounced, blocked), and any sender-side classification. Use this for SIEM ingestion, abuse detection, or simply giving end-users a per-alias volume chart.

A minimal request looks like this (paths and field names from EmailAlias.io’s spec; the shape is identical at SimpleLogin and Addy.io with different names):

POST /api/aliases
Authorization: Bearer ea_live_abc123…
Idempotency-Key: 7f3c9a16-3c4f-4f4c-b87c-5e0c5e7c5a4e
Content-Type: application/json

{
  "local_part": "support-tenant-42",
  "destination": "ops@yourcompany.com",
  "label": "tenant:42",
  "active": true
}

The 201 response includes the assigned alias address (support-tenant-42@yourdomain.com), the alias ID for future PATCH and DELETE calls, and the creation timestamp. Store the ID in your tenant row; you’ll need it on offboarding. For custom-domain registration through the same API, our custom domain email alias setup covers the two-phase TXT-then-records flow that the API surfaces through POST /domains and POST /domains/{id}/verify.

Building a CI/CD secret-scanner integration

The integration pattern that earns the email forwarding API its keep is the secret-scanner remediation loop. Modern CI pipelines run scanners on every push; when one flags an alias address in a committed file, you want the alias disabled before the developer has switched git branches. Done by hand, that’s a Slack message, a dashboard click, and a fifteen-minute window where the leaked address is live. Done through the API, it’s a five-line script and a sub-second window.

The skeleton, in bash + curl, runs against any of the hosted forwarding APIs (path and field names from EmailAlias.io; substitute your provider’s). The script reads the alias address from the scanner output, resolves it to an alias ID via the list endpoint, then revokes:

#!/usr/bin/env bash
set -euo pipefail

LEAKED_ALIAS="$1"   # e.g. "support-tenant-42@yourdomain.com"
API_KEY="${EMAILALIAS_API_KEY}"
BASE="https://emailalias.io/api"

# Resolve address → ID
ALIAS_ID=$(curl -fsS -H "Authorization: Bearer $API_KEY" \
  "$BASE/aliases?alias_email=$LEAKED_ALIAS" \
  | jq -r '.items[0].id')

# Revoke
curl -fsS -X DELETE \
  -H "Authorization: Bearer $API_KEY" \
  "$BASE/aliases/$ALIAS_ID"

echo "Revoked $LEAKED_ALIAS ($ALIAS_ID) after secret-scanner hit"

Wire that into a CI step that runs after the scanner, gated on a non-zero exit code from the scanner that names an alias in its output, and you have a closed-loop remediation pattern that fires within seconds of a leak being introduced. The same shape generalises to PR-review bots, runtime exfil detection, or any other signal that an alias has escaped its blast radius. Larger pipelines wrap the script in an idempotent retry loop and emit a Slack notification on success; the smallest version is the four curl calls above.

Webhook deliveries versus polling

Two integration patterns dominate downstream consumption of an email forwarding API: webhooks (the API pushes events to a URL you publish) and polling (your consumer pulls /aliases/{id}/logs?since=<cursor> on a schedule). The choice depends almost entirely on whether you can run a publicly reachable endpoint.

Webhooks are the right pattern when you have a public-facing service and want near-real-time latency. Each forwarding event triggers an HTTPS POST to your endpoint, carrying the message metadata and an HMAC signature in a header (X-EmailAlias-Signature on EmailAlias.io; named variations elsewhere). You compute the HMAC over the raw body with your shared secret and reject any request whose signature doesn’t match — this prevents an attacker from spoofing webhook deliveries with crafted bodies. The pattern is the same as Stripe’s webhook signature verification, which remains the canonical reference. Replay protection comes from a timestamp in the signed payload — reject anything older than a few minutes.

Polling wins when you’re behind a firewall, when the consumer is a CI job that runs occasionally, or when you genuinely want the cursor-and-batch shape (easier to debug, no signature verification). The right cadence is whatever your latency budget allows: one minute for SIEM ingestion, one hour for daily-rollup dashboards. Use cursor-based pagination so the consumer’s state is just the cursor, not a timestamp it has to translate. Re-running with the same cursor returns the same window — pure-function semantics that compose well with retry logic.

In practice, many teams run both: a webhook for the realtime alerting path (high-volume sender on this alias → page oncall) and a nightly polling job for the comprehensive audit trail. The two paths feed different downstream systems and don’t need to share infrastructure.

Common mistakes with an email forwarding API

The failures we’ve seen are nearly all operational — the API itself is forgiving, but a few patterns turn that forgiveness into a footgun. The list below is in rough order of how often we’ve watched each one cost an integration something.

  • Hardcoding the API key in client-side code. If the key is anywhere a browser can fetch it, it’s compromised — there’s no client-side secret in a public web app. The fix is a small server-side proxy that holds the key and exposes the subset of endpoints the client needs.
  • No rate-limit handling. Clients that ignore X-RateLimit-Remaining and treat 429 as “just retry harder” turn a soft limit into a hard outage. The right pattern is exponential backoff respecting Retry-After, or proactive throttling when remaining drops below ~10% of the limit.
  • Treating list endpoints as unbounded. GET /aliases returns a page, not the whole account. Iterate next_cursor to completion. The integration that “works” on a test account with 12 aliases and silently truncates to the first 100 in production is the canonical version of this bug.
  • Not retrying idempotently. A 5xx response usually means “the server choked before committing”; without an Idempotency-Key on the retry, you risk double-creating the alias. With one, the retry returns the cached response or replays the original — safe either way.
  • Ignoring webhook signature verification. An unsigned webhook endpoint is a public RPC that anyone can invoke. Verify the HMAC on every request; reject anything that fails. Stripe-style reference implementations exist for every major language.
  • Logging API responses to disk. Alias addresses are personally-identifying — they belong to a person who would prefer not to have their address in your log aggregation system unencrypted. Strip alias_email and destination from log payloads, or at minimum encrypt the log volume at rest.
  • Not rotating API keys. A key that’s been live for two years has been touched by every contractor, every laptop, every Slack export. Rotate annually as a baseline; immediately on any access change. The whole point of the scoped-key pattern is that rotation is cheap — use it.

The single biggest production-affecting mistake is the unbounded-list assumption — the bug doesn’t show up until the account grows past the page size, and by then the integration has been in production long enough that nobody remembers it has the bug. The cursor pattern is so cheap to implement correctly that there’s no excuse for the shortcut, but the shortcut keeps appearing because dashboards default to “show all” and developers reach for the same mental model.

Final thoughts

An email forwarding API earns its keep the moment the unit of work shifts from human-clicking-buttons to system-managing-aliases. Bulk creation, per-customer provisioning, secret-scanner remediation, SIEM streaming — every one of those patterns has the same shape: the API turns a dashboard task into a function call that composes with the rest of the system. The dashboard isn’t going away; it’s still the right tool for the everyday case. The API is the right tool everywhere else.

The properties that separate a workable email forwarding API from a frustrating one are the operational ones: scoped keys, predictable rate limits, idempotency on writes, cursor pagination on lists, HMAC-signed webhooks, and a published OpenAPI spec. None of them is exotic; all of them are table-stakes once you’ve been bitten by their absence. The first two providers in the comparison table above (EmailAlias.io, Addy.io) tick every box; the SimpleLogin variant ticks most. The DIY-on-SES path is sometimes the right answer, but only when you’ve explicitly chosen to own the operational layer yourself.

If you want to start integrating, the EmailAlias.io free tier includes API access with the 10-alias cap — enough to wire up a CI pipeline or a side-project tenant model and confirm the shape works end-to-end. Premium removes the cap and opens custom-domain registration through POST /domains, which pairs with the alias portability guide for any setup that wants the addresses to survive a future provider switch. The integration cost is one afternoon; the upside is every loop in your system that used to require a human in the middle.

Frequently asked questions

What’s the difference between an email forwarding API and the dashboard?

The dashboard is for humans creating aliases one at a time; the API is for systems managing aliases programmatically. The underlying forwarding behavior is identical — same routing, same destinations, same logs. The API just removes the human from the loop for bulk creation, per-customer provisioning, CI-driven revocation, and audit-log streaming. Most accounts use both: the dashboard for everyday personal aliases, the API for anything that scales beyond a click.

How is an email forwarding API authenticated?

Production APIs authenticate with a bearer token (Authorization: Bearer ) or a custom header (X-API-Key: ) carrying a high-entropy random string the user generates in the dashboard. The API stores only a hash; the user sees the raw value once at creation. Keys should support at least two scopes — read-only and read-write — so that a leaked monitoring key can’t be used to revoke aliases. Rotate keys at least annually and immediately on any access-control change.

What rate limits should I expect from an email forwarding API?

Typical limits are around 30 requests per second burst and 1000 per minute sustained per key, exposed in X-RateLimit-Limit / Remaining / Reset response headers on every response. Clients that read the headers and back off proactively never hit hard 429s; clients that ignore them get throttled. The bulk-creation pattern (deploy-time provisioning of dozens of aliases at once) usually fits inside the burst limit; the secret-scanner pattern is sequential and never approaches it.

Do I need idempotency keys for an email forwarding API?

For every POST that creates a resource, yes. An Idempotency-Key header (a client-generated UUID stored by the server for ~24 hours) means a retry after a 5xx returns the original response without re-creating the alias. Without it, a network blip during alias creation can silently produce two aliases pointing at the same destination. The pattern is the same as Stripe’s idempotency keys and is one of the cheapest reliability wins available.

When should I use webhooks instead of polling for forwarding events?

Webhooks when you have a publicly reachable endpoint and want near-real-time latency; polling when you don’t, or when you specifically want the cursor-based replay semantics. Many production integrations run both — a webhook for realtime alerting (high-volume sender → page oncall) and a nightly polling job for the comprehensive audit trail. Both consume the same underlying log resource; they just differ in latency and operational requirements.

How do I verify a webhook signature from an email forwarding API?

Compute an HMAC-SHA256 of the raw request body using the shared secret from your dashboard, encode it as the provider expects (usually hex), and compare it to the value in the signature header (X-EmailAlias-Signature on EmailAlias.io). Reject any request whose computed signature doesn’t match, and reject any whose signed timestamp is older than a few minutes (to prevent replay). The Stripe webhook-signature docs are the canonical reference implementation.

Can I use an email forwarding API to create custom-domain aliases programmatically?

Yes, on every hosted forwarding API that supports custom domains at all. The flow is two-phase: POST /domains with the domain name to register it locally (and receive a TXT verification record), then POST /domains/{id}/verify after publishing the TXT to provision the SES identity, DKIM tokens, and MAIL FROM configuration. The subsequent POST /aliases calls accept the custom domain as a target. Premium tiers usually include up to five custom domains per account.

What happens to forwarding logs when I delete an alias via the API?

Most providers retain the per-alias forwarding logs for a configurable window after the alias itself is deleted, so audit trails survive the revocation. EmailAlias.io retains logs for 30 days post-deletion by default; check the provider’s retention policy if your compliance requirements differ. The deletion itself is immediate — inbound mail to a deleted alias starts bouncing on the next inbound attempt, usually within seconds of the DELETE call.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.