What are Permissions?
Permissions let you restrict what an API key can do. By default, an API key has full access within its scope (organization, pod, or inbox). When you provide a permissions object, it acts as a whitelist: only the permissions you explicitly set to true are granted. Everything else is denied.
This gives you fine-grained control over which resources and operations each key can access, on top of the existing scope-based isolation provided by pod-scoped and inbox-scoped keys.
How Permissions Work
Whitelist model
When you create an API key with a permissions object, it switches from “full access” mode to “whitelist” mode:
- No
permissionsfield: The key has full access within its scope. This is the default and is backward compatible with existing keys. permissionspresent: Only permissions set totrueare allowed. Any permission that is omitted or set tofalseis denied.
Backward compatibility
Existing API keys without a permissions field continue to work exactly as before with full access. The whitelist only activates when you explicitly provide the permissions object.
Intersection with scope
Permissions are intersected with the key’s scope. A key scoped to a single inbox cannot gain organization-level capabilities (like inbox_create or domain_create) even if those permissions are set to true. The effective permissions are always the intersection of what the scope allows and what the permissions object grants.
Privilege escalation protection
A restricted API key cannot create a child key with more permissions than itself. When creating a new key, the child’s permissions are automatically constrained to the parent’s effective permissions. This prevents privilege escalation through key creation.
Permissions Reference
Inboxes
| Permission | Description |
|---|---|
inbox_read |
Read inbox details |
inbox_create |
Create new inboxes |
inbox_update |
Update inbox settings |
inbox_delete |
Delete inboxes |
Threads
| Permission | Description |
|---|---|
thread_read |
Read threads |
thread_delete |
Delete threads |
Messages
| Permission | Description |
|---|---|
message_read |
Read messages |
message_send |
Send messages |
message_update |
Update message labels |
Label Visibility
| Permission | Description |
|---|---|
label_spam_read |
Access messages labeled as spam |
label_blocked_read |
Access messages labeled as blocked |
label_trash_read |
Access messages labeled as trash |
When a label visibility permission is denied, items with that label are automatically excluded from list results and return “not found” on direct access. For example, setting label_spam_read to false means the key will never see spam messages in any listing or lookup.
Event subscriptions
Label visibility permissions also control whether an API key can subscribe to the corresponding event types on webhooks and WebSockets. An API key without label_spam_read cannot create a webhook or WebSocket subscription for message.received.spam events, and an API key without label_blocked_read cannot subscribe to message.received.blocked events.
Drafts
| Permission | Description |
|---|---|
draft_read |
Read drafts |
draft_create |
Create drafts |
draft_update |
Update drafts |
draft_delete |
Delete drafts |
draft_send |
Send drafts |
Webhooks
| Permission | Description |
|---|---|
webhook_read |
Read webhook configurations |
webhook_create |
Create webhooks |
webhook_update |
Update webhooks |
webhook_delete |
Delete webhooks |
Domains
| Permission | Description |
|---|---|
domain_read |
Read domain details |
domain_create |
Create domains |
domain_update |
Update domains |
domain_delete |
Delete domains |
Lists
| Permission | Description |
|---|---|
list_entry_read |
Read list entries |
list_entry_create |
Create list entries |
list_entry_delete |
Delete list entries |
Metrics
| Permission | Description |
|---|---|
metrics_read |
Read metrics |
API Keys
| Permission | Description |
|---|---|
api_key_read |
Read API keys |
api_key_create |
Create API keys |
api_key_delete |
Delete API keys |
Pods
| Permission | Description |
|---|---|
pod_read |
Read pods |
pod_create |
Create pods |
pod_delete |
Delete pods |
Code Examples
Read-only key
Create an API key that can read all resources but cannot create, update, or delete anything.
PythonTypeScriptCLI
from agentmail import AgentMail
client = AgentMail(api_key="YOUR_API_KEY")
key = client.api_keys.create(
name="read-only-agent",
permissions={
"inbox_read": True,
"thread_read": True,
"message_read": True,
"draft_read": True,
"webhook_read": True,
"domain_read": True,
"list_entry_read": True,
"metrics_read": True,
"api_key_read": True,
"pod_read": True,
"label_spam_read": True,
"label_blocked_read": True,
"label_trash_read": True,
}
)
print(key.api_key)
No-spam key
Create a key with full access but block visibility into spam, blocked, and trash content. This is useful for agent-facing keys where you want to prevent the agent from processing unwanted email.
PythonTypeScriptCLI
key = client.api_keys.create(
name="clean-inbox-agent",
permissions={
"inbox_read": True,
"inbox_create": True,
"inbox_update": True,
"inbox_delete": True,
"thread_read": True,
"thread_delete": True,
"message_read": True,
"message_send": True,
"message_update": True,
"label_spam_read": False,
"label_blocked_read": False,
"label_trash_read": False,
"draft_read": True,
"draft_create": True,
"draft_update": True,
"draft_delete": True,
"draft_send": True,
"webhook_read": True,
"webhook_create": True,
"webhook_update": True,
"webhook_delete": True,
"domain_read": True,
"domain_create": True,
"domain_update": True,
"domain_delete": True,
"list_entry_read": True,
"list_entry_create": True,
"list_entry_delete": True,
"metrics_read": True,
"api_key_read": True,
"api_key_create": True,
"api_key_delete": True,
"pod_read": True,
"pod_create": True,
"pod_delete": True,
}
)
Best Practices
- Use the principle of least privilege. Only grant the permissions your agent actually needs. A support agent that reads and replies to emails does not need
domain_createorinbox_delete. - Combine with scopes for defense in depth. Pair permissions with pod-scoped or inbox-scoped keys. Scopes limit which resources a key can see, while permissions limit what it can do.
- Filter unwanted content from agents. Set
label_spam_read,label_blocked_read, andlabel_trash_readtofalseon agent-facing keys. This prevents agents from seeing or processing unwanted email, keeping their context clean.