import { createClient } from "@mailsai/sdk";
const client = createClient(); // reads MAILS_API_KEY
const result = await client.api_keys.create({
name: "Production server",
scopes: ["send", "read"],
mode: "live",
});
console.log(result);from mailsai import create_client
client = create_client() # reads MAILS_API_KEY
result = client.create_api_key(
name="Production server",
scopes=["send", "read"],
mode="live",
)
print(result)curl -X POST 'https://api.mails.ai/v1/api-keys' \
-H "Authorization: Bearer $MAILS_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Production server",
"scopes": ["send", "read"],
"mode": "live"
}'mails api-keys create --mode test --save-as test
mails api-keys create --name "Production server" \
--scopes send,read --key-file ./mails.key{
"name": "mails_api_keys_create",
"arguments": {
"name": "Production server",
"scopes": ["send", "read"],
"mode": "live"
}
}{
"id": "key_01JZXD7R9T1V3X5Z7B9D1F3H5K",
"key": "mk_live_a1b2c3d4e5f60718293a4b5c6d7e8f90",
"prefix": "mk_live_a1b2",
"mode": "live",
"scopes": ["send", "read"],
"agent_id": null,
"name": "Production server",
"expires_at": null,
"created_at": "2026-06-24T17:20:00.000Z"
}201 The created key, including the one-time plaintext
value.
400 Invalid request — malformed JSON or a field failed
validation. Also feature_not_enabled when this
server has a feature switched off (custom domains
before they are available).
401 Missing or invalid API key.
403 The API key lacks the required scope
(insufficient_scope), or the token belongs to an
app connected by sign-in and this operation is
closed to connected apps
(connected_app_not_allowed).
404 Resource not found in this workspace, or the agent
a send names is archived (agent_archived).
500 Internal server error.Create an API key
import { createClient } from "@mailsai/sdk";
const client = createClient(); // reads MAILS_API_KEY
const result = await client.api_keys.create({
name: "Production server",
scopes: ["send", "read"],
mode: "live",
});
console.log(result);from mailsai import create_client
client = create_client() # reads MAILS_API_KEY
result = client.create_api_key(
name="Production server",
scopes=["send", "read"],
mode="live",
)
print(result)curl -X POST 'https://api.mails.ai/v1/api-keys' \
-H "Authorization: Bearer $MAILS_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Production server",
"scopes": ["send", "read"],
"mode": "live"
}'mails api-keys create --mode test --save-as test
mails api-keys create --name "Production server" \
--scopes send,read --key-file ./mails.key{
"name": "mails_api_keys_create",
"arguments": {
"name": "Production server",
"scopes": ["send", "read"],
"mode": "live"
}
}{
"id": "key_01JZXD7R9T1V3X5Z7B9D1F3H5K",
"key": "mk_live_a1b2c3d4e5f60718293a4b5c6d7e8f90",
"prefix": "mk_live_a1b2",
"mode": "live",
"scopes": ["send", "read"],
"agent_id": null,
"name": "Production server",
"expires_at": null,
"created_at": "2026-06-24T17:20:00.000Z"
}201 The created key, including the one-time plaintext
value.
400 Invalid request — malformed JSON or a field failed
validation. Also feature_not_enabled when this
server has a feature switched off (custom domains
before they are available).
401 Missing or invalid API key.
403 The API key lacks the required scope
(insufficient_scope), or the token belongs to an
app connected by sign-in and this operation is
closed to connected apps
(connected_app_not_allowed).
404 Resource not found in this workspace, or the agent
a send names is archived (agent_archived).
500 Internal server error.Body Parameters
A label for the key, 1 to 80 characters, returned as name wherever the key is listed. It need not be unique; left out, name is null.
Tie the key to one agent. Such a key reads and acts on that agent's mail only: another agent's message, thread, draft, attachment or raw email answers 404, as if it did not exist; lists and search hold its own agent's mail; naming another agent in a filter is a 403. Webhooks and labels belong to the whole workspace, so it cannot create, change, delete, test or replay a webhook, redeliver an event, or create, rename or delete a label (403). Nor can it create an agent, change its own agent's domain lists or send limits, read the request log, the workspace's usage or the send-anyway list, add or revoke a send-anyway entry, revoke an API key, open billing, or add, verify or remove a domain (403), and another agent answers 404 to a change; its reputation and suppressed-recipient reads hold its own agent. The keys it makes are tied to the same agent. Leave it out for a key that reaches every agent.
send sends mail, read reads it, and draft writes drafts but can neither send nor schedule one. manage changes the workspace: it creates, changes and archives agents; creates and revokes API keys; creates, changes, tests and deletes webhooks and rotates their secrets; replays webhook deliveries and redelivers events; creates, renames and deletes labels; adds, verifies and removes domains; adds and removes send-anyway entries; opens the billing portal; lists and revokes connected apps; changes and deletes threads and drafts; and cancels and reschedules scheduled messages (rescheduling needs send too).
live makes an mk_live_… key that sends real mail, and test an mk_test_… key whose sends are stored and raise events but are never transmitted or billed. A test key can only make test keys.
When the key stops working: an ISO 8601 UTC time ending in Z. From then on it answers 401 expired_api_key; left out, the key never expires. A key that expires can only make keys that expire no later than it does.
The plaintext key is returned ONCE in this response and never again. Closed to apps connected by sign-in (403 connected_app_not_allowed): use the dashboard, an API key or the mails CLI.
Response
API key id (key_…); DELETE /v1/api-keys/{id} revokes the key.
The full plaintext API key. SHOWN ONCE — store it now; it cannot be retrieved again.
The first 12 characters of key: how the key is shown in lists once key is gone.
The key's mode: live unless the request asked for test. A test key's sends are never transmitted or billed.
The scopes the key holds: those requested, or send and read when none were.
The agent the key is tied to, or null for a key that reaches every agent.
The name given in the request, or null.
When the key stops working, as given in the request. Null for a key that never expires.
When the key was created.
Was this page helpful?