{"openapi":"3.1.0","info":{"title":"OutreachAgent API","version":"0.1.0","description":"Production-grade email infrastructure for AI agents. Send, receive, parse, personalize, and act on emails safely."},"servers":[{"url":"https://api.outreachagent.dev","description":"Production"},{"url":"http://localhost:4000","description":"Local development"}],"security":[{"bearerAuth":[]},{"apiKeyAuth":[]}],"tags":[{"name":"api_keys","description":"Manage API keys"},{"name":"approvals","description":"Review and resolve pending approval requests"},{"name":"audit_logs","description":"Audit trail for state-changing actions"},{"name":"inboxes","description":"Manage inboxes and pods"},{"name":"messages","description":"Send and retrieve messages"},{"name":"policies","description":"Guardrails for outbound delivery actions"},{"name":"search","description":"Search across message content"},{"name":"threads","description":"Conversation threads"},{"name":"domains","description":"Custom sending domains"},{"name":"webhooks","description":"Webhook endpoints and deliveries"},{"name":"realtime","description":"Realtime event session issuance"},{"name":"metrics","description":"Usage and delivery metrics"},{"name":"extractions","description":"Structured data extraction from message content"},{"name":"contacts","description":"Contact management"},{"name":"segments","description":"Manual audience segments"},{"name":"templates","description":"Email templates with Liquid support"},{"name":"workflows","description":"Workflow definitions and lifecycle"},{"name":"enrollments","description":"Workflow enrollments and execution"},{"name":"billing","description":"Subscription and usage billing"},{"name":"organizations","description":"Team and membership management"}],"paths":{"/v1/api-keys":{"get":{"tags":["api_keys"],"summary":"List API keys","operationId":"listApiKeys","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"post":{"tags":["api_keys"],"summary":"Create API key","operationId":"createApiKey","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"/v1/api-keys/{apiKeyId}":{"delete":{"tags":["api_keys"],"summary":"Revoke API key","operationId":"revokeApiKey","parameters":[{"name":"apiKeyId","in":"path","required":true,"schema":{"type":"string"},"description":"API key ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/audit-logs":{"get":{"tags":["audit_logs"],"summary":"List audit logs","operationId":"listAuditLogs","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AuditLog"}}}}}}}},"/v1/policies":{"get":{"tags":["policies"],"summary":"List policies","operationId":"listPolicies","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}}}}}}},"post":{"tags":["policies"],"summary":"Create policy","operationId":"createPolicy","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","scope","decision"],"properties":{"name":{"type":"string","description":"Human-readable policy name"},"scope":{"type":"string","enum":["outbound_send"],"description":"Policy scope (currently only outbound_send is supported)"},"decision":{"type":"string","enum":["allow","block","require_approval"],"description":"Action to take when policy conditions match"},"enabled":{"type":"boolean","description":"Whether the policy is active"},"priority":{"type":"integer","description":"Evaluation order (lower numbers evaluated first)"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/PolicyCondition"},"description":"Conditions that must match for this policy to apply"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Policy"}}}}}}},"/v1/policies/{policyId}":{"patch":{"tags":["policies"],"summary":"Update policy","operationId":"updatePolicy","parameters":[{"name":"policyId","in":"path","required":true,"schema":{"type":"string"},"description":"Policy ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"decision":{"type":"string","enum":["allow","block","require_approval"]},"enabled":{"type":"boolean"},"priority":{"type":"integer"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/PolicyCondition"}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Policy"}}}}}},"delete":{"tags":["policies"],"summary":"Delete policy","operationId":"deletePolicy","parameters":[{"name":"policyId","in":"path","required":true,"schema":{"type":"string"},"description":"Policy ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/approvals":{"get":{"tags":["approvals"],"summary":"List approval requests","operationId":"listApprovals","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApprovalRequest"}}}}}}}},"/v1/approvals/{approvalId}":{"get":{"tags":["approvals"],"summary":"Get approval request","operationId":"getApproval","parameters":[{"name":"approvalId","in":"path","required":true,"schema":{"type":"string"},"description":"Approval ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequest"}}}}}}},"/v1/approvals/{approvalId}/approve":{"post":{"tags":["approvals"],"summary":"Approve a pending approval request","operationId":"approveApproval","parameters":[{"name":"approvalId","in":"path","required":true,"schema":{"type":"string"},"description":"Approval ID"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"subject":{"type":"string","description":"Override the email subject line"},"body":{"type":"string","description":"Override the full email body content (plaintext)"},"text":{"type":"string","description":"Override the plaintext body (alias for body)"},"html":{"type":"string","description":"Override or provide an HTML version of the email body"},"from":{"type":"string","format":"email","description":"Override the sender email address"},"to":{"type":"array","items":{"type":"string","format":"email"},"description":"Override the recipient list"},"reason":{"type":"string","description":"Reason for approving this request"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalDecisionResponse"}}}}}}},"/v1/approvals/{approvalId}/reject":{"post":{"tags":["approvals"],"summary":"Reject a pending approval request","operationId":"rejectApproval","parameters":[{"name":"approvalId","in":"path","required":true,"schema":{"type":"string"},"description":"Approval ID"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequest"}}}}}}},"/v1/inboxes":{"get":{"tags":["inboxes"],"summary":"List inboxes","operationId":"listInboxes","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Inbox"}}}}}}},"post":{"tags":["inboxes"],"summary":"Create inbox","operationId":"createInbox","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address","displayName","podId"],"properties":{"address":{"type":"string","format":"email"},"displayName":{"type":"string","description":"The sender name recipients see in their inbox and push notifications"},"podId":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Inbox"}}}}}}},"/v1/inboxes/{inboxId}":{"get":{"tags":["inboxes"],"summary":"Get inbox","operationId":"getInbox","parameters":[{"name":"inboxId","in":"path","required":true,"schema":{"type":"string"},"description":"Inbox ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Inbox"}}}}}},"patch":{"tags":["inboxes"],"summary":"Update inbox","operationId":"updateInbox","parameters":[{"name":"inboxId","in":"path","required":true,"schema":{"type":"string"},"description":"Inbox ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"displayName":{"type":"string","description":"The sender name recipients see in their inbox and push notifications"},"status":{"type":"string","enum":["active","warming","disabled"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Inbox"}}}}}},"delete":{"tags":["inboxes"],"summary":"Delete inbox","operationId":"deleteInbox","parameters":[{"name":"inboxId","in":"path","required":true,"schema":{"type":"string"},"description":"Inbox ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/pods":{"get":{"tags":["inboxes"],"summary":"List pods","operationId":"listPods","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Pod"}}}}}}},"post":{"tags":["inboxes"],"summary":"Create pod","operationId":"createPod","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","region"],"properties":{"name":{"type":"string"},"region":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pod"}}}}}}},"/v1/pods/{podId}":{"get":{"tags":["inboxes"],"summary":"Get pod","operationId":"getPod","parameters":[{"name":"podId","in":"path","required":true,"schema":{"type":"string"},"description":"Pod ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pod"}}}}}},"delete":{"tags":["inboxes"],"summary":"Delete pod","operationId":"deletePod","parameters":[{"name":"podId","in":"path","required":true,"schema":{"type":"string"},"description":"Pod ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/messages":{"get":{"tags":["messages"],"summary":"List messages","operationId":"listMessages","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}}}}}}},"/v1/messages/send":{"post":{"tags":["messages"],"summary":"Send message","operationId":"sendMessage","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["inboxId","subject","body","from","to"],"properties":{"inboxId":{"type":"string","description":"ID of the inbox to send from"},"subject":{"type":"string","description":"Email subject line"},"body":{"type":"string","description":"The full email body content (plaintext). This is the main content of the email."},"html":{"type":"string","description":"Optional HTML version of the email body. When provided, the email is sent as multipart with both plaintext and HTML parts."},"from":{"type":"string","format":"email","description":"Sender email address (must belong to the inbox's domain)"},"to":{"type":"array","items":{"type":"string","format":"email"},"description":"List of recipient email addresses"}}}}}},"responses":{"200":{"description":"Message sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageResponse"}}}},"202":{"description":"Approval required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageResponse"}}}}}}},"/v1/messages/{messageId}":{"get":{"tags":["messages"],"summary":"Get message","operationId":"getMessage","parameters":[{"name":"messageId","in":"path","required":true,"schema":{"type":"string"},"description":"Message ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}}}}},"/v1/search/messages":{"post":{"tags":["search"],"summary":"Search messages","operationId":"searchMessages","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string"},"limit":{"type":"integer","minimum":1,"maximum":25},"inboxId":{"type":"string"},"threadId":{"type":"string"},"dateFrom":{"type":"string"},"dateTo":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSearchResponse"}}}}}}},"/v1/extractions/otp":{"post":{"tags":["extractions"],"summary":"Extract OTP from a message or text input","operationId":"extractOtp","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string"},"text":{"type":"string"},"codeLength":{"type":"integer","minimum":4,"maximum":8}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpExtractionResult"}}}}}}},"/v1/extractions/invoice-basic":{"post":{"tags":["extractions"],"summary":"Extract basic invoice fields from a message or text input","operationId":"extractInvoiceBasic","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string"},"text":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceBasicExtractionResult"}}}}}}},"/v1/threads":{"get":{"tags":["threads"],"summary":"List threads","operationId":"listThreads","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Thread"}}}}}}}},"/v1/threads/{threadId}":{"get":{"tags":["threads"],"summary":"Get thread","operationId":"getThread","parameters":[{"name":"threadId","in":"path","required":true,"schema":{"type":"string"},"description":"Thread ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Thread"}}}}}}},"/v1/domains":{"get":{"tags":["domains"],"summary":"List domains","operationId":"listDomains","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}}}}}},"post":{"tags":["domains"],"summary":"Add domain","operationId":"createDomain","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}}}}}},"/v1/domains/{domainId}":{"get":{"tags":["domains"],"summary":"Get domain","operationId":"getDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string"},"description":"Domain ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Domain"}}}}}},"delete":{"tags":["domains"],"summary":"Delete domain","operationId":"deleteDomain","parameters":[{"name":"domainId","in":"path","required":true,"schema":{"type":"string"},"description":"Domain ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/webhooks/endpoints":{"get":{"tags":["webhooks"],"summary":"List webhook endpoints","operationId":"listWebhookEndpoints","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}}},"post":{"tags":["webhooks"],"summary":"Create webhook endpoint","operationId":"createWebhookEndpoint","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","subscribedEvents"],"properties":{"url":{"type":"string","format":"uri"},"subscribedEvents":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}}},"/v1/webhooks/endpoints/{endpointId}":{"get":{"tags":["webhooks"],"summary":"Get webhook endpoint","operationId":"getWebhookEndpoint","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string"},"description":"Endpoint ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}},"patch":{"tags":["webhooks"],"summary":"Update webhook endpoint","operationId":"updateWebhookEndpoint","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string"},"description":"Endpoint ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"subscribedEvents":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}},"delete":{"tags":["webhooks"],"summary":"Delete webhook endpoint","operationId":"deleteWebhookEndpoint","parameters":[{"name":"endpointId","in":"path","required":true,"schema":{"type":"string"},"description":"Endpoint ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/webhooks/deliveries":{"get":{"tags":["webhooks"],"summary":"List webhook deliveries","operationId":"listWebhookDeliveries","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}}}},"/v1/webhooks/deliveries/{deliveryId}/replay":{"post":{"tags":["webhooks"],"summary":"Replay a webhook delivery","operationId":"replayWebhookDelivery","parameters":[{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string"},"description":"Delivery ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}}}}},"/v1/events":{"get":{"tags":["webhooks"],"summary":"List events","operationId":"listEvents","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}}}}}}}},"/v1/realtime/sessions":{"post":{"tags":["realtime"],"summary":"Create realtime session","operationId":"createRealtimeSession","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeSession"}}}}}}},"/v1/metrics/summary":{"get":{"tags":["metrics"],"summary":"Get metrics summary","operationId":"getMetricsSummary","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"}}}}}}},"/v1/metrics/timeseries":{"get":{"tags":["metrics"],"summary":"Get metrics timeseries","operationId":"getMetricsTimeseries","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"sent":{"type":"integer"},"delivered":{"type":"integer"}}}}}}}}}},"/v1/contacts":{"get":{"tags":["contacts"],"summary":"List contacts","operationId":"listContacts","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}}}}}}},"post":{"tags":["contacts"],"summary":"Create contact","operationId":"createContact","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","fullName"],"properties":{"email":{"type":"string","format":"email","description":"Contact email address (unique per organization)"},"fullName":{"type":"string","description":"Contact full name"},"attributes":{"type":"object","description":"Custom key-value attributes for personalization (e.g. firstName, company, title). Accessible in templates as {{ contact.attributes.<key> }}.","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"segmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of segments this contact belongs to"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}}}}},"/v1/contacts/{contactId}":{"get":{"tags":["contacts"],"summary":"Get contact","operationId":"getContact","parameters":[{"name":"contactId","in":"path","required":true,"schema":{"type":"string"},"description":"Contact ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}}}},"patch":{"tags":["contacts"],"summary":"Update contact","operationId":"updateContact","parameters":[{"name":"contactId","in":"path","required":true,"schema":{"type":"string"},"description":"Contact ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fullName":{"type":"string","description":"Contact full name"},"email":{"type":"string","format":"email","description":"Contact email address (unique per organization)"},"attributes":{"type":"object","description":"Custom key-value attributes for personalization. Replaces existing attributes entirely.","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"segmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of segments this contact belongs to"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}}}},"delete":{"tags":["contacts"],"summary":"Delete contact","operationId":"deleteContact","parameters":[{"name":"contactId","in":"path","required":true,"schema":{"type":"string"},"description":"Contact ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/segments":{"get":{"tags":["segments"],"summary":"List segments","operationId":"listSegments","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}}}}}}},"post":{"tags":["segments"],"summary":"Create segment","operationId":"createSegment","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Segment"}}}}}}},"/v1/segments/{segmentId}":{"get":{"tags":["segments"],"summary":"Get segment","operationId":"getSegment","parameters":[{"name":"segmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Segment ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Segment"}}}}}},"patch":{"tags":["segments"],"summary":"Update segment","operationId":"updateSegment","parameters":[{"name":"segmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Segment ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Segment"}}}}}},"delete":{"tags":["segments"],"summary":"Delete segment","operationId":"deleteSegment","parameters":[{"name":"segmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Segment ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/templates":{"get":{"tags":["templates"],"summary":"List templates","operationId":"listTemplates","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Template"}}}}}}},"post":{"tags":["templates"],"summary":"Create template","operationId":"createTemplate","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","subject"],"properties":{"name":{"type":"string","description":"Human-readable template name for identification"},"subject":{"type":"string","description":"Email subject line (supports Liquid variables e.g. {{ contact.attributes.firstName }})"},"html":{"type":"string","description":"HTML email body content (supports Liquid variables)"},"text":{"type":"string","description":"Plaintext email body content (supports Liquid variables)"},"body":{"type":"string","description":"Alias for text — plaintext email body content. If both text and body are provided, text takes precedence."}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}}}}},"/v1/templates/{templateId}":{"get":{"tags":["templates"],"summary":"Get template","operationId":"getTemplate","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string"},"description":"Template ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}}}},"patch":{"tags":["templates"],"summary":"Update template","operationId":"updateTemplate","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string"},"description":"Template ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable template name"},"subject":{"type":"string","description":"Email subject line (supports Liquid variables)"},"html":{"type":"string","description":"HTML email body content (supports Liquid variables)"},"text":{"type":"string","description":"Plaintext email body content (supports Liquid variables)"},"body":{"type":"string","description":"Alias for text — plaintext email body content"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}}}}},"delete":{"tags":["templates"],"summary":"Delete template","operationId":"deleteTemplate","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string"},"description":"Template ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/templates/{templateId}/preview":{"post":{"tags":["templates"],"summary":"Preview template","operationId":"previewTemplate","parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"string"},"description":"Template ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["variables"],"properties":{"variables":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplatePreview"}}}}}}},"/v1/workflows":{"get":{"tags":["workflows"],"summary":"List workflows","operationId":"listWorkflows","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"post":{"tags":["workflows"],"summary":"Create workflow","operationId":"createWorkflow","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","trigger","nodes"],"properties":{"name":{"type":"string"},"trigger":{"type":"string","enum":["manual","api","event","scheduled"]},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowNode"}},"exitCriteria":{"type":"array","items":{"$ref":"#/components/schemas/ExitCriterion"}},"optOutMode":{"type":"string","enum":["link","reply","header_only"],"description":"Opt-out mode for emails. Default: reply."},"schedule":{"type":"object","properties":{"cronExpression":{"type":"string"},"contactFilter":{"type":"object","properties":{"segmentId":{"type":"string"}}}}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/workflows/{workflowId}":{"get":{"tags":["workflows"],"summary":"Get workflow","operationId":"getWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}},"patch":{"tags":["workflows"],"summary":"Update workflow","operationId":"updateWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"trigger":{"type":"string","enum":["manual","api","event","scheduled"]},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowNode"}},"exitCriteria":{"type":"array","items":{"$ref":"#/components/schemas/ExitCriterion"}},"optOutMode":{"type":"string","enum":["link","reply","header_only"],"description":"Opt-out mode for emails. Default: reply."},"schedule":{"type":"object","properties":{"cronExpression":{"type":"string"},"contactFilter":{"type":"object","properties":{"segmentId":{"type":"string"}}}}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}},"delete":{"tags":["workflows"],"summary":"Delete workflow","operationId":"deleteWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}}}},"/v1/workflows/{workflowId}/publish":{"post":{"tags":["workflows"],"summary":"Publish workflow","operationId":"publishWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/workflows/{workflowId}/pause":{"post":{"tags":["workflows"],"summary":"Pause workflow","operationId":"pauseWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/workflows/{workflowId}/resume":{"post":{"tags":["workflows"],"summary":"Resume workflow","operationId":"resumeWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/workflows/{workflowId}/nodes/{nodeId}/pause":{"post":{"tags":["workflows"],"summary":"Pause a workflow node","operationId":"pauseWorkflowNode","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"},{"name":"nodeId","in":"path","required":true,"schema":{"type":"string"},"description":"Node ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/workflows/{workflowId}/nodes/{nodeId}/resume":{"post":{"tags":["workflows"],"summary":"Resume a workflow node","operationId":"resumeWorkflowNode","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"},{"name":"nodeId","in":"path","required":true,"schema":{"type":"string"},"description":"Node ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/enrollments":{"get":{"tags":["enrollments"],"summary":"List enrollments","operationId":"listEnrollments","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Enrollment"}}}}}}},"post":{"tags":["enrollments"],"summary":"Create enrollment","operationId":"createEnrollment","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workflowId","contactId"],"properties":{"workflowId":{"type":"string","description":"ID of the workflow to enroll the contact into"},"contactId":{"type":"string","description":"ID of the contact to enroll"},"variables":{"type":"object","additionalProperties":true,"description":"Per-enrollment template variable overrides merged into the Liquid context at render time"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enrollment"}}}}}}},"/v1/enrollments/{enrollmentId}":{"get":{"tags":["enrollments"],"summary":"Get enrollment","operationId":"getEnrollment","parameters":[{"name":"enrollmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Enrollment ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enrollment"}}}}}}},"/v1/enrollments/{enrollmentId}/logs":{"get":{"tags":["enrollments"],"summary":"List execution logs","operationId":"listEnrollmentLogs","parameters":[{"name":"enrollmentId","in":"path","required":true,"schema":{"type":"string"},"description":"Enrollment ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ExecutionLog"}}}}}}}},"/v1/billing/subscription":{"get":{"tags":["billing"],"summary":"Get subscription","operationId":"getSubscription","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}}}}},"/v1/billing/usage-counters":{"get":{"tags":["billing"],"summary":"List usage counters","operationId":"listUsageCounters","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UsageCounter"}}}}}}}},"/v1/billing/checkout-session":{"post":{"tags":["billing"],"summary":"Create checkout session","operationId":"createCheckoutSession","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tier"],"properties":{"tier":{"type":"string","enum":["pro"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSession"}}}}}}},"/v1/billing/portal-session":{"post":{"tags":["billing"],"summary":"Create portal session","operationId":"createPortalSession","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"portalUrl":{"type":"string","format":"uri"}}}}}}}}},"/v1/workflows/{workflowId}/analytics":{"get":{"tags":["workflows"],"summary":"Get workflow analytics","operationId":"getWorkflowAnalytics","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowAnalytics"}}}}}}},"/v1/workflows/{workflowId}/test-send":{"post":{"tags":["workflows"],"summary":"Send a test email for a workflow node","description":"Renders a send_email node's template with contact data and/or provided variables, then sends the email to the specified test address. Use this to verify template rendering before enrolling real contacts.","operationId":"testSendWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["nodeId","to"],"properties":{"nodeId":{"type":"string","description":"ID of a send_email node in the workflow to test"},"to":{"type":"string","format":"email","description":"Recipient email address for the test email"},"contactId":{"type":"string","description":"Optional contact ID to pull attributes from for template rendering"},"variables":{"type":"object","additionalProperties":true,"description":"Template variable overrides merged into the Liquid context as {{ vars.<key> }}"}}}}}},"responses":{"200":{"description":"Test email sent","content":{"application/json":{"schema":{"type":"object","properties":{"sent":{"type":"boolean","description":"Whether the email was sent"},"to":{"type":"string","description":"Recipient address"},"subject":{"type":"string","description":"Rendered subject line"},"text":{"type":"string","description":"Rendered plaintext body"},"html":{"type":"string","nullable":true,"description":"Rendered HTML body (null if not provided)"}}}}}}}}},"/v1/workflows/{workflowId}/simulate":{"post":{"tags":["workflows"],"summary":"Dry-run a workflow without side effects","operationId":"simulateWorkflow","parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string"},"description":"Workflow ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowSimulationRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowSimulationResponse"}}}}}}},"/v1/enrollments/bulk":{"post":{"tags":["enrollments"],"summary":"Bulk enroll contacts","operationId":"bulkCreateEnrollment","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workflowId","contactIds"],"properties":{"workflowId":{"type":"string","description":"ID of the workflow to enroll contacts into"},"contactIds":{"type":"array","items":{"type":"string"},"maxItems":100,"description":"Contact IDs to enroll (max 100 per request)"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/BulkEnrollmentResult"}}}}}}}}}},"/v1/send-limits":{"get":{"tags":["billing"],"summary":"List send limits","operationId":"listSendLimits","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SendLimit"}}}}}}},"put":{"tags":["billing"],"summary":"Create or update send limit","operationId":"upsertSendLimit","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["dailyLimit"],"properties":{"inboxId":{"type":"string"},"dailyLimit":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendLimit"}}}}}}},"/v1/workflow-templates":{"get":{"tags":["workflows"],"summary":"List workflow templates","operationId":"listWorkflowTemplates","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowTemplate"}}}}}}}},"/v1/workflows/from-template":{"post":{"tags":["workflows"],"summary":"Create workflow from template","operationId":"cloneFromTemplate","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["templateId"],"properties":{"templateId":{"type":"string"},"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDefinition"}}}}}}},"/v1/organizations/{organizationId}/invitations":{"get":{"tags":["organizations"],"summary":"List invitations","operationId":"listInvitations","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"},"description":"Organization ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}}}}}},"post":{"tags":["organizations"],"summary":"Create invitation","operationId":"createInvitation","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"},"description":"Organization ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","role"],"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["owner","admin","member"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}}}}},"/v1/organizations/{organizationId}/memberships":{"get":{"tags":["organizations"],"summary":"List memberships","operationId":"listMemberships","parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"},"description":"Organization ID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationMembership"}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk JWT token"},"apiKeyAuth":{"type":"http","scheme":"bearer","description":"OutreachAgent API key (rm_ prefix)"}},"schemas":{"ApiKey":{"type":"object","properties":{"id":{"type":"string","description":"Unique API key identifier"},"name":{"type":"string","description":"Human-readable name for the API key"},"maskedKey":{"type":"string","description":"Masked version of the key (e.g. rm_live_...abc)"},"lastUsedAt":{"type":"string","nullable":true,"description":"ISO 8601 timestamp of last use, or null if never used"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"Inbox":{"type":"object","properties":{"id":{"type":"string","description":"Unique inbox identifier"},"address":{"type":"string","description":"Email address for this inbox (e.g. outreach@yourdomain.com)"},"displayName":{"type":"string","description":"The sender name recipients see in their inbox and push notifications"},"status":{"type":"string","enum":["active","warming","disabled"],"description":"Inbox lifecycle status"},"podId":{"type":"string","description":"ID of the pod this inbox belongs to"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","description":"ISO 8601 last update timestamp"}}},"Pod":{"type":"object","properties":{"id":{"type":"string","description":"Unique pod identifier"},"name":{"type":"string","description":"Human-readable pod name"},"region":{"type":"string","description":"Deployment region (e.g. us-east-1)"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"Domain":{"type":"object","properties":{"id":{"type":"string","description":"Unique domain identifier"},"name":{"type":"string","description":"Domain name (e.g. yourdomain.com)"},"status":{"type":"string","enum":["pending","verifying","verified","failed"],"description":"Overall domain verification status"},"dkimStatus":{"type":"string","enum":["missing","pending","verified"],"description":"DKIM DNS record verification status"},"spfStatus":{"type":"string","enum":["missing","pending","verified"],"description":"SPF DNS record verification status"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"Message":{"type":"object","properties":{"id":{"type":"string","description":"Unique message identifier"},"inboxId":{"type":"string","description":"ID of the inbox this message belongs to"},"threadId":{"type":"string","description":"ID of the thread this message belongs to"},"direction":{"type":"string","enum":["inbound","outbound"],"description":"Whether the message was received or sent"},"subject":{"type":"string","description":"Email subject line"},"preview":{"type":"string","description":"A plaintext preview/snippet of the email body for display in message lists (not the full body)"},"from":{"type":"string","description":"Sender email address"},"to":{"type":"array","items":{"type":"string"},"description":"Recipient email addresses"},"status":{"type":"string","enum":["queued","sent","delivered","received","bounced"],"description":"Delivery status of the message"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"},"description":"File attachments on this message"}}},"MessageSearchResult":{"type":"object","properties":{"message":{"$ref":"#/components/schemas/Message","description":"The matched message"},"score":{"type":"number","description":"Relevance score (higher is more relevant)"},"excerpt":{"type":"string","description":"Text excerpt highlighting the match"},"matchedFields":{"type":"array","items":{"type":"string","enum":["subject","preview","from","to"]},"description":"Which fields matched the search query"}}},"MessageSearchResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MessageSearchResult"},"description":"Search results"},"total":{"type":"integer","description":"Total number of matching messages"}}},"OtpExtractionResult":{"type":"object","properties":{"matched":{"type":"boolean","description":"Whether an OTP code was found"},"code":{"type":"string","nullable":true,"description":"The extracted OTP code"},"confidence":{"type":"number","description":"Confidence score (0-1)"},"source":{"type":"string","enum":["input","preview","raw_payload","attachment","provider"],"nullable":true,"description":"Where the code was found"},"excerpt":{"type":"string","nullable":true,"description":"Text surrounding the extracted code"}}},"InvoiceBasicExtractionResult":{"type":"object","properties":{"matched":{"type":"boolean","description":"Whether invoice fields were found"},"invoiceNumber":{"type":"string","nullable":true,"description":"Extracted invoice number"},"vendorName":{"type":"string","nullable":true,"description":"Extracted vendor/company name"},"totalAmount":{"type":"number","nullable":true,"description":"Extracted total amount"},"currency":{"type":"string","nullable":true,"description":"Extracted currency code (e.g. USD)"},"invoiceDate":{"type":"string","nullable":true,"description":"Extracted invoice date"},"dueDate":{"type":"string","nullable":true,"description":"Extracted due date"},"source":{"type":"string","enum":["input","preview","raw_payload","attachment","provider"],"nullable":true,"description":"Where the data was extracted from"}}},"Attachment":{"type":"object","properties":{"id":{"type":"string","description":"Unique attachment identifier"},"fileName":{"type":"string","description":"Original file name"},"contentType":{"type":"string","description":"MIME type (e.g. application/pdf)"},"size":{"type":"integer","description":"File size in bytes"},"url":{"type":"string","description":"URL to download the attachment"}}},"Thread":{"type":"object","properties":{"id":{"type":"string","description":"Unique thread identifier"},"inboxId":{"type":"string","description":"ID of the inbox this thread belongs to"},"subject":{"type":"string","description":"Thread subject line"},"participants":{"type":"array","items":{"type":"string"},"description":"Email addresses of all participants"},"lastMessageAt":{"type":"string","description":"ISO 8601 timestamp of most recent message"},"messageCount":{"type":"integer","description":"Total messages in this thread"}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","description":"Unique endpoint identifier"},"url":{"type":"string","description":"URL that receives webhook payloads"},"status":{"type":"string","enum":["healthy","degraded","failing"],"description":"Delivery health status based on recent error rate"},"subscribedEvents":{"type":"array","items":{"type":"string"},"description":"Event types this endpoint receives (e.g. message.received)"},"errorRate":{"type":"number","description":"Recent delivery error rate (0-1)"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","description":"Unique delivery identifier"},"endpointId":{"type":"string","description":"ID of the target webhook endpoint"},"eventId":{"type":"string","nullable":true,"description":"ID of the event that triggered this delivery"},"replayedFromDeliveryId":{"type":"string","nullable":true,"description":"If this is a replay, the ID of the original delivery"},"eventName":{"type":"string","description":"Event type (e.g. message.received)"},"status":{"type":"string","enum":["delivered","retrying","failed"],"description":"Delivery status"},"attemptCount":{"type":"integer","description":"Number of delivery attempts made"},"lastAttemptAt":{"type":"string","description":"ISO 8601 timestamp of most recent attempt"}}},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","description":"Unique event identifier"},"name":{"type":"string","description":"Event type (e.g. message.received, enrollment.completed)"},"createdAt":{"type":"string","description":"ISO 8601 timestamp when the event occurred"},"resourceId":{"type":"string","description":"ID of the resource that triggered the event"},"resourceType":{"type":"string","description":"Type of resource (e.g. message, enrollment)"}}},"AuditLog":{"type":"object","properties":{"id":{"type":"string","description":"Unique audit log entry identifier"},"action":{"type":"string","description":"Action performed (e.g. message.sent, workflow.published)"},"actorType":{"type":"string","enum":["user","api_key","system"],"description":"Type of actor that performed the action"},"actorId":{"type":"string","nullable":true,"description":"ID of the actor (user ID, API key ID, or null for system)"},"resourceType":{"type":"string","description":"Type of resource affected"},"resourceId":{"type":"string","nullable":true,"description":"ID of the resource affected"},"metadata":{"type":"object","additionalProperties":true,"description":"Additional context about the action"},"createdAt":{"type":"string","description":"ISO 8601 timestamp"}}},"PolicyCondition":{"type":"object","properties":{"field":{"type":"string","description":"Field path to evaluate (e.g. contact.email, message.subject)"},"operator":{"type":"string","enum":["equals","contains","exists","not_equals","is_true","is_false"],"description":"Comparison operator"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}],"description":"Value to compare against (not used for exists, is_true, is_false)"}}},"Policy":{"type":"object","properties":{"id":{"type":"string","description":"Unique policy identifier"},"name":{"type":"string","description":"Human-readable policy name"},"scope":{"type":"string","enum":["outbound_send"],"description":"Policy scope"},"decision":{"type":"string","enum":["allow","block","require_approval"],"description":"Action to take when conditions match"},"enabled":{"type":"boolean","description":"Whether the policy is active"},"priority":{"type":"integer","description":"Evaluation order (lower numbers evaluated first)"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/PolicyCondition"},"description":"Conditions that must all match for the policy to apply"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","description":"ISO 8601 last update timestamp"}}},"ApprovalRequest":{"type":"object","properties":{"id":{"type":"string","description":"Unique approval request identifier"},"scope":{"type":"string","enum":["outbound_send"],"description":"Scope of the approval"},"status":{"type":"string","enum":["pending","approved","rejected"],"description":"Current approval status"},"resourceType":{"type":"string","description":"Type of resource awaiting approval"},"resourceId":{"type":"string","nullable":true,"description":"ID of the resource awaiting approval"},"policyId":{"type":"string","nullable":true,"description":"ID of the policy that triggered this approval"},"policySnapshot":{"allOf":[{"$ref":"#/components/schemas/Policy"}],"nullable":true,"description":"Snapshot of the policy at the time of the request"},"proposedPayload":{"type":"object","additionalProperties":true,"description":"The original payload submitted for approval"},"resolvedPayload":{"type":"object","additionalProperties":true,"nullable":true,"description":"The final payload after approval (may include overrides)"},"requestedByActorType":{"type":"string","enum":["user","api_key","system"],"description":"Type of actor that triggered the approval"},"requestedByActorId":{"type":"string","nullable":true,"description":"ID of the requesting actor"},"decisionByActorType":{"type":"string","enum":["user","api_key","system"],"nullable":true,"description":"Type of actor that made the decision"},"decisionByActorId":{"type":"string","nullable":true,"description":"ID of the deciding actor"},"decisionReason":{"type":"string","nullable":true,"description":"Reason provided with the approval/rejection"},"metadata":{"type":"object","additionalProperties":true,"description":"Additional context (workflow ID, node ID, etc.)"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","description":"ISO 8601 last update timestamp"},"decidedAt":{"type":"string","nullable":true,"description":"ISO 8601 timestamp of when the decision was made"}}},"SendMessageResponse":{"oneOf":[{"type":"object","properties":{"result":{"type":"string","enum":["sent"],"description":"Message was sent successfully"},"message":{"$ref":"#/components/schemas/Message","description":"The sent message"}},"required":["result","message"]},{"type":"object","properties":{"result":{"type":"string","enum":["requires_approval"],"description":"Message requires approval before sending"},"approval":{"$ref":"#/components/schemas/ApprovalRequest","description":"The created approval request"}},"required":["result","approval"]}]},"ApprovalDecisionResponse":{"type":"object","properties":{"approval":{"$ref":"#/components/schemas/ApprovalRequest","description":"The updated approval request"},"result":{"$ref":"#/components/schemas/SendMessageResponse","description":"Send result (present when approved and sent)"}},"required":["approval"]},"RealtimeSession":{"type":"object","properties":{"ticket":{"type":"string","description":"One-time ticket for WebSocket authentication"},"expiresAt":{"type":"string","description":"ISO 8601 expiration timestamp for the ticket"},"websocketUrl":{"type":"string","format":"uri","description":"WebSocket URL to connect to"}}},"Contact":{"type":"object","properties":{"id":{"type":"string","description":"Unique contact identifier"},"email":{"type":"string","description":"Contact email address"},"fullName":{"type":"string","description":"Contact full name"},"attributes":{"type":"object","description":"Custom key-value attributes for personalization (e.g. { firstName, company, title }). Accessible in templates as {{ contact.attributes.<key> }}.","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"segmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of segments this contact belongs to"},"lastSeenAt":{"type":"string","description":"ISO 8601 timestamp of last activity"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"Segment":{"type":"object","properties":{"id":{"type":"string","description":"Unique segment identifier"},"name":{"type":"string","description":"Segment name"},"description":{"type":"string","description":"Optional description of the segment"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"Template":{"type":"object","properties":{"id":{"type":"string","description":"Unique template identifier"},"name":{"type":"string","description":"Human-readable template name"},"subject":{"type":"string","description":"Email subject line (supports Liquid variables)"},"status":{"type":"string","enum":["active","draft","paused","failed","archived"],"description":"Template lifecycle status"},"version":{"type":"integer","description":"Current version number (incremented on each update)"},"updatedAt":{"type":"string","description":"ISO 8601 last update timestamp"}}},"TemplatePreview":{"type":"object","properties":{"subject":{"type":"string","description":"Rendered subject line with variables resolved"},"html":{"type":"string","description":"Rendered HTML body with variables resolved"},"text":{"type":"string","description":"Rendered plaintext body with variables resolved"},"missingVariables":{"type":"array","items":{"type":"string"},"description":"Variable names referenced in the template but not provided in the preview request"}}},"WorkflowNode":{"type":"object","properties":{"id":{"type":"string","description":"Unique node identifier within the workflow"},"type":{"type":"string","enum":["delay","send_email","send_webhook","wait_for_event","branch","ab_test","goto","exit"],"description":"Node type determining its behavior"},"label":{"type":"string","description":"Human-readable label for the node"},"nextNodeId":{"type":"string","nullable":true,"description":"ID of the next node to execute (null for exit nodes)"},"waitForEvent":{"type":"string","description":"Event name to wait for (wait_for_event nodes only)"},"timeoutMinutes":{"type":"integer","description":"Timeout window in minutes for wait_for_event nodes"},"timeoutNextNodeId":{"type":"string","description":"Node to resume when a wait_for_event timeout expires"},"delayMinutes":{"type":"integer","description":"Legacy delay in minutes. Prefer delayAmount + delayUnit."},"delayAmount":{"type":"integer","description":"Delay duration amount (used with delayUnit)"},"delayUnit":{"type":"string","enum":["minutes","hours","days"],"description":"Delay duration unit"},"templateId":{"type":"string","description":"ID of the email template to send (send_email nodes)"},"inboxId":{"type":"string","description":"Inbox ID to send from for send_email nodes"},"webhookUrl":{"type":"string","format":"uri","description":"Target URL for send_webhook nodes"},"webhookBody":{"type":"string","description":"Liquid-templated JSON body for webhooks"},"webhookAuthHeader":{"type":"string","description":"Authorization header value for webhooks"},"branches":{"type":"array","description":"Conditional branches for branch nodes","items":{"type":"object","properties":{"condition":{"$ref":"#/components/schemas/WorkflowCondition"},"nextNodeId":{"type":"string","description":"Node to jump to when condition matches"}}}},"webhookResponseBranches":{"type":"array","description":"Branch on webhook response data","items":{"type":"object","properties":{"condition":{"$ref":"#/components/schemas/WorkflowCondition"},"nextNodeId":{"type":"string","description":"Node to jump to when condition matches"}}}},"variants":{"type":"array","description":"A/B test variants with weighted distribution","items":{"$ref":"#/components/schemas/AbTestVariant"}},"targetNodeId":{"type":"string","description":"Target node ID for goto nodes"},"maxIterations":{"type":"integer","description":"Max loop iterations for goto nodes (default 10)"}}},"WorkflowCondition":{"type":"object","properties":{"field":{"type":"string","description":"Field path: contact.email, contact.fullName, contact.segmentIds, contact.attributes.*, event.*, message.*, engagement.opened, engagement.clicked, engagement.replied, webhook_response.statusCode, webhook_response.body.*"},"operator":{"type":"string","enum":["equals","contains","exists","not_equals","is_true","is_false"],"description":"Comparison operator"},"value":{"type":"string","description":"Value to compare against (not required for exists, is_true, is_false operators)"}}},"ExitCriterion":{"type":"object","properties":{"trigger":{"type":"string","enum":["reply","bounce","unsubscribe","manual","custom_event"],"description":"Event that triggers workflow exit for the contact"},"eventName":{"type":"string","description":"Custom event name. Required when trigger is custom_event."},"replyClassifications":{"type":"array","items":{"type":"string","enum":["interested","not_interested","out_of_office","wrong_person","unsubscribe","auto_reply"]},"description":"Filter which reply classifications trigger exit (only applies when trigger is reply)"}}},"WorkflowDefinition":{"type":"object","properties":{"id":{"type":"string","description":"Unique workflow identifier"},"name":{"type":"string","description":"Human-readable workflow name"},"version":{"type":"integer","description":"Current version number"},"status":{"type":"string","enum":["active","draft","paused","failed","archived"],"description":"Workflow lifecycle status"},"trigger":{"type":"string","enum":["manual","api","event","scheduled"],"description":"How enrollments are initiated"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowNode"},"description":"Ordered list of workflow steps"},"exitCriteria":{"type":"array","items":{"$ref":"#/components/schemas/ExitCriterion"},"description":"Conditions that automatically exit enrolled contacts from the workflow"},"optOutMode":{"type":"string","enum":["link","reply","header_only"],"description":"Controls how opt-out is presented in emails. 'reply' (default): no visible link, relies on reply-based opt-out and List-Unsubscribe headers. 'link': visible hyperlinked unsubscribe. 'header_only': List-Unsubscribe headers only."},"schedule":{"type":"object","description":"Schedule configuration (only for scheduled trigger workflows)","properties":{"cronExpression":{"type":"string","description":"Cron expression for scheduled enrollment runs"},"contactFilter":{"type":"object","properties":{"segmentId":{"type":"string","description":"Only enroll contacts in this segment"}}}}},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","description":"ISO 8601 last update timestamp"}}},"WorkflowSimulationEvent":{"type":"object","properties":{"eventName":{"type":"string","description":"Simulated event name"},"resourceId":{"type":"string","description":"Simulated resource ID"},"subject":{"type":"string","description":"Simulated message subject"},"preview":{"type":"string","description":"Simulated message preview text"},"payload":{"type":"object","additionalProperties":true,"description":"Custom event payload"}}},"WorkflowSimulationWebhookResponse":{"type":"object","properties":{"statusCode":{"type":"integer","description":"Simulated HTTP status code"},"body":{"type":"object","additionalProperties":true,"description":"Simulated response body"}}},"WorkflowSimulationRequest":{"type":"object","required":["contactId"],"properties":{"contactId":{"type":"string","description":"ID of the contact to simulate the workflow for"},"event":{"$ref":"#/components/schemas/WorkflowSimulationEvent","description":"Simulated inbound event for wait_for_event and exit criteria evaluation"},"webhookResponsesByNodeId":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/WorkflowSimulationWebhookResponse"},"description":"Simulated webhook responses keyed by node ID"},"forcedVariantId":{"type":"string","description":"Force a specific A/B test variant instead of random selection"},"seed":{"type":"integer","description":"Random seed for deterministic variant selection"}}},"WorkflowSimulationTraceStep":{"type":"object","properties":{"nodeId":{"type":"string","description":"ID of the executed node"},"nodeType":{"type":"string","enum":["delay","send_email","send_webhook","wait_for_event","branch","ab_test","goto","exit"],"description":"Type of the executed node"},"label":{"type":"string","description":"Node label"},"outcome":{"type":"string","enum":["advanced","completed","blocked","requires_approval","would_wait","would_delay","failed"],"description":"Result of executing this node"},"nextNodeId":{"type":"string","nullable":true,"description":"Next node that would be executed"},"message":{"type":"string","description":"Human-readable description of what happened"},"details":{"type":"object","additionalProperties":true,"description":"Additional details (rendered email, policy match, etc.)"}}},"WorkflowSimulationResponse":{"type":"object","properties":{"workflowId":{"type":"string","description":"ID of the simulated workflow"},"contactId":{"type":"string","description":"ID of the contact used in the simulation"},"terminalStatus":{"type":"string","enum":["completed","would_wait","blocked","requires_approval","failed"],"description":"Final status the workflow would reach"},"terminalReason":{"type":"string","nullable":true,"description":"Explanation of why the workflow stopped"},"trace":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowSimulationTraceStep"},"description":"Step-by-step execution trace"}}},"Enrollment":{"type":"object","properties":{"id":{"type":"string","description":"Unique enrollment identifier"},"workflowId":{"type":"string","description":"ID of the workflow this enrollment belongs to"},"contactId":{"type":"string","description":"ID of the enrolled contact"},"status":{"type":"string","enum":["active","completed","paused","failed","exited"],"description":"Current enrollment status"},"currentNodeId":{"type":"string","nullable":true,"description":"ID of the workflow node currently being executed"},"exitReason":{"type":"string","nullable":true,"description":"Reason the contact exited the workflow (e.g. reply, bounce)"},"variantId":{"type":"string","nullable":true,"description":"Selected A/B test variant ID (if the workflow uses A/B testing)"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"ExecutionLog":{"type":"object","properties":{"id":{"type":"string","description":"Unique log entry identifier"},"enrollmentId":{"type":"string","description":"ID of the enrollment this log belongs to"},"nodeId":{"type":"string","description":"ID of the workflow node that generated this log"},"status":{"type":"string","enum":["scheduled","running","completed","failed","skipped"],"description":"Execution status of the node"},"message":{"type":"string","description":"Human-readable description of what happened"},"createdAt":{"type":"string","description":"ISO 8601 timestamp"}}},"UsageSummary":{"type":"object","properties":{"totalSent":{"type":"integer","description":"Total emails sent in the current period"},"totalDelivered":{"type":"integer","description":"Total emails successfully delivered"},"deliveryRate":{"type":"number","description":"Delivery success rate (0-1)"},"bounceRate":{"type":"number","description":"Bounce rate (0-1). Alert threshold: 0.02"},"complaintRate":{"type":"number","description":"Spam complaint rate (0-1). Alert threshold: 0.001"},"rejectionRate":{"type":"number","description":"Provider rejection rate (0-1)"}}},"Subscription":{"type":"object","properties":{"id":{"type":"string","description":"Unique subscription identifier"},"organizationId":{"type":"string","description":"ID of the organization"},"plan":{"type":"string","enum":["free","pro"],"description":"Current subscription plan"},"status":{"type":"string","description":"Stripe subscription status (active, past_due, canceled, etc.)"},"stripeCustomerId":{"type":"string","nullable":true,"description":"Stripe customer ID"},"stripeSubscriptionId":{"type":"string","nullable":true,"description":"Stripe subscription ID"},"currentPeriodEnd":{"type":"string","nullable":true,"description":"ISO 8601 timestamp when the current billing period ends"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","description":"ISO 8601 last update timestamp"}}},"UsageCounter":{"type":"object","properties":{"id":{"type":"string","description":"Unique counter identifier"},"metric":{"type":"string","description":"Metric being tracked (e.g. messages_monthly, messages_daily)"},"count":{"type":"integer","description":"Current count for this metric in the current window"},"windowStart":{"type":"string","description":"ISO 8601 start of the counting window"}}},"CheckoutSession":{"type":"object","properties":{"checkoutUrl":{"type":"string","description":"Stripe checkout URL to redirect the user to"},"tier":{"type":"string","description":"Plan tier being purchased"}}},"Invitation":{"type":"object","properties":{"id":{"type":"string","description":"Unique invitation identifier"},"organizationId":{"type":"string","description":"ID of the organization"},"email":{"type":"string","description":"Email address of the invited user"},"role":{"type":"string","enum":["owner","admin","member"],"description":"Role assigned to the invited user"},"accepted":{"type":"boolean","description":"Whether the invitation has been accepted"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"OrganizationMembership":{"type":"object","properties":{"id":{"type":"string","description":"Unique membership identifier"},"organizationId":{"type":"string","description":"ID of the organization"},"userId":{"type":"string","description":"ID of the member user"},"role":{"type":"string","enum":["owner","admin","member"],"description":"Member role within the organization"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"WorkflowAnalytics":{"type":"object","properties":{"workflowId":{"type":"string","description":"ID of the workflow"},"totalEnrollments":{"type":"integer","description":"Total enrollments across all statuses"},"activeEnrollments":{"type":"integer","description":"Currently active enrollments"},"completedEnrollments":{"type":"integer","description":"Enrollments that completed all nodes"},"exitedEnrollments":{"type":"integer","description":"Enrollments that exited via exit criteria"},"failedEnrollments":{"type":"integer","description":"Enrollments that failed due to errors"},"emailsSent":{"type":"integer","description":"Total emails sent by this workflow"},"emailsBounced":{"type":"integer","description":"Total emails that bounced"},"completionRate":{"type":"number","description":"Ratio of completed to total enrollments (0-1)"},"exitRate":{"type":"number","description":"Ratio of exited to total enrollments (0-1)"}}},"BulkEnrollmentResult":{"type":"object","properties":{"contactId":{"type":"string","description":"ID of the contact"},"enrollmentId":{"type":"string","description":"ID of the created enrollment (present when status is enrolled)"},"status":{"type":"string","enum":["enrolled","skipped","failed"],"description":"Outcome for this contact"},"reason":{"type":"string","description":"Explanation when status is skipped or failed"}}},"SendLimit":{"type":"object","properties":{"id":{"type":"string","description":"Unique send limit identifier"},"organizationId":{"type":"string","description":"ID of the organization"},"inboxId":{"type":"string","nullable":true,"description":"ID of the inbox this limit applies to (null for org-wide limit)"},"dailyLimit":{"type":"integer","description":"Maximum emails allowed per day"},"createdAt":{"type":"string","description":"ISO 8601 creation timestamp"}}},"WorkflowTemplate":{"type":"object","properties":{"id":{"type":"string","description":"Unique workflow template identifier"},"name":{"type":"string","description":"Template name"},"description":{"type":"string","description":"What this workflow template does"},"category":{"type":"string","description":"Template category (e.g. onboarding, outreach)"},"trigger":{"type":"string","enum":["manual","api","event","scheduled"],"description":"Default trigger type"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowNode"},"description":"Pre-configured workflow steps"},"exitCriteria":{"type":"array","items":{"$ref":"#/components/schemas/ExitCriterion"},"description":"Pre-configured exit criteria"},"optOutMode":{"type":"string","enum":["link","reply","header_only"],"description":"Default opt-out mode for emails"}}},"AbTestVariant":{"type":"object","properties":{"id":{"type":"string","description":"Unique variant identifier"},"templateId":{"type":"string","description":"ID of the email template for this variant"},"weight":{"type":"integer","minimum":1,"maximum":100,"description":"Percentage weight for this variant (all variant weights should sum to 100)"}}},"ApiError":{"type":"object","properties":{"error":{"type":"object","description":"Error details","properties":{"code":{"type":"string","description":"Machine-readable error code (e.g. invalid_request, not_found, internal_error)"},"message":{"type":"string","description":"Human-readable error description"},"requestId":{"type":"string","description":"Request ID for support reference"}}}}}}},"x-route-catalog":["GET /v1/me","GET /v1/api-keys","POST /v1/api-keys","DELETE /v1/api-keys/:apiKeyId","GET /v1/audit-logs","GET /v1/policies","POST /v1/policies","PATCH /v1/policies/:policyId","DELETE /v1/policies/:policyId","GET /v1/approvals","GET /v1/approvals/:approvalId","POST /v1/approvals/:approvalId/approve","POST /v1/approvals/:approvalId/reject","GET /v1/inboxes","POST /v1/inboxes","GET /v1/inboxes/:inboxId","PATCH /v1/inboxes/:inboxId","DELETE /v1/inboxes/:inboxId","GET /v1/messages","POST /v1/messages/send","GET /v1/messages/:messageId","POST /v1/search/messages","POST /v1/extractions/otp","POST /v1/extractions/invoice-basic","GET /v1/threads","GET /v1/threads/:threadId","GET /v1/domains","POST /v1/domains","GET /v1/domains/:domainId","DELETE /v1/domains/:domainId","GET /v1/webhooks/endpoints","POST /v1/webhooks/endpoints","GET /v1/webhooks/endpoints/:endpointId","PATCH /v1/webhooks/endpoints/:endpointId","DELETE /v1/webhooks/endpoints/:endpointId","GET /v1/webhooks/deliveries","POST /v1/webhooks/deliveries/:deliveryId/replay","GET /v1/events","POST /v1/realtime/sessions","GET /v1/metrics/summary","GET /v1/metrics/timeseries","GET /v1/pods","POST /v1/pods","GET /v1/pods/:podId","DELETE /v1/pods/:podId","GET /v1/contacts","POST /v1/contacts","GET /v1/contacts/:contactId","PATCH /v1/contacts/:contactId","DELETE /v1/contacts/:contactId","GET /v1/segments","POST /v1/segments","GET /v1/segments/:segmentId","PATCH /v1/segments/:segmentId","DELETE /v1/segments/:segmentId","GET /v1/templates","POST /v1/templates","GET /v1/templates/:templateId","PATCH /v1/templates/:templateId","DELETE /v1/templates/:templateId","POST /v1/templates/:templateId/preview","GET /v1/workflows","POST /v1/workflows","GET /v1/workflows/:workflowId","PATCH /v1/workflows/:workflowId","DELETE /v1/workflows/:workflowId","POST /v1/workflows/:workflowId/publish","POST /v1/workflows/:workflowId/pause","POST /v1/workflows/:workflowId/resume","POST /v1/workflows/:workflowId/simulate","GET /v1/enrollments","POST /v1/enrollments","GET /v1/enrollments/:enrollmentId","GET /v1/enrollments/:enrollmentId/logs","GET /v1/organizations","GET /v1/organizations/:organizationId/invitations","POST /v1/organizations/:organizationId/invitations","GET /v1/organizations/:organizationId/memberships","GET /v1/billing/subscription","GET /v1/billing/usage-counters","POST /v1/billing/checkout-session","POST /v1/billing/portal-session","GET /v1/workflow-templates","POST /v1/workflows/from-template","POST /v1/enrollments/bulk","GET /v1/workflows/:workflowId/analytics","GET /v1/send-limits","PUT /v1/send-limits","POST /v1/workflows/:workflowId/nodes/:nodeId/pause","POST /v1/workflows/:workflowId/nodes/:nodeId/resume"]}