# API keys

> Create Full Access and Sending Only API keys, restrict them to a domain, use them for SMTP, and rotate them without downtime.

API keys authenticate your requests to the REST API, your SMTP connections and API-key sessions on the MCP server. This page explains the two key scopes, how to create and manage keys, and how to store and rotate them safely.

## How API keys work

- Each key belongs to one workspace. Everything you do with it happens in that workspace.
- New keys start with `secret_` followed by 32 letters and digits, for example `secret_••••••••`. Keys created before the prefix was introduced keep working.
- Emailit shows the full key once, when you create or regenerate it. Copy it then; you can't view it again.
- You send the key as a bearer token: `Authorization: Bearer secret_…`. For SMTP, the key is the password.

## Scopes

Every key has one of two scopes. You choose the scope when you create the key.

| | Full Access (`full`) | Sending Only (`sending`) |
| --- | --- | --- |
| Send email (`POST /emails`) | Yes | Yes |
| Reschedule, cancel, retry and forward an email | Yes | Yes |
| SMTP relay | Yes | Yes |
| Read emails (list, retrieve, raw, body, metadata, attachments) | Yes | No |
| Domains, templates, contacts, audiences, suppressions, webhooks, events, campaigns, automations, verification and API keys | Yes | No |
| MCP tools | All tools | `send-email`, `update-email`, `cancel-email`, `retry-email`, `forward-email` and `get-current-workspace` |
| Can be restricted to one sending domain | No | Yes |

A Sending Only key that calls any other endpoint gets `403` with a message such as `Permission denied: read`. Use Full Access keys for back-office jobs that manage resources, and Sending Only keys for anything that only needs to send.

### Restrict a key to one domain

When you create a Sending Only key you can pick one verified sending domain. The key can then only send from addresses on that domain:

- Over the API, sending from another domain returns `403` with `"error": "Domain not authorized"`.
- Over SMTP, the message is rejected after `DATA` with `530 API key is restricted to sending domain: …`.

Restricted keys are a good fit for per-app or per-customer credentials, and for keys you have to hand to third-party software such as a CMS plugin.

## Before you begin

- You need the **Admin** role in the workspace to create, edit, regenerate or delete keys. Members can see the list of keys but not change it. See [Members and roles](/docs/workspaces/members-and-roles/).
- To send with a key, you need at least one [verified sending domain](/docs/domains/add-a-domain/).

## Create an API key

**Dashboard**

  1. **Open API keys.** Go to **Email API → API Keys** and select **Add API key**.

  2. **Name the key.** Enter a **Name** that says where the key is used, for example `production-web` or `wordpress-blog`. Names must be unique in the workspace.

  3. **Choose a scope.** Under **Scope**, choose **Full Access** or **Sending Only**.

  4. **Optionally restrict the domain.** For a Sending Only key, pick a sending domain under **Domain**, or leave it empty to allow every verified domain.

  5. **Create and copy the key.** Select **Create**. Copy the key from the dialog and store it in your secrets manager before you close it. Emailit shows the key only once.

**API**

  Call [Create an API key](/docs/api-reference/api-keys/create/) with a Full Access key. `scope` defaults to `full`; `sending_domain_id` only applies to Sending Only keys.

```bash
curl https://api.emailit.com/v2/api-keys \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production-web",
    "scope": "sending",
    "sending_domain_id": "dom_3xQ7mLp2RkT9vB4nHs8YcWd1Ze6"
  }'
```

  The `201` response is the only one that includes `key`:

```json
{
  "object": "api_key",
  "id": "key_4F2kN8sQwE1rT6yU3iO9pA7sD5f",
  "name": "production-web",
  "scope": "sending",
  "sending_domain_id": "dom_3xQ7mLp2RkT9vB4nHs8YcWd1Ze6",
  "last_used_at": null,
  "created_at": "2026-10-01T09:30:00.000Z",
  "updated_at": "2026-10-01T09:30:00.000Z",
  "key": "secret_••••••••••••••••••••••••••••••••"
}
```

  A name that's already taken returns `409`.

## Use the key

Pass the key in the `Authorization` header of every API request:

```bash
curl https://api.emailit.com/v2/emails \
  -H "Authorization: Bearer $EMAILIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Acme <hello@acme.com>",
    "to": "ada@example.com",
    "subject": "Your order has shipped",
    "text": "Your order #1042 is on its way."
  }'
```

To send over SMTP, use the key as the password:

| Setting | Value |
| --- | --- |
| Host | `smtp.emailit.com` |
| Port | `587` (STARTTLS, recommended), `465` (TLS), `2525` or `2587` (STARTTLS) |
| Username | `emailit` |
| Password | Your API key |

See [SMTP settings](/docs/smtp/settings/) for every option.

## Manage keys

Open a key from **Email API → API Keys** to see its scope, domain, **Created** date and **Last used** time, and the SMTP settings to use with it.

| Action | What happens | API |
| --- | --- | --- |
| **Edit** | Renames the key. Only the name is saved; to change the scope or domain restriction, create a new key and rotate to it. | [Update an API key](/docs/api-reference/api-keys/update/) |
| **Regenerate** | Issues a new secret for the same key and shows it once. The old secret stops working immediately. The key keeps its ID, name, scope and domain, and **Last used** resets. | [Regenerate an API key](/docs/api-reference/api-keys/regenerate/) |
| **Delete** | The key stops working immediately and disappears from the list. You can't undo this. | [Delete an API key](/docs/api-reference/api-keys/delete/) |

**Last used** updates whenever the key authenticates an API request or an SMTP login. A key that has never been used shows **Never**. In the API, endpoints that take a key ID also accept the key's name.

## Store keys safely

- **Keep keys on the server.** Never put a key in browser JavaScript, a mobile app, a public repository or a support ticket. Anyone with the key can send email as you and spend your credits.
- **Use environment variables or a secrets manager.** Load the key at runtime, for example from `EMAILIT_API_KEY`. Add `.env` files to `.gitignore`.
- **Give each app and environment its own key.** Separate keys for production, staging and each third-party tool make it easy to see who sent what and to revoke one without touching the others.
- **Use the narrowest scope.** If an app only sends email, give it a Sending Only key, restricted to its domain where possible.
- **Watch usage.** **Email API → Logs** lists API and SMTP requests per key, and you can filter **Email API → Emails** by API key. See [Request logs](/docs/logs/request-logs/).
- **Act fast on a leak.** If a key is exposed, regenerate or delete it right away, then check the logs for unexpected sends.

## Rotate a key without downtime

Regenerating a key cuts off the old secret at once, so use it only when a key is compromised. For planned rotation, run the old and new keys side by side:

1. **Create a new key.** Add a key with the same scope and domain restriction as the one you're replacing. Give it a name that shows the date, such as `production-web-2026-10`.

2. **Deploy the new key.** Update the secret in your secrets manager or environment and roll it out to every server, worker and scheduled job that uses the old key.

3. **Confirm the switch.** Open the new key and check that **Last used** is recent. In **Email API → Logs**, filter by the old key and check that requests have stopped.

4. **Delete the old key.** When the old key's **Last used** time no longer changes, delete it.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| `401` `Invalid API key` | The key was deleted, regenerated or mistyped. | Copy the current key into your configuration, including the `secret_` prefix. |
| `403` `Permission denied: read` or `Permission denied: full` | A Sending Only key called an endpoint outside its scope. | Use a Full Access key for that call. |
| `403` `Domain not authorized` | The key is restricted to a different domain than the `from` address. | Send from the key's domain or use another key. |
| SMTP `535 Authentication failed` | The password isn't a valid API key. | Use the API key as the password and `emailit` as the username. |

## Related

  - [Authentication](/docs/api-reference/authentication/): How requests are authenticated.
  - [API keys API](/docs/api-reference/api-keys/): Create, list, update, regenerate and delete keys.
  - [SMTP settings](/docs/smtp/settings/): Host, ports, TLS and credentials.
  - [Security](/docs/security/): How Emailit protects your account and data.

---
Source: https://emailit.com/docs/developers/api-keys/
