WarmblyDocs

Endpoint scope map

Every endpoint, which auth types it accepts, and which permission it requires.

This page is the source of truth for what an API key can and cannot reach. Every route in the backend falls into one of three buckets:

  • API key accepted: works with both a JWT (dashboard user) and an API key with the listed permission.
  • JWT only: never reachable via an API key. Used for billing, governance, websocket bootstrap, danger-zone destruction, the OAuth onboarding flow, and admin tools.
  • Public: no auth required (webhooks with signature verification, health check, OAuth bouncer pages).

When an endpoint says "JWT permission: X / API permission: Y", the dual-auth middleware checks the relevant one based on which credential the caller used.

All paths below are relative to the versioned base URL https://api.warmbly.com/v1 (for example /campaigns is https://api.warmbly.com/v1/campaigns). See versioning for details.

API key accepted

Emails

MethodPathAPI Permission
GET/emailsREAD_EMAILS
GET/emails/:idREAD_EMAILS
PATCH/emails/:idWRITE_EMAILS
PATCH/emails/:id/trackWRITE_EMAILS
DELETE/emails/:idWRITE_EMAILS
POST/emails/:id/sendSEND_CAMPAIGNS

Campaigns and sequences

MethodPathAPI Permission
GET/campaignsREAD_CAMPAIGNS
POST/campaignsWRITE_CAMPAIGNS
GET/campaigns/:idREAD_CAMPAIGNS
PATCH/campaigns/:idWRITE_CAMPAIGNS
DELETE/campaigns/:idWRITE_CAMPAIGNS
GET/campaigns/:id/advancedREAD_CAMPAIGNS
PATCH/campaigns/:id/advancedWRITE_CAMPAIGNS
GET/campaigns/:id/ab-variantsREAD_CAMPAIGNS
POST/campaigns/:id/ab-variantsWRITE_CAMPAIGNS
PATCH/campaigns/:id/ab-variants/:variantIdWRITE_CAMPAIGNS
DELETE/campaigns/:id/ab-variants/:variantIdWRITE_CAMPAIGNS
GET/campaigns/:id/ab-analysisREAD_ANALYTICS
POST/campaigns/:id/preflightSEND_CAMPAIGNS
POST/campaigns/:id/test-emailSEND_CAMPAIGNS
POST/campaigns/:id/startSEND_CAMPAIGNS
POST/campaigns/:id/stopSEND_CAMPAIGNS
GET/campaigns/:id/logsREAD_CAMPAIGNS
GET/POST/PATCH/DELETE/campaigns/:id/steps[/:sid]READ_CAMPAIGNS for GET, WRITE_CAMPAIGNS otherwise
PATCH/campaigns/:id/step-layoutWRITE_CAMPAIGNS

Contacts

MethodPathAPI Permission
POST/contacts/searchREAD_CONTACTS
POST/contactsWRITE_CONTACTS
DELETE/contactsBULK_CONTACTS
PATCH/contactsBULK_CONTACTS
PATCH/contacts/:idWRITE_CONTACTS
DELETE/contacts/:idWRITE_CONTACTS
GET/contacts/:id/notesREAD_CONTACTS
POST/contacts/:id/notesWRITE_CONTACTS
PATCH/contacts/:id/notes/:noteIdWRITE_CONTACTS
DELETE/contacts/:id/notes/:noteIdWRITE_CONTACTS
GET/contacts/:id/activitiesREAD_CONTACTS
GET/contacts/:id/dealsREAD_CRM

Unibox

MethodPathAPI Permission
GET/uniboxREAD_UNIBOX
GET/unibox/countREAD_UNIBOX
GET/unibox/threadREAD_UNIBOX
GET/unibox/:idREAD_UNIBOX
PATCH/unibox/seenWRITE_UNIBOX
POST/unibox/replyWRITE_UNIBOX

Templates and CRM

MethodPathAPI Permission
GET/templates, /templates/:idREAD_TEMPLATES
POST/PATCH/DELETE/templates[/:id]WRITE_TEMPLATES
GET/crm/pipelines, /crm/pipelines/:idREAD_CRM
POST/PATCH/DELETE/crm/pipelines[/:id][/stages[/:stageId]]WRITE_CRM
GET/crm/deals, /crm/deals/:idREAD_CRM
POST/PATCH/DELETE/crm/deals[/:id]WRITE_CRM
GET/crm/tasks, /crm/tasks/:idREAD_CRM
POST/PATCH/DELETE/crm/tasks[/:id]WRITE_CRM

Analytics and audit

MethodPathAPI Permission
GET/analytics/* (dashboard, deliverability, warmup, campaigns, accounts, usage)READ_ANALYTICS
GET/audit-logsREAD_AUDIT_LOGS

API key self-service

MethodPathAPI Permission
GET/api-keysAPI_KEYS
POST/api-keysAPI_KEYS
GET/api-keys/permissionsAPI_KEYS
GET/api-keys/:idAPI_KEYS
PATCH/api-keys/:idAPI_KEYS
DELETE/api-keys/:idAPI_KEYS

OAuth apps

Registering and managing the OAuth apps your workspace owns. The flow itself (authorize, token, revoke) is listed under JWT only and Public below.

MethodPathAPI Permission
GET/oauth/applicationsAPI_KEYS
POST/oauth/applicationsAPI_KEYS
GET/oauth/applications/:idAPI_KEYS
PATCH/oauth/applications/:idAPI_KEYS
DELETE/oauth/applications/:idAPI_KEYS
POST/oauth/applications/:id/rotate-secretAPI_KEYS
GET/oauth/applications/:id/webhook-secretAPI_KEYS
POST/oauth/applications/:id/webhook-secret/rotateAPI_KEYS
GET/oauth/applications/:id/webhook-endpointsAPI_KEYS
GET/oauth/applications/:id/webhook-deliveriesAPI_KEYS

Operations

MethodPathAPI Permission
GET/PATCH/outreach/settingsWRITE_CAMPAIGNS
POST/deliverability/eventsWRITE_CAMPAIGNS
GET/tasks/dlqSEND_CAMPAIGNS
POST/tasks/dlq/:id/replaySEND_CAMPAIGNS
GET/POST/PATCH/DELETE/webhooks[/:id]WEBHOOKS
POST/webhooks/:id/rotate-secretWEBHOOKS
POST/webhooks/:id/verifyWEBHOOKS
GET/webhooks/event-typesWEBHOOKS
GET/webhooks/deliveriesWEBHOOKS
GET/webhooks/:id/deliveriesWEBHOOKS
POST/webhooks/deliveries/:deliveryId/redeliverWEBHOOKS
GET/webhooks/throttle-dropsWEBHOOKS
GET/POST/DELETE/integrations/*INTEGRATIONS
GET/POST/PATCH/DELETE/automations[/:id]INTEGRATIONS
PATCH/automations/:id/layoutINTEGRATIONS
GET/POST/PATCH/DELETE/warmup/routing[/:id]WARMUP_ROUTING

Retry safety

Mutating API requests may include an Idempotency-Key header. Warmbly stores the completed response for 24 hours per organization and key. Reusing the same key with the same method, route, query, and body replays the original response with X-Idempotent-Replayed: true; reusing the key with a different request returns 409 Conflict.

Identity

MethodPathAPI Permission
GET/me(any authenticated key)

GET /me returns who the active credential belongs to: user_id, email, name, organization_id, organization_name, auth_type (api_key, oauth, or jwt), and the granted scopes. It requires no specific permission, so it is the right call for validating a connection and rendering a human-readable label. Unlike /auth/me (JWT only), it is reachable by API keys and OAuth tokens.

Reference data

MethodPathAPI Permission
GET/plans(any authenticated key)
GET/timezones(any authenticated key)

JWT only

These never accept an API key. They depend on a human-bound session: billing flows, governance, OAuth onboarding, websocket bootstrap, and operational destruction.

  • POST /auth/login, /auth/login/confirm, /auth/register, /auth/register/confirm, /auth/refresh, /auth/reset-password, /auth/reset-password/confirm
  • POST /auth/logout, POST /auth/logout-all, GET /auth/me, PATCH /auth/me/onboarding
  • POST /auth/me/avatar, DELETE /auth/me/avatar
  • POST /emails/onboarding/oauth/start, POST /emails/onboarding/oauth/finish, POST /emails/onboarding/smtp-imap
  • GET /oauth/authorize/details, POST /oauth/authorize (the consent flow: a human approves a third-party app)
  • GET /oauth/authorized-apps, DELETE /oauth/authorized-apps/:id (apps the user has authorized)
  • POST /getaway (websocket bootstrap)
  • GET /realtime/info
  • GET /me/danger-zone, POST /me/danger-zone/delete, DELETE /me/danger-zone/delete
  • GET /invitations, POST /invitations/accept
  • All of /organization/* (create, switch, members, invitations, transfer ownership, avatar, danger zone)
  • All of /subscription/* (checkout, portal, cancel, change-plan, preview-change, enterprise-inquiry, discounts, referrals, etc.)
  • All of /admin/*

Referrals and discounts

The referral program and billing discount history are part of /subscription/*, so they are JWT only and never accept an API key. There is no API permission scope for them; browser callers are gated by the org permission below. The discount validation and checkout endpoints are listed under Subscription and billing in the reference.

MethodPathJWT permission
GET/subscription/referralmanage_billing
POST/subscription/referralmanage_billing
GET/subscription/referral/attributionsmanage_billing
GET/subscription/referral/earningsmanage_billing
GET/subscription/discountsmanage_billing

Public

  • GET /health
  • POST /webhooks/github/releases (HMAC-SHA256 signature)
  • POST /webhook/stripe (Stripe signature)
  • POST /webhook/campaign, /webhook/email, /webhook/user-email (Google OIDC token from Cloud Tasks)
  • GET /addresses/google/callback, GET /addresses/outlook/callback (OAuth bouncer pages)
  • POST /oauth/token, POST /oauth/revoke (OAuth token endpoints, authenticated by the client's id and secret)
  • GET /.well-known/oauth-authorization-server (OAuth discovery metadata)

Notes

  • When a route has both a JWT permission and an API permission listed, the dual-auth middleware checks the JWT user's organization role for browser callers and the key's permission bitmask for API key callers. They're independent gates: a user's role doesn't constrain what an API key can do beyond what was granted at creation.
  • Every API key request is logged to api_key_usage_logs with the endpoint pattern (e.g. /campaigns/:id), method, IP, user-agent, response status, and elapsed milliseconds. JWT requests are not logged here.
  • Rate limit categories (X-RateLimit-* headers) are scoped to the underlying user, not the key; every key issued by a user shares the user's quota.

See also

On this page