What You Can and Cannot Build With the Emcognito API Today
If you are building an email alias for a custom dashboard, you must build directly against the verified v1 API surface rather than assuming typical REST conventions. In v1, the Emcognito developer API exposes exactly two endpoints: GET /v1/aliases to list aliases with cursor pagination, and POST /v1/aliases to generate an alias programmatically. The base URL is https://api.emcognito.com/v1—there is no /api/v1 route. Authentication relies on an Authorization: Bearer <key> header, where your key consists of the literal prefix emk_ followed by 43 URL-safe characters. As documented in the Emcognito developer API documentation, authentication uses a single production key format without a live or test environment split, so keys never carry prefixes like emk_live_ or emk_test_.
You must also recognize the functional boundary of the API before planning your interface. v1 of the Emcognito API creates and lists aliases (GET and POST /v1/aliases). Suspending, resuming and deleting an alias are one-click dashboard actions today; there is no PATCH or DELETE endpoint yet. As a result, an email alias for a custom dashboard acts as an automated provisioning and auditing layer, rather than a full administrative control plane. Privacy-conscious developers typically build this integration because they assign a dedicated forwarding address to every online service, and vendor-provided interfaces rarely match their internal data models, ticketing systems, or local identity workflows.
Decide First: Is a Custom Dashboard the Right Layer for You?
Before writing client code, evaluate whether Emcognito's API fits your technical requirements. You can resolve this decision by evaluating three operational questions:
- Do you require programmatic address generation? If your system provisions user accounts, triggers test environments, or automates subscriptions, the developer API handles this directly through
POST /v1/aliases. - Do you require programmatic address deactivation or teardown? If your application must automatically revoke an alias via script upon a specific webhook event, the API cannot execute that step today. The official dashboard button is "Pause alias", and deletion requires manual web confirmation. Your interface should present deep links to the Emcognito web console rather than attempting local mutation calls.
- Do you require your own domain? Emcognito aliases use the shared emcognito.com domain. Custom subdomain support is planned, but custom domains are not available today.
Operational trade-offs also dictate architecture choices. Emcognito is closed source and runs only as a hosted service; if open source or self-hosting is a requirement, addy.io is the better fit. You can review how those architectures differ in our detailed comparison of Emcognito vs addy.io.
If your system architecture accepts these bounds, review the API throughput tiers on the Emcognito pricing page before provisioning your token.
Plan Limits Before You Write a Line of Code
Emcognito meters inbound and outbound email volume rather than total address storage. However, address creation velocity and message forwarding are strictly metered, as detailed on the Emcognito pricing schedule. Source: Emcognito source.
For automated generation via the developer API, limits depend on your tier as published on the Emcognito pricing table:
- Plus Plan: $20 per year (or $2 per month) as documented on the Emcognito pricing page. It provides 2,500 forwarded messages per month and caps developer API creation at 50 aliases per day.
- Pro Plan: $36 per year (or $4 per month) as published on the Emcognito pricing page. It provides 15,000 forwarded messages per month and caps developer API creation at 200 aliases per day.
- Free Tier: Unlimited email aliases and 100 forwarded messages per month, but developer API access is reserved for paid tiers.
Network interactions rely on standard mail protocol semantics as defined in RFC 5321. Mail received by an alias is evaluated against monthly quotas before envelope relay to your real destination address. Do not construct code that expects instant multi-thousand alias ingestion.
Create an Alias From Your Dashboard: The POST Contract
Unlike REST designs that respond with HTTP 200 OK and an unwrapped root object, the Emcognito API responds with HTTP 200 and wraps the entity inside an alias key. The schema contains eleven explicit fields:
{
"alias": {
"id": "id_9k2m1x04p8a",
"address": "k8x92mq1z@emcognito.com",
"status": "active",
"created_at": 1772668800,
"forward_count": 0,
"label": "Stripe Billing Production",
"note": "Used exclusively for merchant invoices",
"source": "api",
"category": "infrastructure",
"single_use": false,
"expires_at": ""
}
}
Your client-side serialization layer must observe three structural guarantees documented in the Emcognito developer documentation:
created_atis returned as an integer Unix epoch timestamp rather than an ISO-8601 string, as specified in the Emcognito API documentation.- According to the official Emcognito developer documentation, unset or empty string attributes return an empty string (
""), nevernull. - The request payload allows optional keys:
label,note,source,category,single_use(boolean), andexpires_at(Unix epoch string or integer), per the developer reference.
The following Node.js implementation safely executes a creation call for your custom administrative dashboard:
import axios from 'axios';interface CreateAliasOptions { label: string; category?: string; note?: string; singleUse?: boolean; }
interface AliasRecord { id: string; address: string; status: string; created_at: number; forward_count: number; label: string; note: string; source: string; category: string; single_use: boolean; expires_at: string; }
export async function provisionDashboardAlias( apiKey: string, options: CreateAliasOptions ): Promise<AliasRecord> { try { const response = await axios.post<{ alias: AliasRecord }>( 'https://api.emcognito.com/v1/aliases', { label: options.label, category: options.category || '', note: options.note || '', single_use: options.singleUse ?? false, source: 'dashboard-internal' }, { headers: { 'Authorization':
Bearer ${apiKey}, 'Content-Type': 'application/json' } } );// Endpoint returns HTTP 200 on success return response.data.alias;
} catch (error: any) { if (error.response?.status === 429) { throw new Error(Rate limit encountered: ${error.response.data?.message || 'Check daily cap or burst limits'}); } throw error; } }
List and Page Through Aliases for Your Alias Management UI
To populate your alias management UI, fetch stored records using GET /v1/aliases. This endpoint implements cursor-based pagination using the query parameters next_cursor and last_key. Because active installations easily scale to hundreds of records, your backend synchronization job must iterate through pages until the response returns an empty or absent cursor value.
The response structure contains an aliases array alongside pagination metadata. When rendering records in an email routing dashboard, the forward_count field serves as your primary diagnostic metric. Sorting your UI table by descending forward_count instantly highlights which service endpoints are actively transmitting data versus stale aliases created for one-time registrations.
import axios from 'axios';export async function fetchAllAliases(apiKey: string): Promise<any[]> { let records: any[] = []; let nextCursor: string | null = null;
do { const params: Record<string, string> = {}; if (nextCursor) { params['next_cursor'] = nextCursor; }
const response = await axios.get('https://api.emcognito.com/v1/aliases', { headers: { 'Authorization': `Bearer ${apiKey}` }, params }); const data = response.data; if (Array.isArray(data.aliases)) { records = records.concat(data.aliases); } // Assign cursor for the next iteration; terminate when undefined or empty nextCursor = data.next_cursor || null;} while (nextCursor);
return records; }
When designing your UI rendering layer, observe these data-handling rules:
- Parse
created_atfrom an epoch integer into your local system display format (such asnew Date(created_at * 1000)). - Empty string values (
"") in optional fields such asnote,label, orexpires_atshould render as an explicit dash (—) in the UI rather than whitespace to avoid layout shift. - v1 of the Emcognito API creates and lists aliases (GET and POST /v1/aliases). Suspending, resuming and deleting an alias are one-click dashboard actions today; there is no PATCH or DELETE endpoint yet. Do not mount HTTP action verbs like PATCH or DELETE on UI row buttons; render those elements as outbound deep links pointing to
https://emcognito.com/dashboard.
Handling Both 429s: Burst Limit vs Daily Creation Cap
A production integration must distinguish between the two distinct HTTP 429 Too Many Requests errors Emcognito emits. Because rate limits are checked at different infrastructure tiers, their error payloads and response headers behave differently.
The per-key burst limit allows 60 requests per minute. This quota is calculated across all calls to /v1/aliases (both GET and POST). It is enforced at the network proxy layer. In accordance with RFC 9110 and specifications documented by MDN Web Docs on the Retry-After header, the returned 429 response includes a standard Retry-After header containing the integer value in whole seconds required to clear the window. Live production measurement on /v1/aliases on 2026-09-20 confirmed that the 61st call within a 60-second window yields an immediate HTTP 429 with retry-after: 60.
Conversely, the daily creation cap (50 per day on Plus, 200 per day on Pro) is enforced by application business logic during POST processing. This application-level 429 response contains a bare JSON payload ({"message": "Daily alias creation limit reached"}) and does not send a Retry-After header. The daily allocation resets strictly at 00:00 UTC.
import axios, { AxiosError } from 'axios';export async function executeWithRateLimitHandling( apiCall: () => Promise<any> ): Promise<any> { try { return await apiCall(); } catch (err: any) { const axiosError = err as AxiosError<{ message?: string }>;
if (axiosError.response) { const status = axiosError.response.status; const retryAfterHeader = axiosError.response.headers['retry-after']; if (status === 429) { if (retryAfterHeader) { // Burst limiter tripped: sleep for the duration specified in header const waitSeconds = parseInt(retryAfterHeader, 10) || 60; console.warn(`Burst limit reached. Backing off for ${waitSeconds} seconds.`); await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000)); return executeWithRateLimitHandling(apiCall); } else { // Daily creation cap reached: no Retry-After provided. // Resets at 00:00 UTC. Halt worker loops until the next UTC day. const errorMessage = axiosError.response.data?.message || 'Daily limit exhausted'; throw new Error(`Daily cap reached. Halting executions until 00:00 UTC. Reason: ${errorMessage}`); } } if (status === 503 && retryAfterHeader) { const waitSeconds = parseInt(retryAfterHeader, 10) || 30; console.warn(`Service backpressure (503). Retrying after ${waitSeconds} seconds.`); await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000)); return executeWithRateLimitHandling(apiCall); } } throw err;
} }
Designing the Dashboard Around One Alias Per Site
The primary security objective of assigning unique aliases is to isolate identities per domain. If a service provider experiences a data breach or trades customer lists, a dedicated address allows you to pinpoint the origin of incoming spam immediately.
When architecting your internal database and views, store the relationship using the site identifier as the primary indexing key rather than treating the email address as the central entity. As detailed in RFC 8058, modern email senders embed tracking mechanisms and header signals that assist in tracing message trajectories. Linking an alias directly to a third-party domain in your dashboard makes leakage detection straightforward.
| Dashboard UI Element | Emcognito API Mapping | System Function |
|---|---|---|
| Service / Vendor | label |
Identifies the external domain or platform holding the alias. |
| Environment / Type | category |
Groups accounts by context (e.g., billing, dev, testing, subscriptions). |
| Forwarded Address | address |
The generated forwarding endpoint (ending in @emcognito.com). |
| Traffic Counter | forward_count |
Monitors cumulative inbound messages routed across this boundary. |
| Operational State | status |
Reflects current delivery status (active or paused). |
| Killswitch Target | id |
Provides the entity key for manual dashboard intervention. |
When an alias begins receiving unauthorized solicitations or credential-stuffing attempts, containment must be swift. Suspend the alias in the Emcognito management console, and the sender is cut off immediately. If you need to respond to legitimate incoming messages, note the reply mechanism carefully. Replying to a forwarded message is included on every Emcognito plan, Free as well, and it happens in your delivery log: open the delivered message and choose Reply securely, and Emcognito sends it with the alias as the sender. Replying from your own mail app is paused for security and is refused rather than delivered. Composing a brand-new message from an alias is the Plus and Pro feature.
What Your Dashboard Cannot Do, and What to Do Instead
Clear architectural boundaries prevent brittle integrations. Build your dashboard around these system limits:
- No programmatic status toggling: v1 of the Emcognito API creates and lists aliases (GET and POST /v1/aliases). Suspending, resuming and deleting an alias are one-click dashboard actions today; there is no PATCH or DELETE endpoint yet. Add a deep link in your interface that routes your operator to the specific address record within
https://emcognito.com/dashboard. - Shared domains only: Emcognito aliases use the shared emcognito.com domain. Custom subdomain support is planned, but custom domains are not available today.
- No mailbox encryption layer: Emcognito forwards mail over TLS-encrypted transport and does not read message contents or retain them after delivery, apart from a brief hold on mail that arrives over your monthly forward cap, but it is not end-to-end encrypted. For content confidentiality, pair it with an encrypted mailbox such as Proton Mail or Tuta.
- Data minimisation instead of zero logs: Emcognito is not a zero-knowledge service. It does not read or analyse message contents, or retain them after delivery, apart from a brief hold on mail that arrives over your monthly forward cap, but it necessarily handles mail in readable form in order to deliver it. Furthermore, Emcognito collects no personal information beyond a destination address and does not retain message bodies after delivery, apart from a brief hold on mail that arrives over your monthly forward cap, but it keeps the delivery and operational logs any mail service needs. That is data minimisation, not a no-log policy.
- Wind-down protections instead of SLAs: Emcognito publishes a wind-down commitment: advance notice before a planned shutdown and alias export so accounts can be migrated, on a best-efforts basis. It is not a contractual guarantee. Design your internal workflows around these published operational parameters rather than assuming contractual uptime guarantees.
A Minimal Working Shape for the Dashboard
A stable internal dashboard needs three primary UI panels:
1. Provisioning Form
A simple creation view collecting label (the service name), category (production, testing, marketing), and an optional single_use toggle. When submitted, the form issues a POST request, captures the returned address, and copies it to the operator's clipboard for pasting into external signup forms.
2. Filtered Routing Table
A paginated overview consuming GET /v1/aliases. Implement server-side caching using Redis or a local database table that refreshes periodically to avoid hitting the 60 calls/minute burst threshold during team use. Render empty fields as dashes, display forward_count to expose high-volume senders, and format epoch integers into readable timestamps.
3. Detail and Audit Modal
Selecting any record displays the full JSON entity. Include an external link pointing directly to the Emcognito management view for that alias ID, allowing the operator to click "Pause alias" or execute manual deletions with native confirmation modals.
Frequently Asked Questions
Can I suspend or delete an alias through the Emcognito API?
v1 of the Emcognito API creates and lists aliases (GET and POST /v1/aliases). Suspending, resuming and deleting an alias are one-click dashboard actions today; there is no PATCH or DELETE endpoint yet. To deactivate an alias, locate the address in the Emcognito web console and click Pause alias.
What does POST /v1/aliases return, and why is it 200 and not 201?
POST /v1/aliases returns HTTP 200 (not 201) with the new alias under an "alias" object containing id, address, status, created_at, forward_count, label, note, source, category, single_use, and expires_at. The API uses HTTP 200 for successful creations, and created_at is provided as an integer Unix epoch rather than an ISO timestamp.
How do I tell the burst-limit 429 apart from the daily-cap 429?
The burst-limit 429 triggers when you exceed 60 calls per minute and includes a Retry-After header with the wait time in whole seconds. The daily creation cap 429 triggers from application logic when you pass 50 creations on Plus or 200 on Pro; it sends no Retry-After header and clears strictly at 00:00 UTC.
How many aliases can my dashboard create per day on Plus and on Pro?
Through the developer API, Plus plans can create up to 50 aliases per day, while Pro plans can create up to 200 aliases per day, as outlined on the Emcognito pricing schedule.
Does the Emcognito API send rate-limit headers I can read?
Next Step
To start integrating programmatic alias creation into your internal tooling, explore the developer alias API. The API is included with paid plans—capped at 50 aliases per day on Plus ($20/year or $2/month) and 200 aliases per day on Pro ($36/year or $4/month).