Files
warmbly/docs/public/openapi.json

27732 lines
735 KiB
JSON

{
"openapi": "3.1.0",
"info": {
"title": "Warmbly API",
"version": "1.0.0",
"description": "The Warmbly API lets you drive mailboxes, campaigns, contacts, the unibox, CRM, and more programmatically. Authenticate with an API key as a Bearer token. All paths are relative to the versioned base URL.",
"contact": {
"name": "Warmbly",
"url": "https://docs.warmbly.com"
},
"license": {
"name": "Proprietary",
"url": "https://warmbly.com"
}
},
"servers": [
{
"url": "https://api.warmbly.com/v1",
"description": "Production (v1)"
}
],
"security": [
{
"bearerAuth": []
}
],
"tags": [
{
"name": "auth",
"description": "Authentication: login, registration, password reset, 2FA, and sessions."
},
{
"name": "mailboxes",
"description": "Connected sending mailboxes and their warmup lifecycle."
},
{
"name": "campaigns",
"description": "Cold outreach campaigns, steps, and A/B variants."
},
{
"name": "contacts",
"description": "Contacts and their tags."
},
{
"name": "unibox",
"description": "Unified inbox: threads, replies, and labels."
},
{
"name": "crm",
"description": "Deals, tasks, notes, and pipelines."
},
{
"name": "api-keys",
"description": "API key management and usage logs."
},
{
"name": "webhooks",
"description": "Outbound webhook endpoints and deliveries."
},
{
"name": "analytics",
"description": "Campaign and deliverability analytics."
},
{
"name": "integrations",
"description": "Third-party connections and automations."
},
{
"name": "account-org",
"description": "Account, organization, and plan reference data."
},
{
"name": "deliverability-ops",
"description": "Deliverability event ingest, suppression, and seed placement."
}
],
"paths": {
"/auth/login": {
"post": {
"operationId": "auth_login_start",
"summary": "Start login (request email code)",
"description": "Step 1 of email login. Verifies the email/password and Turnstile token, then emails a one-time confirmation code. Returns an opaque session handle to pass to /auth/login/confirm.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthCredentials"
}
}
}
},
"responses": {
"200": {
"description": "Confirmation code sent; returns the session handle.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthSession"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Turnstile / captcha rejected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/login/confirm": {
"post": {
"operationId": "auth_login_confirm",
"summary": "Confirm login (exchange code for tokens)",
"description": "Step 2 of email login. Exchanges the session handle plus the emailed code for a token pair. If 2FA is enabled, returns a 2FA challenge (pending_token) instead of a session.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ConfirmRequest"
}
}
}
},
"responses": {
"200": {
"description": "Login result: either a full token pair, or a 2FA challenge.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LoginResult"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Wrong or expired code, or invalid session.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Turnstile / captcha rejected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited / too many attempts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/register": {
"post": {
"operationId": "auth_register_start",
"summary": "Start registration (request email code)",
"description": "Step 1 of registration. Validates email/password and Turnstile, then emails a confirmation code. Returns an opaque session handle for /auth/register/confirm.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthCredentials"
}
}
}
},
"responses": {
"200": {
"description": "Confirmation code sent; returns the session handle.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuthSession"
}
}
}
},
"400": {
"description": "Invalid request body or weak password.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Email already in use or not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Turnstile / captcha rejected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/register/confirm": {
"post": {
"operationId": "auth_register_confirm",
"summary": "Confirm registration",
"description": "Step 2 of registration. Exchanges the session handle plus the emailed code to finalize the account. Returns 204 on success.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ConfirmRequest"
}
}
}
},
"responses": {
"204": {
"description": "Account confirmed."
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Wrong or expired code, or invalid session.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Turnstile / captcha rejected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/refresh": {
"post": {
"operationId": "auth_refresh",
"summary": "Refresh the token pair",
"description": "Exchanges a valid refresh token for a new token pair (rotating refresh).",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefreshRequest"
}
}
}
},
"responses": {
"200": {
"description": "A fresh token pair.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenPair"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Refresh token invalid, expired, or revoked.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/reset-password": {
"post": {
"operationId": "auth_reset_password_start",
"summary": "Start password reset",
"description": "Sends a password-reset code to the email if an account exists. Always returns 200 to avoid account enumeration.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResetPasswordStartRequest"
}
}
}
},
"responses": {
"200": {
"description": "Reset email sent if the account exists."
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Turnstile / captcha rejected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/reset-password/confirm": {
"post": {
"operationId": "auth_reset_password_confirm",
"summary": "Confirm password reset",
"description": "Exchanges the reset session handle plus a new password to set a new password.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResetPasswordConfirmRequest"
}
}
}
},
"responses": {
"200": {
"description": "Password updated."
},
"400": {
"description": "Invalid request body or weak password.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Invalid or expired reset session.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Turnstile / captcha rejected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/2fa/verify": {
"post": {
"operationId": "auth_2fa_verify_login",
"summary": "Verify 2FA login challenge",
"description": "Exchanges the single-use pending_token from /auth/login/confirm plus a TOTP or recovery code for a real token pair.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TwoFAVerifyRequest"
}
}
}
},
"responses": {
"200": {
"description": "A full token pair.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenPair"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Pending token invalid/expired, or code wrong.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Too many attempts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/passkey/login/begin": {
"post": {
"operationId": "auth_passkey_login_begin",
"summary": "Begin passkey (WebAuthn) login",
"description": "Starts a discoverable/usernameless passkey login. Returns the WebAuthn assertion options plus an opaque session handle to pass to /auth/passkey/login/finish.",
"tags": [
"auth"
],
"security": [],
"responses": {
"200": {
"description": "WebAuthn assertion options and the login session handle.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasskeyLoginChallenge"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/passkey/login/finish": {
"post": {
"operationId": "auth_passkey_login_finish",
"summary": "Finish passkey (WebAuthn) login",
"description": "Submits the WebAuthn assertion together with the login session handle. On success returns a full token pair.",
"tags": [
"auth"
],
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasskeyLoginFinishRequest"
}
}
}
},
"responses": {
"200": {
"description": "A full token pair.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenPair"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Assertion rejected or session invalid.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/logout": {
"post": {
"operationId": "auth_logout",
"summary": "Log out the current session",
"description": "Revokes the session bound to the bearer access token. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Session revoked."
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/logout-all": {
"post": {
"operationId": "auth_logout_all",
"summary": "Log out all sessions",
"description": "Revokes every active session for the authenticated user. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "All sessions revoked."
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/me": {
"get": {
"operationId": "auth_get_me",
"summary": "Get the authenticated user",
"description": "Returns the current user profile, including per-user folders, tags, and categories. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The authenticated user.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "auth_update_me",
"summary": "Update the authenticated user's profile",
"description": "Updates basic profile fields for the current user. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateProfileRequest"
}
}
}
},
"responses": {
"200": {
"description": "The updated user.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/me/password": {
"post": {
"operationId": "auth_change_password",
"summary": "Change password",
"description": "Changes the signed-in user's password (current + new). Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChangePasswordRequest"
}
}
}
},
"responses": {
"200": {
"description": "Password changed."
},
"400": {
"description": "Invalid request body or weak new password.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Current password wrong or session invalid.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/sessions": {
"get": {
"operationId": "auth_list_sessions",
"summary": "List active sessions",
"description": "Lists the authenticated user's active sessions, with the caller's current session flagged. Requires a user session token (not an API key). This endpoint returns a plain array, not a paginated wrapper.",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Active sessions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionList"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "auth_revoke_other_sessions",
"summary": "Revoke all other sessions",
"description": "Ends every active session except the current one. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Other sessions revoked."
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/sessions/{id}": {
"delete": {
"operationId": "auth_revoke_session",
"summary": "Revoke a specific session",
"description": "Ends one of the user's sessions by id. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Session id to revoke."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Session revoked."
},
"400": {
"description": "Invalid session id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Session not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/2fa/status": {
"get": {
"operationId": "auth_2fa_status",
"summary": "Get 2FA status",
"description": "Reports whether the authenticated user has 2FA enabled. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "2FA status.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TwoFAStatus"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/2fa/enroll/start": {
"post": {
"operationId": "auth_2fa_enroll_start",
"summary": "Begin 2FA enrollment",
"description": "Generates a fresh TOTP secret and otpauth provisioning URI (shown once). Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "The TOTP secret and otpauth URI.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TwoFAEnrollStart"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/2fa/enroll/confirm": {
"post": {
"operationId": "auth_2fa_enroll_confirm",
"summary": "Confirm 2FA enrollment",
"description": "Verifies a TOTP code, enables 2FA, and returns one-time recovery codes (shown once). Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TwoFACodeRequest"
}
}
}
},
"responses": {
"200": {
"description": "Recovery codes.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TwoFARecoveryCodes"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Wrong code or session invalid.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/2fa": {
"delete": {
"operationId": "auth_2fa_disable",
"summary": "Disable 2FA",
"description": "Turns off 2FA for the user. Requires a current TOTP or recovery code in the body. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TwoFACodeRequest"
}
}
}
},
"responses": {
"200": {
"description": "2FA disabled.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/OkResponse"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Wrong code or session invalid.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/passkey/credentials": {
"get": {
"operationId": "auth_list_passkey_credentials",
"summary": "List passkey credentials",
"description": "Lists the authenticated user's registered passkeys. Requires a user session token (not an API key). Returns a plain array, not a paginated wrapper.",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Registered passkeys.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasskeyCredentialList"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/passkey/credentials/{id}": {
"patch": {
"operationId": "auth_rename_passkey_credential",
"summary": "Rename a passkey",
"description": "Renames a registered passkey by id. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Passkey credential id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasskeyRenameRequest"
}
}
}
},
"responses": {
"200": {
"description": "The updated passkey.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PasskeyCredential"
}
}
}
},
"400": {
"description": "Invalid request body or id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Passkey not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "auth_delete_passkey_credential",
"summary": "Delete a passkey",
"description": "Removes a registered passkey by id. Requires a user session token (not an API key).",
"tags": [
"auth"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Passkey credential id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Passkey deleted."
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid session token.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Passkey not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails": {
"get": {
"operationId": "mailboxes_list",
"summary": "List mailboxes",
"description": "Returns the organization's connected mailboxes, newest first, with cursor pagination.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "q",
"in": "query",
"required": false,
"description": "Free-text search over mailbox address and name.",
"schema": {
"type": "string"
}
},
{
"name": "tag",
"in": "query",
"required": false,
"description": "Tag id to filter by.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination token from a previous pagination.next_cursor.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size. Default 50, max 100.",
"schema": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
}
}
],
"responses": {
"200": {
"description": "A page of mailboxes.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxList"
}
}
}
},
"400": {
"description": "Invalid cursor, limit, or tag.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}": {
"get": {
"operationId": "mailboxes_get",
"summary": "Get a mailbox",
"description": "Returns a single mailbox by id.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox (email account) id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The mailbox.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "mailboxes_update",
"summary": "Update a mailbox",
"description": "Updates mailbox settings. All fields are optional; only present fields are applied.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated mailbox.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"400": {
"description": "Invalid request body or id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "mailboxes_delete",
"summary": "Delete a mailbox",
"description": "Disconnects and deletes a mailbox. It is removed from all warmup pools.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"204": {
"description": "Mailbox deleted."
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/track": {
"patch": {
"operationId": "mailboxes_update_tracking_domain",
"summary": "Update the tracking domain",
"description": "Sets or clears the custom open/click tracking domain for a mailbox. Send an empty domain to clear it and fall back to the shared default.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "domain",
"in": "query",
"required": false,
"description": "The custom tracking subdomain (for example t.acme.com). Empty clears it.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The resolved tracking-domain state.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxTrackingDomain"
}
}
}
},
"400": {
"description": "Invalid id or domain.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/warmup/start": {
"post": {
"operationId": "mailboxes_warmup_start",
"summary": "Start warmup",
"description": "Enables warmup for a mailbox. When resuming from a paused state it preserves ramp progress.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The updated mailbox.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/warmup/pause": {
"post": {
"operationId": "mailboxes_warmup_pause",
"summary": "Pause warmup",
"description": "Pauses warmup without losing ramp progress. A later start continues from the same daily volume.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The updated mailbox. A paused mailbox has a non-null warmup_paused_at.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/warmup/resume": {
"post": {
"operationId": "mailboxes_warmup_resume",
"summary": "Resume warmup",
"description": "Resumes a paused warmup, shifting the ramp anchor forward so progress continues where it left off.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The updated mailbox, with warmup_paused_at cleared.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/warmup/stop": {
"post": {
"operationId": "mailboxes_warmup_stop",
"summary": "Stop warmup",
"description": "Disables warmup entirely and clears ramp progress. A later start begins a fresh ramp.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The updated mailbox, with warmup disabled.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Mailbox"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/auth-check": {
"get": {
"operationId": "mailboxes_auth_check",
"summary": "Check domain authentication",
"description": "Validates SPF, DKIM, and DMARC for the mailbox's sending domain on demand.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id. The domain is derived from the mailbox address.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The authentication-check result.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxAuthCheck"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/verify": {
"post": {
"operationId": "mailboxes_verify_address",
"summary": "Verify an email address",
"description": "Verifies a single email address on demand (syntax, MX, SMTP RCPT probe, catch-all detection). The address may be supplied in the JSON body or as the email query param; the body takes precedence.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "email",
"in": "query",
"required": false,
"description": "The address to verify. Used when not supplied in the body.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxVerifyRequest"
}
}
}
},
"responses": {
"200": {
"description": "The verification result.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxVerifyResult"
}
}
}
},
"400": {
"description": "Missing or empty address.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/warmup/ban-status": {
"get": {
"operationId": "mailboxes_warmup_ban_status",
"summary": "Get warmup ban status",
"description": "Returns whether a mailbox is blocked from the shared warmup pool, why, and whether the owner can appeal.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The warmup ban status.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxWarmupBanStatus"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/warmup/appeal": {
"post": {
"operationId": "mailboxes_warmup_appeal",
"summary": "Submit a warmup appeal",
"description": "Lets the mailbox owner appeal a warmup ban with a reason.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxWarmupAppealRequest"
}
}
}
},
"responses": {
"200": {
"description": "The created appeal id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxWarmupAppealResult"
}
}
}
},
"400": {
"description": "Invalid id or request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/emails/{id}/send": {
"post": {
"operationId": "mailboxes_send",
"summary": "Send from a mailbox",
"description": "Sends a one-off email from a specific mailbox, scheduled and dispatched through the mailbox's assigned worker. Requires an active organization.",
"tags": [
"mailboxes"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
},
{
"name": "id",
"in": "path",
"required": true,
"description": "The sending mailbox id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxSendRequest"
}
}
}
},
"responses": {
"200": {
"description": "The queued send task.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MailboxSendResult"
}
}
}
},
"400": {
"description": "Invalid id, request body, or no active organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope, permission, or mailbox not allowed for this key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Mailbox not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns": {
"get": {
"operationId": "campaigns_list",
"summary": "List campaigns",
"description": "Search and page through the organization's campaigns. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "q",
"in": "query",
"required": false,
"description": "Free-text filter on campaign name.",
"schema": {
"type": "string"
}
},
{
"name": "folder",
"in": "query",
"required": false,
"description": "Restrict to a single folder id.",
"schema": {
"type": "string"
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination cursor from the previous page.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size (default 50, max 100).",
"schema": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
}
}
],
"responses": {
"200": {
"description": "A page of campaigns.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignList"
}
}
}
},
"400": {
"description": "Invalid cursor or limit.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "campaigns_create",
"summary": "Create a campaign",
"description": "Create a campaign. Only name is required. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignCreate"
}
}
}
},
"responses": {
"201": {
"description": "The created campaign.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Campaign"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}": {
"get": {
"operationId": "campaigns_get",
"summary": "Get a campaign",
"description": "Fetch a single campaign by id. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The campaign.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Campaign"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "campaigns_update",
"summary": "Update a campaign",
"description": "Patch any subset of campaign fields. Omitted fields are unchanged. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated campaign.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Campaign"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "campaigns_delete",
"summary": "Delete a campaign",
"description": "Permanently delete a campaign. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Deleted."
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/advanced": {
"get": {
"operationId": "campaigns_get_advanced",
"summary": "Get advanced settings",
"description": "Return the campaign's advanced outreach overrides. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The advanced settings.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignAdvancedSettings"
}
}
}
},
"400": {
"description": "Invalid id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "campaigns_update_advanced",
"summary": "Update advanced settings",
"description": "Replace the campaign's advanced overrides. Scope WRITE_CAMPAIGNS, org permission manage_settings.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignAdvancedUpdate"
}
}
}
},
"responses": {
"204": {
"description": "Updated."
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/ab-variants": {
"get": {
"operationId": "campaigns_list_ab_variants",
"summary": "List A/B variants",
"description": "List the campaign's A/B variants. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The variants.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignABVariantList"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "campaigns_create_ab_variant",
"summary": "Create an A/B variant",
"description": "Add a variant to the campaign (or one step via step_id). Scope WRITE_CAMPAIGNS, org permission manage_settings.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignABVariantCreate"
}
}
}
},
"responses": {
"201": {
"description": "The created variant.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignABVariant"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/ab-variants/{variantId}": {
"patch": {
"operationId": "campaigns_update_ab_variant",
"summary": "Update an A/B variant",
"description": "Patch a variant. Omitted fields are unchanged. Scope WRITE_CAMPAIGNS, org permission manage_settings.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "variantId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignABVariantUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated variant.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignABVariant"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "campaigns_delete_ab_variant",
"summary": "Delete an A/B variant",
"description": "Remove a variant. Scope WRITE_CAMPAIGNS, org permission manage_settings.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "variantId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Deleted."
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/ab-analysis": {
"get": {
"operationId": "campaigns_get_ab_analysis",
"summary": "Get A/B analysis",
"description": "Return per-variant engagement stats and the computed winner. Scope READ_ANALYTICS, org permission view_analytics.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The A/B analysis.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ABWinnerAnalysis"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/attachments": {
"get": {
"operationId": "campaigns_list_attachments",
"summary": "List attachments",
"description": "List the campaign's attachments, each with a short-lived presigned download url. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The attachments.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignAttachmentList"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "campaigns_upload_attachment",
"summary": "Upload an attachment",
"description": "Upload a file (max 15 MB) to attach to the campaign or one step. Multipart form data. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"file"
],
"properties": {
"file": {
"type": "string",
"format": "binary",
"description": "The file to upload (max 15 MB). Executable and script types are rejected."
},
"step_id": {
"type": "string",
"format": "uuid",
"description": "Scope the attachment to one sequence step."
}
}
}
}
}
},
"responses": {
"201": {
"description": "The created attachment.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignAttachment"
}
}
}
},
"400": {
"description": "Validation error or rejected file type.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/attachments/{attachmentId}": {
"delete": {
"operationId": "campaigns_delete_attachment",
"summary": "Delete an attachment",
"description": "Delete a campaign attachment and its stored object. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "attachmentId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Deleted."
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/preflight": {
"post": {
"operationId": "campaigns_run_preflight",
"summary": "Run preflight",
"description": "Run the campaign's preflight validation checks and return a scored report. No mail is sent. Scope SEND_CAMPAIGNS, org permission send_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "The preflight report.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PreflightReport"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/test-email": {
"post": {
"operationId": "campaigns_send_test_email",
"summary": "Send a test email",
"description": "Send a one-off preview of a sequence step to a recipient through a chosen mailbox. Scope SEND_CAMPAIGNS, org permission send_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignTestEmailRequest"
}
}
}
},
"responses": {
"200": {
"description": "Test email sent.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignTestEmailResult"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/start": {
"post": {
"operationId": "campaigns_start",
"summary": "Start a campaign",
"description": "Activate the campaign so it begins sending real mail. Scope SEND_CAMPAIGNS, org permission send_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Started.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignStartResult"
}
}
}
},
"400": {
"description": "Campaign not in a startable state.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/stop": {
"post": {
"operationId": "campaigns_stop",
"summary": "Stop a campaign",
"description": "Pause an active campaign. Scope SEND_CAMPAIGNS, org permission send_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Stopped.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignStopResult"
}
}
}
},
"400": {
"description": "Campaign not in a stoppable state.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/logs": {
"get": {
"operationId": "campaigns_list_logs",
"summary": "Get campaign logs",
"description": "Page through the campaign's activity log. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination cursor from the previous page.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 100 (default 50).",
"schema": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
}
}
],
"responses": {
"200": {
"description": "A page of log entries.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignLogList"
}
}
}
},
"400": {
"description": "Invalid cursor or limit.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/senders": {
"get": {
"operationId": "campaigns_list_senders",
"summary": "List campaign senders",
"description": "Return the campaign's explicit sender pool. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The sender pool.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignSenderList"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"put": {
"operationId": "campaigns_replace_senders",
"summary": "Replace senders",
"description": "Atomically replace the campaign's explicit sender pool. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignSendersReplace"
}
}
}
},
"responses": {
"200": {
"description": "The resulting sender pool.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignSenderList"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/tracking-domain/verify": {
"post": {
"operationId": "campaigns_verify_tracking_domain",
"summary": "Verify campaign tracking domain",
"description": "Resolve the campaign-scoped tracking domain's CNAME and flip tracking_domain_verified on success. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "The tracking-domain status.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrackingDomainStatus"
}
}
}
},
"400": {
"description": "Verification failed or no domain configured.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/steps": {
"get": {
"operationId": "campaigns_list_steps",
"summary": "List steps",
"description": "Return the campaign's sequence steps in order. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The sequence steps (bare array, no envelope).",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignStep"
}
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "campaigns_create_step",
"summary": "Create a step",
"description": "Append a new empty sequence step created with defaults, then edited with PATCH. No request body. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"201": {
"description": "The created step.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignStep"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaigns/{id}/steps/{sid}": {
"patch": {
"operationId": "campaigns_update_step",
"summary": "Update a step",
"description": "Patch a sequence step: copy, spacing, node kind, branching tree, or action config. Omitted fields are unchanged. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "sid",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignStepUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated step.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignStep"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "campaigns_delete_step",
"summary": "Delete a step",
"description": "Delete a sequence step. Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "sid",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Deleted (empty body)."
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/campaign-template-preview": {
"post": {
"operationId": "campaigns_template_preview",
"summary": "Preview a template",
"description": "Render subject and body templates against a sample (or supplied) contact and report parse errors plus unresolved tokens. No side effects. Scope READ_CAMPAIGNS, org permission view_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TemplatePreviewRequest"
}
}
}
},
"responses": {
"200": {
"description": "The rendered preview.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TemplatePreview"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/generation/write": {
"post": {
"operationId": "campaigns_generate_writing",
"summary": "Generate copy with the writing assistant",
"description": "Generate outreach copy with the AI writing assistant. Gated to paid and free-trial orgs; consumes one AI credit (refunded on provider failure). Scope WRITE_CAMPAIGNS, org permission manage_campaigns.",
"tags": [
"campaigns"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenerationWriteRequest"
}
}
}
},
"responses": {
"200": {
"description": "The generated copy.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenerationWriteResult"
}
}
}
},
"400": {
"description": "Validation error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"402": {
"description": "Out of AI credits (code insufficient_credits).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/search": {
"post": {
"tags": [
"contacts"
],
"operationId": "contacts_search",
"summary": "Search contacts",
"description": "Faceted, org-scoped contact search. Filters live in the body; pagination is via query params. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination cursor from the previous page's pagination.next_cursor.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size (numeric string). Default 50, max 100.",
"schema": {
"type": "string"
}
},
{
"name": "category",
"in": "query",
"required": false,
"description": "Convenience filter for a single category ID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"required": false,
"description": "All filters optional; an empty body matches every contact in the organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactSearchRequest"
}
}
}
},
"responses": {
"200": {
"description": "Matching contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactList"
}
}
}
},
"400": {
"description": "Invalid body, cursor, or limit.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts": {
"post": {
"tags": [
"contacts"
],
"operationId": "contacts_create",
"summary": "Create contacts",
"description": "Creates one or more contacts. The body is a JSON array, so a single create is an array of length one. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/components/schemas/ContactCreate"
}
}
}
}
},
"responses": {
"200": {
"description": "The created contacts as a bare array.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Contact"
}
}
}
}
},
"400": {
"description": "Empty array or too many contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"tags": [
"contacts"
],
"operationId": "contacts_bulk_update",
"summary": "Bulk update contacts",
"description": "Applies one set of edits across up to 1000 contacts: add/remove campaigns and categories, custom-field operations, and subscription. Scope `BULK_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactBulkUpdateRequest"
}
}
}
},
"responses": {
"200": {
"description": "The updated contacts as a bare array.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Contact"
}
}
}
}
},
"400": {
"description": "No contacts provided or more than 1000.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks BULK_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"tags": [
"contacts"
],
"operationId": "contacts_bulk_delete",
"summary": "Bulk delete contacts",
"description": "Deletes up to 1000 contacts by ID. Scope `BULK_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"description": "A JSON array of contact ID strings (1 to 1000).",
"content": {
"application/json": {
"schema": {
"type": "array",
"minItems": 1,
"maxItems": 1000,
"items": {
"type": "string",
"format": "uuid"
}
}
}
}
},
"responses": {
"204": {
"description": "Contacts deleted."
},
"400": {
"description": "Empty array or more than 1000 IDs.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks BULK_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/export": {
"post": {
"tags": [
"contacts"
],
"operationId": "contacts_export",
"summary": "Export contacts",
"description": "Exports contacts to CSV, XLSX, or JSON. The response is the file itself, not JSON. Capped at 50,000 rows. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactExportRequest"
}
}
}
},
"responses": {
"200": {
"description": "The export file as an attachment.",
"headers": {
"Content-Disposition": {
"description": "attachment; filename=\"...\".",
"schema": {
"type": "string"
}
},
"X-Total-Rows": {
"description": "Number of rows written.",
"schema": {
"type": "integer"
}
}
},
"content": {
"text/csv": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/json": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"400": {
"description": "Invalid format, scope, or filters.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/import/preview": {
"post": {
"tags": [
"contacts"
],
"operationId": "contacts_import_preview",
"summary": "Preview an import",
"description": "Uploads a CSV or XLSX file and returns detected columns plus a sample so the client can build a column mapping. Uploads capped at 50 MB. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"file"
],
"properties": {
"file": {
"type": "string",
"format": "binary",
"description": "The CSV/XLSX upload."
}
}
}
}
}
},
"responses": {
"200": {
"description": "Detected columns, sample rows, and a suggested mapping.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactImportPreview"
}
}
}
},
"400": {
"description": "Missing file, unsupported format, or over the size cap.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/import/commit": {
"post": {
"tags": [
"contacts"
],
"operationId": "contacts_import_commit",
"summary": "Commit an import",
"description": "Re-uploads the file with a mapping and dedup options, applies it, and returns per-row results. Imports capped at 50,000 rows. Scope `BULK_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"file",
"options"
],
"properties": {
"file": {
"type": "string",
"format": "binary",
"description": "The CSV/XLSX upload (max 50 MB)."
},
"options": {
"type": "string",
"description": "JSON-encoded ContactImportCommitOptions as a string."
}
}
}
}
}
},
"responses": {
"200": {
"description": "Per-row import results.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactImportResult"
}
}
}
},
"400": {
"description": "Missing file/options, invalid mapping or dedup, or over a cap.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks BULK_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/lookup": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_lookup",
"summary": "Look up a contact by email",
"description": "Resolves a sender address to a contact. Returns 200 with {\"contact\": null} when nothing matches. A display-name wrapped address (`Name <addr@example.com>`) is accepted and unwrapped. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "email",
"in": "query",
"required": true,
"description": "The email address to resolve.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The resolved contact, or null.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactLookupResult"
}
}
}
},
"400": {
"description": "Missing or malformed email.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_get",
"summary": "Get a contact",
"description": "Returns the hydrated contact 360 payload: the contact plus an engagement summary and, when present, suppression state. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The hydrated contact.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactDetail"
}
}
}
},
"400": {
"description": "Invalid contact ID.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"tags": [
"contacts"
],
"operationId": "contacts_update",
"summary": "Update a contact",
"description": "Partially updates a single contact; only the fields present change. Category lists can be set wholesale or adjusted with diff-style add/remove. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated contact.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Contact"
}
}
}
},
"400": {
"description": "Invalid contact ID or body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"tags": [
"contacts"
],
"operationId": "contacts_delete",
"summary": "Delete a contact",
"description": "Deletes a single contact. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Contact deleted."
},
"400": {
"description": "Invalid contact ID.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}/emails": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_emails_list",
"summary": "List emails sent to a contact",
"description": "One row per email sent (or attempted) to the contact, newest first. Keyset paginated on (created_at, task_id); pass both before_at and before_id together. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 200 (default 50).",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
},
{
"name": "before_at",
"in": "query",
"required": false,
"description": "created_at of the last row from the previous page (RFC 3339 nano).",
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "before_id",
"in": "query",
"required": false,
"description": "task_id of the last row from the previous page.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Sent emails.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactSentEmailList"
}
}
}
},
"400": {
"description": "Invalid contact ID or limit.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}/timeline": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_timeline_list",
"summary": "List a contact's timeline",
"description": "Merged activity feed: sends, opens, clicks, replies, bounces, deliverability/suppression events, notes, and meeting bookings. Requires a selected organization. Paginate via the `before` timestamp. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 200 (default 50).",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
},
{
"name": "before",
"in": "query",
"required": false,
"description": "The `at` timestamp of the oldest event from the previous page (RFC 3339 nano).",
"schema": {
"type": "string",
"format": "date-time"
}
}
],
"responses": {
"200": {
"description": "Timeline events with a has_more flag.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactTimelineResult"
}
}
}
},
"400": {
"description": "Invalid contact ID, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}/activities": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_activities_list",
"summary": "List a contact's activities",
"description": "Structured CRM activity log for a contact. Requires a selected organization. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 100 (default 50).",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque cursor from the previous page's pagination.next_cursor.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "CRM activity log.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactActivityList"
}
}
}
},
"400": {
"description": "Invalid contact ID, cursor, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}/notes": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_notes_list",
"summary": "List a contact's notes",
"description": "CRM notes attached to a contact, newest first. Requires a selected organization. Scope `READ_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 100 (default 50).",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque cursor from the previous page's pagination.next_cursor.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Contact notes.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactNoteList"
}
}
}
},
"400": {
"description": "Invalid contact ID, cursor, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CONTACTS or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"tags": [
"contacts"
],
"operationId": "contacts_notes_create",
"summary": "Create a contact note",
"description": "Adds a note to a contact. Requires a selected organization. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactNoteCreate"
}
}
}
},
"responses": {
"201": {
"description": "The created note.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactNote"
}
}
}
},
"400": {
"description": "Invalid contact ID, missing/too-long content, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}/notes/{noteId}": {
"patch": {
"tags": [
"contacts"
],
"operationId": "contacts_notes_update",
"summary": "Update a contact note",
"description": "Edits a note's content. Requires a selected organization. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "noteId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactNoteUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated note.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ContactNote"
}
}
}
},
"400": {
"description": "Invalid IDs, body, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact or note not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"tags": [
"contacts"
],
"operationId": "contacts_notes_delete",
"summary": "Delete a contact note",
"description": "Deletes a note. Requires a selected organization. Scope `WRITE_CONTACTS`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "noteId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Note deleted."
},
"400": {
"description": "Invalid IDs or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks WRITE_CONTACTS or caller lacks manage_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact or note not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/contacts/{id}/deals": {
"get": {
"tags": [
"contacts"
],
"operationId": "contacts_deals_list",
"summary": "List a contact's deals",
"description": "CRM deals associated with a contact, returned as a bare JSON array. Scope `READ_CRM`.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The contact's deals.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Deal"
}
}
}
}
},
"400": {
"description": "Invalid contact ID.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "API key lacks READ_CRM or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Contact not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox": {
"get": {
"operationId": "unibox_list",
"summary": "List incoming mail",
"description": "Org-wide inbox list, collapsed to one row per thread (newest message), with filtering and cursor pagination. Excludes snoozed threads unless `snoozed=true`.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination cursor from a previous response.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, clamped to the server min/max.",
"schema": {
"type": "integer",
"default": 50,
"maximum": 100
}
},
{
"name": "from",
"in": "query",
"required": false,
"description": "Filter by sender address (substring).",
"schema": {
"type": "string"
}
},
{
"name": "subject",
"in": "query",
"required": false,
"description": "Filter by subject (substring).",
"schema": {
"type": "string"
}
},
{
"name": "unseen",
"in": "query",
"required": false,
"description": "`true` returns only threads with unread messages.",
"schema": {
"type": "boolean"
}
},
{
"name": "awaiting_reply",
"in": "query",
"required": false,
"description": "`true` returns only threads whose latest message was sent by you.",
"schema": {
"type": "boolean"
}
},
{
"name": "snoozed",
"in": "query",
"required": false,
"description": "`true` returns only snoozed threads. Omit to exclude snoozed threads.",
"schema": {
"type": "string"
}
},
{
"name": "since",
"in": "query",
"required": false,
"description": "Lower bound on date, `YYYY-MM-DD`.",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "until",
"in": "query",
"required": false,
"description": "Upper bound on date, `YYYY-MM-DD`.",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "email_id",
"in": "query",
"required": false,
"description": "Restrict to a single mailbox by UUID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "email_ids",
"in": "query",
"required": false,
"description": "Comma-separated mailbox UUIDs. A thread matches if it landed in any of them.",
"schema": {
"type": "string"
}
},
{
"name": "category_ids",
"in": "query",
"required": false,
"description": "Comma-separated conversation-label UUIDs. A thread matches if it carries any of them.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Inbox list page.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxThreadList"
}
}
}
},
"400": {
"description": "Invalid cursor, limit, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/count": {
"get": {
"operationId": "unibox_count",
"summary": "Get unread count",
"description": "Org-wide unread message count, optionally scoped to one mailbox.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "email_id",
"in": "query",
"required": false,
"description": "Optional mailbox UUID to count unread for a single mailbox.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Unread count.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxCount"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/overview": {
"get": {
"operationId": "unibox_overview",
"summary": "Get inbox overview",
"description": "Rolls up scope-rail and metric-strip counts (unread, today, week, snoozed, awaiting-reply, pending-scheduled) plus per-mailbox, per-tag, and per-conversation-label breakdowns.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Inbox overview rollup.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxOverview"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/thread": {
"get": {
"operationId": "unibox_get_thread",
"summary": "Get a thread",
"description": "Every message in a single conversation, with cursor pagination. With no `email_id` the thread is read across every mailbox in the organization.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "thread_id",
"in": "query",
"required": true,
"description": "The thread to read. Also accepted as `id`.",
"schema": {
"type": "string"
}
},
{
"name": "email_id",
"in": "query",
"required": false,
"description": "Optional mailbox UUID to scope the thread to one mailbox. Also accepted as `email`.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination cursor.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size. Out-of-range values return 400.",
"schema": {
"type": "integer",
"default": 50,
"maximum": 100
}
}
],
"responses": {
"200": {
"description": "Thread messages page.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxMessageList"
}
}
}
},
"400": {
"description": "Missing `thread_id`, invalid cursor/limit, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/thread/labels": {
"get": {
"operationId": "unibox_get_thread_labels",
"summary": "Get thread labels",
"description": "Conversation labels (your categories) attached to a thread.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "thread_id",
"in": "query",
"required": true,
"description": "The thread to read labels for. Also accepted as `id`.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Label set wrapped in a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxLabelList"
}
}
}
},
"400": {
"description": "Missing `thread_id` or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"put": {
"operationId": "unibox_set_thread_labels",
"summary": "Set thread labels",
"description": "Replaces the full conversation-label set on a thread. `category_ids` is the desired set, so the call is idempotent and retries are naturally safe.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxSetThreadLabelsRequest"
}
}
}
},
"responses": {
"200": {
"description": "Resulting label set wrapped in a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxLabelList"
}
}
}
},
"400": {
"description": "Missing `thread_id` or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/seen": {
"patch": {
"operationId": "unibox_mark_seen",
"summary": "Mark messages seen",
"description": "Marks a batch of messages as read or unread, org-wide. Up to 500 ids per call.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxMarkSeenRequest"
}
}
}
},
"responses": {
"200": {
"description": "Echoes the request back.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxMarkSeenRequest"
}
}
}
},
"400": {
"description": "Invalid body, more than 500 ids, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/reply": {
"post": {
"operationId": "unibox_reply",
"summary": "Reply from the inbox",
"description": "Sends or schedules a reply from one of your mailboxes, routed through the per-mailbox scheduler according to `send_mode`. Requires an active organization.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxReplyRequest"
}
}
}
},
"responses": {
"200": {
"description": "Reply queued or scheduled.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxReplyResult"
}
}
}
},
"400": {
"description": "Invalid body, invalid mailbox UUID, missing future `scheduled_at`, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/snoozes": {
"get": {
"operationId": "unibox_list_snoozes",
"summary": "List active snoozes",
"description": "Your active thread snoozes.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Active snoozes wrapped in a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxSnoozeList"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/snooze": {
"post": {
"operationId": "unibox_snooze",
"summary": "Snooze a thread",
"description": "Hides a thread from your inbox until `snoozed_until` passes. Upsert semantics: a second call on the same thread updates the time in place.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxSnoozeRequest"
}
}
}
},
"responses": {
"200": {
"description": "The created or updated snooze.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxSnooze"
}
}
}
},
"400": {
"description": "Invalid body or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "unibox_unsnooze",
"summary": "Unsnooze a thread",
"description": "Un-snoozes a thread immediately. Idempotent: deleting a snooze that does not exist still succeeds with 204.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "thread_id",
"in": "query",
"required": true,
"description": "The thread to un-snooze.",
"schema": {
"type": "string"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Snooze removed (or already absent). Empty body."
},
"400": {
"description": "Missing `thread_id` or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/scheduled": {
"get": {
"operationId": "unibox_list_scheduled",
"summary": "List scheduled sends",
"description": "Outbound emails you have queued but not yet sent. Pass `thread_id` to scope to a single conversation; the response shape is identical either way.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "thread_id",
"in": "query",
"required": false,
"description": "Restrict to scheduled sends queued into one thread.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Queued message previews wrapped in a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxScheduledList"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/scheduled/{task_id}": {
"delete": {
"operationId": "unibox_cancel_scheduled",
"summary": "Cancel a scheduled send",
"description": "Cancels a pending scheduled send before it fires. The queued task is marked cancelled and short-circuits to a no-op when its run time arrives.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "task_id",
"in": "path",
"required": true,
"description": "UUID of the scheduled task to cancel.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Scheduled send cancelled. Empty body."
},
"400": {
"description": "Invalid task id or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Scheduled send not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/unibox/{id}": {
"get": {
"operationId": "unibox_get",
"summary": "Get a message by id",
"description": "A single message by its UUID, including the full envelope and body.",
"tags": [
"unibox"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "UUID of the message.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The message.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UniboxEmail"
}
}
}
},
"400": {
"description": "Invalid message id or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing scope/permission, or organization lacks unified-inbox access.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Message not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/pipelines": {
"get": {
"operationId": "crm_list_pipelines",
"summary": "List pipelines",
"description": "Return every pipeline in the organization, each with its ordered stages. Returns a bare array, not a list envelope.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Array of pipelines (each with its stages).",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Pipeline"
}
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "crm_create_pipeline",
"summary": "Create pipeline",
"description": "Create a pipeline, optionally seeding it with an ordered set of stages.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePipeline"
}
}
}
},
"responses": {
"201": {
"description": "Created pipeline (including its stages).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pipeline"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/pipelines/{id}": {
"get": {
"operationId": "crm_get_pipeline",
"summary": "Get pipeline",
"description": "Fetch a single pipeline with its stages.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Pipeline ID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The pipeline.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pipeline"
}
}
}
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Pipeline not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "crm_update_pipeline",
"summary": "Update pipeline",
"description": "Rename a pipeline. Only the name can be changed here; stages have their own endpoints.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Pipeline ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdatePipeline"
}
}
}
},
"responses": {
"200": {
"description": "Updated pipeline.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Pipeline"
}
}
}
},
"400": {
"description": "Invalid request body or path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Pipeline not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "crm_delete_pipeline",
"summary": "Delete pipeline",
"description": "Delete a pipeline and its stages.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Pipeline ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Pipeline deleted."
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Pipeline not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/pipelines/{id}/stages": {
"post": {
"operationId": "crm_create_stage",
"summary": "Create stage",
"description": "Append a stage to a pipeline.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Pipeline ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePipelineStage"
}
}
}
},
"responses": {
"201": {
"description": "Created stage.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PipelineStage"
}
}
}
},
"400": {
"description": "Invalid request body or path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Pipeline not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/pipelines/{id}/stages/{stageId}": {
"patch": {
"operationId": "crm_update_stage",
"summary": "Update stage",
"description": "Rename or recolor a stage.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Pipeline ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "stageId",
"in": "path",
"required": true,
"description": "Stage ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdatePipelineStage"
}
}
}
},
"responses": {
"200": {
"description": "Updated stage.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PipelineStage"
}
}
}
},
"400": {
"description": "Invalid request body or path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Pipeline or stage not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "crm_delete_stage",
"summary": "Delete stage",
"description": "Remove a stage from a pipeline.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Pipeline ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "stageId",
"in": "path",
"required": true,
"description": "Stage ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Stage deleted."
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Pipeline or stage not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/deals": {
"get": {
"operationId": "crm_list_deals",
"summary": "List deals",
"description": "List deals with optional pipeline, stage, and status filters, keyset-paginated.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "pipeline_id",
"in": "query",
"required": false,
"description": "Restrict to deals in this pipeline.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "stage_id",
"in": "query",
"required": false,
"description": "Restrict to deals in this stage.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "status",
"in": "query",
"required": false,
"description": "Restrict to a deal status.",
"schema": {
"type": "string",
"enum": [
"open",
"won",
"lost"
]
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque keyset cursor from a previous page's pagination.next_cursor.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 100.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
}
],
"responses": {
"200": {
"description": "Page of deals.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DealList"
}
}
}
},
"400": {
"description": "Invalid cursor, limit, or filter value.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "crm_create_deal",
"summary": "Create deal",
"description": "Create a deal in a pipeline stage, optionally linked to a contact and attributed to a campaign and source mailbox. New deals default to status open.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateDeal"
}
}
}
},
"responses": {
"201": {
"description": "Created deal.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Deal"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/deals/search": {
"post": {
"operationId": "crm_search_deals",
"summary": "Search deals",
"description": "Faceted, offset-paginated deal search. Every filter is optional; an empty body matches every deal in the organization. Filters go in the JSON body; limit and offset are query params.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 200.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque cursor from a previous response's pagination.next_cursor. Omit for the first page.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchDeals"
}
}
}
},
"responses": {
"200": {
"description": "Offset-paginated deal results with an exact total.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DealsSearchResult"
}
}
}
},
"400": {
"description": "Invalid limit, offset, or filter body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/deals/summary": {
"post": {
"operationId": "crm_deals_summary",
"summary": "Deals summary",
"description": "Aggregate counts and value sums over the same filter body as deal search, including per-stage totals. All facets are optional.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchDeals"
}
}
}
},
"responses": {
"200": {
"description": "Aggregate deal totals.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DealsSummary"
}
}
}
},
"400": {
"description": "Invalid filter body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/deals/{id}": {
"get": {
"operationId": "crm_get_deal",
"summary": "Get deal",
"description": "Fetch a single deal. Joined contact, stage, and campaign_name are only populated by the list and search queries, not by this single-row read.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Deal ID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The deal.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Deal"
}
}
}
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Deal not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "crm_update_deal",
"summary": "Update deal",
"description": "Update a deal. Moving it to a different stage_id records a stage-change activity, and setting status to won or lost stamps the corresponding close timestamp.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Deal ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateDeal"
}
}
}
},
"responses": {
"200": {
"description": "Updated deal.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Deal"
}
}
}
},
"400": {
"description": "Invalid request body or path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Deal not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "crm_delete_deal",
"summary": "Delete deal",
"description": "Delete a deal.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Deal ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Deal deleted."
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Deal not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/task-types": {
"get": {
"operationId": "crm_list_task_types",
"summary": "List task types",
"description": "List the organization's CRM task types. A default set is seeded the first time an org lists its types. Returns a data array with no pagination envelope.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Task types.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTaskTypeList"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "crm_create_task_type",
"summary": "Create task type",
"description": "Create a CRM task type.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateCRMTaskType"
}
}
}
},
"responses": {
"201": {
"description": "Created task type.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTaskType"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/task-types/{id}": {
"patch": {
"operationId": "crm_update_task_type",
"summary": "Update task type",
"description": "Rename, recolor, or reorder a task type.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Task type ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateCRMTaskType"
}
}
}
},
"responses": {
"200": {
"description": "Updated task type.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTaskType"
}
}
}
},
"400": {
"description": "Invalid request body or path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Task type not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "crm_delete_task_type",
"summary": "Delete task type",
"description": "Delete a task type. Tasks reference their type by name, so existing tasks keep their label and fall back to a neutral color rather than being orphaned.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Task type ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Task type deleted."
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Task type not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/tasks": {
"get": {
"operationId": "crm_list_tasks",
"summary": "List tasks",
"description": "List CRM tasks with optional contact, deal, assignee, and status filters, keyset-paginated.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "contact_id",
"in": "query",
"required": false,
"description": "Restrict to tasks linked to this contact.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "deal_id",
"in": "query",
"required": false,
"description": "Restrict to tasks linked to this deal.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "assigned_to",
"in": "query",
"required": false,
"description": "Restrict to tasks assigned to this user.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "status",
"in": "query",
"required": false,
"description": "Restrict to a task status.",
"schema": {
"type": "string",
"enum": [
"pending",
"in_progress",
"completed",
"cancelled"
]
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque keyset cursor from a previous page's pagination.next_cursor.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 100.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
}
],
"responses": {
"200": {
"description": "Page of tasks.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTaskList"
}
}
}
},
"400": {
"description": "Invalid cursor, limit, or filter value.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "crm_create_task",
"summary": "Create task",
"description": "Create a CRM task, optionally linked to a contact and deal and assigned to a user or team. created_by is set to the authenticated user.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateCRMTask"
}
}
}
},
"responses": {
"201": {
"description": "Created task.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTask"
}
}
}
},
"400": {
"description": "Invalid request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/tasks/search": {
"post": {
"operationId": "crm_search_tasks",
"summary": "Search tasks",
"description": "Faceted, offset-paginated task search. Every filter is optional; an empty body matches every task in the organization. Filters go in the JSON body; limit and offset are query params.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 200.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque cursor from a previous response's pagination.next_cursor. Omit for the first page.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchTasks"
}
}
}
},
"responses": {
"200": {
"description": "Offset-paginated task results with an exact total.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TasksSearchResult"
}
}
}
},
"400": {
"description": "Invalid limit, offset, or filter body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/tasks/summary": {
"post": {
"operationId": "crm_tasks_summary",
"summary": "Tasks summary",
"description": "Aggregate counts over the same filter body as task search (by status, overdue, high priority). All facets are optional.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchTasks"
}
}
}
},
"responses": {
"200": {
"description": "Aggregate task counts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TasksSummary"
}
}
}
},
"400": {
"description": "Invalid filter body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/crm/tasks/{id}": {
"get": {
"operationId": "crm_get_task",
"summary": "Get task",
"description": "Fetch a single CRM task.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Task ID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The task.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTask"
}
}
}
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Task not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "crm_update_task",
"summary": "Update task",
"description": "Update a CRM task. Setting status to completed stamps the completion timestamp.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Task ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateCRMTask"
}
}
}
},
"responses": {
"200": {
"description": "Updated task.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CRMTask"
}
}
}
},
"400": {
"description": "Invalid request body or path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Task not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "crm_delete_task",
"summary": "Delete task",
"description": "Delete a CRM task.",
"tags": [
"crm"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Task ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Task deleted."
},
"400": {
"description": "Malformed path parameter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing required scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Task not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys": {
"get": {
"operationId": "api-keys_list",
"summary": "List API keys",
"description": "Returns the organization's API keys, newest first. The plaintext secret is never included.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination token from the previous page's pagination.next_cursor. Omit for the first page.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 100. Defaults to 50.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
}
],
"responses": {
"200": {
"description": "A page of API keys.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyList"
}
}
}
},
"400": {
"description": "Invalid cursor or limit, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "api-keys_create",
"summary": "Create an API key",
"description": "Creates a new key and returns the plaintext secret exactly once. Unknown permission bits are rejected.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateAPIKey"
}
}
}
},
"responses": {
"201": {
"description": "The created key, including the one-time secret.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyWithSecret"
}
}
}
},
"400": {
"description": "Invalid body, no organization selected, or permission bitmask contains unknown bits.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys/permissions": {
"get": {
"operationId": "api-keys_list_permissions",
"summary": "List available permissions",
"description": "Returns the catalog of permission bits plus the read_only and full_access presets.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The permission catalog and presets.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIPermissionCatalog"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys/usage/summary": {
"get": {
"operationId": "api-keys_usage_summary",
"summary": "Usage summary",
"description": "Org-level usage strip: key counts by status plus a 24-hour request, error, and latency rollup.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The usage summary object.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyUsageSummary"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys/usage/analytics": {
"get": {
"operationId": "api-keys_usage_analytics",
"summary": "Org-wide usage analytics",
"description": "Time-bucketed request series plus a per-endpoint breakdown for the whole organization. For this org-wide form api_key_id is the all-zero UUID.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "from",
"in": "query",
"required": false,
"description": "Start of the window (RFC3339). Defaults to 24 hours before to.",
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "to",
"in": "query",
"required": false,
"description": "End of the window (RFC3339). Defaults to now.",
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "interval",
"in": "query",
"required": false,
"description": "Bucket granularity.",
"schema": {
"type": "string",
"enum": [
"minute",
"hour",
"day"
]
}
}
],
"responses": {
"200": {
"description": "The analytics payload.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyAnalytics"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys/{id}": {
"get": {
"operationId": "api-keys_get",
"summary": "Get an API key",
"description": "Returns a single key by id. The secret is never included.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKey"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Invalid UUID or key not found in this organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "api-keys_update",
"summary": "Update an API key",
"description": "Updates the mutable fields of a key. Every field is optional; only the fields you send are changed. The secret cannot be rotated here.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateAPIKey"
}
}
}
},
"responses": {
"200": {
"description": "The updated API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKey"
}
}
}
},
"400": {
"description": "Invalid body, no organization selected, or permission bitmask contains unknown bits.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Invalid UUID or key not found in this organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "api-keys_revoke",
"summary": "Revoke an API key",
"description": "Revokes a key immediately. The key stops authenticating right away; this is not reversible.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "reason",
"in": "query",
"required": false,
"description": "Optional revocation note stored on the key. Defaults to \"Revoked by user\".",
"schema": {
"type": "string"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Revocation status envelope.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyRevokeResult"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Invalid UUID or key not found in this organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys/{id}/analytics": {
"get": {
"operationId": "api-keys_analytics",
"summary": "Per-key usage analytics",
"description": "Time-bucketed request series plus a per-endpoint breakdown for a single key. Pass the literal id value `all` for the org-wide aggregate.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The API key id, or the literal `all` for the org-wide aggregate.",
"schema": {
"type": "string"
}
},
{
"name": "from",
"in": "query",
"required": false,
"description": "Start of the window (RFC3339). Defaults to 24 hours before to.",
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "to",
"in": "query",
"required": false,
"description": "End of the window (RFC3339). Defaults to now.",
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "interval",
"in": "query",
"required": false,
"description": "Bucket granularity.",
"schema": {
"type": "string",
"enum": [
"minute",
"hour",
"day"
]
}
}
],
"responses": {
"200": {
"description": "The analytics payload.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyAnalytics"
}
}
}
},
"400": {
"description": "No organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Invalid UUID (when not `all`) or key not found in this organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api-keys/{id}/logs": {
"get": {
"operationId": "api-keys_list_logs",
"summary": "List per-key usage logs",
"description": "Returns the recent raw request entries for a single key, newest first.",
"tags": [
"api-keys"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque pagination token from the previous page's pagination.next_cursor.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size, 1 to 200. Defaults to 50.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
}
],
"responses": {
"200": {
"description": "A page of usage log entries.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/APIKeyUsageLogList"
}
}
}
},
"400": {
"description": "Invalid cursor, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthenticated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Missing API_KEYS scope or manage_api_keys org permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Invalid UUID or key not found in this organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/webhooks": {
"get": {
"operationId": "webhooks_list",
"tags": [
"webhooks"
],
"summary": "List webhook endpoints",
"description": "Returns every webhook endpoint configured for the caller's organization, plus the canonical `event_types` vocabulary for building a picker. Secrets are never returned. This endpoint does NOT use the `data` + `pagination` cursor envelope. Requires the `WEBHOOKS` scope and the `manage_settings` org permission.",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The organization's webhook endpoints and the full event vocabulary.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointList"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "webhooks_create",
"tags": [
"webhooks"
],
"summary": "Create a webhook endpoint",
"description": "Creates a new event subscription. The `url` must be HTTPS and resolve to a publicly routable host (loopback, private, and link-local targets are rejected unless the server runs with unsafe webhook URLs enabled for local or self-hosted development). The response is the only time the signing `secret` (prefixed `whsec_`) is returned, so capture it immediately. Requires the `WEBHOOKS` scope and the `manage_settings` org permission.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointRequest"
}
}
}
},
"responses": {
"201": {
"description": "The created endpoint, including the one-time `secret`.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointWithSecret"
}
}
}
},
"400": {
"description": "Invalid payload, non-HTTPS or non-routable url, or unknown event type.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/webhooks/{id}": {
"patch": {
"operationId": "webhooks_update",
"tags": [
"webhooks"
],
"summary": "Update a webhook endpoint",
"description": "Replaces the endpoint's url, description, event filter, and enabled state with the values sent (send the complete desired state; `event_types` is overwritten, not merged). The signing secret is not changed here; use the rotate-secret endpoint. Requires the `WEBHOOKS` scope and the `manage_settings` org permission.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The endpoint id to update.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointRequest"
}
}
}
},
"responses": {
"200": {
"description": "The updated endpoint (no secret).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
}
},
"400": {
"description": "Invalid payload, invalid endpoint id, non-HTTPS or non-routable url, or unknown event type.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Endpoint not found or not owned by your organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "webhooks_delete",
"tags": [
"webhooks"
],
"summary": "Delete a webhook endpoint",
"description": "Deletes a subscription and cascades to its delivery history. Requires the `WEBHOOKS` scope and the `manage_settings` org permission.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The endpoint id to delete.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Deleted. Empty body."
},
"400": {
"description": "Invalid endpoint id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Endpoint not found or not owned by your organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/webhooks/{id}/rotate-secret": {
"post": {
"operationId": "webhooks_rotate_secret",
"tags": [
"webhooks"
],
"summary": "Rotate the signing secret",
"description": "Issues a new HMAC signing secret and returns it once. In-flight deliveries already signed continue to verify against the old secret until they settle; new deliveries use the new secret. Update your `X-Warmbly-Signature` verifier promptly. Requires the `WEBHOOKS` scope and the `manage_settings` org permission.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The endpoint id to rotate.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "The new signing secret. Returned only once.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookSecretResponse"
}
}
}
},
"400": {
"description": "Invalid endpoint id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Endpoint not found or not owned by your organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/webhooks/{id}/deliveries": {
"get": {
"operationId": "webhooks_list_deliveries",
"tags": [
"webhooks"
],
"summary": "List delivery attempts",
"description": "Returns recent delivery attempts for an endpoint, newest first. Each row updates in place across retries, so an event that retried several times appears as one record whose `attempt_count` and `status` reflect the latest state. This endpoint does NOT use the `data` + `pagination` cursor envelope; it returns a `deliveries` array bounded by `limit`. Requires the `WEBHOOKS` scope and the `manage_settings` org permission.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The endpoint id whose deliveries to list.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Max rows to return. Between 1 and 200. Defaults to 50. Out-of-range values return 400.",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}
}
],
"responses": {
"200": {
"description": "Recent delivery attempts for the endpoint.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookDeliveryList"
}
}
}
},
"400": {
"description": "Invalid endpoint id or a limit outside 1 to 200.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient scope or permission.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Endpoint not found or not owned by your organization.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/dashboard": {
"get": {
"operationId": "analytics_dashboard",
"tags": [
"analytics"
],
"summary": "Get dashboard analytics",
"description": "Org-wide dashboard overview: aggregate stats, recent activity, top campaigns, account health, and a daily trend series.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "period",
"in": "query",
"required": false,
"description": "One of 7d, 30d, 90d. Any other value falls back to 7d.",
"schema": {
"type": "string",
"enum": [
"7d",
"30d",
"90d"
],
"default": "7d"
}
}
],
"responses": {
"200": {
"description": "Dashboard analytics overview.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DashboardAnalytics"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/deliverability": {
"get": {
"operationId": "analytics_deliverability",
"tags": [
"analytics"
],
"summary": "Get deliverability dashboard",
"description": "Deliverability posture over a window: bounce/complaint/open/click/reply counts and rates, suppression and dead-letter pressure, reply-intent breakdown, seed inbox-placement, health band, daily timeseries, and per-mailbox/per-campaign breakdowns.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "from",
"in": "query",
"required": false,
"description": "Window start as an RFC 3339 timestamp. Defaults to 7 days ago (UTC).",
"schema": {
"type": "string",
"format": "date-time"
}
},
{
"name": "to",
"in": "query",
"required": false,
"description": "Window end as an RFC 3339 timestamp. Defaults to now (UTC).",
"schema": {
"type": "string",
"format": "date-time"
}
}
],
"responses": {
"200": {
"description": "Deliverability dashboard.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeliverabilityDashboard"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/warmup": {
"get": {
"operationId": "analytics_warmup",
"tags": [
"analytics"
],
"summary": "Get warmup analytics",
"description": "Warmup send and reply statistics over a date range, with a summary and per-day series. Optionally scoped to a single mailbox.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "from",
"in": "query",
"required": true,
"description": "Range start (YYYY-MM-DD).",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "to",
"in": "query",
"required": true,
"description": "Range end (YYYY-MM-DD).",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "email_id",
"in": "query",
"required": false,
"description": "Limit to one email account. Invalid UUIDs are ignored.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Warmup analytics.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WarmupAnalytics"
}
}
}
},
"400": {
"description": "Missing or invalid range.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/campaigns/compare": {
"get": {
"operationId": "analytics_campaigns_compare",
"tags": [
"analytics"
],
"summary": "Compare campaigns",
"description": "Side-by-side performance for up to 10 campaigns over a date range. Every requested campaign must belong to the caller.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "ids",
"in": "query",
"required": true,
"description": "Comma-separated campaign UUIDs. Invalid entries are dropped; capped at 10. At least one valid id is required.",
"schema": {
"type": "string"
}
},
{
"name": "from",
"in": "query",
"required": true,
"description": "Range start (YYYY-MM-DD).",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "to",
"in": "query",
"required": true,
"description": "Range end (YYYY-MM-DD).",
"schema": {
"type": "string",
"format": "date"
}
}
],
"responses": {
"200": {
"description": "Campaign comparison.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignComparison"
}
}
}
},
"400": {
"description": "Missing or invalid ids/range.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "A requested campaign was not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/campaigns/{id}": {
"get": {
"operationId": "analytics_campaign_get",
"tags": [
"analytics"
],
"summary": "Get campaign analytics",
"description": "A single campaign's performance summary plus per-step stats. The campaign must belong to the caller.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Campaign id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Campaign analytics.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignAnalytics"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Campaign not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/campaigns/{id}/daily": {
"get": {
"operationId": "analytics_campaign_daily",
"tags": [
"analytics"
],
"summary": "Get campaign daily stats",
"description": "Per-day send, open, click, and reply counts for one campaign over a date range. The campaign must belong to the caller.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Campaign id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "from",
"in": "query",
"required": true,
"description": "Range start (YYYY-MM-DD).",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "to",
"in": "query",
"required": true,
"description": "Range end (YYYY-MM-DD).",
"schema": {
"type": "string",
"format": "date"
}
}
],
"responses": {
"200": {
"description": "Per-day series under a data envelope.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignDailyStats"
}
}
}
},
"400": {
"description": "Missing or invalid range.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Campaign not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/campaigns/{id}/hourly": {
"get": {
"operationId": "analytics_campaign_hourly",
"tags": [
"analytics"
],
"summary": "Get campaign hourly stats",
"description": "Per-hour stats for one campaign on a single day. The campaign must belong to the caller.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Campaign id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "date",
"in": "query",
"required": false,
"description": "Day to report (YYYY-MM-DD). Defaults to today.",
"schema": {
"type": "string",
"format": "date"
}
}
],
"responses": {
"200": {
"description": "Per-hour series under a data envelope with the resolved date echoed back.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignHourlyStats"
}
}
}
},
"400": {
"description": "Invalid date.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Campaign not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/accounts": {
"get": {
"operationId": "analytics_accounts_list",
"tags": [
"analytics"
],
"summary": "List account statuses",
"description": "Health and usage status of every email account the caller owns. Returned under a data envelope (no cursor; all accounts included). Accounts that fail to build are skipped.",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Account statuses.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountStatusList"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/accounts/{id}": {
"get": {
"operationId": "analytics_account_get",
"tags": [
"analytics"
],
"summary": "Get account status",
"description": "Detailed status for one email account: combined health score (folding in warmup-pool reputation), active errors, today's usage, warmup status, and warmup-pool health. The account must belong to the caller.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "Email account id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Account status detail.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AccountStatusDetail"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Account not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/analytics/usage": {
"get": {
"operationId": "analytics_usage",
"tags": [
"analytics"
],
"summary": "Get usage overview",
"description": "Account, campaign, contact, and API usage counters for the caller.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "period",
"in": "query",
"required": false,
"description": "One of day, week, month. Any other value falls back to day.",
"schema": {
"type": "string",
"enum": [
"day",
"week",
"month"
],
"default": "day"
}
}
],
"responses": {
"200": {
"description": "Usage overview.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UsageOverview"
}
}
}
},
"400": {
"description": "Invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/audit-logs": {
"get": {
"operationId": "analytics_audit_logs_list",
"tags": [
"analytics"
],
"summary": "List audit logs",
"description": "Organization-wide activity trail for the caller's current organization. The organization is always taken from the session, never from a parameter. Auth: scope READ_AUDIT_LOGS, org permission view_analytics.",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "limit",
"in": "query",
"required": false,
"description": "Page size. Defaults to 50; must be between 10 and 200 or a 400 is returned.",
"schema": {
"type": "integer",
"minimum": 10,
"maximum": 200,
"default": 50
}
},
{
"name": "cursor",
"in": "query",
"required": false,
"description": "Opaque cursor from pagination.next_cursor. Invalid cursors return 400.",
"schema": {
"type": "string"
}
},
{
"name": "actor_id",
"in": "query",
"required": false,
"description": "Filter to a single acting member.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "entity_id",
"in": "query",
"required": false,
"description": "Filter to a single entity.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "entity_type",
"in": "query",
"required": false,
"description": "Filter by entity type (for example campaign, contact, email_account, api_key, webhook).",
"schema": {
"type": "string"
}
},
{
"name": "action",
"in": "query",
"required": false,
"description": "Filter by action (for example create, update, delete, send, revoke).",
"schema": {
"type": "string"
}
},
{
"name": "date",
"in": "query",
"required": false,
"description": "Single-day filter (YYYY-MM-DD), expanded to that whole UTC day.",
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "start_date",
"in": "query",
"required": false,
"description": "Range start. RFC 3339 or YYYY-MM-DD. Overrides date.",
"schema": {
"type": "string"
}
},
{
"name": "end_date",
"in": "query",
"required": false,
"description": "Range end. RFC 3339 or YYYY-MM-DD. Overrides date.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Audit log page (data plus pagination).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AuditLogList"
}
}
}
},
"400": {
"description": "Invalid cursor, limit, or filter.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Insufficient permissions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/catalog": {
"get": {
"operationId": "integrations_catalog_list",
"summary": "List the integration catalog",
"description": "Static metadata for every provider Warmbly supports, annotated with whether each OAuth provider has server-side credentials wired (`configured`).",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Provider catalog.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationCatalogList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden (missing INTEGRATIONS scope).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections": {
"get": {
"operationId": "integrations_connections_list",
"summary": "List connections",
"description": "This org's connection rows. Secrets are never serialized. Returns a bare `connections` array, not the cursor-paginated envelope.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Connections.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationConnectionList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "integrations_connections_create",
"summary": "Create a connection",
"description": "Creates a credential-based connection for `api_key` / `webhook` providers (e.g. Close, Discord). OAuth providers are rejected with a hint to start the authorize flow instead. Inbound providers (Calendly, Cal.com) include `inbound_webhook_url` once. Requires the `manage_settings` org permission for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationConnectionCreate"
}
}
}
},
"responses": {
"201": {
"description": "Connection created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationConnection"
}
}
}
},
"400": {
"description": "Bad request (e.g. OAuth provider, invalid provider).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden (paid-plan feature or missing permission).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}": {
"get": {
"operationId": "integrations_connections_get",
"summary": "Get a connection",
"description": "One connection plus its event subscriptions and up to 20 recent sync runs.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"responses": {
"200": {
"description": "Connection detail.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationConnectionDetail"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "integrations_connections_delete",
"summary": "Disconnect",
"description": "Removes a connection row. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Disconnected."
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/config": {
"patch": {
"operationId": "integrations_connections_update_config",
"summary": "Update connection config",
"description": "Saves a connection's onboarding/capability snapshot and its sync direction. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationConnectionConfigUpdate"
}
}
}
},
"responses": {
"200": {
"description": "Updated connection.",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"connection"
],
"properties": {
"connection": {
"$ref": "#/components/schemas/IntegrationConnection"
}
}
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/events": {
"get": {
"operationId": "integrations_event_subscriptions_list",
"summary": "List event subscriptions",
"description": "The event-to-action routes configured on a connection.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"responses": {
"200": {
"description": "Event subscriptions.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationEventSubscriptionList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "integrations_event_subscriptions_create",
"summary": "Create an event subscription",
"description": "Routes a Warmbly event to a provider action on this connection. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationEventSubscriptionCreate"
}
}
}
},
"responses": {
"201": {
"description": "Event subscription created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationEventSubscription"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden (paid-plan feature or missing permission).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/events/{eventId}": {
"delete": {
"operationId": "integrations_event_subscriptions_delete",
"summary": "Delete an event subscription",
"description": "Removes one event subscription. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
},
{
"name": "eventId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Event subscription id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Deleted."
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/field-mappings": {
"get": {
"operationId": "integrations_field_mappings_list",
"summary": "List field mappings",
"description": "The Warmbly-field to provider-field maps configured for a connection.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"responses": {
"200": {
"description": "Field mappings.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationFieldMappingList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"put": {
"operationId": "integrations_field_mappings_replace",
"summary": "Replace field mappings",
"description": "Swaps the connection-default field map for an object wholesale. A full replace is naturally idempotent so no `Idempotency-Key` is required. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationFieldMappingReplace"
}
}
}
},
"responses": {
"200": {
"description": "Full mapping set after the replace.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationFieldMappingList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/runs": {
"get": {
"operationId": "integrations_sync_runs_list",
"summary": "List sync runs",
"description": "Up to 50 recent observability records for a connection (connect, token refresh, event dispatch, manual push).",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"responses": {
"200": {
"description": "Sync runs.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationSyncRunList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/webhook-secret": {
"get": {
"operationId": "integrations_webhook_secret_get",
"summary": "Get the connection webhook secret",
"description": "Returns (generating on first call) the HMAC signing secret for an automation connection so you can verify Warmbly's outbound webhook signatures. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"responses": {
"200": {
"description": "Signing secret.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationWebhookSecret"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/test": {
"post": {
"operationId": "integrations_connection_test",
"summary": "Test a connection",
"description": "Fires a synthetic event through the connection's notify/webhook automations so you can confirm the channel is wired. Requires `manage_settings` for JWT callers.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Test event dispatched.",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"sent"
],
"properties": {
"sent": {
"type": "boolean"
}
}
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/connections/{id}/push": {
"post": {
"operationId": "integrations_connection_push",
"summary": "Push contacts to a CRM",
"description": "Synchronously upserts the given org contacts into a connected CRM (HubSpot, Pipedrive, Salesforce, Close). Retries are naturally safe (every upsert is keyed by email), so no `Idempotency-Key` is required. Requires the `use_integrations` org permission for JWT callers. A connection whose token can no longer be refreshed returns 409.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Connection id."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationPushRequest"
}
}
}
},
"responses": {
"200": {
"description": "Per-record push results.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IntegrationPushResult"
}
}
}
},
"400": {
"description": "Bad request (no/too many/invalid contact ids).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden (paid-plan feature or missing permission).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Connection or matching contacts not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"409": {
"description": "Connection needs to be reconnected (token not refreshable).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/integrations/bookings": {
"get": {
"operationId": "integrations_bookings_list",
"summary": "List meeting bookings (integrations view)",
"description": "Up to 50 recent booked meetings, surfaced on the integrations page. For the full Meetings list with filters and pagination, use `GET /meetings`.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Recent bookings.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MeetingBookingList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/automations": {
"get": {
"operationId": "automations_list",
"summary": "List automations",
"description": "This org's automation flows (the visual flow builder). Returns a bare `automations` array.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Automations.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AutomationList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "automations_create",
"summary": "Create an automation",
"description": "Creates a new automation flow: a trigger event plus a graph of condition and action nodes. Action nodes may reference provider actions (e.g. `slack.notify`, `hubspot.upsert_contact`) or Warmbly-native actions (e.g. `warmbly.add_tag`, `warmbly.label_email`) that need no external connection.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AutomationWrite"
}
}
}
},
"responses": {
"201": {
"description": "Automation created.",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"automation"
],
"properties": {
"automation": {
"$ref": "#/components/schemas/Automation"
}
}
}
}
}
},
"400": {
"description": "Bad request (invalid graph, missing trigger).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden (paid-plan feature or missing permission).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/automations/{id}": {
"get": {
"operationId": "automations_get",
"summary": "Get an automation",
"description": "One automation with its full graph.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Automation id."
}
],
"responses": {
"200": {
"description": "Automation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"automation"
],
"properties": {
"automation": {
"$ref": "#/components/schemas/Automation"
}
}
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "automations_update",
"summary": "Update an automation",
"description": "Replaces an automation's name, enabled state, trigger, filter, and graph. The body shape matches the create payload.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Automation id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AutomationWrite"
}
}
}
},
"responses": {
"200": {
"description": "Updated automation.",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"automation"
],
"properties": {
"automation": {
"$ref": "#/components/schemas/Automation"
}
}
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "automations_delete",
"summary": "Delete an automation",
"description": "Removes an automation. Returns 409 when the automation is still referenced by campaign steps.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Automation id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Deleted.",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"deleted"
],
"properties": {
"deleted": {
"type": "boolean"
}
}
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"409": {
"description": "Still referenced by campaign steps.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/automations/{id}/test": {
"post": {
"operationId": "automations_test",
"summary": "Test an automation",
"description": "Runs the automation against sample (or provided) data without side effects and returns the walked trace plus per-action previews.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Automation id."
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AutomationDryRunRequest"
}
}
}
},
"responses": {
"200": {
"description": "Dry-run trace plus resolved event data.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AutomationDryRunResponse"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/automations/{id}/runs": {
"get": {
"operationId": "automations_runs_list",
"summary": "List automation runs",
"description": "Recent run history for an automation (per fired event or manual launch), with per-node outcomes.",
"tags": [
"integrations"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Automation id."
},
{
"name": "limit",
"in": "query",
"required": false,
"schema": {
"type": "integer",
"default": 50
},
"description": "Max runs to return. Defaults to 50."
}
],
"responses": {
"200": {
"description": "Automation runs.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AutomationRunList"
}
}
}
},
"400": {
"description": "Bad request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/teams": {
"get": {
"operationId": "account-org_teams_list",
"summary": "List teams",
"description": "Returns the current organization's teams, each hydrated with its members. Requires a selected organization.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The organization's teams.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TeamCollection"
}
}
}
},
"400": {
"description": "No organization selected or invalid request.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the READ_CRM scope or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "account-org_teams_create",
"summary": "Create a team",
"description": "Creates a team (members start empty). Requires a selected organization.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TeamCreate"
}
}
}
},
"responses": {
"201": {
"description": "The created team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Team"
}
}
}
},
"400": {
"description": "Validation error or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the WRITE_CRM scope or caller lacks manage_team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/teams/{id}": {
"get": {
"operationId": "account-org_teams_get",
"summary": "Get a team",
"description": "Returns a single team with its members.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The team id.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Team"
}
}
}
},
"400": {
"description": "Invalid id or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the READ_CRM scope or caller lacks view_contacts.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Team not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "account-org_teams_update",
"summary": "Update a team",
"description": "Partial-updates a team's name or color. Omitted fields are left untouched.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The team id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TeamUpdate"
}
}
}
},
"responses": {
"200": {
"description": "The updated team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Team"
}
}
}
},
"400": {
"description": "Validation error, invalid id, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the WRITE_CRM scope or caller lacks manage_team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Team not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "account-org_teams_delete",
"summary": "Delete a team",
"description": "Deletes a team.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The team id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Team deleted."
},
"400": {
"description": "Invalid id or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the WRITE_CRM scope or caller lacks manage_team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Team not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/teams/{id}/members": {
"post": {
"operationId": "account-org_teams_add_member",
"summary": "Add a team member",
"description": "Adds an existing organization member to the team and returns the updated team.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The team id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TeamAddMember"
}
}
}
},
"responses": {
"200": {
"description": "The updated team, including the new member.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Team"
}
}
}
},
"400": {
"description": "Validation error, invalid id, or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the WRITE_CRM scope or caller lacks manage_team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Team not found, or the user is not an organization member.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/teams/{id}/members/{userId}": {
"delete": {
"operationId": "account-org_teams_remove_member",
"summary": "Remove a team member",
"description": "Removes a member from the team.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The team id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "userId",
"in": "path",
"required": true,
"description": "The member's user id.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Member removed."
},
"400": {
"description": "Invalid id or no organization selected.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Key lacks the WRITE_CRM scope or caller lacks manage_team.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Team or membership not found.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/plans": {
"get": {
"operationId": "account-org_plans_list",
"summary": "List plans",
"description": "Returns the available public subscription plans. Open to any authenticated caller (JWT or API key); auth exists only to deter scraping.",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The public subscription plans.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PlanList"
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/timezones": {
"get": {
"operationId": "account-org_timezones_list",
"summary": "List timezones",
"description": "Returns the supported timezone identifiers (for campaign schedule windows and the like). Open to any authenticated caller (JWT or API key).",
"tags": [
"account-org"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The supported timezones, sorted by UTC offset.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TimezoneOption"
}
}
}
}
},
"401": {
"description": "Missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/outreach/settings": {
"get": {
"operationId": "deliverability-ops_get_settings",
"summary": "Get outreach settings",
"description": "Returns the organization's advanced outreach settings (bounce pipeline, task reliability, A/B testing, reply-intent, send-time optimization, preflight, dashboard).",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "The advanced outreach settings object (not envelope-wrapped).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AdvancedOutreachSettings"
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden (missing WRITE_CAMPAIGNS scope or manage_settings permission)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "deliverability-ops_update_settings",
"summary": "Update outreach settings",
"description": "Replaces the organization's advanced outreach settings with the supplied object (upserted, not deep-merged). Returns no body.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpsertOutreachSettingsRequest"
}
}
}
},
"responses": {
"204": {
"description": "Settings updated"
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/deliverability/events": {
"post": {
"operationId": "deliverability-ops_ingest_event",
"summary": "Ingest a deliverability event",
"description": "Posts a single deliverability signal (bounce, complaint, unsubscribe, open, click, reply) into the platform. API-key callable so downstream pipelines can report events. Supply idempotency_key to make retries safe. Requires WRITE_CAMPAIGNS scope and send_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IngestDeliverabilityEventRequest"
}
}
}
},
"responses": {
"202": {
"description": "Event accepted and queued for processing (no body)."
},
"400": {
"description": "Invalid event payload (e.g. missing event_type or recipient_email)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/tasks/dlq": {
"get": {
"operationId": "deliverability-ops_list_dead_letters",
"summary": "List task dead letters",
"description": "Lists tasks that exhausted their retry budget and landed in the dead-letter queue. Not cursor-paginated: returns up to `limit` rows in one response. Requires SEND_CAMPAIGNS scope and send_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "status",
"in": "query",
"required": false,
"description": "Optional status filter (e.g. pending, replayed).",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"required": false,
"description": "Max rows to return, 1 to 200 (default 100).",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 100
}
}
],
"responses": {
"200": {
"description": "Dead-letter records under a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TaskDeadLetterList"
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/tasks/dlq/{id}/replay": {
"post": {
"operationId": "deliverability-ops_replay_dead_letter",
"summary": "Replay a task dead letter",
"description": "Re-dispatches a dead-lettered task. Because a replay can transmit real mail this requires SEND_CAMPAIGNS scope and send_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The dead-letter record ID (the `id` field, not `task_id`).",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "Replay dispatched.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplayDeadLetterResponse"
}
}
}
},
"400": {
"description": "Invalid dead-letter id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Dead-letter record not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/warmup/routing": {
"get": {
"operationId": "deliverability-ops_list_routing_rules",
"summary": "List warmup routing rules",
"description": "Returns every warmup routing rule for the organization, ordered by priority ascending. Not cursor-paginated. Requires WARMUP_ROUTING scope and manage_settings permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Routing rules under a `rules` array (never null).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WarmupRoutingRuleList"
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "deliverability-ops_create_routing_rule",
"summary": "Create a warmup routing rule",
"description": "Creates a routing rule for the organization. Both sender and recipient sides are matched; a rule applies only when both match. Match values are lowercased and trimmed on write. Requires WARMUP_ROUTING scope and manage_settings permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WarmupRoutingRuleInput"
}
}
}
},
"responses": {
"201": {
"description": "Rule created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WarmupRoutingRule"
}
}
}
},
"400": {
"description": "Invalid payload (e.g. missing name, bad match type, missing required match value, negative weight)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/warmup/routing/{id}": {
"patch": {
"operationId": "deliverability-ops_update_routing_rule",
"summary": "Update a warmup routing rule",
"description": "Replaces a rule by ID. The body is the same full payload as create (all fields applied, not deep-merged). Requires WARMUP_ROUTING scope and manage_settings permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The rule ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WarmupRoutingRuleInput"
}
}
}
},
"responses": {
"200": {
"description": "Rule updated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WarmupRoutingRule"
}
}
}
},
"400": {
"description": "Invalid payload or rule id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Rule not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "deliverability-ops_delete_routing_rule",
"summary": "Delete a warmup routing rule",
"description": "Removes a routing rule by ID. Requires WARMUP_ROUTING scope and manage_settings permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The rule ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Rule deleted"
},
"400": {
"description": "Invalid rule id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Rule not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/templates": {
"get": {
"operationId": "deliverability-ops_list_templates",
"summary": "List reply templates",
"description": "Lists the organization's reply templates, ordered by position. Optional `q` filter matches name and subject (case-insensitive). Not cursor-paginated. Requires READ_TEMPLATES scope and view_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "q",
"in": "query",
"required": false,
"description": "Optional case-insensitive search over name and subject.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Reply templates under a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyTemplateList"
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "deliverability-ops_create_template",
"summary": "Create a reply template",
"description": "Creates a reply template owned by the calling user, appended to the end of the org's list. Requires WRITE_TEMPLATES scope and manage_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateReplyTemplate"
}
}
}
},
"responses": {
"200": {
"description": "Template created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyTemplate"
}
}
}
},
"400": {
"description": "Invalid payload (e.g. missing name or name over 255 chars)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/templates/reorder": {
"patch": {
"operationId": "deliverability-ops_reorder_templates",
"summary": "Reorder reply templates",
"description": "Repositions templates to match the supplied ID order (1-indexed). IDs omitted from the list are left untouched. Returns the full reordered list. Requires WRITE_TEMPLATES scope and manage_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReorderReplyTemplates"
}
}
}
},
"responses": {
"200": {
"description": "Reordered list under a `data` array.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyTemplateList"
}
}
}
},
"400": {
"description": "Invalid payload (e.g. missing ids)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/templates/score": {
"post": {
"operationId": "deliverability-ops_score_template",
"summary": "Score template content",
"description": "Returns an advisory deliverability content score (0 to 100, higher is safer) for a subject and body, plus the issues found. Advisory only and never blocks sending. Scores content in the request body, not a stored template. Requires READ_TEMPLATES scope and view_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ScoreTemplateRequest"
}
}
}
},
"responses": {
"200": {
"description": "Content score and advisory issues.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TemplateScoreResult"
}
}
}
},
"400": {
"description": "Invalid request body",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/templates/{id}": {
"get": {
"operationId": "deliverability-ops_get_template",
"summary": "Get a reply template",
"description": "Retrieves a single reply template by ID. Requires READ_TEMPLATES scope and view_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The template ID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "The reply template.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyTemplate"
}
}
}
},
"400": {
"description": "Invalid template id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Template not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "deliverability-ops_update_template",
"summary": "Update a reply template",
"description": "Updates a reply template. All fields optional; omitted fields are left unchanged. Requires WRITE_TEMPLATES scope and manage_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The template ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateReplyTemplate"
}
}
}
},
"responses": {
"200": {
"description": "Template updated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyTemplate"
}
}
}
},
"400": {
"description": "Invalid payload or template id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Template not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"operationId": "deliverability-ops_delete_template",
"summary": "Delete a reply template",
"description": "Deletes a reply template by ID. Requires WRITE_TEMPLATES scope and manage_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The template ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"204": {
"description": "Template deleted"
},
"400": {
"description": "Invalid template id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Template not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/templates/{id}/duplicate": {
"post": {
"operationId": "deliverability-ops_duplicate_template",
"summary": "Duplicate a reply template",
"description": "Clones a template, appending \" (copy)\" to the name and placing the clone at the end of the org's list. Requires WRITE_TEMPLATES scope and manage_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The source template ID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"description": "The newly created template.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReplyTemplate"
}
}
}
},
"400": {
"description": "Invalid template id",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Source template not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/templates/{id}/render": {
"post": {
"operationId": "deliverability-ops_render_template",
"summary": "Render a reply template",
"description": "Expands {{.Key}} placeholders in the template's subject and body using a caller-supplied variable map. The body is optional; an empty map renders all placeholders empty. Requires READ_TEMPLATES scope and view_campaigns permission.",
"tags": [
"deliverability-ops"
],
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "The template ID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"required": false,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RenderReplyTemplateRequest"
}
}
}
},
"responses": {
"200": {
"description": "The rendered subject and body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RenderedReplyTemplate"
}
}
}
},
"400": {
"description": "Invalid template id or body",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Template not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"description": "A Warmbly API key (wmbly_...) sent as a Bearer token."
}
},
"parameters": {
"IdempotencyKey": {
"name": "Idempotency-Key",
"in": "header",
"required": false,
"description": "Optional client-generated key (1-255 chars). A retried request with the same key, method, path, and body replays the original response instead of acting twice.",
"schema": {
"type": "string",
"maxLength": 255
}
}
},
"schemas": {
"Error": {
"type": "object",
"description": "Standard error envelope returned for every 4xx/5xx response.",
"required": [
"error",
"code"
],
"properties": {
"error": {
"type": "string",
"description": "Human-readable message. Do not branch on this."
},
"message": {
"type": "string",
"description": "Alias of error in some responses."
},
"code": {
"type": "string",
"description": "Stable machine-readable code, e.g. bad_request, unauthorized, forbidden, not_found, conflict, rate_limit_exceeded, internal_error."
},
"request_id": {
"type": "string",
"description": "Correlates the response with server logs. Also returned as the X-Request-Id header."
}
}
},
"Pagination": {
"type": "object",
"description": "Keyset pagination metadata. next_cursor is an opaque token (not a record id).",
"required": [
"has_more"
],
"properties": {
"total": {
"type": [
"integer",
"null"
],
"description": "Total matching rows when cheaply known, else null."
},
"next_cursor": {
"type": [
"string",
"null"
],
"description": "Opaque cursor for the next page, or null on the last page."
},
"has_more": {
"type": "boolean"
}
}
},
"AuthCredentials": {
"type": "object",
"description": "Email/password credentials with a Cloudflare Turnstile token. Used for login start and registration start.",
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string",
"format": "email",
"description": "Account email address."
},
"password": {
"type": "string",
"format": "password",
"description": "Account password."
},
"turnstile": {
"type": "string",
"description": "Cloudflare Turnstile challenge token."
}
}
},
"ConfirmRequest": {
"type": "object",
"description": "Confirms an in-flight login or registration: the opaque session handle plus the emailed one-time code.",
"required": [
"session",
"code"
],
"properties": {
"session": {
"type": "string",
"description": "Opaque session handle from the matching start call."
},
"code": {
"type": "string",
"description": "One-time confirmation code emailed to the user."
},
"turnstile": {
"type": "string",
"description": "Cloudflare Turnstile challenge token."
}
}
},
"AuthSession": {
"type": "object",
"description": "Opaque session handle returned by login/register start; pass it to the matching confirm call.",
"required": [
"session"
],
"properties": {
"session": {
"type": "string",
"description": "Opaque session handle."
}
}
},
"TokenPair": {
"type": "object",
"description": "An access/refresh token pair with absolute expiry timestamps.",
"required": [
"access_token",
"access_token_expires_at",
"refresh_token",
"refresh_token_expires_at"
],
"properties": {
"access_token": {
"type": "string",
"description": "Bearer access token for authenticated session requests."
},
"access_token_expires_at": {
"type": "string",
"format": "date-time",
"description": "When the access token expires."
},
"refresh_token": {
"type": "string",
"description": "Refresh token used to obtain a new pair."
},
"refresh_token_expires_at": {
"type": "string",
"format": "date-time",
"description": "When the refresh token expires."
}
}
},
"LoginResult": {
"type": "object",
"description": "Result of /auth/login/confirm: either a full token pair (the TokenPair fields are present) or a 2FA challenge (two_fa_required=true with a pending_token). The two cases are mutually exclusive.",
"properties": {
"access_token": {
"type": "string",
"description": "Present only when 2FA is not required."
},
"access_token_expires_at": {
"type": "string",
"format": "date-time"
},
"refresh_token": {
"type": "string"
},
"refresh_token_expires_at": {
"type": "string",
"format": "date-time"
},
"two_fa_required": {
"type": "boolean",
"description": "True when a 2FA challenge must be completed via /auth/2fa/verify."
},
"pending_token": {
"type": "string",
"description": "Single-use pending token to pass to /auth/2fa/verify. Present only when two_fa_required is true."
},
"expires_in": {
"type": "integer",
"description": "Seconds until the pending token expires. Present only when two_fa_required is true."
}
}
},
"RefreshRequest": {
"type": "object",
"description": "Request body for /auth/refresh.",
"required": [
"refresh_token"
],
"properties": {
"refresh_token": {
"type": "string",
"description": "A valid, unexpired refresh token."
}
}
},
"ResetPasswordStartRequest": {
"type": "object",
"description": "Request body for /auth/reset-password.",
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"format": "email",
"description": "Email of the account to reset."
},
"turnstile": {
"type": "string",
"description": "Cloudflare Turnstile challenge token."
}
}
},
"ResetPasswordConfirmRequest": {
"type": "object",
"description": "Request body for /auth/reset-password/confirm.",
"required": [
"session",
"password"
],
"properties": {
"session": {
"type": "string",
"description": "Opaque reset session handle."
},
"password": {
"type": "string",
"format": "password",
"description": "The new password."
},
"turnstile": {
"type": "string",
"description": "Cloudflare Turnstile challenge token."
}
}
},
"ChangePasswordRequest": {
"type": "object",
"description": "Request body for /auth/me/password.",
"required": [
"current_password",
"new_password"
],
"properties": {
"current_password": {
"type": "string",
"format": "password",
"description": "The user's current password."
},
"new_password": {
"type": "string",
"format": "password",
"description": "The new password."
}
}
},
"UpdateProfileRequest": {
"type": "object",
"description": "Editable profile fields for the authenticated user.",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
}
}
},
"TwoFAVerifyRequest": {
"type": "object",
"description": "Request body for /auth/2fa/verify.",
"required": [
"pending_token",
"code"
],
"properties": {
"pending_token": {
"type": "string",
"description": "Single-use pending token from the login result."
},
"code": {
"type": "string",
"description": "A current TOTP code or a recovery code."
}
}
},
"TwoFACodeRequest": {
"type": "object",
"description": "A single TOTP or recovery code. Used to confirm enrollment or disable 2FA.",
"properties": {
"code": {
"type": "string",
"description": "A current TOTP code or a recovery code."
}
}
},
"TwoFAStatus": {
"type": "object",
"description": "Whether 2FA is enabled for the user.",
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean"
}
}
},
"TwoFAEnrollStart": {
"type": "object",
"description": "The TOTP secret and otpauth provisioning URI, returned once at enrollment start.",
"required": [
"secret",
"otpauth_uri"
],
"properties": {
"secret": {
"type": "string",
"description": "Base32 (no padding) TOTP secret."
},
"otpauth_uri": {
"type": "string",
"description": "otpauth://totp/... provisioning URI for authenticator apps."
}
}
},
"TwoFARecoveryCodes": {
"type": "object",
"description": "One-time recovery codes, returned once when 2FA is enabled.",
"required": [
"recovery_codes"
],
"properties": {
"recovery_codes": {
"type": "array",
"items": {
"type": "string"
},
"description": "Single-use recovery codes."
}
}
},
"OkResponse": {
"type": "object",
"description": "Generic success acknowledgement.",
"required": [
"ok"
],
"properties": {
"ok": {
"type": "boolean"
}
}
},
"PasskeyLoginChallenge": {
"type": "object",
"description": "WebAuthn assertion options plus the opaque login session handle for /auth/passkey/login/finish. The publicKey options follow the WebAuthn PublicKeyCredentialRequestOptions shape.",
"properties": {
"session": {
"type": "string",
"description": "Opaque login session handle."
},
"publicKey": {
"type": "object",
"additionalProperties": true,
"description": "WebAuthn PublicKeyCredentialRequestOptions (passed to navigator.credentials.get)."
}
}
},
"PasskeyLoginFinishRequest": {
"type": "object",
"description": "Request body for /auth/passkey/login/finish.",
"required": [
"session",
"credential"
],
"properties": {
"session": {
"type": "string",
"description": "Opaque login session handle from begin."
},
"credential": {
"type": "object",
"additionalProperties": true,
"description": "The WebAuthn assertion (PublicKeyCredential JSON) from navigator.credentials.get."
}
}
},
"PasskeyRenameRequest": {
"type": "object",
"description": "Request body for renaming a passkey.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "New display name for the passkey."
}
}
},
"PasskeyCredential": {
"type": "object",
"description": "A registered passkey (WebAuthn credential).",
"required": [
"id",
"name",
"credential_id",
"transports",
"backup_state",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"description": "User-assigned display name."
},
"provider": {
"type": "string",
"description": "Originating provider, when known."
},
"credential_id": {
"type": "string",
"description": "The WebAuthn credential id."
},
"transports": {
"type": "array",
"items": {
"type": "string"
},
"description": "Supported authenticator transports (e.g. internal, usb, hybrid)."
},
"backup_state": {
"type": "boolean",
"description": "Whether the credential is backed up / multi-device."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"last_used_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"PasskeyCredentialList": {
"type": "array",
"description": "A plain array of registered passkeys (not a paginated wrapper).",
"items": {
"$ref": "#/components/schemas/PasskeyCredential"
}
},
"Session": {
"type": "object",
"description": "A customer-facing view of an authenticated session.",
"required": [
"id",
"current",
"auth_provider",
"created_at",
"last_active_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"current": {
"type": "boolean",
"description": "True if this is the session making the request."
},
"browser": {
"type": "string"
},
"os": {
"type": "string"
},
"location_city": {
"type": "string"
},
"location_region": {
"type": "string"
},
"location_country": {
"type": "string"
},
"country_code": {
"type": "string"
},
"auth_provider": {
"type": "string",
"description": "How this session authenticated: email, google, apple, or webauthn."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"last_active_at": {
"type": "string",
"format": "date-time"
}
}
},
"SessionList": {
"type": "array",
"description": "A plain array of active sessions (not a paginated wrapper); the current session is floated to the top.",
"items": {
"$ref": "#/components/schemas/Session"
}
},
"UserLabelGroup": {
"type": "object",
"description": "A per-user label group (folder, tag, or category).",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
}
},
"additionalProperties": true
},
"User": {
"type": "object",
"description": "The authenticated user profile returned by /auth/me.",
"required": [
"id",
"first_name",
"last_name",
"email",
"roles",
"is_admin",
"folders",
"tags",
"categories",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"avatar_url": {
"type": [
"string",
"null"
]
},
"roles": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Organization role ids assigned to the user."
},
"referral_source": {
"type": [
"string",
"null"
]
},
"onboarding_completed_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"max_organizations": {
"type": "integer"
},
"free_trial_used": {
"type": "boolean"
},
"admin_permissions": {
"type": "integer",
"description": "Raw platform-admin permission bitmask."
},
"is_admin": {
"type": "boolean",
"description": "True if the user has any platform-admin permission."
},
"deletion_scheduled_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"deletion_scheduled_for": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"folders": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UserLabelGroup"
},
"description": "Per-user folders (always an array)."
},
"tags": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UserLabelGroup"
},
"description": "Per-user tags (always an array)."
},
"categories": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UserLabelGroup"
},
"description": "Per-user categories (always an array)."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"Mailbox": {
"type": "object",
"description": "A connected sender mailbox (email account).",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"worker_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"email": {
"type": "string",
"description": "The mailbox address."
},
"name": {
"type": "string",
"description": "Display name on outgoing mail."
},
"signature_plain": {
"type": "string"
},
"signature_html": {
"type": "string"
},
"signature_sync": {
"type": "boolean"
},
"signature_code": {
"type": "boolean"
},
"provider": {
"type": "string",
"enum": [
"gmail",
"outlook",
"smtp_imap"
]
},
"status": {
"type": "string",
"enum": [
"active",
"inactive",
"revoked"
]
},
"last_synced_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_id": {
"type": "integer"
},
"campaign_limit": {
"type": "integer",
"description": "Daily cold-campaign cap for this mailbox."
},
"min_wait_time": {
"type": "integer",
"description": "Minimum seconds between sends."
},
"reply_to": {
"type": "string"
},
"tracking_domain": {
"type": "string"
},
"tracking_domain_verified": {
"type": "boolean"
},
"tracking_domain_verified_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"warmup": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Warmup anchor timestamp; null when warmup has never been enabled."
},
"warmup_paused_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Non-null when warmup is enabled but paused."
},
"warmup_base": {
"type": "integer"
},
"warmup_max": {
"type": "integer"
},
"warmup_increase": {
"type": "integer"
},
"warmup_reply_rate": {
"type": "integer"
},
"warmup_tag": {
"type": "string"
},
"warmup_pool_type": {
"type": "string",
"enum": [
"free",
"premium"
]
},
"warmup_start_time": {
"type": "string",
"description": "Daily warmup window start, HH:MM."
},
"warmup_end_time": {
"type": "string",
"description": "Daily warmup window end, HH:MM."
},
"warmup_days": {
"type": "integer"
},
"timezone": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"email",
"provider",
"status",
"campaign_limit",
"min_wait_time",
"created_at",
"updated_at"
]
},
"MailboxList": {
"type": "object",
"description": "A page of mailboxes.",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Mailbox"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
},
"required": [
"data",
"pagination"
]
},
"MailboxUpdate": {
"type": "object",
"description": "Mailbox settings patch. All fields optional; only present fields are applied.",
"properties": {
"name": {
"type": "string",
"description": "Display name on outgoing mail."
},
"signature_plain": {
"type": "string"
},
"signature_html": {
"type": "string"
},
"signature_sync": {
"type": "boolean"
},
"signature_code": {
"type": "boolean",
"description": "Treat the HTML signature as raw code."
},
"status": {
"type": "string",
"enum": [
"active",
"inactive",
"revoked"
]
},
"campaign_limit": {
"type": "integer",
"description": "Daily cold-campaign cap (validated up to 100)."
},
"min_wait_time": {
"type": "integer",
"description": "Minimum seconds between sends."
},
"reply_to": {
"type": "string"
},
"warmup": {
"type": "boolean",
"description": "Enable or disable warmup."
},
"warmup_base": {
"type": "integer",
"description": "Warmup starting volume per day."
},
"warmup_max": {
"type": "integer",
"description": "Warmup daily ceiling."
},
"warmup_increase": {
"type": "integer",
"description": "Per-day warmup ramp increment."
},
"warmup_reply_rate": {
"type": "integer",
"description": "Percentage of warmup threads to reply to."
},
"warmup_tag": {
"type": "string"
},
"warmup_start_time": {
"type": "string",
"description": "Daily warmup window start, HH:MM."
},
"warmup_end_time": {
"type": "string",
"description": "Daily warmup window end, HH:MM."
},
"warmup_days": {
"type": "integer"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tag ids assigned to the mailbox."
}
}
},
"MailboxTrackingDomain": {
"type": "object",
"description": "The resolved custom tracking-domain state for a mailbox.",
"properties": {
"tracking_domain": {
"type": "string"
},
"tracking_domain_verified": {
"type": "boolean"
},
"tracking_domain_verified_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Null until the CNAME resolves to the tracking host."
}
},
"required": [
"tracking_domain",
"tracking_domain_verified"
]
},
"MailboxAuthCheck": {
"type": "object",
"description": "On-demand SPF/DKIM/DMARC check for the mailbox's sending domain.",
"properties": {
"domain": {
"type": "string"
},
"spf_found": {
"type": "boolean"
},
"spf_record": {
"type": "string",
"description": "Omitted when SPF is not found."
},
"dkim_found": {
"type": "boolean"
},
"dkim_selectors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Omitted when DKIM is not found."
},
"dmarc_found": {
"type": "boolean"
},
"dmarc_policy": {
"type": "string",
"description": "Omitted when DMARC is not found."
},
"all_aligned": {
"type": "boolean"
},
"summary": {
"type": "string"
}
},
"required": [
"domain",
"spf_found",
"dkim_found",
"dmarc_found",
"all_aligned",
"summary"
]
},
"MailboxVerifyRequest": {
"type": "object",
"description": "Address to verify. Required if the email query param is not set.",
"properties": {
"email": {
"type": "string",
"description": "The address to verify."
}
}
},
"MailboxVerifyResult": {
"type": "object",
"description": "Result of a single-address verification.",
"properties": {
"email": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"valid",
"risky",
"invalid",
"unknown"
]
},
"reason": {
"type": "string"
},
"is_catch_all": {
"type": "boolean"
},
"has_mx": {
"type": "boolean"
},
"checked_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"email",
"status",
"reason",
"is_catch_all",
"has_mx",
"checked_at"
]
},
"MailboxWarmupBanStatus": {
"type": "object",
"description": "Whether a mailbox is blocked from the shared warmup pool.",
"properties": {
"email_account_id": {
"type": "string",
"format": "uuid"
},
"blocked": {
"type": "boolean"
},
"health_state": {
"type": "string",
"description": "Rolling warmup health.",
"enum": [
"healthy",
"watch",
"throttled",
"quarantined",
"blocked"
]
},
"reason": {
"type": "string",
"description": "Omitted when not blocked."
},
"blocked_at": {
"type": "string",
"format": "date-time",
"description": "Omitted when not blocked."
},
"blocked_until": {
"type": "string",
"format": "date-time",
"description": "Omitted when not blocked."
},
"can_appeal": {
"type": "boolean"
},
"pending_appeal": {
"type": "boolean"
}
},
"required": [
"email_account_id",
"blocked",
"health_state",
"can_appeal",
"pending_appeal"
]
},
"MailboxWarmupAppealRequest": {
"type": "object",
"description": "A warmup-ban appeal.",
"properties": {
"reason": {
"type": "string",
"description": "The owner's explanation for the appeal."
}
}
},
"MailboxWarmupAppealResult": {
"type": "object",
"properties": {
"appeal_id": {
"type": "string",
"format": "uuid"
}
},
"required": [
"appeal_id"
]
},
"MailboxSendRequest": {
"type": "object",
"description": "A one-off send from a specific mailbox.",
"properties": {
"to": {
"type": "array",
"items": {
"type": "string"
},
"description": "Recipient addresses."
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"in_reply_to": {
"type": "array",
"items": {
"type": "string"
},
"description": "Message ids this email replies to."
},
"thread_id": {
"type": "string",
"description": "Thread id to attach the message to."
},
"send_mode": {
"type": "string",
"enum": [
"instant",
"smart",
"scheduled"
],
"default": "instant",
"description": "instant (default), smart (next per-mailbox scheduler gap), or scheduled (use scheduled_at)."
},
"scheduled_at": {
"type": "string",
"format": "date-time",
"description": "Required when send_mode is scheduled. Must be in the future."
}
},
"required": [
"to",
"subject"
]
},
"MailboxSendResult": {
"type": "object",
"description": "The queued send task.",
"properties": {
"task_id": {
"type": "string",
"format": "uuid",
"description": "Identifies the queued send task."
},
"scheduled_at": {
"type": "string",
"format": "date-time",
"description": "Resolved dispatch time."
},
"send_mode": {
"type": "string",
"enum": [
"instant",
"smart",
"scheduled"
]
}
},
"required": [
"task_id",
"scheduled_at",
"send_mode"
]
},
"CampaignStatus": {
"type": "string",
"description": "Campaign lifecycle status.",
"enum": [
"draft",
"scheduled",
"active",
"paused",
"paused_no_accounts",
"completed",
"stopped"
]
},
"ScheduleWindows": {
"type": "array",
"description": "Per-day sending schedule. 7-element array indexed by time.Weekday (Sunday = 0); each day is a list of {start, end} minute intervals. When non-empty it supersedes days/start_time/end_time.",
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"start": {
"type": "integer",
"description": "Minutes from midnight."
},
"end": {
"type": "integer",
"description": "Minutes from midnight."
}
}
}
}
},
"Campaign": {
"type": "object",
"required": [
"id",
"name",
"status",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": "string",
"description": "Creator user id."
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/CampaignStatus"
},
"stop_on_reply": {
"type": "boolean"
},
"open_tracking": {
"type": "boolean"
},
"link_tracking": {
"type": "boolean"
},
"text_only": {
"type": "boolean"
},
"daily_limit": {
"type": "integer"
},
"unsubscribe_header": {
"type": "boolean"
},
"risky_emails": {
"type": "boolean"
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"start_date": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"end_date": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timezone": {
"type": "string",
"description": "IANA timezone."
},
"days": {
"type": "integer",
"description": "Legacy weekday bitmask (0-127), superseded by schedule_windows."
},
"start_time": {
"type": "string",
"description": "Legacy daily start (HH:MM)."
},
"end_time": {
"type": "string",
"description": "Legacy daily end (HH:MM)."
},
"schedule_windows": {
"$ref": "#/components/schemas/ScheduleWindows"
},
"email_tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Mailbox tag ids resolving the sender pool (tags strategy)."
},
"folders": {
"type": "array",
"items": {
"type": "string"
}
},
"contact_order_by": {
"type": "string"
},
"contact_order_dir": {
"type": "string",
"enum": [
"asc",
"desc"
]
},
"contact_order_field": {
"type": [
"string",
"null"
]
},
"sender_strategy": {
"type": "string",
"enum": [
"tags",
"explicit"
]
},
"rotation_mode": {
"type": "string",
"description": "How volume spreads across mailboxes."
},
"ramp_enabled": {
"type": "boolean"
},
"ramp_start": {
"type": "integer"
},
"ramp_increment": {
"type": "integer"
},
"ramp_ceiling": {
"type": "integer"
},
"ramp_level": {
"type": "integer",
"description": "Server-managed current ramp level."
},
"esp_match_mode": {
"type": "string",
"enum": [
"off",
"prefer",
"strict"
]
},
"max_new_leads_per_day": {
"type": "integer",
"description": "0 = unlimited."
},
"prioritize_new_leads": {
"type": "boolean"
},
"tracking_domain": {
"type": "string"
},
"tracking_domain_verified": {
"type": "boolean"
},
"tracking_domain_verified_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_status_change_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignList": {
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Campaign"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"CampaignCreate": {
"type": "object",
"required": [
"name"
],
"description": "Only name is required; every other field is optional and applied only when sent.",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"stop_on_reply": {
"type": "boolean"
},
"open_tracking": {
"type": "boolean"
},
"link_tracking": {
"type": "boolean"
},
"text_only": {
"type": "boolean"
},
"daily_limit": {
"type": "integer"
},
"unsubscribe_header": {
"type": "boolean"
},
"risky_emails": {
"type": "boolean"
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"start_date": {
"type": "string",
"format": "date-time"
},
"end_date": {
"type": "string",
"format": "date-time"
},
"timezone": {
"type": "string"
},
"days": {
"type": "integer",
"description": "Legacy weekday bitmask (0-127), superseded by schedule_windows."
},
"start_time": {
"type": "string",
"description": "Legacy daily start (HH:MM)."
},
"end_time": {
"type": "string",
"description": "Legacy daily end (HH:MM)."
},
"schedule_windows": {
"$ref": "#/components/schemas/ScheduleWindows"
},
"email_tag_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Mailbox tag ids that resolve the sender pool (tags strategy)."
},
"folder_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"sender_strategy": {
"type": "string",
"enum": [
"tags",
"explicit"
]
},
"rotation_mode": {
"type": "string"
},
"senders": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignSenderInput"
},
"description": "Explicit-strategy mailbox pool."
},
"ramp_enabled": {
"type": "boolean"
},
"ramp_start": {
"type": "integer"
},
"ramp_increment": {
"type": "integer"
},
"ramp_ceiling": {
"type": "integer"
},
"esp_match_mode": {
"type": "string",
"enum": [
"off",
"prefer",
"strict"
]
},
"max_new_leads_per_day": {
"type": "integer",
"description": "0 = unlimited."
},
"prioritize_new_leads": {
"type": "boolean"
},
"tracking_domain": {
"type": "string"
},
"sequences": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignStepCreate"
},
"description": "Initial sequence steps in order."
},
"variants": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignABVariantCreate"
},
"description": "A/B variants for the first step."
},
"advanced_overrides": {
"$ref": "#/components/schemas/AdvancedOutreachSettings"
}
}
},
"CampaignUpdate": {
"type": "object",
"description": "Every field optional; any field sent is applied, omitted fields unchanged.",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/CampaignStatus"
},
"stop_on_reply": {
"type": "boolean"
},
"open_tracking": {
"type": "boolean"
},
"link_tracking": {
"type": "boolean"
},
"text_only": {
"type": "boolean"
},
"daily_limit": {
"type": "integer"
},
"unsubscribe_header": {
"type": "boolean"
},
"risky_emails": {
"type": "boolean"
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"start_date": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"end_date": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"timezone": {
"type": "string"
},
"days": {
"type": "integer"
},
"start_time": {
"type": "string"
},
"end_time": {
"type": "string"
},
"schedule_windows": {
"$ref": "#/components/schemas/ScheduleWindows"
},
"email_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folders": {
"type": "array",
"items": {
"type": "string"
}
},
"contact_order_by": {
"type": "string"
},
"contact_order_dir": {
"type": "string",
"enum": [
"asc",
"desc"
]
},
"contact_order_field": {
"type": "string"
},
"sender_strategy": {
"type": "string",
"enum": [
"tags",
"explicit"
]
},
"rotation_mode": {
"type": "string"
},
"ramp_enabled": {
"type": "boolean"
},
"ramp_start": {
"type": "integer"
},
"ramp_increment": {
"type": "integer"
},
"ramp_ceiling": {
"type": "integer"
},
"esp_match_mode": {
"type": "string",
"enum": [
"off",
"prefer",
"strict"
]
},
"max_new_leads_per_day": {
"type": "integer"
},
"prioritize_new_leads": {
"type": "boolean"
},
"tracking_domain": {
"type": "string"
}
}
},
"CampaignSender": {
"type": "object",
"required": [
"email_account_id",
"weight",
"enabled"
],
"properties": {
"email_account_id": {
"type": "string",
"format": "uuid"
},
"weight": {
"type": "integer"
},
"last_sent_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"enabled": {
"type": "boolean"
}
}
},
"CampaignSenderInput": {
"type": "object",
"required": [
"email_account_id"
],
"properties": {
"email_account_id": {
"type": "string",
"format": "uuid"
},
"weight": {
"type": "integer"
},
"enabled": {
"type": "boolean"
}
}
},
"CampaignSenderList": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignSender"
}
}
}
},
"CampaignSendersReplace": {
"type": "object",
"required": [
"senders"
],
"properties": {
"senders": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignSenderInput"
},
"description": "The full new sender pool."
}
}
},
"CampaignStep": {
"type": "object",
"description": "A sequence step (email or action/condition node).",
"required": [
"id",
"kind",
"position",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"subject": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_sync": {
"type": "boolean",
"description": "Keep plain and HTML bodies in sync."
},
"body_code": {
"type": "boolean",
"description": "Treat the body as raw code."
},
"wait_after": {
"type": "integer",
"description": "Minutes to wait after this step before the next."
},
"position": {
"type": "integer"
},
"kind": {
"type": "string",
"enum": [
"email",
"action",
"wait"
]
},
"conditions": {
"type": "object",
"description": "Branching tree ({branches: [...]}).",
"additionalProperties": true
},
"action": {
"type": "object",
"description": "Typed config for non-email nodes.",
"additionalProperties": true
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignStepCreate": {
"type": "object",
"description": "Initial step shape used inside campaign create (sequences[]).",
"properties": {
"name": {
"type": "string"
},
"subject": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"body_html": {
"type": "string"
},
"wait_after": {
"type": "integer"
},
"kind": {
"type": "string",
"enum": [
"email",
"action",
"wait"
]
}
}
},
"CampaignStepUpdate": {
"type": "object",
"description": "Patch a step. All fields optional.",
"properties": {
"name": {
"type": "string"
},
"subject": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_sync": {
"type": "boolean"
},
"body_code": {
"type": "boolean"
},
"wait_after": {
"type": "integer",
"description": "Minutes to wait after this step (spacing model; no standalone wait node for email steps)."
},
"conditions": {
"type": "object",
"description": "Branching tree ({branches: [...]}). Send {} or empty branches to clear branching.",
"additionalProperties": true
},
"kind": {
"type": "string",
"enum": [
"email",
"action",
"wait"
]
},
"action": {
"type": "object",
"description": "Typed config for non-email nodes; type is the switch (wait, add_tag, remove_tag, unsubscribe, notify, create_task, create_deal, move_deal_stage, run_automation, end).",
"additionalProperties": true
}
}
},
"CampaignABVariant": {
"type": "object",
"required": [
"id",
"campaign_id",
"name",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"campaign_id": {
"type": "string",
"format": "uuid"
},
"step_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Step the variant is scoped to; null is campaign-level."
},
"name": {
"type": "string"
},
"weight": {
"type": "integer"
},
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"is_control": {
"type": "boolean"
},
"is_active": {
"type": "boolean"
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignABVariantList": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignABVariant"
}
}
}
},
"CampaignABVariantCreate": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"step_id": {
"type": "string",
"format": "uuid",
"description": "Step to scope the variant to; omit for campaign-level."
},
"weight": {
"type": "integer"
},
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"is_control": {
"type": "boolean"
},
"is_active": {
"type": "boolean"
},
"metadata": {
"type": "object",
"additionalProperties": true
}
}
},
"CampaignABVariantUpdate": {
"type": "object",
"description": "Patch a variant. All fields optional.",
"properties": {
"name": {
"type": "string"
},
"weight": {
"type": "integer"
},
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"is_control": {
"type": "boolean"
},
"is_active": {
"type": "boolean"
},
"metadata": {
"type": "object",
"additionalProperties": true
}
}
},
"ABWinnerAnalysis": {
"type": "object",
"required": [
"campaign_id",
"variants"
],
"properties": {
"campaign_id": {
"type": "string",
"format": "uuid"
},
"variants": {
"type": "array",
"items": {
"type": "object",
"properties": {
"variant_id": {
"type": "string",
"format": "uuid"
},
"variant_name": {
"type": "string"
},
"total_sent": {
"type": "integer"
},
"opened": {
"type": "integer"
},
"clicked": {
"type": "integer"
},
"replied": {
"type": "integer"
},
"bounced": {
"type": "integer"
},
"open_rate": {
"type": "number"
},
"click_rate": {
"type": "number"
},
"reply_rate": {
"type": "number"
},
"bounce_rate": {
"type": "number"
}
}
}
},
"winner_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"winner_name": {
"type": [
"string",
"null"
]
},
"winning_rule": {
"type": "string"
},
"confidence": {
"type": "string",
"description": "Winner confidence (e.g. low, medium, high)."
}
}
},
"CampaignAttachment": {
"type": "object",
"required": [
"id",
"campaign_id",
"filename",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"campaign_id": {
"type": "string",
"format": "uuid"
},
"step_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"filename": {
"type": "string"
},
"size": {
"type": "integer",
"description": "Size in bytes."
},
"mime_type": {
"type": "string"
},
"url": {
"type": "string",
"description": "Short-lived presigned download URL."
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignAttachmentList": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignAttachment"
}
}
}
},
"CampaignLog": {
"type": "object",
"required": [
"id",
"campaign_id",
"event_type",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"campaign_id": {
"type": "string",
"format": "uuid"
},
"event_type": {
"type": "string",
"description": "e.g. campaign_started."
},
"message": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignLogList": {
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignLog"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"CampaignAdvancedSettings": {
"type": "object",
"required": [
"campaign_id",
"overrides"
],
"properties": {
"campaign_id": {
"type": "string",
"format": "uuid"
},
"overrides": {
"$ref": "#/components/schemas/AdvancedOutreachSettings"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignAdvancedUpdate": {
"type": "object",
"required": [
"settings"
],
"properties": {
"settings": {
"$ref": "#/components/schemas/AdvancedOutreachSettings"
}
}
},
"AdvancedOutreachSettings": {
"type": "object",
"description": "Advanced outreach overrides for a campaign.",
"properties": {
"bounce_pipeline": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"auto_suppress_on_bounce": {
"type": "boolean"
},
"auto_suppress_on_complaint": {
"type": "boolean"
},
"auto_suppress_on_unsubscribe": {
"type": "boolean"
},
"auto_pause_campaign_on_spike": {
"type": "boolean"
},
"pause_bounce_rate_threshold": {
"type": "number"
},
"pause_complaint_rate_threshold": {
"type": "number"
}
}
},
"task_reliability": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"dlq_enabled": {
"type": "boolean"
},
"max_attempts": {
"type": "integer"
},
"execution_window_seconds": {
"type": "integer"
}
}
},
"ab_testing": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"default_winning_rule": {
"type": "string"
},
"auto_promote_winner": {
"type": "boolean"
},
"min_sample_size": {
"type": "integer"
}
}
},
"reply_intent": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"positive_keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"negative_keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"out_of_office_keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"question_keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"auto_create_crm_task": {
"type": "boolean"
},
"auto_pause_on_negative": {
"type": "boolean"
},
"auto_suppress_on_unsubscribe_keyword": {
"type": "boolean"
}
}
},
"send_time_optimization": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"use_contact_timezone": {
"type": "boolean"
},
"default_contact_timezone": {
"type": "string"
},
"preferred_hours": {
"type": "array",
"items": {
"type": "integer"
}
},
"weekend_weight_multiplier": {
"type": "number"
}
}
},
"preflight": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"check_tracking_domain": {
"type": "boolean"
},
"check_unsubscribe_header": {
"type": "boolean"
},
"check_ab_variant_configured": {
"type": "boolean"
},
"check_daily_limit": {
"type": "boolean"
},
"check_schedule_window": {
"type": "boolean"
}
}
},
"dashboard": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"show_suppression_log": {
"type": "boolean"
},
"show_intent_summary": {
"type": "boolean"
},
"show_dlq_stats": {
"type": "boolean"
}
}
}
}
},
"PreflightReport": {
"type": "object",
"required": [
"campaign_id",
"passed",
"score",
"checks"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"campaign_id": {
"type": "string",
"format": "uuid"
},
"passed": {
"type": "boolean"
},
"score": {
"type": "integer"
},
"checks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"passed": {
"type": "boolean"
},
"severity": {
"type": "string",
"description": "e.g. warning, error."
},
"message": {
"type": "string"
},
"remediation": {
"type": "string"
}
}
}
},
"recommendations": {
"type": "array",
"items": {
"type": "string"
}
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignTestEmailRequest": {
"type": "object",
"required": [
"account_id",
"recipient"
],
"properties": {
"account_id": {
"type": "string",
"format": "uuid",
"description": "Sending mailbox id."
},
"recipient": {
"type": "string",
"format": "email",
"description": "Where to send the test."
},
"step_id": {
"type": "string",
"format": "uuid",
"description": "Step to render and send; defaults to the first step."
}
}
},
"CampaignTestEmailResult": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"recipient": {
"type": "string",
"format": "email"
},
"subject": {
"type": "string"
},
"account_id": {
"type": "string",
"format": "uuid"
}
}
},
"CampaignStartResult": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "started"
}
}
},
"CampaignStopResult": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "stopped"
}
}
},
"TrackingDomainStatus": {
"type": "object",
"properties": {
"tracking_domain": {
"type": "string"
},
"tracking_domain_verified": {
"type": "boolean"
},
"tracking_domain_verified_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"TemplatePreviewRequest": {
"type": "object",
"properties": {
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"contact": {
"type": "object",
"description": "Override fields on the built-in sample contact.",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"company": {
"type": "string"
},
"phone": {
"type": "string"
},
"custom_fields": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
}
}
},
"TemplatePreview": {
"type": "object",
"properties": {
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"errors": {
"type": "array",
"items": {
"type": "string"
},
"description": "Template parse errors that would block sending. Omitted when empty."
},
"unresolved": {
"type": "array",
"items": {
"type": "string"
},
"description": "Literal {{...}} tokens left after render. Omitted when empty."
}
}
},
"GenerationWriteRequest": {
"type": "object",
"required": [
"prompt"
],
"properties": {
"prompt": {
"type": "string",
"maxLength": 8000,
"description": "The instruction to generate from."
},
"tone": {
"type": "string",
"description": "Desired tone (e.g. friendly, direct)."
}
}
},
"GenerationWriteResult": {
"type": "object",
"properties": {
"text": {
"type": "string"
},
"credits_remaining": {
"type": "integer"
},
"model": {
"type": "string"
}
}
},
"MiniCategory": {
"type": "object",
"description": "Denormalised category chip attached to a contact.",
"required": [
"id",
"title",
"color"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"color": {
"type": "string",
"description": "Hex color, e.g. #0ea5e9."
}
}
},
"MiniCampaign": {
"type": "object",
"description": "Denormalised campaign reference attached to a contact.",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"ContactCampaignProgress": {
"type": "object",
"description": "A contact's aggregate processing state inside one campaign. Present on search results only when filtering by exactly one campaign.",
"required": [
"status",
"sent",
"opened",
"clicked",
"replied",
"bounced"
],
"properties": {
"status": {
"type": "string",
"enum": [
"pending",
"active",
"replied",
"bounced",
"unsubscribed"
]
},
"sent": {
"type": "integer"
},
"opened": {
"type": "integer"
},
"clicked": {
"type": "integer"
},
"replied": {
"type": "integer"
},
"bounced": {
"type": "integer"
},
"current_step": {
"type": "string",
"description": "Label of the step the contact is on now. Empty when nothing sent yet."
},
"last_activity_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"Contact": {
"type": "object",
"description": "A contact record.",
"required": [
"id",
"first_name",
"last_name",
"email",
"company",
"phone",
"custom_fields",
"subscribed",
"campaigns",
"categories",
"verification_status",
"verification_reason",
"is_catch_all",
"esp_provider",
"updated_at",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"company": {
"type": "string"
},
"phone": {
"type": "string"
},
"custom_fields": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Arbitrary string key/value custom fields."
},
"subscribed": {
"type": "boolean"
},
"campaigns": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MiniCampaign"
}
},
"categories": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MiniCategory"
}
},
"verification_status": {
"type": "string",
"enum": [
"valid",
"risky",
"invalid",
"unknown"
],
"description": "Pre-send verification state."
},
"verification_reason": {
"type": "string"
},
"is_catch_all": {
"type": "boolean"
},
"verification_checked_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"esp_provider": {
"type": "string",
"description": "Recipient ESP derived from the domain: '' | gmail | outlook | other."
},
"esp_resolved_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"campaign_lead": {
"allOf": [
{
"$ref": "#/components/schemas/ContactCampaignProgress"
}
],
"description": "Present only when search filters by exactly one campaign."
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"ContactList": {
"type": "object",
"description": "A page of contacts.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Contact"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"ContactEngagement": {
"type": "object",
"description": "Aggregate email engagement summary for a single contact.",
"required": [
"total_sent",
"total_opened",
"total_clicked",
"total_replied",
"total_bounced",
"total_complained"
],
"properties": {
"total_sent": {
"type": "integer"
},
"total_opened": {
"type": "integer"
},
"total_clicked": {
"type": "integer"
},
"total_replied": {
"type": "integer"
},
"total_bounced": {
"type": "integer"
},
"total_complained": {
"type": "integer"
},
"last_sent_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_opened_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_clicked_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_replied_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_bounced_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"ContactSuppression": {
"type": "object",
"description": "Suppression state for the contact's email. Null when not suppressed.",
"required": [
"reason",
"source",
"created_at"
],
"properties": {
"reason": {
"type": "string"
},
"source": {
"type": "string",
"enum": [
"bounce",
"complaint",
"unsubscribe"
]
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"ContactDetail": {
"description": "The hydrated contact 360 payload: the contact plus engagement and suppression.",
"allOf": [
{
"$ref": "#/components/schemas/Contact"
},
{
"type": "object",
"required": [
"engagement"
],
"properties": {
"engagement": {
"$ref": "#/components/schemas/ContactEngagement"
},
"suppression": {
"allOf": [
{
"$ref": "#/components/schemas/ContactSuppression"
}
]
}
}
}
]
},
"ContactSearchRequest": {
"type": "object",
"description": "Faceted contact search filters. All fields optional.",
"properties": {
"query": {
"type": "string",
"description": "Text search across name, email, company."
},
"custom_field_filters": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactCustomFieldFilter"
}
},
"campaign_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Contact must be in ALL of these campaigns."
},
"category_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Contact must have ALL of these categories."
},
"min_campaigns": {
"type": "integer",
"description": "Minimum number of associated campaigns."
},
"max_campaigns": {
"type": "integer",
"description": "Maximum number of associated campaigns."
},
"subscribed": {
"type": "boolean"
},
"created_after": {
"type": "string",
"format": "date-time"
},
"created_before": {
"type": "string",
"format": "date-time"
},
"updated_after": {
"type": "string",
"format": "date-time"
},
"updated_before": {
"type": "string",
"format": "date-time"
},
"sort_by": {
"type": "string",
"description": "Sort column, e.g. first_name, campaign_count."
},
"reverse": {
"type": "boolean",
"description": "Descending when true."
}
}
},
"ContactCustomFieldFilter": {
"type": "object",
"description": "A single custom-field filter clause.",
"required": [
"name",
"value",
"type"
],
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"equal",
"starts_with",
"ends_with",
"contains"
]
}
}
},
"ContactCreate": {
"type": "object",
"description": "A contact to create.",
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"format": "email"
},
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"company": {
"type": "string"
},
"phone": {
"type": "string"
},
"campaigns": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Campaign IDs to add the contact to."
},
"categories": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Category IDs to assign."
},
"custom_fields": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
"ContactUpdate": {
"type": "object",
"description": "Partial update for a single contact. Only present fields change.",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"company": {
"type": "string"
},
"phone": {
"type": "string"
},
"custom_fields": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Replaces the custom-fields map."
},
"subscribed": {
"type": "boolean"
},
"campaigns": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Set the full campaign membership (omit to leave as-is)."
},
"categories": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Set the full category list (omit to leave as-is)."
},
"add_categories": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Diff-style add (ignored when categories is set)."
},
"remove_categories": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Diff-style remove (ignored when categories is set)."
}
}
},
"ContactBulkUpdateRequest": {
"type": "object",
"description": "One set of edits applied across many contacts.",
"required": [
"contacts"
],
"properties": {
"contacts": {
"type": "array",
"minItems": 1,
"maxItems": 1000,
"items": {
"type": "string",
"format": "uuid"
},
"description": "Contact IDs to edit (1 to 1000)."
},
"add_campaigns": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"remove_campaigns": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"add_categories": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"remove_categories": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"fields": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactBulkFieldOp"
}
},
"subscribe": {
"type": "boolean",
"description": "Set subscription status for all listed contacts."
}
}
},
"ContactBulkFieldOp": {
"type": "object",
"description": "A custom-field operation applied during a bulk update.",
"required": [
"type",
"key"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ADD",
"EDIT",
"DELETE",
"RENAME"
]
},
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"ContactExportRequest": {
"type": "object",
"description": "Body for a contact export.",
"required": [
"format",
"scope"
],
"properties": {
"format": {
"type": "string",
"enum": [
"csv",
"xlsx",
"json"
]
},
"scope": {
"type": "string",
"enum": [
"all",
"filtered",
"selected"
]
},
"contact_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Contact IDs when scope is selected."
},
"filters": {
"allOf": [
{
"$ref": "#/components/schemas/ContactSearchRequest"
}
],
"description": "A search filter body when scope is filtered."
},
"fields": {
"type": "array",
"items": {
"type": "string"
},
"description": "Column identifiers in display order (built-ins like email, first_name, or custom:<key>). Empty uses defaults."
},
"filename": {
"type": "string",
"description": "Filename without extension. Sanitized server-side; empty falls back to contacts-<YYYY-MM-DD>."
}
}
},
"ContactImportColumnMapping": {
"type": "object",
"description": "Maps a source column index to a target contact field.",
"required": [
"index",
"target"
],
"properties": {
"index": {
"type": "integer",
"description": "Zero-based source column index."
},
"target": {
"type": "string",
"enum": [
"ignore",
"email",
"first_name",
"last_name",
"company",
"phone",
"subscribed",
"categories"
],
"description": "Target field, or a custom:<key> string for a custom field."
},
"custom_key": {
"type": "string",
"description": "Custom-field key when target is custom:<key>."
}
}
},
"ContactImportPreview": {
"type": "object",
"description": "Detected columns and a sample for building a column mapping.",
"required": [
"filename",
"format",
"total_rows",
"columns",
"has_header",
"sample_rows",
"suggested_mapping"
],
"properties": {
"filename": {
"type": "string"
},
"format": {
"type": "string",
"description": "csv or xlsx."
},
"total_rows": {
"type": "integer"
},
"columns": {
"type": "array",
"items": {
"type": "string"
}
},
"has_header": {
"type": "boolean"
},
"sample_rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
}
},
"description": "Capped at 20 rows."
},
"suggested_mapping": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactImportColumnMapping"
}
}
}
},
"ContactImportRowError": {
"type": "object",
"description": "A single failed import row.",
"required": [
"line",
"reason"
],
"properties": {
"line": {
"type": "integer"
},
"email": {
"type": "string"
},
"values": {
"type": "array",
"items": {
"type": "string"
}
},
"reason": {
"type": "string"
}
}
},
"ContactImportResult": {
"type": "object",
"description": "Per-row results of an import commit.",
"required": [
"total",
"imported",
"updated",
"skipped",
"failed",
"started_at",
"ended_at"
],
"properties": {
"total": {
"type": "integer"
},
"imported": {
"type": "integer"
},
"updated": {
"type": "integer"
},
"skipped": {
"type": "integer"
},
"failed": {
"type": "integer"
},
"started_at": {
"type": "string",
"format": "date-time"
},
"ended_at": {
"type": "string",
"format": "date-time"
},
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactImportRowError"
}
}
}
},
"ContactLookupResult": {
"type": "object",
"description": "Resolved contact for a sender address; contact is null when nothing matches.",
"required": [
"contact"
],
"properties": {
"contact": {
"allOf": [
{
"$ref": "#/components/schemas/Contact"
}
]
}
}
},
"ContactSentEmail": {
"type": "object",
"description": "One email sent (or attempted) to a contact.",
"required": [
"task_id",
"status",
"message_id",
"subject",
"sent_at"
],
"properties": {
"task_id": {
"type": "string",
"format": "uuid"
},
"status": {
"type": "string"
},
"message_id": {
"type": "string"
},
"subject": {
"type": "string"
},
"sent_at": {
"type": "string",
"format": "date-time"
},
"email_account_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"email_account_email": {
"type": [
"string",
"null"
]
},
"email_account_name": {
"type": [
"string",
"null"
]
},
"campaign_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"campaign_name": {
"type": [
"string",
"null"
]
},
"step_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"step_name": {
"type": [
"string",
"null"
]
},
"opened_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"clicked_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"replied_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"bounced_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"ContactSentEmailList": {
"type": "object",
"description": "A page of emails sent to a contact.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactSentEmail"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"ContactTimelineEvent": {
"type": "object",
"description": "One entry in a contact's merged activity feed. Fields not relevant to the event type are omitted.",
"required": [
"type",
"at"
],
"properties": {
"type": {
"type": "string",
"enum": [
"email_sent",
"email_opened",
"email_clicked",
"email_replied",
"email_bounced",
"reply_received",
"deliverability",
"suppressed",
"note",
"meeting_booked",
"meeting_rescheduled",
"meeting_canceled"
]
},
"at": {
"type": "string",
"format": "date-time"
},
"email_account_id": {
"type": "string",
"format": "uuid"
},
"email_account_email": {
"type": "string"
},
"email_account_name": {
"type": "string"
},
"campaign_id": {
"type": "string",
"format": "uuid"
},
"campaign_name": {
"type": "string"
},
"step_id": {
"type": "string",
"format": "uuid"
},
"step_name": {
"type": "string"
},
"task_id": {
"type": "string",
"format": "uuid"
},
"subject": {
"type": "string"
},
"reason": {
"type": "string",
"description": "Deliverability / suppression / meeting cancellation reason."
},
"source": {
"type": "string",
"description": "Suppression: bounce/complaint/unsubscribe; meeting: calendly/cal_com."
},
"provider": {
"type": "string"
},
"intent": {
"type": "string",
"description": "reply_intent classification."
},
"content": {
"type": "string",
"description": "Note body."
},
"scheduled_for": {
"type": "string",
"format": "date-time",
"description": "When the call is set for (meeting events)."
},
"join_url": {
"type": "string"
},
"meeting_state": {
"type": "string",
"enum": [
"booked",
"rescheduled",
"canceled"
]
},
"user_id": {
"type": "string",
"format": "uuid",
"description": "Note author."
}
}
},
"ContactTimelineResult": {
"type": "object",
"description": "A page of timeline events. Paginate via has_more and the `before` query param; this list does not use a cursor envelope.",
"required": [
"data",
"has_more"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactTimelineEvent"
}
},
"has_more": {
"type": "boolean"
}
}
},
"ContactActivity": {
"type": "object",
"description": "One structured CRM activity-log entry.",
"required": [
"id",
"contact_id",
"organization_id",
"activity_type",
"metadata",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"contact_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"activity_type": {
"type": "string",
"enum": [
"email_sent",
"email_opened",
"email_clicked",
"email_replied",
"email_bounced",
"note_added",
"note_updated",
"deal_created",
"deal_stage_changed",
"deal_won",
"deal_lost",
"task_created",
"task_completed",
"contact_created",
"contact_updated",
"campaign_added",
"campaign_removed"
]
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"created_at": {
"type": "string",
"format": "date-time"
},
"user": {
"type": "object",
"additionalProperties": true,
"description": "Joined user record, when present."
}
}
},
"ContactActivityList": {
"type": "object",
"description": "A page of CRM activities.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactActivity"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"ContactNote": {
"type": "object",
"description": "A CRM note attached to a contact.",
"required": [
"id",
"contact_id",
"organization_id",
"user_id",
"content",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"contact_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": "string",
"format": "uuid"
},
"content": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"user": {
"type": "object",
"additionalProperties": true,
"description": "Joined author record, when present."
}
}
},
"ContactNoteList": {
"type": "object",
"description": "A page of contact notes.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ContactNote"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"ContactNoteCreate": {
"type": "object",
"description": "Body to create a contact note.",
"required": [
"content"
],
"properties": {
"content": {
"type": "string",
"minLength": 1,
"maxLength": 10000,
"description": "Note body (1 to 10,000 characters)."
}
}
},
"ContactNoteUpdate": {
"type": "object",
"description": "Body to edit a contact note.",
"properties": {
"content": {
"type": "string",
"maxLength": 10000,
"description": "New note body."
}
}
},
"Deal": {
"type": "object",
"description": "A CRM deal. Nullable attribution fields are omitted when unset.",
"required": [
"id",
"organization_id",
"pipeline_id",
"stage_id",
"name",
"currency",
"status",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"pipeline_id": {
"type": "string",
"format": "uuid"
},
"stage_id": {
"type": "string",
"format": "uuid"
},
"contact_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"name": {
"type": "string"
},
"value": {
"type": [
"number",
"null"
]
},
"currency": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"open",
"won",
"lost"
]
},
"expected_close_date": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"won_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"lost_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"lost_reason": {
"type": [
"string",
"null"
]
},
"assigned_to": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"campaign_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"source_mailbox_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"UniboxLabel": {
"type": "object",
"description": "A conversation label (one of the caller's categories).",
"required": [
"id",
"title",
"color"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"color": {
"type": "string",
"description": "Hex color, e.g. `#16a34a`."
}
}
},
"UniboxThread": {
"type": "object",
"description": "One inbox row, summarising the newest message of a thread plus thread-level rollups.",
"required": [
"id",
"email_id",
"thread_id",
"subject",
"internal_date",
"seen",
"message_count",
"has_unread"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "UUID of the newest message in the thread."
},
"email_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the mailbox the message landed in."
},
"thread_id": {
"type": "string",
"description": "Thread identifier."
},
"from_addr": {
"type": "array",
"items": {
"type": "string"
}
},
"to_addr": {
"type": "array",
"items": {
"type": "string"
}
},
"subject": {
"type": "string"
},
"snippet": {
"type": "string"
},
"internal_date": {
"type": "string",
"format": "date-time"
},
"seen": {
"type": "boolean",
"description": "Whether the newest message is read."
},
"message_count": {
"type": "integer",
"description": "Number of messages in the thread."
},
"has_unread": {
"type": "boolean",
"description": "Whether the thread has any unread message."
},
"labels": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxLabel"
}
}
}
},
"UniboxThreadList": {
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxThread"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"UniboxMessage": {
"type": "object",
"description": "A full message row inside a thread (envelope plus body).",
"required": [
"id",
"email_id",
"thread_id",
"subject",
"internal_date",
"seen"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"email_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the mailbox the message landed in."
},
"mailbox": {
"type": "integer",
"description": "IMAP mailbox/folder index."
},
"thread_id": {
"type": "string"
},
"message_id": {
"type": "string",
"description": "RFC Message-ID header."
},
"gmail_id": {
"type": "string"
},
"parent_id": {
"type": "string"
},
"uid": {
"type": "integer"
},
"mod_seq": {
"type": "integer"
},
"flags": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"from_addr": {
"type": "array",
"items": {
"type": "string"
}
},
"in_reply_to": {
"type": "array",
"items": {
"type": "string"
}
},
"reply_to": {
"type": "array",
"items": {
"type": "string"
}
},
"to_addr": {
"type": "array",
"items": {
"type": "string"
}
},
"subject": {
"type": "string"
},
"size": {
"type": "integer",
"description": "Raw message size in bytes."
},
"internal_date": {
"type": "string",
"format": "date-time"
},
"sent_date": {
"type": "string",
"format": "date-time"
},
"snippet": {
"type": "string"
},
"seen": {
"type": "boolean"
},
"body_plain": {
"type": "string"
},
"body_html": {
"type": "string"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"UniboxMessageList": {
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxMessage"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"UniboxEmail": {
"type": "object",
"description": "A single message fetched by id. Note the field names differ from the thread message shape (e.g. `from`/`to`/`date`).",
"required": [
"id",
"thread_id",
"subject"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"gmail_id": {
"type": "string"
},
"uid": {
"type": "integer"
},
"parent_id": {
"type": "string"
},
"thread_id": {
"type": "string"
},
"flags": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"date": {
"type": "string",
"format": "date-time",
"description": "Sent date."
},
"from": {
"type": "array",
"items": {
"type": "string"
}
},
"in_reply_to": {
"type": "array",
"items": {
"type": "string"
}
},
"message_id": {
"type": "string",
"description": "RFC Message-ID header."
},
"ReplyTo": {
"type": "array",
"items": {
"type": "string"
},
"description": "Reply-To addresses (serialized as `ReplyTo`)."
},
"to": {
"type": "array",
"items": {
"type": "string"
}
},
"subject": {
"type": "string"
},
"size": {
"type": "integer"
},
"internal_date": {
"type": "string",
"format": "date-time"
},
"mod_seq": {
"type": "integer"
},
"body_plain": {
"type": "string"
},
"body_html": {
"type": "string"
}
}
},
"UniboxCount": {
"type": "object",
"required": [
"count"
],
"properties": {
"count": {
"type": "integer",
"description": "Org-wide unread message count."
}
}
},
"UniboxOverviewMailbox": {
"type": "object",
"required": [
"id",
"email",
"unread",
"total"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string"
},
"name": {
"type": "string"
},
"unread": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"UniboxOverviewBucket": {
"type": "object",
"description": "A tag or conversation-label breakdown bucket.",
"required": [
"id",
"title",
"unread",
"total"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"color": {
"type": "string"
},
"unread": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"UniboxOverview": {
"type": "object",
"required": [
"total",
"unread",
"today",
"week",
"snoozed",
"awaiting_reply",
"scheduled_pending"
],
"properties": {
"total": {
"type": "integer"
},
"unread": {
"type": "integer"
},
"today": {
"type": "integer"
},
"week": {
"type": "integer"
},
"snoozed": {
"type": "integer"
},
"awaiting_reply": {
"type": "integer"
},
"scheduled_pending": {
"type": "integer"
},
"scheduled_pending_max": {
"type": "integer",
"description": "Max queued scheduled sends allowed."
},
"mailboxes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxOverviewMailbox"
}
},
"tags": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxOverviewBucket"
}
},
"categories": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxOverviewBucket"
}
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"window_today_start": {
"type": "string",
"format": "date-time"
},
"window_week_start": {
"type": "string",
"format": "date-time"
}
}
},
"UniboxLabelList": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxLabel"
}
}
}
},
"UniboxSetThreadLabelsRequest": {
"type": "object",
"required": [
"thread_id"
],
"properties": {
"thread_id": {
"type": "string",
"description": "The thread to label."
},
"category_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Full desired set of category UUIDs. An empty array clears all labels."
}
}
},
"UniboxMarkSeenRequest": {
"type": "object",
"description": "Also the echoed response body.",
"required": [
"email_ids"
],
"properties": {
"email_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"maxItems": 500,
"description": "Message UUIDs to update (max 500)."
},
"seen": {
"type": "boolean",
"description": "`true` marks as read, `false` marks as unread."
}
}
},
"UniboxReplyRequest": {
"type": "object",
"required": [
"email_account_id",
"to",
"subject"
],
"properties": {
"email_account_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the sending mailbox."
},
"to": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "Recipient addresses (at least one)."
},
"cc": {
"type": "array",
"items": {
"type": "string"
}
},
"bcc": {
"type": "array",
"items": {
"type": "string"
}
},
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"in_reply_to": {
"type": "array",
"items": {
"type": "string"
},
"description": "Message-ID(s) this reply threads under."
},
"thread_id": {
"type": "string"
},
"send_mode": {
"type": "string",
"enum": [
"instant",
"smart",
"scheduled"
],
"default": "instant",
"description": "`instant`, `smart` (next mailbox gap), or `scheduled`."
},
"scheduled_at": {
"type": "string",
"format": "date-time",
"description": "Required when `send_mode` is `scheduled`; must be in the future."
}
}
},
"UniboxReplyResult": {
"type": "object",
"required": [
"task_id",
"scheduled_at",
"send_mode"
],
"properties": {
"task_id": {
"type": "string",
"format": "uuid"
},
"scheduled_at": {
"type": "string",
"format": "date-time",
"description": "When the send is scheduled to fire."
},
"send_mode": {
"type": "string",
"enum": [
"instant",
"smart",
"scheduled"
]
}
}
},
"UniboxSnoozeRequest": {
"type": "object",
"required": [
"thread_id",
"snoozed_until"
],
"properties": {
"thread_id": {
"type": "string",
"description": "The thread to snooze."
},
"snoozed_until": {
"type": "string",
"format": "date-time",
"description": "RFC 3339 timestamp to un-hide the thread."
}
}
},
"UniboxSnooze": {
"type": "object",
"required": [
"id",
"user_id",
"thread_id",
"snoozed_until"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": "string",
"format": "uuid",
"description": "Snoozes are attached to the calling user."
},
"thread_id": {
"type": "string"
},
"snoozed_until": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"UniboxSnoozeList": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxSnooze"
}
}
}
},
"UniboxScheduledSend": {
"type": "object",
"description": "A preview of a queued, not-yet-sent outbound message.",
"required": [
"task_id",
"scheduled_at",
"account_id",
"subject"
],
"properties": {
"task_id": {
"type": "string",
"format": "uuid"
},
"scheduled_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"account_id": {
"type": "string",
"format": "uuid",
"description": "UUID of the sending mailbox."
},
"account_email": {
"type": "string"
},
"account_name": {
"type": "string"
},
"to": {
"type": "array",
"items": {
"type": "string"
}
},
"subject": {
"type": "string"
},
"snippet": {
"type": "string"
},
"thread_id": {
"type": "string"
}
}
},
"UniboxScheduledList": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UniboxScheduledSend"
}
}
}
},
"Pipeline": {
"type": "object",
"description": "A sales pipeline with its ordered stages.",
"required": [
"id",
"organization_id",
"name",
"position",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"position": {
"type": "integer"
},
"stages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PipelineStage"
}
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"PipelineStage": {
"type": "object",
"description": "A stage within a pipeline.",
"required": [
"id",
"pipeline_id",
"name",
"color",
"position",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"pipeline_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"color": {
"type": "string",
"description": "Hex color."
},
"position": {
"type": "integer"
},
"deal_count": {
"type": "integer",
"description": "Count of deals in this stage (populated by the pipeline list/get queries)."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"CreatePipeline": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "Pipeline name."
},
"stages": {
"type": "array",
"description": "Stages to create with the pipeline, in order.",
"items": {
"$ref": "#/components/schemas/CreatePipelineStage"
}
}
}
},
"CreatePipelineStage": {
"type": "object",
"required": [
"name",
"color"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "Stage name."
},
"color": {
"type": "string",
"description": "Stage color (hex)."
}
}
},
"UpdatePipeline": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "New pipeline name."
}
}
},
"UpdatePipelineStage": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "New stage name."
},
"color": {
"type": "string",
"description": "New stage color (hex)."
}
}
},
"DealList": {
"type": "object",
"description": "Keyset-paginated page of deals.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Deal"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"CreateDeal": {
"type": "object",
"required": [
"pipeline_id",
"stage_id",
"name"
],
"properties": {
"pipeline_id": {
"type": "string",
"format": "uuid",
"description": "Pipeline the deal belongs to."
},
"stage_id": {
"type": "string",
"format": "uuid",
"description": "Initial stage."
},
"contact_id": {
"type": "string",
"format": "uuid",
"description": "Linked contact."
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "Deal name."
},
"value": {
"type": "number",
"description": "Monetary value."
},
"currency": {
"type": "string",
"description": "ISO currency code."
},
"expected_close_date": {
"type": "string",
"format": "date-time",
"description": "Expected close date."
},
"assigned_to": {
"type": "string",
"format": "uuid",
"description": "Owner (org member user ID)."
},
"campaign_id": {
"type": "string",
"format": "uuid",
"description": "Attributed campaign."
},
"source_mailbox_id": {
"type": "string",
"format": "uuid",
"description": "Sending mailbox that produced the originating reply."
}
}
},
"UpdateDeal": {
"type": "object",
"description": "All fields optional. Moving stage_id records a stage-change activity; setting status to won/lost stamps the close timestamp.",
"properties": {
"stage_id": {
"type": "string",
"format": "uuid",
"description": "Move the deal to this stage."
},
"contact_id": {
"type": "string",
"format": "uuid",
"description": "Linked contact."
},
"name": {
"type": "string",
"description": "Deal name."
},
"value": {
"type": "number",
"description": "Monetary value."
},
"currency": {
"type": "string",
"description": "ISO currency code."
},
"status": {
"type": "string",
"enum": [
"open",
"won",
"lost"
]
},
"expected_close_date": {
"type": "string",
"format": "date-time"
},
"lost_reason": {
"type": "string",
"description": "Reason recorded when marking lost."
},
"assigned_to": {
"type": "string",
"format": "uuid",
"description": "Owner (org member user ID)."
}
}
},
"SearchDeals": {
"type": "object",
"description": "Faceted deal filter body shared by deal search and deal summary. All facets optional; an empty body matches every deal.",
"properties": {
"query": {
"type": "string",
"description": "Case-insensitive match on deal name."
},
"statuses": {
"type": "array",
"items": {
"type": "string",
"enum": [
"open",
"won",
"lost"
]
}
},
"pipeline_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"stage_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"assigned_to": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Owner is any of these user IDs."
},
"campaign_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
},
"min_value": {
"type": "number",
"description": "Value greater than or equal to."
},
"max_value": {
"type": "number",
"description": "Value less than or equal to."
},
"close_after": {
"type": "string",
"format": "date-time",
"description": "Expected close date on or after."
},
"close_before": {
"type": "string",
"format": "date-time",
"description": "Expected close date on or before."
},
"created_after": {
"type": "string",
"format": "date-time"
},
"created_before": {
"type": "string",
"format": "date-time"
},
"sort_by": {
"type": "string",
"enum": [
"created_at",
"updated_at",
"value",
"expected_close_date",
"name"
]
},
"reverse": {
"type": "boolean",
"description": "true sorts ascending, false (default) descending."
}
}
},
"DealsSearchResult": {
"type": "object",
"description": "Offset-paginated deal search result with an exact total.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Deal"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"DealsSummary": {
"type": "object",
"description": "Aggregate counts and value sums over a deal search filter body. mixed_currency true means top-level value sums should be treated as approximate.",
"required": [
"total",
"open_count",
"open_value",
"won_count",
"won_value",
"lost_count",
"lost_value",
"currency",
"stages",
"mixed_currency"
],
"properties": {
"total": {
"type": "integer",
"format": "int64"
},
"open_count": {
"type": "integer",
"format": "int64"
},
"open_value": {
"type": "number"
},
"won_count": {
"type": "integer",
"format": "int64"
},
"won_value": {
"type": "number"
},
"lost_count": {
"type": "integer",
"format": "int64"
},
"lost_value": {
"type": "number"
},
"currency": {
"type": "string"
},
"stages": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DealStageSummary"
}
},
"mixed_currency": {
"type": "boolean"
}
}
},
"DealStageSummary": {
"type": "object",
"required": [
"stage_id",
"count",
"value"
],
"properties": {
"stage_id": {
"type": "string",
"format": "uuid"
},
"count": {
"type": "integer",
"format": "int64"
},
"value": {
"type": "number",
"description": "Open-deal value in this stage."
}
}
},
"CRMTaskType": {
"type": "object",
"description": "A user-managed CRM task type (the kind of work a task represents).",
"required": [
"id",
"organization_id",
"name",
"color",
"position",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"color": {
"type": "string",
"description": "Hex color."
},
"position": {
"type": "integer"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"CRMTaskTypeList": {
"type": "object",
"description": "Task types (no pagination envelope).",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CRMTaskType"
}
}
}
},
"CreateCRMTaskType": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Type name."
},
"color": {
"type": "string",
"description": "Type color (hex)."
}
}
},
"UpdateCRMTaskType": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "New type name."
},
"color": {
"type": "string",
"description": "New type color (hex)."
},
"position": {
"type": "integer",
"description": "New ordering position."
}
}
},
"CRMTask": {
"type": "object",
"description": "A CRM task (follow-up work attached to contacts and deals).",
"required": [
"id",
"organization_id",
"created_by",
"title",
"priority",
"type",
"status",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"contact_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"deal_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"assigned_to": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Assignee user ID."
},
"assigned_team_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Assignee team ID."
},
"created_by": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"description": {
"type": [
"string",
"null"
]
},
"due_date": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"priority": {
"type": "string",
"enum": [
"low",
"medium",
"high",
"urgent"
]
},
"type": {
"type": "string",
"description": "Task type name."
},
"status": {
"type": "string",
"enum": [
"pending",
"in_progress",
"completed",
"cancelled"
]
},
"completed_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"CRMTaskList": {
"type": "object",
"description": "Keyset-paginated page of CRM tasks.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CRMTask"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"CreateCRMTask": {
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"description": "Task title."
},
"contact_id": {
"type": "string",
"format": "uuid",
"description": "Linked contact."
},
"deal_id": {
"type": "string",
"format": "uuid",
"description": "Linked deal."
},
"assigned_to": {
"type": "string",
"format": "uuid",
"description": "Assignee user ID."
},
"assigned_team_id": {
"type": "string",
"format": "uuid",
"description": "Assignee team ID."
},
"description": {
"type": "string",
"description": "Free-text description."
},
"due_date": {
"type": "string",
"format": "date-time",
"description": "Due date."
},
"priority": {
"type": "string",
"enum": [
"low",
"medium",
"high",
"urgent"
]
},
"type": {
"type": "string",
"description": "Task type name (matches a configured task type)."
}
}
},
"UpdateCRMTask": {
"type": "object",
"description": "All fields optional. Setting status to completed stamps the completion timestamp.",
"properties": {
"title": {
"type": "string",
"description": "Task title."
},
"assigned_to": {
"type": "string",
"format": "uuid",
"description": "Assignee user ID."
},
"assigned_team_id": {
"type": "string",
"format": "uuid",
"description": "Assignee team ID."
},
"description": {
"type": "string",
"description": "Free-text description."
},
"due_date": {
"type": "string",
"format": "date-time",
"description": "Due date."
},
"priority": {
"type": "string",
"enum": [
"low",
"medium",
"high",
"urgent"
]
},
"type": {
"type": "string",
"description": "Task type name."
},
"status": {
"type": "string",
"enum": [
"pending",
"in_progress",
"completed",
"cancelled"
]
}
}
},
"SearchTasks": {
"type": "object",
"description": "Faceted task filter body shared by task search and task summary. All facets optional; an empty body matches every task.",
"properties": {
"query": {
"type": "string",
"description": "Case-insensitive match on task title."
},
"statuses": {
"type": "array",
"items": {
"type": "string",
"enum": [
"pending",
"in_progress",
"completed",
"cancelled"
]
}
},
"priorities": {
"type": "array",
"items": {
"type": "string",
"enum": [
"low",
"medium",
"high",
"urgent"
]
}
},
"types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Task type name is any of these."
},
"assigned_to": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Assignee user ID is any of these."
},
"team_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Task team is any of these, or the assignee belongs to one."
},
"contact_id": {
"type": "string",
"format": "uuid",
"description": "Linked contact."
},
"deal_id": {
"type": "string",
"format": "uuid",
"description": "Linked deal."
},
"due_after": {
"type": "string",
"format": "date-time",
"description": "Due on or after."
},
"due_before": {
"type": "string",
"format": "date-time",
"description": "Due on or before."
},
"overdue": {
"type": "boolean",
"description": "Only tasks past due and not completed or cancelled."
},
"sort_by": {
"type": "string",
"enum": [
"created_at",
"due_date",
"priority",
"title",
"updated_at"
]
},
"reverse": {
"type": "boolean",
"description": "true sorts ascending, false (default) descending."
}
}
},
"TasksSearchResult": {
"type": "object",
"description": "Offset-paginated task search result with an exact total.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CRMTask"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"TasksSummary": {
"type": "object",
"description": "Aggregate task counts over a task search filter body.",
"required": [
"total",
"pending_count",
"in_progress_count",
"completed_count",
"cancelled_count",
"overdue_count",
"high_priority_count"
],
"properties": {
"total": {
"type": "integer",
"format": "int64"
},
"pending_count": {
"type": "integer",
"format": "int64"
},
"in_progress_count": {
"type": "integer",
"format": "int64"
},
"completed_count": {
"type": "integer",
"format": "int64"
},
"cancelled_count": {
"type": "integer",
"format": "int64"
},
"overdue_count": {
"type": "integer",
"format": "int64"
},
"high_priority_count": {
"type": "integer",
"format": "int64"
}
}
},
"APIKey": {
"type": "object",
"description": "An API key without its plaintext secret.",
"required": [
"id",
"user_id",
"organization_id",
"name",
"key_prefix",
"key_suffix",
"permissions",
"rate_limit_per_minute",
"status",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": "string",
"format": "uuid",
"description": "The member who created the key."
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"description": "Human-readable label."
},
"description": {
"type": "string",
"description": "Free-form note about the key's purpose."
},
"key_prefix": {
"type": "string",
"description": "Short display prefix of the secret (e.g. wmbly_3f)."
},
"key_suffix": {
"type": "string",
"description": "Short display suffix of the secret."
},
"permissions": {
"type": "integer",
"format": "int64",
"description": "uint64 permission bitmask. Combine bits with bitwise OR; the key may perform a request only when its mask contains every required bit. See GET /api-keys/permissions for bit names and values."
},
"allowed_ips": {
"type": "array",
"items": {
"type": "string"
},
"description": "If non-empty, the key is usable only from these source IPs."
},
"allowed_email_accounts": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "If non-empty, mailbox-scoped routes accept only these email account ids."
},
"rate_limit_per_minute": {
"type": "integer",
"description": "Per-key sliding-window request cap. 0 means the default (60 r/m)."
},
"status": {
"$ref": "#/components/schemas/APIKeyStatus"
},
"last_used_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_request_ip": {
"type": [
"string",
"null"
]
},
"expires_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the key stops working. Null for a non-expiring key."
},
"revoked_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"revoked_reason": {
"type": [
"string",
"null"
]
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"APIKeyStatus": {
"type": "string",
"enum": [
"active",
"revoked",
"expired"
],
"description": "Lifecycle status of the key."
},
"APIKeyWithSecret": {
"type": "object",
"description": "An API key plus the one-time plaintext secret, returned only on creation.",
"allOf": [
{
"$ref": "#/components/schemas/APIKey"
},
{
"type": "object",
"required": [
"secret"
],
"properties": {
"secret": {
"type": "string",
"description": "The full plaintext key. Returned only once, at creation; it cannot be recovered later."
}
}
}
]
},
"APIKeyList": {
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIKey"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"CreateAPIKey": {
"type": "object",
"required": [
"name",
"permissions"
],
"properties": {
"name": {
"type": "string",
"maxLength": 255,
"description": "Human-readable label."
},
"description": {
"type": "string",
"description": "Free-form note about the key's purpose."
},
"permissions": {
"type": "integer",
"format": "int64",
"description": "uint64 permission bitmask. Must contain only defined bits; unknown bits are rejected."
},
"allowed_ips": {
"type": "array",
"items": {
"type": "string"
},
"description": "If set, the key is usable only from these source IPs. Omit or leave empty to allow any IP."
},
"allowed_email_accounts": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "If set, mailbox-scoped routes accept only these email account ids."
},
"rate_limit_per_minute": {
"type": "integer",
"description": "Per-key request cap. Omit or send 0 to use the default (60 r/m)."
},
"expires_at": {
"type": "string",
"format": "date-time",
"description": "When the key should stop working (RFC3339). Omit for a non-expiring key."
}
}
},
"UpdateAPIKey": {
"type": "object",
"description": "Every field is optional; only the fields you send are changed.",
"properties": {
"name": {
"type": "string",
"description": "New label."
},
"description": {
"type": "string",
"description": "New description."
},
"permissions": {
"type": "integer",
"format": "int64",
"description": "Replacement uint64 permission bitmask."
},
"allowed_ips": {
"type": "array",
"items": {
"type": "string"
},
"description": "Replacement IP allowlist."
},
"allowed_email_accounts": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Replacement mailbox allowlist."
},
"rate_limit_per_minute": {
"type": "integer",
"description": "New per-key rate cap. 0 means use the default."
}
}
},
"APIKeyRevokeResult": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"type": "string",
"enum": [
"revoked"
]
}
}
},
"APIPermission": {
"type": "object",
"required": [
"name",
"value",
"description",
"category"
],
"properties": {
"name": {
"type": "string",
"description": "Bit name, e.g. READ_EMAILS."
},
"value": {
"type": "integer",
"format": "int64",
"description": "Numeric bit value."
},
"description": {
"type": "string"
},
"category": {
"type": "string",
"enum": [
"read",
"write",
"bulk",
"special"
]
}
}
},
"APIPermissionCatalog": {
"type": "object",
"required": [
"permissions",
"presets"
],
"properties": {
"permissions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIPermission"
}
},
"presets": {
"type": "object",
"required": [
"read_only",
"full_access"
],
"properties": {
"read_only": {
"type": "integer",
"format": "int64",
"description": "Bitmask granting all read scopes."
},
"full_access": {
"type": "integer",
"format": "int64",
"description": "Bitmask granting every scope."
}
}
}
}
},
"APIKeyUsageSummary": {
"type": "object",
"description": "Org-level usage strip. The 24h fields cover the last 24 hours.",
"required": [
"active_keys",
"revoked_keys",
"expired_keys",
"requests_24h",
"errors_24h",
"avg_latency_ms_24h"
],
"properties": {
"active_keys": {
"type": "integer"
},
"revoked_keys": {
"type": "integer"
},
"expired_keys": {
"type": "integer"
},
"requests_24h": {
"type": "integer",
"format": "int64"
},
"errors_24h": {
"type": "integer",
"format": "int64"
},
"avg_latency_ms_24h": {
"type": "number"
},
"last_call_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"APIKeyUsageBucket": {
"type": "object",
"description": "One point on a time-bucketed request graph.",
"required": [
"bucket",
"total",
"success",
"client_errors",
"server_errors",
"avg_latency_ms"
],
"properties": {
"bucket": {
"type": "string",
"format": "date-time"
},
"total": {
"type": "integer",
"format": "int64"
},
"success": {
"type": "integer",
"format": "int64",
"description": "2xx responses."
},
"client_errors": {
"type": "integer",
"format": "int64",
"description": "4xx responses."
},
"server_errors": {
"type": "integer",
"format": "int64",
"description": "5xx responses."
},
"avg_latency_ms": {
"type": "number"
}
}
},
"APIKeyEndpointStat": {
"type": "object",
"description": "One row in the per-endpoint breakdown.",
"required": [
"endpoint",
"method",
"count",
"error_count",
"avg_latency_ms"
],
"properties": {
"endpoint": {
"type": "string"
},
"method": {
"type": "string"
},
"count": {
"type": "integer",
"format": "int64"
},
"error_count": {
"type": "integer",
"format": "int64"
},
"avg_latency_ms": {
"type": "number"
}
}
},
"APIKeyAnalytics": {
"type": "object",
"required": [
"api_key_id",
"from",
"to",
"interval",
"buckets",
"endpoints",
"total",
"errors"
],
"properties": {
"api_key_id": {
"type": "string",
"format": "uuid",
"description": "The key id, or the all-zero UUID for the org-wide aggregate."
},
"from": {
"type": "string",
"format": "date-time"
},
"to": {
"type": "string",
"format": "date-time"
},
"interval": {
"type": "string",
"enum": [
"minute",
"hour",
"day"
]
},
"buckets": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIKeyUsageBucket"
}
},
"endpoints": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIKeyEndpointStat"
}
},
"total": {
"type": "integer",
"format": "int64"
},
"errors": {
"type": "integer",
"format": "int64"
}
}
},
"APIKeyUsageLog": {
"type": "object",
"description": "One recorded request made with the key.",
"required": [
"id",
"api_key_id",
"endpoint",
"method",
"ip_address",
"user_agent",
"response_code",
"response_time_ms",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"api_key_id": {
"type": "string",
"format": "uuid"
},
"endpoint": {
"type": "string"
},
"method": {
"type": "string"
},
"ip_address": {
"type": "string"
},
"user_agent": {
"type": "string"
},
"response_code": {
"type": "integer"
},
"response_time_ms": {
"type": "integer"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"APIKeyUsageLogList": {
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIKeyUsageLog"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"WebhookEventType": {
"type": "string",
"description": "Canonical event name carried in the subscription filter and the delivery payload. An endpoint with an empty `event_types` filter receives all of these.",
"enum": [
"email_account.connected",
"email_account.removed",
"campaign.email_sent",
"campaign.email_delivered",
"campaign.email_opened",
"campaign.email_clicked",
"campaign.email_bounced",
"campaign.reply_received",
"campaign.unsubscribed",
"campaign.started",
"campaign.paused",
"campaign.completed",
"campaign.deliverability_warning",
"campaign.action",
"warmup.email_sent",
"warmup.health_changed",
"warmup.placement_in_spam",
"warmup.quarantined",
"warmup.blocked",
"deliverability.bounce",
"deliverability.complaint",
"meeting.booked",
"meeting.rescheduled",
"meeting.canceled"
]
},
"WebhookEndpoint": {
"type": "object",
"description": "A customer's subscription to events. Returned without the signing secret on all reads and updates.",
"required": [
"id",
"organization_id",
"url",
"description",
"event_types",
"enabled",
"consecutive_failures",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"url": {
"type": "string",
"format": "uri",
"description": "HTTPS URL that receives POST callbacks."
},
"description": {
"type": "string",
"description": "Free-text label for your own reference."
},
"event_types": {
"type": "array",
"description": "Subscribed event names. An empty array means all events.",
"items": {
"$ref": "#/components/schemas/WebhookEventType"
}
},
"enabled": {
"type": "boolean",
"description": "Whether the endpoint is active."
},
"last_success_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Time of the last successful delivery, or null."
},
"last_failure_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "Time of the last failed delivery, or null."
},
"last_failure_reason": {
"type": [
"string",
"null"
],
"description": "Reason for the last failure, or null."
},
"consecutive_failures": {
"type": "integer",
"description": "Current run of consecutive delivery failures."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"WebhookEndpointWithSecret": {
"allOf": [
{
"$ref": "#/components/schemas/WebhookEndpoint"
},
{
"type": "object",
"required": [
"secret"
],
"properties": {
"secret": {
"type": "string",
"description": "The `whsec_`-prefixed HMAC signing secret. Returned only at create and rotate time."
}
}
}
]
},
"WebhookEndpointRequest": {
"type": "object",
"description": "Create/update body. The same body shape is used for both; on update all fields are replaced with the values sent (send the complete desired state). The secret is server-generated and cannot be set here.",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "HTTPS URL that will receive POST callbacks. Must be publicly routable."
},
"description": {
"type": "string",
"description": "Free-text label for your own reference."
},
"event_types": {
"type": "array",
"description": "Event names to subscribe to. Each must be a known type. An empty or omitted array subscribes to all events. On update this overwrites the existing filter (not merged).",
"items": {
"$ref": "#/components/schemas/WebhookEventType"
}
},
"enabled": {
"type": "boolean",
"default": true,
"description": "Whether the endpoint is active. Defaults to true."
}
}
},
"WebhookEndpointList": {
"type": "object",
"description": "List response. Not a `data` + `pagination` cursor envelope: it returns the configured endpoints plus the full event vocabulary.",
"required": [
"endpoints",
"event_types"
],
"properties": {
"endpoints": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
},
"event_types": {
"type": "array",
"description": "Every event Warmbly can emit, for building a picker.",
"items": {
"$ref": "#/components/schemas/WebhookEventType"
}
}
}
},
"WebhookSecretResponse": {
"type": "object",
"required": [
"secret"
],
"properties": {
"secret": {
"type": "string",
"description": "The new `whsec_`-prefixed HMAC signing secret. Returned only once."
}
}
},
"WebhookDeliveryStatus": {
"type": "string",
"description": "Lifecycle state of a delivery attempt. `abandoned` means retries were exhausted.",
"enum": [
"pending",
"in_flight",
"delivered",
"failed",
"abandoned"
]
},
"WebhookDelivery": {
"type": "object",
"description": "One delivery-history record. The row updates in place across retries; `attempt_count` and `status` reflect the latest state.",
"required": [
"id",
"endpoint_id",
"organization_id",
"event_type",
"event_id",
"payload",
"status",
"attempt_count",
"max_attempts",
"next_attempt_at",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"endpoint_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"event_type": {
"$ref": "#/components/schemas/WebhookEventType"
},
"event_id": {
"type": "string",
"format": "uuid",
"description": "Stable across retries. Matches the `X-Warmbly-Event-Id` header and the payload `id`."
},
"payload": {
"$ref": "#/components/schemas/WebhookPayload"
},
"status": {
"$ref": "#/components/schemas/WebhookDeliveryStatus"
},
"attempt_count": {
"type": "integer",
"description": "Number of delivery attempts made so far."
},
"max_attempts": {
"type": "integer",
"description": "Maximum attempts before the delivery is abandoned (default 8)."
},
"next_attempt_at": {
"type": "string",
"format": "date-time",
"description": "Scheduled time of the next retry."
},
"last_attempt_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"response_status": {
"type": [
"integer",
"null"
],
"description": "HTTP status returned by the subscriber on the last attempt, or null."
},
"response_body_excerpt": {
"type": [
"string",
"null"
],
"description": "First 1024 bytes of the subscriber's response, or null."
},
"error_reason": {
"type": [
"string",
"null"
],
"description": "Connection or timeout error from the last attempt, or null."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"WebhookDeliveryList": {
"type": "object",
"description": "Delivery list response, newest first. Not a `data` + `pagination` cursor envelope; bounded by the `limit` query param.",
"required": [
"deliveries"
],
"properties": {
"deliveries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookDelivery"
}
}
}
},
"WebhookPayload": {
"type": "object",
"description": "The JSON body POSTed to a subscriber endpoint. Signed with HMAC-SHA256: the `X-Warmbly-Signature` header is `t=<unix>,v1=<hex>`, where `v1 = hex(hmac_sha256(secret, \"<t>.\" + rawBody))`. Other headers: `X-Warmbly-Event` (event type), `X-Warmbly-Event-Id` (the event id for dedupe), `User-Agent: Warmbly-Webhooks/1.0`.",
"required": [
"id",
"event_type",
"organization_id",
"created_at",
"data"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique event id, stable across retries. Matches `X-Warmbly-Event-Id`."
},
"event_type": {
"$ref": "#/components/schemas/WebhookEventType"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "RFC 3339 UTC timestamp of when the event was dispatched."
},
"data": {
"type": "object",
"additionalProperties": true,
"description": "Event-specific payload. Shape depends on `event_type`."
}
}
},
"DashboardAnalytics": {
"type": "object",
"description": "Org-wide dashboard overview.",
"required": [
"period",
"overall_stats",
"recent_activity",
"top_campaigns",
"account_health",
"daily_trend"
],
"properties": {
"period": {
"type": "string",
"enum": [
"7d",
"30d",
"90d"
]
},
"overall_stats": {
"$ref": "#/components/schemas/OverallStats"
},
"recent_activity": {
"type": "array",
"items": {
"$ref": "#/components/schemas/RecentActivity"
}
},
"top_campaigns": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TopCampaign"
}
},
"account_health": {
"$ref": "#/components/schemas/AccountHealthSummary"
},
"daily_trend": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DailyTrendPoint"
}
}
}
},
"OverallStats": {
"type": "object",
"properties": {
"total_emails_sent": {
"type": "integer"
},
"total_opens": {
"type": "integer"
},
"machine_opens": {
"type": "integer"
},
"total_clicks": {
"type": "integer"
},
"total_replies": {
"type": "integer"
},
"total_bounces": {
"type": "integer"
},
"open_rate": {
"type": "number"
},
"click_rate": {
"type": "number"
},
"reply_rate": {
"type": "number"
},
"bounce_rate": {
"type": "number"
},
"active_campaigns": {
"type": "integer"
},
"active_accounts": {
"type": "integer"
}
}
},
"RecentActivity": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Activity type, for example replied, opened, clicked."
},
"campaign_id": {
"type": "string",
"format": "uuid"
},
"campaign_name": {
"type": "string"
},
"contact_email": {
"type": "string"
},
"contact_id": {
"type": "string",
"format": "uuid"
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
},
"TopCampaign": {
"type": "object",
"properties": {
"campaign_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"emails_sent": {
"type": "integer"
},
"open_rate": {
"type": "number"
},
"click_rate": {
"type": "number"
},
"reply_rate": {
"type": "number"
}
}
},
"AccountHealthSummary": {
"type": "object",
"properties": {
"total_accounts": {
"type": "integer"
},
"healthy_accounts": {
"type": "integer"
},
"warning_accounts": {
"type": "integer"
},
"error_accounts": {
"type": "integer"
}
}
},
"DailyTrendPoint": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date"
},
"sent": {
"type": "integer"
},
"opens": {
"type": "integer"
},
"clicks": {
"type": "integer"
},
"replies": {
"type": "integer"
}
}
},
"DeliverabilityDashboard": {
"type": "object",
"description": "Deliverability posture over a window. spam_placement_rate and inbox_placement_rate are omitted when there are no seed samples.",
"required": [
"from",
"to",
"band"
],
"properties": {
"from": {
"type": "string",
"format": "date-time"
},
"to": {
"type": "string",
"format": "date-time"
},
"events_total": {
"type": "integer"
},
"bounce_count": {
"type": "integer"
},
"complaint_count": {
"type": "integer"
},
"unsubscribe_count": {
"type": "integer"
},
"reply_count": {
"type": "integer"
},
"open_count": {
"type": "integer"
},
"click_count": {
"type": "integer"
},
"suppressed_recipients": {
"type": "integer"
},
"dlq_pending": {
"type": "integer"
},
"intent_positive": {
"type": "integer"
},
"intent_negative": {
"type": "integer"
},
"intent_out_of_office": {
"type": "integer"
},
"intent_question": {
"type": "integer"
},
"intent_neutral": {
"type": "integer"
},
"emails_sent": {
"type": "integer"
},
"bounce_rate": {
"type": "number"
},
"complaint_rate": {
"type": "number"
},
"open_rate": {
"type": "number"
},
"click_rate": {
"type": "number"
},
"reply_rate": {
"type": "number"
},
"spam_placement_rate": {
"type": "number",
"description": "Omitted when there are no seed samples in the window."
},
"inbox_placement_rate": {
"type": "number",
"description": "Omitted when there are no seed samples in the window."
},
"placement_samples": {
"type": "integer"
},
"band": {
"type": "string",
"description": "Overall health band.",
"enum": [
"healthy",
"watch",
"throttled",
"quarantined",
"blocked"
]
},
"timeseries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DeliverabilityDayPoint"
}
},
"by_mailbox": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DeliverabilityMailbox"
}
},
"by_campaign": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DeliverabilityCampaign"
}
}
}
},
"DeliverabilityDayPoint": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date"
},
"sent": {
"type": "integer"
},
"bounces": {
"type": "integer"
},
"complaints": {
"type": "integer"
},
"opens": {
"type": "integer"
},
"clicks": {
"type": "integer"
},
"replies": {
"type": "integer"
},
"unsubscribes": {
"type": "integer"
}
}
},
"DeliverabilityMailbox": {
"type": "object",
"properties": {
"email_account_id": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string"
},
"sent": {
"type": "integer"
},
"bounces": {
"type": "integer"
},
"complaints": {
"type": "integer"
},
"bounce_rate": {
"type": "number"
},
"complaint_rate": {
"type": "number"
},
"band": {
"type": "string"
}
}
},
"DeliverabilityCampaign": {
"type": "object",
"properties": {
"campaign_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"sent": {
"type": "integer"
},
"bounces": {
"type": "integer"
},
"complaints": {
"type": "integer"
},
"bounce_rate": {
"type": "number"
},
"complaint_rate": {
"type": "number"
},
"band": {
"type": "string"
}
}
},
"WarmupAnalytics": {
"type": "object",
"description": "Warmup send and reply statistics over a date range. email_account_id is the zero UUID when no email_id filter is supplied.",
"required": [
"email_account_id",
"date_range",
"summary",
"daily_stats"
],
"properties": {
"email_account_id": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string"
},
"date_range": {
"$ref": "#/components/schemas/DateRange"
},
"summary": {
"$ref": "#/components/schemas/WarmupSummary"
},
"daily_stats": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WarmupDayPoint"
}
}
}
},
"WarmupSummary": {
"type": "object",
"properties": {
"total_sent": {
"type": "integer"
},
"total_replied": {
"type": "integer"
},
"average_daily": {
"type": "number"
},
"reply_rate": {
"type": "number"
},
"target_progress": {
"type": "number"
},
"days_active": {
"type": "integer"
}
}
},
"WarmupDayPoint": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date"
},
"emails_sent": {
"type": "integer"
},
"emails_replied": {
"type": "integer"
},
"target_volume": {
"type": "integer"
}
}
},
"DateRange": {
"type": "object",
"properties": {
"from": {
"type": "string",
"format": "date-time"
},
"to": {
"type": "string",
"format": "date-time"
}
}
},
"CampaignAnalytics": {
"type": "object",
"description": "A single campaign's performance summary plus per-step stats.",
"required": [
"campaign_id",
"name",
"status",
"summary",
"steps"
],
"properties": {
"campaign_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"date_range": {
"$ref": "#/components/schemas/DateRange"
},
"summary": {
"$ref": "#/components/schemas/CampaignAnalyticsSummary"
},
"steps": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignStepStats"
}
}
}
},
"CampaignAnalyticsSummary": {
"type": "object",
"description": "machine_opens is the subset of unique_opens from automated fetchers; human opens are unique_opens minus machine_opens.",
"properties": {
"total_contacts": {
"type": "integer"
},
"emails_sent": {
"type": "integer"
},
"emails_pending": {
"type": "integer"
},
"unique_opens": {
"type": "integer"
},
"machine_opens": {
"type": "integer"
},
"unique_clicks": {
"type": "integer"
},
"replies": {
"type": "integer"
},
"bounces": {
"type": "integer"
},
"unsubscribes": {
"type": "integer"
},
"open_rate": {
"type": "number"
},
"click_rate": {
"type": "number"
},
"reply_rate": {
"type": "number"
},
"bounce_rate": {
"type": "number"
}
}
},
"CampaignStepStats": {
"type": "object",
"properties": {
"step_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"position": {
"type": "integer"
},
"emails_sent": {
"type": "integer"
},
"opens": {
"type": "integer"
},
"clicks": {
"type": "integer"
},
"replies": {
"type": "integer"
},
"bounces": {
"type": "integer"
}
}
},
"CampaignDailyStats": {
"type": "object",
"description": "Per-day campaign series under a data envelope.",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignDayPoint"
}
}
}
},
"CampaignDayPoint": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date"
},
"sent": {
"type": "integer"
},
"opens": {
"type": "integer"
},
"clicks": {
"type": "integer"
},
"replies": {
"type": "integer"
}
}
},
"CampaignHourlyStats": {
"type": "object",
"description": "Per-hour campaign series under a data envelope with the resolved date echoed back.",
"required": [
"data",
"date"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignHourPoint"
}
},
"date": {
"type": "string",
"format": "date"
}
}
},
"CampaignHourPoint": {
"type": "object",
"properties": {
"hour": {
"type": "integer",
"minimum": 0,
"maximum": 23
},
"sent": {
"type": "integer"
},
"opens": {
"type": "integer"
},
"clicks": {
"type": "integer"
},
"replies": {
"type": "integer"
}
}
},
"CampaignComparison": {
"type": "object",
"description": "Side-by-side performance for up to 10 campaigns over a date range.",
"required": [
"campaigns",
"period"
],
"properties": {
"campaigns": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CampaignComparisonItem"
}
},
"period": {
"$ref": "#/components/schemas/DateRange"
}
}
},
"CampaignComparisonItem": {
"type": "object",
"properties": {
"campaign_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"emails_sent": {
"type": "integer"
},
"open_rate": {
"type": "number"
},
"click_rate": {
"type": "number"
},
"reply_rate": {
"type": "number"
},
"bounce_rate": {
"type": "number"
}
}
},
"AccountStatus": {
"type": "object",
"description": "Summary health and usage status of an email account.",
"required": [
"id",
"email",
"provider",
"status",
"health",
"daily_usage"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string"
},
"provider": {
"type": "string"
},
"status": {
"type": "string"
},
"last_synced_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"health": {
"$ref": "#/components/schemas/AccountHealth"
},
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AccountError"
}
},
"daily_usage": {
"$ref": "#/components/schemas/AccountDailyUsage"
},
"in_campaign": {
"type": "boolean"
}
}
},
"AccountStatusDetail": {
"allOf": [
{
"$ref": "#/components/schemas/AccountStatus"
},
{
"type": "object",
"description": "warmup_status is present only when warmup has ever been enabled; warmup_health is present only when the mailbox is in a warmup pool.",
"properties": {
"warmup_status": {
"$ref": "#/components/schemas/WarmupStatus"
},
"warmup_health": {
"$ref": "#/components/schemas/WarmupHealth"
}
}
}
]
},
"AccountHealth": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "For example healthy, warning, error."
},
"score": {
"type": "integer"
},
"issues": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"AccountError": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"error_code": {
"type": "string"
},
"severity": {
"type": "string"
},
"title": {
"type": "string"
},
"message": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"AccountDailyUsage": {
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date"
},
"campaign_sent": {
"type": "integer"
},
"campaign_limit": {
"type": "integer"
},
"warmup_sent": {
"type": "integer"
},
"warmup_limit": {
"type": "integer"
}
}
},
"WarmupStatus": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"paused": {
"type": "boolean"
},
"started_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"current_volume": {
"type": "integer"
},
"target_volume": {
"type": "integer"
},
"max_volume": {
"type": "integer"
},
"reply_rate": {
"type": "number"
},
"days_active": {
"type": "integer"
}
}
},
"WarmupHealth": {
"type": "object",
"properties": {
"state": {
"type": "string",
"enum": [
"healthy",
"watch",
"throttled",
"quarantined",
"blocked"
]
},
"score": {
"type": "integer"
},
"spam_score": {
"type": "integer"
},
"evaluated_at": {
"type": "string",
"format": "date-time"
}
}
},
"AccountStatusList": {
"type": "object",
"description": "All of the caller's account statuses under a data envelope (no cursor).",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AccountStatus"
}
}
}
},
"UsageOverview": {
"type": "object",
"description": "Account, campaign, contact, and API usage counters for the caller.",
"required": [
"period"
],
"properties": {
"user_id": {
"type": "string",
"format": "uuid"
},
"period": {
"type": "string",
"enum": [
"day",
"week",
"month"
]
},
"email_accounts": {
"type": "object",
"properties": {
"total": {
"type": "integer"
},
"active": {
"type": "integer"
},
"in_warmup": {
"type": "integer"
},
"with_errors": {
"type": "integer"
}
}
},
"campaigns": {
"type": "object",
"properties": {
"total": {
"type": "integer"
},
"active": {
"type": "integer"
},
"paused": {
"type": "integer"
},
"draft": {
"type": "integer"
},
"emails_sent": {
"type": "integer"
}
}
},
"contacts": {
"type": "object",
"properties": {
"total": {
"type": "integer"
},
"subscribed": {
"type": "integer"
},
"added_today": {
"type": "integer"
}
}
},
"api": {
"type": "object",
"properties": {
"total_calls": {
"type": "integer"
},
"daily_limit": {
"type": "integer"
},
"top_endpoints": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
},
"AuditLog": {
"type": "object",
"description": "One organization audit-trail entry. actor is null when the acting user has since been deleted; entity_id, changes, and metadata are omitted when empty.",
"required": [
"id",
"org_id",
"action",
"entity_type",
"action_date"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"org_id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"actor": {
"$ref": "#/components/schemas/AuditActor"
},
"action_date": {
"type": "string",
"format": "date-time"
},
"action": {
"type": "string"
},
"entity_type": {
"type": "string"
},
"entity_id": {
"type": "string",
"format": "uuid"
},
"ip_address": {
"type": "string"
},
"user_agent": {
"type": "string"
},
"changes": {
"type": "object",
"additionalProperties": true,
"description": "Field-level change set; secret values are never recorded."
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
},
"AuditActor": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"email": {
"type": "string"
}
}
},
"AuditLogList": {
"type": "object",
"description": "A page of audit logs with an opaque cursor.",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AuditLog"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
},
"IntegrationCatalogEntry": {
"type": "object",
"description": "Static metadata for one provider the dashboard renders even when no connection exists.",
"required": [
"provider",
"name",
"auth_method",
"supports_push",
"configured"
],
"properties": {
"provider": {
"type": "string",
"description": "Provider id.",
"enum": [
"hubspot",
"salesforce",
"pipedrive",
"close",
"zapier",
"make",
"n8n",
"slack",
"discord",
"calendly",
"cal_com",
"google_sheets"
]
},
"name": {
"type": "string"
},
"tagline": {
"type": "string"
},
"category": {
"type": "string",
"enum": [
"crm",
"automation",
"notifications",
"meetings",
"data"
]
},
"docs_url": {
"type": "string"
},
"auth_method": {
"type": "string",
"enum": [
"oauth",
"api_key",
"webhook"
]
},
"badge_color": {
"type": "string"
},
"beta": {
"type": "boolean"
},
"webhook_hint": {
"type": "string"
},
"highlights": {
"type": "array",
"items": {
"type": "string"
}
},
"scopes": {
"type": "array",
"items": {
"type": "string"
},
"description": "OAuth scopes requested at authorize time."
},
"events": {
"type": "array",
"items": {
"type": "string"
},
"description": "Warmbly events this provider can react to."
},
"action_types": {
"type": "array",
"items": {
"type": "string"
},
"description": "Provider action identifiers with a real backend handler."
},
"supports_push": {
"type": "boolean",
"description": "Whether this provider can be the target of the synchronous push-contacts action."
},
"capability": {
"type": [
"object",
"null"
],
"additionalProperties": true,
"description": "Configurable-action descriptor the dashboard renders onboarding + field-mapping UI from."
},
"configured": {
"type": "boolean",
"description": "Whether the server has OAuth client credentials wired for this provider."
}
}
},
"IntegrationCatalogList": {
"type": "object",
"required": [
"catalog"
],
"properties": {
"catalog": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationCatalogEntry"
}
}
}
},
"IntegrationConnection": {
"type": "object",
"description": "One org's link to one provider. Secrets are never serialized.",
"required": [
"id",
"organization_id",
"provider",
"label",
"status",
"auth_method",
"sync_direction",
"health",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"provider": {
"type": "string"
},
"label": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"pending",
"authorizing",
"connected",
"degraded",
"reauth_required",
"disconnected"
]
},
"auth_method": {
"type": "string",
"enum": [
"oauth",
"api_key",
"webhook"
]
},
"display_fields": {
"type": "object",
"additionalProperties": true,
"description": "Non-secret display fields."
},
"config_capabilities": {
"type": "object",
"additionalProperties": true,
"description": "Per-connection onboarding/capability snapshot."
},
"sync_direction": {
"type": "string",
"enum": [
"push",
"pull",
"both"
]
},
"connected_by_user_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"external_account_id": {
"type": "string"
},
"external_account_name": {
"type": "string"
},
"granted_scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"token_expires_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"health": {
"type": "string",
"enum": [
"unknown",
"healthy",
"degraded",
"down"
]
},
"health_detail": {
"type": [
"string",
"null"
]
},
"health_checked_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_synced_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"last_error": {
"type": [
"string",
"null"
]
},
"last_error_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"inbound_webhook_url": {
"type": "string",
"description": "Returned only at create time for inbound providers (Calendly, Cal.com)."
}
}
},
"IntegrationConnectionList": {
"type": "object",
"required": [
"connections"
],
"properties": {
"connections": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationConnection"
}
}
}
},
"IntegrationConnectionDetail": {
"type": "object",
"description": "A connection plus its event subscriptions and recent sync runs (the detail drawer payload).",
"required": [
"connection",
"events",
"runs"
],
"properties": {
"connection": {
"$ref": "#/components/schemas/IntegrationConnection"
},
"events": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationEventSubscription"
}
},
"runs": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationSyncRun"
}
}
}
},
"IntegrationConnectionCreate": {
"type": "object",
"required": [
"provider"
],
"properties": {
"provider": {
"type": "string",
"description": "A valid api_key/webhook provider id (e.g. close, discord). OAuth providers are rejected."
},
"label": {
"type": "string",
"description": "Friendly name shown on the connection card."
},
"config": {
"type": "object",
"additionalProperties": true,
"description": "Provider-specific config (e.g. the pasted API key or webhook URL)."
}
}
},
"IntegrationConnectionConfigUpdate": {
"type": "object",
"properties": {
"config_capabilities": {
"type": "object",
"additionalProperties": true,
"description": "Per-connection capability snapshot (picker selections, enabled use-cases)."
},
"sync_direction": {
"type": "string",
"enum": [
"push",
"pull",
"both"
]
}
}
},
"IntegrationEventSubscription": {
"type": "object",
"description": "Routes a Warmbly event to a provider (or native) action on a connection.",
"required": [
"id",
"connection_id",
"event_type",
"action",
"enabled",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"connection_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"event_type": {
"type": "string",
"description": "The Warmbly event to react to (e.g. email.replied)."
},
"action": {
"type": "string",
"description": "Provider action id (e.g. slack.notify, hubspot.upsert_contact) or native action (e.g. warmbly.add_tag, warmbly.label_email)."
},
"config": {
"type": "object",
"additionalProperties": true,
"description": "Action config (e.g. a Slack channel or message template)."
},
"enabled": {
"type": "boolean"
},
"use_case": {
"type": "string",
"description": "Discriminator describing what this automation is for (e.g. crm_sync, notify, custom)."
},
"automation_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Set when this subscription is one step of an Automation flow."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"IntegrationEventSubscriptionList": {
"type": "object",
"required": [
"events"
],
"properties": {
"events": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationEventSubscription"
}
}
}
},
"IntegrationEventSubscriptionCreate": {
"type": "object",
"required": [
"event_type",
"action"
],
"properties": {
"event_type": {
"type": "string",
"description": "The Warmbly event to react to (e.g. email.replied)."
},
"action": {
"type": "string",
"description": "Provider action id (e.g. slack.notify, hubspot.upsert_contact)."
},
"config": {
"type": "object",
"additionalProperties": true,
"description": "Action config (e.g. a Slack channel or message template)."
},
"enabled": {
"type": "boolean",
"description": "Defaults to true when omitted."
}
}
},
"IntegrationFieldMapping": {
"type": "object",
"description": "One Warmbly-field to provider-field mapping row.",
"required": [
"id",
"connection_id",
"object_name",
"warmbly_field",
"external_field",
"is_default",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"connection_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"subscription_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"direction": {
"type": "string",
"enum": [
"push",
"pull",
"both"
]
},
"object_name": {
"type": "string"
},
"warmbly_field": {
"type": "string"
},
"external_field": {
"type": "string"
},
"transform": {
"type": "string",
"description": "One of '' (none), none, static, uppercase, lowercase, trim."
},
"static_value": {
"type": "string"
},
"is_default": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time"
}
}
},
"IntegrationFieldMappingList": {
"type": "object",
"required": [
"mappings"
],
"properties": {
"mappings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationFieldMapping"
}
}
}
},
"IntegrationFieldMappingReplace": {
"type": "object",
"required": [
"mappings"
],
"properties": {
"object": {
"type": "string",
"description": "The provider object the mappings apply to (e.g. contact)."
},
"mappings": {
"type": "array",
"description": "The full set of mappings to store (replaces any existing).",
"items": {
"type": "object",
"required": [
"external_field"
],
"properties": {
"external_field": {
"type": "string",
"description": "Destination field on the provider. Required for every mapping."
},
"warmbly_field": {
"type": "string",
"description": "Source Warmbly field. Required unless transform is 'static'."
},
"transform": {
"type": "string",
"description": "One of '' (none), none, static, uppercase, lowercase, trim."
},
"static_value": {
"type": "string",
"description": "Required when transform is 'static'."
}
}
}
}
}
},
"IntegrationSyncRun": {
"type": "object",
"description": "One observability record of work done against a connection.",
"required": [
"id",
"connection_id",
"kind",
"status",
"records_processed",
"started_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"connection_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"kind": {
"type": "string",
"description": "e.g. connect, refresh, dispatch, push."
},
"status": {
"type": "string",
"description": "e.g. success, error."
},
"detail": {
"type": "string"
},
"records_processed": {
"type": "integer"
},
"started_at": {
"type": "string",
"format": "date-time"
},
"finished_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"IntegrationSyncRunList": {
"type": "object",
"required": [
"runs"
],
"properties": {
"runs": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IntegrationSyncRun"
}
}
}
},
"IntegrationWebhookSecret": {
"type": "object",
"required": [
"signing_secret",
"signature_header",
"scheme"
],
"properties": {
"signing_secret": {
"type": "string",
"description": "HMAC signing secret used to verify outbound webhook signatures."
},
"signature_header": {
"type": "string",
"description": "Header carrying the signature (X-Warmbly-Signature)."
},
"scheme": {
"type": "string",
"description": "Signature scheme description."
}
}
},
"IntegrationPushRequest": {
"type": "object",
"required": [
"contact_ids"
],
"properties": {
"contact_ids": {
"type": "array",
"description": "Contact ids to push. Deduplicated server-side. At least 1, at most 500.",
"items": {
"type": "string",
"format": "uuid"
},
"minItems": 1,
"maxItems": 500
}
}
},
"IntegrationPushResult": {
"type": "object",
"required": [
"provider",
"pushed",
"failed",
"results"
],
"properties": {
"provider": {
"type": "string"
},
"pushed": {
"type": "integer"
},
"failed": {
"type": "integer"
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"contact_id",
"ok"
],
"properties": {
"contact_id": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string"
},
"ok": {
"type": "boolean"
},
"error": {
"type": "string",
"description": "Present when ok is false."
}
}
}
}
}
},
"MeetingBooking": {
"type": "object",
"description": "One booked meeting from a connected scheduling provider (Calendly, Cal.com) or a manually logged meeting.",
"required": [
"id",
"source",
"status",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"source": {
"type": "string",
"description": "e.g. calendly, cal_com, manual."
},
"external_event_id": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"booked",
"rescheduled",
"canceled",
"completed",
"no_show"
]
},
"invitee_email": {
"type": "string"
},
"invitee_name": {
"type": "string"
},
"event_name": {
"type": "string"
},
"event_type": {
"type": "string"
},
"scheduled_for": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"end_time": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"join_url": {
"type": "string"
},
"location": {
"type": "string"
},
"cancel_url": {
"type": "string"
},
"reschedule_url": {
"type": "string"
},
"canceled_reason": {
"type": "string"
},
"contact_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"campaign_id": {
"type": [
"string",
"null"
],
"format": "uuid"
},
"contact_name": {
"type": "string",
"description": "Joined for list display."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"MeetingBookingList": {
"type": "object",
"required": [
"bookings"
],
"properties": {
"bookings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MeetingBooking"
}
}
}
},
"Automation": {
"type": "object",
"description": "A branching flow: when the trigger event fires, the executor walks the graph, evaluating condition nodes and running the action nodes on matched paths.",
"required": [
"id",
"organization_id",
"name",
"enabled",
"trigger_event",
"graph",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"enabled": {
"type": "boolean"
},
"trigger_event": {
"type": "string",
"description": "The event that fires the flow (e.g. email.replied)."
},
"filter": {
"type": "object",
"additionalProperties": true,
"description": "Optional automation-wide gate (e.g. intents / min_confidence) applied to every action."
},
"graph": {
"$ref": "#/components/schemas/AutomationGraph"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"AutomationList": {
"type": "object",
"required": [
"automations"
],
"properties": {
"automations": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Automation"
}
}
}
},
"AutomationWrite": {
"type": "object",
"description": "Create/update payload from the flow builder.",
"required": [
"name",
"trigger_event",
"graph"
],
"properties": {
"name": {
"type": "string",
"description": "Display name."
},
"enabled": {
"type": "boolean",
"description": "Whether the automation runs on matching events."
},
"trigger_event": {
"type": "string",
"description": "The event that fires the flow (e.g. email.replied)."
},
"filter": {
"type": "object",
"additionalProperties": true,
"description": "Optional automation-wide gate applied to every action."
},
"graph": {
"$ref": "#/components/schemas/AutomationGraph"
}
}
},
"AutomationGraph": {
"type": "object",
"description": "The editable flow: nodes plus the edges connecting them.",
"required": [
"nodes",
"edges"
],
"properties": {
"nodes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AutomationNode"
}
},
"edges": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AutomationEdge"
}
}
}
},
"AutomationNode": {
"type": "object",
"description": "One node on the canvas.",
"required": [
"id",
"type",
"x",
"y"
],
"properties": {
"id": {
"type": "string",
"description": "Node id. The single trigger node uses id 'trigger'."
},
"type": {
"type": "string",
"enum": [
"trigger",
"condition",
"action"
],
"description": "Exactly one trigger node; condition nodes have true/false outgoing edges; action nodes run a handler."
},
"action": {
"type": "string",
"description": "Action node only: provider action (e.g. slack.notify) or native action (e.g. warmbly.add_tag, warmbly.label_email, warmbly.run_automation)."
},
"connection_id": {
"type": [
"string",
"null"
],
"format": "uuid",
"description": "Action node only: the integration connection the action runs against. Omitted for native (warmbly.*) actions."
},
"config": {
"type": "object",
"additionalProperties": true,
"description": "Action node config."
},
"condition": {
"$ref": "#/components/schemas/AutomationCondition"
},
"x": {
"type": "number",
"description": "Canvas x coordinate."
},
"y": {
"type": "number",
"description": "Canvas y coordinate."
}
}
},
"AutomationEdge": {
"type": "object",
"required": [
"id",
"source",
"target"
],
"properties": {
"id": {
"type": "string"
},
"source": {
"type": "string"
},
"target": {
"type": "string"
},
"when": {
"type": "string",
"description": "'' for plain edges; 'true' / 'false' for the two outgoing edges of a condition node."
}
}
},
"AutomationCondition": {
"type": "object",
"description": "An IF test evaluated against the trigger event's data.",
"required": [
"field",
"operator"
],
"properties": {
"field": {
"type": "string",
"description": "Condition kind, e.g. 'field' or 'expression'."
},
"key": {
"type": "string",
"description": "For 'field' conditions, the event-data key to test."
},
"operator": {
"type": "string"
},
"value": {
"description": "Comparison value (any JSON type)."
},
"expression": {
"type": "string",
"description": "For 'expression' conditions, a Go-template predicate evaluated against the event data."
}
}
},
"AutomationDryRunRequest": {
"type": "object",
"description": "Optional. When omitted, the server builds a sample event from the trigger.",
"properties": {
"data": {
"type": "object",
"additionalProperties": true,
"description": "Sample event payload to evaluate the flow against."
}
}
},
"AutomationDryRunResponse": {
"type": "object",
"required": [
"trace",
"data"
],
"properties": {
"trace": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AutomationNodeResult"
}
},
"data": {
"type": "object",
"additionalProperties": true,
"description": "The resolved event data the flow was evaluated against."
}
}
},
"AutomationRun": {
"type": "object",
"description": "One execution of an automation graph (per fired event or manual launch).",
"required": [
"id",
"automation_id",
"trigger_event",
"status",
"node_results",
"started_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"automation_id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"trigger_event": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"running",
"success",
"error"
]
},
"node_results": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AutomationNodeResult"
}
},
"error_detail": {
"type": "string"
},
"started_at": {
"type": "string",
"format": "date-time"
},
"finished_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"AutomationRunList": {
"type": "object",
"required": [
"runs"
],
"properties": {
"runs": {
"type": "array",
"items": {
"$ref": "#/components/schemas/AutomationRun"
}
}
}
},
"AutomationNodeResult": {
"type": "object",
"description": "One node's outcome in a run (or a dry-run trace).",
"required": [
"node_id",
"type",
"status"
],
"properties": {
"node_id": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"trigger",
"condition",
"action"
]
},
"action": {
"type": "string",
"description": "Action nodes only."
},
"label": {
"type": "string",
"description": "Human summary (e.g. 'Slack · #sales')."
},
"status": {
"type": "string",
"enum": [
"success",
"error",
"skipped",
"branch_true",
"branch_false"
]
},
"error": {
"type": "string"
},
"preview": {
"type": "object",
"additionalProperties": true,
"description": "Dry-run only: what the action would send."
}
}
},
"Team": {
"type": "object",
"description": "A named, color-tagged grouping of an organization's members.",
"required": [
"id",
"organization_id",
"name",
"color",
"members",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"color": {
"type": "string",
"description": "Hex color for the chip (defaults to #94a3b8)."
},
"members": {
"type": "array",
"description": "The members that belong to this team. Always an array (never null).",
"items": {
"$ref": "#/components/schemas/TeamMember"
}
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"TeamMember": {
"type": "object",
"description": "One membership row of a team, with the user's email and name joined for display.",
"required": [
"user_id",
"email",
"name",
"added_at"
],
"properties": {
"user_id": {
"type": "string",
"format": "uuid"
},
"email": {
"type": "string",
"format": "email"
},
"name": {
"type": "string"
},
"added_at": {
"type": "string",
"format": "date-time"
}
}
},
"TeamCollection": {
"type": "object",
"description": "A bare collection of teams (not cursor-paginated).",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Team"
}
}
}
},
"TeamCreate": {
"type": "object",
"description": "Request body for creating a team.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"color": {
"type": "string",
"description": "Hex color (defaults to #94a3b8)."
}
}
},
"TeamUpdate": {
"type": "object",
"description": "Partial-update body for a team. Omitted fields are left untouched.",
"minProperties": 1,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"color": {
"type": "string",
"description": "Hex color."
}
}
},
"TeamAddMember": {
"type": "object",
"description": "Request body for adding an existing organization member to a team.",
"required": [
"user_id"
],
"properties": {
"user_id": {
"type": "string",
"format": "uuid",
"description": "The member's user id (must already belong to the organization)."
}
}
},
"Plan": {
"type": "object",
"description": "A public subscription plan.",
"required": [
"id",
"price",
"duration",
"public"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": [
"string",
"null"
]
},
"max_contacts": {
"type": "integer"
},
"daily_emails": {
"type": "integer"
},
"ai_generation": {
"type": "boolean"
},
"account_limit": {
"type": "integer"
},
"price": {
"type": "number",
"format": "float"
},
"discounted_price": {
"type": "number",
"format": "float"
},
"duration": {
"type": "string",
"enum": [
"month",
"year"
]
},
"savings": {
"type": "integer",
"description": "Percentage savings versus monthly (0-255)."
},
"public": {
"type": "boolean"
},
"stripe_price_id": {
"type": [
"string",
"null"
]
},
"stripe_price_id_yearly": {
"type": [
"string",
"null"
]
},
"stripe_product_id": {
"type": [
"string",
"null"
]
},
"dedicated_workers": {
"type": "integer"
},
"daily_campaign_limit": {
"type": [
"integer",
"null"
]
},
"max_campaigns": {
"type": [
"integer",
"null"
]
},
"max_active_campaigns": {
"type": [
"integer",
"null"
]
},
"max_team_members": {
"type": [
"integer",
"null"
]
},
"max_email_accounts": {
"type": [
"integer",
"null"
]
},
"monthly_credits": {
"type": "integer",
"description": "AI writing-assistant monthly credit grant for this plan."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"PlanList": {
"type": "object",
"description": "The list of public subscription plans.",
"required": [
"plans"
],
"properties": {
"plans": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Plan"
}
}
}
},
"TimezoneOption": {
"type": "object",
"description": "A supported timezone identifier and its display label.",
"required": [
"name",
"display_name"
],
"properties": {
"name": {
"type": "string",
"description": "IANA name, e.g. \"Europe/Budapest\"."
},
"display_name": {
"type": "string",
"description": "Human label, e.g. \"(UTC+02:00) Europe/Budapest\"."
}
}
},
"UpsertOutreachSettingsRequest": {
"type": "object",
"required": [
"settings"
],
"properties": {
"settings": {
"$ref": "#/components/schemas/AdvancedOutreachSettings"
}
}
},
"IngestDeliverabilityEventRequest": {
"type": "object",
"required": [
"event_type",
"recipient_email"
],
"properties": {
"event_type": {
"type": "string",
"enum": [
"bounce",
"complaint",
"unsubscribe",
"open",
"click",
"reply"
],
"description": "The deliverability signal type."
},
"recipient_email": {
"type": "string",
"format": "email",
"description": "The recipient address the event is about."
},
"campaign_id": {
"type": "string",
"format": "uuid",
"description": "Campaign the event is attributed to."
},
"task_id": {
"type": "string",
"format": "uuid",
"description": "Send task the event is attributed to."
},
"contact_id": {
"type": "string",
"format": "uuid",
"description": "Contact the event is attributed to."
},
"provider": {
"type": "string",
"description": "Source provider label (e.g. ses, postmark)."
},
"reason": {
"type": "string",
"description": "Human-readable reason or diagnostic text."
},
"idempotency_key": {
"type": "string",
"description": "De-duplicates retried events."
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Free-form JSON attached to the event."
}
}
},
"TaskDeadLetter": {
"type": "object",
"description": "A task that exhausted its retry budget and landed in the dead-letter queue.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Dead-letter record ID (use this to replay)."
},
"task_id": {
"type": "string",
"format": "uuid",
"description": "The underlying task ID."
},
"task_type": {
"type": "string"
},
"payload": {
"type": "object",
"additionalProperties": true,
"description": "The original task payload."
},
"last_error": {
"type": "string"
},
"attempts": {
"type": "integer"
},
"max_attempts": {
"type": "integer"
},
"status": {
"type": "string",
"description": "e.g. pending, replayed."
},
"next_retry_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"replayed_at": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"task_id",
"task_type",
"status",
"attempts",
"max_attempts",
"created_at",
"updated_at"
]
},
"TaskDeadLetterList": {
"type": "object",
"description": "List of dead-letter records. Not cursor-paginated.",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TaskDeadLetter"
}
}
}
},
"ReplayDeadLetterResponse": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"type": "string",
"example": "replayed"
}
}
},
"WarmupRoutingRule": {
"type": "object",
"description": "A customer-defined preference applied during premium-pool partner selection.",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"priority": {
"type": "integer",
"description": "Evaluation order, ascending (lower runs first)."
},
"sender_match_type": {
"type": "string",
"enum": [
"any",
"domain",
"tld",
"provider"
]
},
"sender_match_value": {
"type": "string",
"description": "Lowercased/trimmed; empty when sender_match_type is any."
},
"recipient_match_type": {
"type": "string",
"enum": [
"any",
"domain",
"tld",
"provider"
]
},
"recipient_match_value": {
"type": "string",
"description": "Lowercased/trimmed; empty when recipient_match_type is any."
},
"weight": {
"type": "number",
"description": "Selection weight, >= 0."
},
"enabled": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"organization_id",
"name",
"priority",
"sender_match_type",
"recipient_match_type",
"weight",
"enabled",
"created_at",
"updated_at"
]
},
"WarmupRoutingRuleInput": {
"type": "object",
"description": "Create/update payload for a warmup routing rule. A match value is required unless its match type is `any`.",
"required": [
"name",
"sender_match_type",
"recipient_match_type"
],
"properties": {
"name": {
"type": "string",
"description": "Display name for the rule."
},
"priority": {
"type": "integer",
"description": "Evaluation order, ascending. Lower runs first."
},
"sender_match_type": {
"type": "string",
"enum": [
"any",
"domain",
"tld",
"provider"
]
},
"sender_match_value": {
"type": "string",
"description": "Required unless sender_match_type is any. Domain (acme.com), TLD (com), or provider bucket (google, microsoft, yahoo, apple, proton, zoho, custom)."
},
"recipient_match_type": {
"type": "string",
"enum": [
"any",
"domain",
"tld",
"provider"
]
},
"recipient_match_value": {
"type": "string",
"description": "Required unless recipient_match_type is any. Same value forms as the sender side."
},
"weight": {
"type": "number",
"minimum": 0,
"description": "Selection weight, must be >= 0."
},
"enabled": {
"type": "boolean",
"description": "Whether the rule is active."
}
}
},
"WarmupRoutingRuleList": {
"type": "object",
"description": "Warmup routing rules under a `rules` key (always an array, never null). Not cursor-paginated.",
"required": [
"rules"
],
"properties": {
"rules": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WarmupRoutingRule"
}
}
}
},
"ReplyTemplate": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"user_id": {
"type": "string",
"format": "uuid",
"description": "Owner (the user that created the template)."
},
"name": {
"type": "string"
},
"subject": {
"type": "string",
"description": "May contain {{.Key}} placeholders."
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
},
"position": {
"type": "integer",
"description": "1-indexed ordering within the org's list."
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"organization_id",
"user_id",
"name",
"position",
"created_at",
"updated_at"
]
},
"ReplyTemplateList": {
"type": "object",
"description": "Reply templates under a `data` key. Not cursor-paginated.",
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ReplyTemplate"
}
}
}
},
"CreateReplyTemplate": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 255,
"description": "Template name."
},
"subject": {
"type": "string",
"description": "Subject line (may contain {{.Key}} placeholders)."
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
}
}
},
"UpdateReplyTemplate": {
"type": "object",
"description": "All fields optional; omitted fields are left unchanged.",
"properties": {
"name": {
"type": "string"
},
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
}
}
},
"ReorderReplyTemplates": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Template IDs in their new order (1-indexed). IDs omitted are left untouched."
}
}
},
"RenderReplyTemplateRequest": {
"type": "object",
"properties": {
"variables": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Values substituted into {{.Key}} placeholders."
}
}
},
"RenderedReplyTemplate": {
"type": "object",
"required": [
"subject",
"body_html",
"body_plain"
],
"properties": {
"subject": {
"type": "string"
},
"body_html": {
"type": "string"
},
"body_plain": {
"type": "string"
}
}
},
"ScoreTemplateRequest": {
"type": "object",
"description": "Content to score. body_plain is preferred over body_html when present.",
"properties": {
"subject": {
"type": "string"
},
"body_html": {
"type": "string",
"description": "Used when body_plain is empty."
},
"body_plain": {
"type": "string",
"description": "Preferred over HTML when present."
}
}
},
"TemplateScoreIssue": {
"type": "object",
"required": [
"severity",
"code",
"message"
],
"properties": {
"severity": {
"type": "string",
"enum": [
"warn",
"high"
]
},
"code": {
"type": "string",
"description": "Stable issue code (e.g. too_many_links)."
},
"message": {
"type": "string"
}
}
},
"TemplateScoreResult": {
"type": "object",
"required": [
"score",
"issues"
],
"properties": {
"score": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Advisory content-safety score (higher is safer)."
},
"issues": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TemplateScoreIssue"
}
}
}
}
}
}
}