# Automated Email Account Creation API Programmatic Setup

Published: September 7, 2026

How to create real, working email accounts from code with one API call, plus webhook delivery, naming patterns, and lifecycle cleanup for agents.

The short answer: you need a mailbox API, not a mail client. An automated email account creation API programmatic flow is a single authenticated POST that returns a live address your code can immediately send from and receive at, with no browser step, no OAuth consent screen, and no human clicking through a signup wizard. With Robotomail that call is one line of curl and the mailbox is usable in seconds.

Most people searching for this have hit the same wall. They tried to provision addresses through Gmail, Outlook, or a Workspace admin API and found that every path assumes a human being with a password, a phone number, and a consent screen. That model breaks the moment you need fifty mailboxes for fifty agents, or one throwaway mailbox per support ticket.

Below is what programmatic account creation actually looks like when the provider is built for it, including the parts people underestimate: inbound delivery, address naming, and lifecycle cleanup.

## What an automated email account creation API programmatic flow gives you

A proper provisioning API gives you four things:

1. **A real, routable address.** Not an alias that forwards into one shared human inbox. A distinct mailbox with its own identity.
2. **Send capability under that identity.** The address in the `From` header is the mailbox, and replies come back to it.
3. **Inbound delivery you can consume.** A webhook POST or an API read, not IMAP polling you have to babysit.
4. **Machine-friendly lifecycle.** Create, list, and delete by API key, no seat purchase and no admin console.

One thing to be clear about: this is infrastructure for systems you own, agents, workflows, per-customer intake addresses. It is not a way to mass-register accounts on someone else's consumer service, and providers that let you do that do not last long. Our [acceptable use policy](/acceptable-use) draws that line explicitly.

## Why Gmail and Outlook fight you here

Consumer mail providers price and design around one identity per human. Provisioning a new user in Google Workspace or Microsoft 365 means an admin-scoped credential, a directory entry, and a billable seat. Automating it is technically possible and operationally miserable: domain-wide delegation, service account impersonation, per-user OAuth grants that expire, and a monthly bill that grows linearly with the number of agents you spin up.

Even after all that, reading mail is the harder half. The Gmail API gives you history IDs and pull-based sync, so you either poll or wire up Pub/Sub push notifications. We cover the tradeoffs in detail in our [Gmail API comparison](/compare/gmail-api), but the summary is that account creation and inbound handling both assume a person is in the loop somewhere.

Transactional senders have the opposite problem. SendGrid, Mailgun, and Resend will happily send on your behalf, but they do not hand you an inbox. You get a sending domain and, at best, an inbound parse route that dumps mail at a URL with no mailbox identity behind it. If your agent needs to hold a threaded conversation as `orders-agent@yourdomain.com`, that is a mailbox concern, not a sending concern.

## Create a mailbox programmatically

Fastest path from the CLI:

```bash
npx @robotomail/cli mailbox create shopping-agent
```

Same thing over HTTP, which is what you will actually call from application code:

```bash
curl -X POST https://api.robotomail.com/v1/mailboxes \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"address": "shopping-agent"}'
```

Omit `domainId` and the mailbox lands on a platform domain, which is fine for internal agents and testing. Pass a verified custom domain's UUID as `domainId` and you get `shopping-agent@yourdomain.com` instead. Domain verification is a one-time DNS step, covered in the [custom domain guide](/docs/guides/custom-domain).

In TypeScript, provisioning at the point where you create the thing that needs an address:

```ts
async function provisionMailbox(slug: string) {
  const res = await fetch("https://api.robotomail.com/v1/mailboxes", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.ROBOTOMAIL_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ address: slug }),
  });

  if (!res.ok) {
    throw new Error(`mailbox create failed: ${res.status}`);
  }

  return res.json();
}

// called when a new agent run, tenant, or ticket is created
const mailbox = await provisionMailbox(`ticket-${ticketId}`);
```

Store the returned mailbox ID next to whatever entity owns it. Every subsequent call, sending, listing threads, deleting, keys off that ID.

Sending from the new mailbox uses the same key:

```bash
curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_shopping/messages \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"to": ["vendor@example.com"], "subject": "Order #A-4521 delivery update?", "bodyText": "Hi, checking on the status of order A-4521."}'
```

Full request and response fields are in the [mailboxes API reference](/docs/api/mailboxes).

## Receiving mail without polling

Creating an account is only useful if you can read what arrives. Register a webhook as its own resource and inbound messages arrive as JSON:

```json
{
  "event": "message.received",
  "data": {
    "message_id": "...", "mailbox_id": "...", "mailbox_address": "shopping-agent@robotomail.co",
    "from": "vendor@example.com", "subject": "Re: ...", "body_text": "...",
    "thread_id": "...", "received_at": "2026-04-17T10:00:00.000Z"
  }
}
```

Note the `thread_id`. That is what turns a pile of individual messages into a conversation your agent can reason about, and it is why a mailbox beats a parse route. To reply in-thread, send from the mailbox with `inReplyTo` set to the inbound `message_id`.

Two practical notes from running this in production. First, acknowledge the webhook fast and process asynchronously, because your model call will outlive any sane HTTP timeout. Second, treat every inbound body as untrusted input, since anyone can email your agent. Our writeup on [email prompt injection](/blog/email-prompt-injection) covers the mitigations, and [parsing inbound webhooks](/blog/parse-inbound-email-webhook) covers the handler shape.

## Address naming and lifecycle patterns

Programmatic creation makes it cheap to have many mailboxes, which means naming matters more than it used to. Patterns that hold up:

- **One mailbox per agent identity.** `research-agent`, `invoice-agent`, `support-triage`. Stable, human-readable, matches how you talk about the system internally.
- **One mailbox per tenant.** `acme-corp`, `globex`. Keeps customer conversations isolated so an agent cannot leak context across accounts.
- **One mailbox per task or run.** `ticket-8842`, `run-2f9a`. Best isolation, highest churn. Delete these when the task closes or you will accumulate thousands of dormant addresses.

Derive addresses deterministically from an ID you already own so a retried provisioning call is idempotent-ish rather than creating `ticket-8842-2`. Handle the collision error rather than appending random suffixes.

For the ephemeral pattern, make cleanup part of the same code path that closes the work item. Deleting a mailbox stops delivery, so if you need a record of the conversation, export the threads before you delete, or keep the mailbox and stop routing to it instead. Per-account and per-mailbox ceilings are documented under [limits](/docs/concepts/limits).

## Deliverability still applies

A programmatically created mailbox is a real mail identity, and mailbox providers judge it like one. Three things to get right early:

- **Authenticate your domain.** SPF, DKIM, and DMARC on any custom domain you send from. This is table stakes and not optional in 2026.
- **Respect suppressions.** If an address hard bounces or complains, stop sending to it. Retrying into a hard bounce is the fastest way to damage a young sending reputation.
- **Warm gradually.** A brand new domain that suddenly emits a few thousand messages a day looks exactly like a compromised one.

Agents make it easy to send volume by accident, so put a rate guard in front of the send call. There is a broader checklist in [email automation best practices](/blog/email-automation-best-practices).

If you are wiring this into a specific framework or agent runtime, the walkthrough in [how to give your AI agent an email address](/how-to-give-your-ai-agent-email-address) goes end to end from provisioning to first reply.

## FAQ

### Can I create Gmail or Outlook accounts programmatically?

Only inside a workspace you administer, using admin-scoped credentials, and each account consumes a paid seat. Consumer Gmail and Outlook signup is deliberately protected against automation. If your goal is many mailboxes for many agents, provisioning them through a mailbox API is cheaper and far less brittle.

### How fast is a new mailbox usable?

Immediately on a platform domain, since routing is already in place. On a custom domain, the domain needs DNS verification once, after which every mailbox you create on it is live as soon as the API returns.

### Do I need SMTP credentials for each account?

No. Authentication is a single API key at the account level, and you address individual mailboxes by ID in the request path. There are no per-mailbox passwords to store, rotate, or leak.

### How many mailboxes can I create?

Enough for one per agent, tenant, or task in normal use. Concrete ceilings are documented under limits, and [pricing](/pricing) shows how mailbox count factors into cost so you can decide between the per-task and per-agent patterns before you build.

Ready to provision your first mailbox? Create one with a single API call at [robotomail.com](https://robotomail.com), or read the [quickstart](/docs/quickstart) to see the full create, send, and receive loop.
