Files
warmbly/docs/content/docs/api/permissions.mdx
T
Matthew Meszaros a7518a8558 docs: refresh the documentation site, fix inaccurate claims and contact addresses, add SEO primitives (#90)
* feat: rewrite the self-hosting docs against repo ground truth: turn the deployment guide into a full self-host guide (quick start with first-admin bootstrap via make grant-admin, .env secrets with exact key formats, PUBLIC_HOST derivation and HTTPS reverse-proxy vars, provider switches with build-tag caveats, mailbox OAuth, remote worker enrollment via SSH or wmenroll tokens, real CI image tags, upgrades and backups), rewrite the events page around the real NATS/Kafka bus topics and {type,body} envelopes, fix Kafka-era and make-target claims in architecture/local-development/deploy README, add API_PUBLIC_URL and drop the dead LOG_DISCORD_WEBHOOK_URL in env.example, and remove the docker-compose.kafka.yml comment pointing at a file that does not exist

* feat: make the self-hosting docs visual and skimmable by adding a Mermaid MDX component (client-rendered, theme-aware) to the docs site, condensing the self-host guide around a control-plane topology diagram, a worker enrollment sequence diagram, a dashboard screenshot, and symptom/check troubleshooting + optional-subsystem tables, and adding an execution-plane flowchart to the architecture page

* feat: stop the docs root flashing a 'Continue to the Warmbly docs' link before redirecting by navigating with an inline location.replace that runs during HTML parse, and demoting the visible link and meta refresh to no-JS fallbacks inside noscript

* feat: cut docs bulk and duplication by deleting three orphaned API pages that were stale forks of the reference section and were unreachable from the sidebar (porting their unique social sign-in, promo-code, and referral endpoints into api/reference/account-org.mdx as compact tables), condensing the deliverability and warmup guides to roughly half their length around tables instead of prose, replacing prose em dashes across the guides and MCP pages, and adding the required trailing slashes to internal links in 24 files

* feat: condense the sequences guide by about 40 percent, folding the switch-step deciders and branch conditions into tables and cutting restated prose while keeping every rule about threading, instant branches, reply matching, and stop on reply

* feat: condense the automations, unibox, advisor, and expressions guides by roughly 40 percent each, folding trigger lists, action catalogs, sending controls, and advisor checks into tables, adding a trigger-condition-action flow diagram to automations, and cutting restated prose while preserving every threshold, permission boundary, and rule

* feat: condense the mailboxes, campaigns, analytics, and team-roles guides by roughly 45 percent each, replacing prose walks through providers, rotation modes, lead statuses, counting rules, A/B confidence, and the permission matrix with compact tables and collapsing the four-way role grid into one capability table plus a one-line mapping

* feat: condense the AI-steps, security, and contacts-CRM guides by roughly 40 percent, turning sign-in methods, AI step modes, switch deciders, credit and failure behavior, import field mappings, and deal views into tables while keeping every safety boundary and dedupe rule

* feat: condense the meetings, notifications, AI-credits, and AI-assistant guides by roughly 40 percent, merging notification categories and their defaults into one table, collapsing credit costs, spend controls, and plan allowances into tables, and tightening the assistant page around its approval and permission boundaries

* feat: condense the integrations, collaboration, zapier, and make guides by roughly 35 percent, grouping the thirty-row Zapier and Make action lists into eight labelled areas, folding CRM default field mappings and presence indicators into tables, and promoting the destructive-action and unattended-delete warnings into callouts

* fix: correct three factual errors in the development docs: NOTIFICATION_EMAIL_DAILY_CAP=0 means uncapped rather than disabled (overEmailBudget returns false at limit<=0, so documenting it as a kill switch inverted the behavior), and the worker-SSH and warmup-pool migration citations in architecture.mdx pointed at pre-squash filenames that no longer exist or now belong to unrelated migrations, so both now cite the tables in 000001_baseline.up.sql

* feat: add the missing docs SEO primitives: a build-time sitemap.xml covering all 64 pages, a robots.txt that points at it and keeps the llms.mdx and og mirrors out of the index as duplicate content, and per-page canonical plus richer OpenGraph URL/title/description metadata

* fix: use the single real team@warmbly.com address everywhere a human is told to write in, replacing the invented hello/sales/legal/support inboxes across the marketing site, the transactional email footer, and the admin outreach composer default Reply-To (which pointed replies at a mailbox that does not exist), and collapse the contact page's two-inbox framing into one inbox with one published response time
2026-08-05 10:37:27 +02:00

267 lines
7.9 KiB
Plaintext

---
title: Permissions reference
description: Complete reference for the 22 API permissions available in Warmbly.
---
Warmbly uses a bitmask system for API permissions. Each permission is one bit in a `uint64`, so a single integer can express any combination of the permissions below.
These same permissions are the [OAuth](/api/oauth/) scopes, lowercased: `READ_EMAILS` is the scope `read_emails`. An OAuth access token carries a bitmask of granted permissions and is checked through the identical gates as an API key.
## Permission values
| Permission | Bit | Value | Category | Description |
|------------|-----|-------|----------|-------------|
| `READ_EMAILS` | 0 | 1 | read | View email accounts and settings |
| `READ_CAMPAIGNS` | 1 | 2 | read | View campaigns and sequences |
| `READ_CONTACTS` | 2 | 4 | read | View contact lists, notes, and activities |
| `READ_UNIBOX` | 3 | 8 | read | Access unified inbox |
| `READ_ANALYTICS` | 4 | 16 | read | View analytics and statistics |
| `WRITE_EMAILS` | 5 | 32 | write | Modify email account settings |
| `WRITE_CAMPAIGNS` | 6 | 64 | write | Create and modify campaigns and sequences |
| `WRITE_CONTACTS` | 7 | 128 | write | Create and modify contacts, notes, activities |
| `WRITE_UNIBOX` | 8 | 256 | write | Mark emails as read/unread and send replies |
| `BULK_CONTACTS` | 9 | 512 | bulk | Bulk import/export/delete contacts |
| `BULK_CAMPAIGNS` | 10 | 1024 | bulk | Bulk campaign operations |
| `REALTIME_SUBSCRIBE` | 11 | 2048 | special | Subscribe to realtime events |
| `WEBHOOKS` | 12 | 4096 | special | Manage webhook endpoints |
| `API_KEYS` | 13 | 8192 | special | Create and manage API keys |
| `SEND_CAMPAIGNS` | 14 | 16384 | write | Start and stop campaigns (sends real mail) |
| `READ_TEMPLATES` | 15 | 32768 | read | View reply templates |
| `WRITE_TEMPLATES` | 16 | 65536 | write | Create and modify reply templates |
| `READ_CRM` | 17 | 131072 | read | View pipelines, deals, and CRM tasks |
| `WRITE_CRM` | 18 | 262144 | write | Create and modify pipelines, deals, CRM tasks |
| `READ_AUDIT_LOGS` | 19 | 524288 | read | View organization audit logs |
| `INTEGRATIONS` | 20 | 1048576 | special | Connect and manage third-party integrations |
| `WARMUP_ROUTING` | 21 | 2097152 | special | Manage warmup routing rules |
| `AI_AGENT` | 22 | 4194304 | special | Run the AI assistant and MCP tools |
| `AI_RESEARCH` | 23 | 8388608 | special | Run AI contact research |
`SEND_CAMPAIGNS` is intentionally separate from `WRITE_CAMPAIGNS`: editing a campaign draft and starting one that actually transmits mail are different blast radii, so a key can be granted the first without the second.
## Categories
### Read
Read-only data access. Safe for monitoring, reporting, BI sync.
### Write
Resource mutation, but no campaign starts. A key with the full write set can edit drafts but cannot turn on a campaign.
### Bulk
High-volume operations. These can touch large numbers of rows in a single request, so they're broken out from the per-record write permissions.
### Special
Realtime subscriptions, webhooks, integrations, warmup routing, AI assistant / MCP access, AI contact research, and self-service key management. Grant individually.
## Preset combinations
Both presets are returned by `GET /api-keys/permissions` for convenience.
### Read only (688159)
All read permissions combined:
```
READ_EMAILS | READ_CAMPAIGNS | READ_CONTACTS | READ_UNIBOX | READ_ANALYTICS
| READ_TEMPLATES | READ_CRM | READ_AUDIT_LOGS
= 1 | 2 | 4 | 8 | 16 | 32768 | 131072 | 524288
= 688159
```
### Full access (16777215)
All 24 permissions:
```
(1 << 24) - 1 = 16777215
```
## Working with bitmasks
### Combining
```javascript
const READ_EMAILS = 1;
const READ_CAMPAIGNS = 2;
const SEND_CAMPAIGNS = 16384;
const permissions = READ_EMAILS | READ_CAMPAIGNS | SEND_CAMPAIGNS;
// 16387
```
### Checking
```javascript
function hasPermission(permissions, required) {
return (permissions & required) === required;
}
hasPermission(16387, 16384); // true: SEND_CAMPAIGNS granted
hasPermission(16387, 64); // false: WRITE_CAMPAIGNS missing
```
### Rejecting unknown bits
`POST /api-keys` rejects any request whose `permissions` field has bits outside the known set, so a stale client can't accidentally request a future permission. The current mask of valid bits is `4194303`.
## Common permission sets
### Monitoring integration
For dashboards and reporting:
```javascript
const MONITORING =
READ_EMAILS | // 1
READ_CAMPAIGNS | // 2
READ_ANALYTICS; // 16
// 19
```
### CRM sync
```javascript
const CRM_SYNC =
READ_CONTACTS | // 4
WRITE_CONTACTS | // 128
BULK_CONTACTS | // 512
READ_CRM | // 131072
WRITE_CRM; // 262144
// 393860
```
### Campaign automation (drafts only, no send)
```javascript
const CAMPAIGN_DRAFTS =
READ_CAMPAIGNS | // 2
WRITE_CAMPAIGNS | // 64
READ_CONTACTS | // 4
READ_TEMPLATES | // 32768
WRITE_TEMPLATES; // 65536
// 98374
```
### Campaign automation (with send)
Same as above, plus `SEND_CAMPAIGNS` (16384). Grant only when the integration genuinely needs to start campaigns.
## Permission constants
<Tabs defaultValue="javascript">
<TabsList>
<LangTab lang="javascript" />
<LangTab lang="python" />
<LangTab lang="go" />
</TabsList>
<Tab value="javascript">
```typescript
export const Permissions = {
READ_EMAILS: 1,
READ_CAMPAIGNS: 2,
READ_CONTACTS: 4,
READ_UNIBOX: 8,
READ_ANALYTICS: 16,
WRITE_EMAILS: 32,
WRITE_CAMPAIGNS: 64,
WRITE_CONTACTS: 128,
WRITE_UNIBOX: 256,
BULK_CONTACTS: 512,
BULK_CAMPAIGNS: 1024,
REALTIME_SUBSCRIBE: 2048,
WEBHOOKS: 4096,
API_KEYS: 8192,
SEND_CAMPAIGNS: 16384,
READ_TEMPLATES: 32768,
WRITE_TEMPLATES: 65536,
READ_CRM: 131072,
WRITE_CRM: 262144,
READ_AUDIT_LOGS: 524288,
INTEGRATIONS: 1048576,
WARMUP_ROUTING: 2097152,
AI_AGENT: 4194304,
AI_RESEARCH: 8388608,
} as const;
```
</Tab>
<Tab value="python">
```python
class Permissions:
READ_EMAILS = 1
READ_CAMPAIGNS = 2
READ_CONTACTS = 4
READ_UNIBOX = 8
READ_ANALYTICS = 16
WRITE_EMAILS = 32
WRITE_CAMPAIGNS = 64
WRITE_CONTACTS = 128
WRITE_UNIBOX = 256
BULK_CONTACTS = 512
BULK_CAMPAIGNS = 1024
REALTIME_SUBSCRIBE = 2048
WEBHOOKS = 4096
API_KEYS = 8192
SEND_CAMPAIGNS = 16384
READ_TEMPLATES = 32768
WRITE_TEMPLATES = 65536
READ_CRM = 131072
WRITE_CRM = 262144
READ_AUDIT_LOGS = 524288
INTEGRATIONS = 1048576
WARMUP_ROUTING = 2097152
AI_AGENT = 4194304
AI_RESEARCH = 8388608
```
</Tab>
<Tab value="go">
```go
const (
APIPermReadEmails uint64 = 1 << iota // 1
APIPermReadCampaigns // 2
APIPermReadContacts // 4
APIPermReadUnibox // 8
APIPermReadAnalytics // 16
APIPermWriteEmails // 32
APIPermWriteCampaigns // 64
APIPermWriteContacts // 128
APIPermWriteUnibox // 256
APIPermBulkContacts // 512
APIPermBulkCampaigns // 1024
APIPermRealtimeSubscribe // 2048
APIPermWebhooks // 4096
APIPermAPIKeys // 8192
APIPermSendCampaigns // 16384
APIPermReadTemplates // 32768
APIPermWriteTemplates // 65536
APIPermReadCRM // 131072
APIPermWriteCRM // 262144
APIPermReadAuditLogs // 524288
APIPermIntegrations // 1048576
APIPermWarmupRouting // 2097152
APIPermAIAgent // 4194304
APIPermAIResearch // 8388608
)
```
</Tab>
</Tabs>
## See also
- [Authentication](/api/authentication/)
- [Endpoints](/api/endpoints/)
- [Team & roles](/guides/team-roles/)