{"version":"1.0","title":"Salesbase CRM API — Integration Reference","baseUrl":"/api/v1","sections":{"auth":{"overview":{"title":"Authentication","description":"Integration endpoints use a workspace API key (Bearer sb_…). API keys are created in the Salesbase app under Settings → Workspace → Automation → API Keys. Mobile app endpoints (voice, notifications, timers, assistant, devices, workspaces switch) require JWT login and are not part of this integration reference."},"apiKey":{"title":"API Key Authentication","description":"Use your workspace API key in the Authorization header","format":"Authorization: Bearer <YOUR_API_KEY>","alternativeFormat":"Query parameter: ?api_key=<YOUR_API_KEY> (for tools that cannot set headers)","keyPrefix":"API keys start with 'sb_' prefix","note":"The full API key is only shown once when created. It is stored as a SHA-256 hash — Salesbase cannot recover lost keys."},"rateLimits":{"title":"Rate Limits","description":"All API keys share fixed rate limits to ensure fair usage and platform stability","defaults":{"minuteLimit":"120 requests per minute","dailyLimit":"50,000 requests per day"},"headers":{"X-RateLimit-Limit-Minute":"Maximum requests allowed per minute (120)","X-RateLimit-Remaining-Minute":"Remaining requests in the current minute window","X-RateLimit-Limit-Day":"Maximum requests allowed per day (50,000)","X-RateLimit-Remaining-Day":"Remaining requests in the current day window"},"exceeded":"Returns HTTP 429 Too Many Requests when limits are exceeded"},"errors":{"title":"Error Responses","codes":{"400":{"description":"Bad Request — invalid parameters or missing required fields"},"401":{"description":"Unauthorized — missing or invalid API key","body":"{ \"error\": \"Invalid API key\" }"},"403":{"description":"Forbidden — API key is revoked or workspace is suspended"},"404":{"description":"Not Found — resource does not exist or belongs to another workspace"},"429":{"description":"Too Many Requests — rate limit exceeded"},"500":{"description":"Internal Server Error — unexpected server error"}}},"responseFormat":{"title":"Standard Response Format","success":{"description":"Successful responses wrap data in a 'data' key","single":"{ \"data\": { \"_id\": \"...\", \"name\": \"...\", ... } }","list":"{ \"data\": [...], \"page\": 1, \"limit\": 20, \"total\": 150 }"},"error":{"description":"Error responses include an 'error' key with a message string","format":"{ \"error\": \"Description of what went wrong\" }"}},"quickStart":{"title":"Quick Start","steps":[{"step":1,"title":"Create an API key","description":"Go to Settings → Workspace → Automation → API Keys and create a new key. Copy the key immediately — it won't be shown again."},{"step":2,"title":"Test the connection","description":"Make a GET request to /api/v1/leads to verify your key works","example":{"curl":"curl -H \"Authorization: Bearer sb_your_api_key_here\" https://app.salesbase.dk/api/v1/leads"}},{"step":3,"title":"Explore the API","description":"Use GET /api/v1/docs to get the full API documentation as JSON"}]},"bestPractices":["Store API keys in environment variables, never in code","Use the minimum required permissions/scopes for each key","Rotate keys periodically and revoke unused keys","Handle rate limit errors (429) with exponential backoff","Always include error handling for network failures","Use the workspace-scoped endpoints — all data is automatically filtered by your workspace"],"inboundWebhooks":{"title":"Inbound webhooks (external → Salesbase)","description":"These endpoints receive data from external systems. They are outside /api/v1 but documented here for integrators.","endpoints":[{"method":"POST","path":"/api/webhooks/automation/:automationId","description":"Trigger a webhook-type automation. JSON body is available as webhookData.* placeholders in the flow.","authentication":"Header x-webhook-secret must match the secret configured on the automation trigger node.","example":{"curl":"curl -X POST -H \"Content-Type: application/json\" -H \"x-webhook-secret: YOUR_SECRET\" -d '{\"email\":\"lead@example.com\"}' https://app.salesbase.dk/api/webhooks/automation/AUTOMATION_ID"}},{"method":"POST","path":"/api/v1/webhooks/zapier","description":"Zapier-specific inbound — creates person, lead, and deal. Uses Bearer API key (inbound scope).","authentication":"Authorization: Bearer sb_…"},{"method":"POST","path":"/api/v1/inbound","description":"Unified inbound creation for forms and integrations. Uses Bearer API key (inbound scope)."}]}},"automations":{"overview":{"title":"Automations","description":"Automations are event-driven flows that execute actions when specific triggers fire. Each automation has exactly one trigger node and one or more action/condition/delay/AI nodes connected by edges. Automations are stored as ReactFlow graphs (nodes + edges) and executed by a cron-based step processor.","concepts":{"flow":"An automation flow is a directed graph of nodes connected by edges. It always starts with a single trigger node.","trigger":"The entry point — fires when a specific event occurs (e.g. lead_created, deal_stage_changed).","action":"Performs an operation (send email, create lead, HTTP request, etc.).","condition":"Evaluates rules and branches the flow into 'true' or 'false' paths.","delay":"Pauses execution for a specified duration before continuing.","ai":"Sends context to an AI model and uses the response in subsequent nodes.","edge":"Connects two nodes. For condition nodes, edges use sourceHandle 'true' or 'false' to define branches."}},"endpoints":[{"method":"GET","path":"/api/v1/automations","description":"List all automations in the workspace","queryParams":{"page":{"type":"number","default":1,"description":"Page number"},"limit":{"type":"number","default":20,"max":100,"description":"Items per page"},"isActive":{"type":"string","enum":["true","false"],"description":"Filter by active status"}},"response":{"data":"Automation[]","page":"number","limit":"number","total":"number"}},{"method":"POST","path":"/api/v1/automations","description":"Create a new automation","body":{"name":{"type":"string","required":true,"description":"Automation name"},"description":{"type":"string","required":false,"description":"Description of what this automation does"},"nodes":{"type":"Node[]","required":false,"description":"Array of flow nodes (see Node Structure below)"},"edges":{"type":"Edge[]","required":false,"description":"Array of edges connecting nodes (see Edge Structure below)"}},"response":{"data":"Automation"},"statusCode":201},{"method":"GET","path":"/api/v1/automations/:id","description":"Get a single automation by ID","response":{"data":"Automation"}},{"method":"PUT","path":"/api/v1/automations/:id","description":"Update an automation","body":{"name":{"type":"string","required":false},"description":{"type":"string","required":false},"nodes":{"type":"Node[]","required":false},"edges":{"type":"Edge[]","required":false},"executionSettings":{"type":"ExecutionSettings","required":false},"rateLimits":{"type":"RateLimits","required":false}},"response":{"data":"Automation"}},{"method":"DELETE","path":"/api/v1/automations/:id","description":"Delete an automation. Fails if there are running executions.","response":{"data":{"deleted":true}}},{"method":"POST","path":"/api/v1/automations/:id/toggle","description":"Toggle automation active/inactive","response":{"data":{"_id":"string","isActive":"boolean"}}},{"method":"GET","path":"/api/v1/automations/:id/executions","description":"List executions for an automation","queryParams":{"page":{"type":"number","default":1},"limit":{"type":"number","default":20,"max":100},"status":{"type":"string","enum":["running","completed","failed","cancelled"]}},"response":{"data":"AutomationExecution[]","page":"number","limit":"number","total":"number"}},{"method":"GET","path":"/api/v1/automations/executions/:executionId","description":"Get a single execution with full step log","response":{"data":"AutomationExecution"}},{"method":"GET","path":"/api/v1/automations/stats","description":"Get aggregate automation statistics for the workspace","response":{"data":{"totalAutomations":"number","activeAutomations":"number","totalExecutions":"number","executionsByStatus":"{ running: number, completed: number, failed: number, cancelled: number }","avgDuration":"number|null (milliseconds)"}}},{"method":"POST","path":"/api/v1/automations/:id/duplicate","description":"Duplicate an automation (creates inactive copy)","response":{"data":"Automation"}},{"method":"POST","path":"/api/v1/automations/:id/test","description":"Run automation in test mode with sample context","body":{"testContext":{"type":"object","description":"Optional context overrides"}}},{"method":"POST","path":"/api/v1/automations/:id/trigger","description":"Manually trigger an active automation","body":{"context":{"type":"object","description":"Trigger context payload"}}},{"method":"POST","path":"/api/v1/automations/executions/:executionId/cancel","description":"Cancel a running automation execution","response":{"data":{"cancelled":true}}}],"nodeStructure":{"description":"Every node in the flow has this base structure:","schema":{"id":{"type":"string","required":true,"description":"Unique node ID. Convention: {type}_{timestamp}_{index}"},"type":{"type":"string","required":true,"enum":["trigger","action","condition","delay","ai","lookup"],"description":"Canvas node type"},"position":{"type":"object","required":true,"description":"Canvas position { x, y }. Vertical flows: x=500, increment y by 200 per row."},"data":{"type":"object","required":true,"description":"Node config. Triggers: triggerType + config. Actions: actionType + config."}}},"triggerTypes":{"description":"Each automation must have exactly ONE trigger node. Set data.triggerType and optional data.config on the trigger node.","types":{"lead_created":{"label":"Lead oprettet","description":"Starter når et nyt lead oprettes.","category":"leads","config":{},"placeholders":["lead.*","person.*","company.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"lead_updated":{"label":"Lead opdateret","description":"Starter når et lead opdateres.","category":"leads","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"company_updated":{"label":"Virksomhed opdateret","description":"Starter når en virksomhed opdateres.","category":"general","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"person_updated":{"label":"Person opdateret","description":"Starter når en person opdateres.","category":"general","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"deal_created":{"label":"Deal oprettet","description":"Starter når en deal oprettes.","category":"deals","config":{},"placeholders":["deal.*","company.*","person.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"deal_updated":{"label":"Deal opdateret","description":"Starter når en deal opdateres.","category":"deals","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"deal_won":{"label":"Deal vundet","description":"Starter når en deal markeres som vundet.","category":"deals","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"deal_lost":{"label":"Deal tabt","description":"Starter når en deal markeres som tabt.","category":"deals","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"deal_stage_changed":{"label":"Deal stage ændret","description":"Starter når en deal flyttes til et nyt stage.","category":"deals","config":{"stageId":{"type":"string","description":"Begræns til et bestemt stage (valgfrit — tom = alle stage-skift)","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"call_completed":{"label":"Opkald afsluttet","description":"Starter når et opkald afsluttes.","category":"calls","config":{},"placeholders":["call.*","lead.*","deal.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"call_answered":{"label":"Opkald besvaret","description":"Starter når et opkald bliver besvaret.","category":"calls","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"email_received":{"label":"Email modtaget","description":"Starter når en email modtages.","category":"email","config":{},"placeholders":["email.*","lead.*","person.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"email_opened":{"label":"Email åbnet","description":"Starter når en sendt email åbnes.","category":"email","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"email_replied":{"label":"Email besvaret","description":"Starter når en email besvares.","category":"email","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"sms_received":{"label":"SMS modtaget","description":"Starter når en SMS modtages.","category":"sms","config":{"keyword":{"type":"string","description":"Valgfrit keyword-filter — kun beskeder der indeholder dette ord udløser","storage":"node.data.config"}},"placeholders":["sms.*","lead.*","person.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"sms_replied":{"label":"SMS besvaret","description":"Starter når en SMS besvares.","category":"sms","config":{"keyword":{"type":"string","description":"Valgfrit keyword-filter","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"event_created":{"label":"Begivenhed oprettet","description":"Starter når en kalenderbegivenhed oprettes.","category":"calendar","config":{},"placeholders":["event.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"agent_field_change":{"label":"Agent: feltændring","description":"Starter når en AI-agent ændrer et felt.","category":"agents","config":{"agentId":{"type":"string","description":"Hvilken agent","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"agent_new_company":{"label":"Agent: ny virksomhed","description":"Starter når en AI-agent opretter en ny virksomhed.","category":"agents","config":{"agentId":{"type":"string","description":"Hvilken agent","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"agent_any":{"label":"Agent: enhver hændelse","description":"Starter ved enhver AI-agent-hændelse.","category":"agents","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"sales_analytics_done":{"label":"Salgsanalyse færdig","description":"Starter når en salgsanalyse er færdig.","category":"analytics","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"transcription_ready":{"label":"Transskription klar","description":"Starter når en opkaldstransskription er klar.","category":"analytics","config":{},"placeholders":["call.*","transcript.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_created":{"label":"Tilbud oprettet","description":"Starter når et tilbud oprettes.","category":"offers","config":{},"placeholders":["offer.*","deal.*","company.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_sent":{"label":"Tilbud sendt","description":"Starter når et tilbud sendes.","category":"offers","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_viewed":{"label":"Tilbud set","description":"Starter når et tilbud åbnes af modtageren.","category":"offers","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_accepted":{"label":"Tilbud accepteret","description":"Starter når et tilbud accepteres.","category":"offers","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_rejected":{"label":"Tilbud afvist","description":"Starter når et tilbud afvises.","category":"offers","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_expired":{"label":"Tilbud udløbet","description":"Starter når et tilbud udløber.","category":"offers","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"offer_pdf_downloaded":{"label":"Tilbuds-PDF hentet","description":"Starter når tilbuds-PDF'en downloades.","category":"offers","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"booking_created":{"label":"Booking oprettet","description":"Starter når en booking oprettes.","category":"bookings","config":{"bookingConfigId":{"type":"string","description":"Begræns til en bestemt bookingside (valgfrit)","storage":"node.data.config"}},"placeholders":["booking.*","person.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"booking_cancelled":{"label":"Booking aflyst","description":"Starter når en booking aflyses.","category":"bookings","config":{"bookingConfigId":{"type":"string","description":"Bookingside (valgfrit)","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"booking_rescheduled":{"label":"Booking flyttet","description":"Starter når en booking flyttes.","category":"bookings","config":{"bookingConfigId":{"type":"string","description":"Bookingside (valgfrit)","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"booking_approved":{"label":"Booking godkendt","description":"Starter når en booking godkendes.","category":"bookings","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"booking_rejected":{"label":"Booking afvist","description":"Starter når en booking afvises.","category":"bookings","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"calculator_submission":{"label":"Beregner indsendt","description":"Starter når en beregner indsendes.","category":"calculators","config":{"calculatorTemplateId":{"type":"string","description":"Begræns til en bestemt beregner (valgfrit)","storage":"node.data.config"}},"placeholders":["calculator.*","lead.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"calculator_submission_processed":{"label":"Beregner behandlet","description":"Starter når en beregner-indsendelse er færdigbehandlet.","category":"calculators","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"reply_intent_detected":{"label":"Svar-intention registreret","description":"Starter når AI registrerer en intention i et svar.","category":"ai","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"lifecycle_stage_changed":{"label":"Livscyklus-stage ændret","description":"Starter når en kontakts livscyklus-stage ændres.","category":"ai","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"engagement_risk_detected":{"label":"Engagement-risiko","description":"Starter når der registreres risiko for lavt engagement.","category":"ai","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"winback_opportunity":{"label":"Winback-mulighed","description":"Starter når der opstår en winback-mulighed.","category":"ai","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_created":{"label":"Supportsag oprettet","description":"Starter når en supportsag oprettes.","category":"support","config":{},"placeholders":["ticket.*","person.*","company.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_updated":{"label":"Supportsag opdateret","description":"Starter når en supportsag opdateres.","category":"support","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_resolved":{"label":"Supportsag løst","description":"Starter når en supportsag løses.","category":"support","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_closed":{"label":"Supportsag lukket","description":"Starter når en supportsag lukkes.","category":"support","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_reopened":{"label":"Supportsag genåbnet","description":"Starter når en supportsag genåbnes.","category":"support","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_stage_changed":{"label":"Supportsag stage ændret","description":"Starter når en supportsag skifter stage.","category":"support","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"support_ticket_assigned":{"label":"Supportsag tildelt","description":"Starter når en supportsag tildeles en bruger.","category":"support","config":{},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"tag_added":{"label":"Tag tilføjet","description":"Starter når et tag tilføjes til en entity.","category":"general","config":{"entityType":{"type":"enum","description":"Hvilken entitetstype skal lyttes på","enum":["all","Lead","People","Company"],"default":"all","storage":"node.data.config"},"tagId":{"type":"string","description":"Specifikt tag-id, eller 'any' for alle tags","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"tag_removed":{"label":"Tag fjernet","description":"Starter når et tag fjernes fra en entity.","category":"general","config":{"entityType":{"type":"enum","description":"Entitetstype","enum":["all","Lead","People","Company"],"default":"all","storage":"node.data.config"},"tagId":{"type":"string","description":"Tag-id eller 'any'","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"user_joined_workspace":{"label":"Bruger tilføjet","description":"Starter når en bruger tilføjes til workspacet.","category":"users","config":{},"placeholders":["owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"meta_lead_form_submitted":{"label":"Meta lead-formular","description":"Starter når en Meta/Facebook lead-formular indsendes. Lead oprettes automatisk medmindre »Opret leads automatisk« er slået fra under Meta-indstillinger.","category":"integrations","config":{},"placeholders":["lead.*","meta.*","person.*","company.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"custom_object_created":{"label":"Brugerdefineret objekt oprettet","description":"Starter når en record oprettes i et brugerdefineret objekt.","category":"custom_objects","config":{"customObjectId":{"type":"string","description":"Begræns til specifikt objekt (valgfrit)","storage":"node.data.config"}},"placeholders":["custom_record.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"custom_object_updated":{"label":"Brugerdefineret objekt opdateret","description":"Starter når en record opdateres i et brugerdefineret objekt.","category":"custom_objects","config":{"customObjectId":{"type":"string","description":"Begræns til specifikt objekt (valgfrit)","storage":"node.data.config"}},"placeholders":["custom_record.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":""},"record_created":{"label":"Record oprettet","description":"Starter når en valgt record-type oprettes (lead, deal, tilbud, event, support ticket, booking).","category":"deals","config":{"entityTypes":{"type":"enum","description":"Hvilke record-typer der overvåges ved oprettelse","enum":["all","lead","deal","offer","event","support_ticket","booking"],"default":"all","storage":"node.data.config"}},"placeholders":["lead.*","deal.*","offer.*","event.*","ticket.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":"","note":"Preferred over legacy single-entity triggers (lead_created, deal_created, etc.) for new flows."},"record_changed":{"label":"Record ændret","description":"Starter når en valgt record opdateres eller tags ændres.","category":"leads","config":{"entityTypes":{"type":"enum","description":"Hvilke entiteter der overvåges","enum":["all","lead","deal","company","person"],"default":"all","storage":"node.data.config"},"changeTypes":{"type":"enum","description":"Hvilke ændringstyper der udløser","enum":["all","updated","tag_added","tag_removed"],"default":"all","storage":"node.data.config"},"tagId":{"type":"string","description":"Specifikt tag-id ved tag-ændringer, eller 'any'","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":"","note":"Preferred over legacy single-entity triggers (lead_created, deal_created, etc.) for new flows."},"scheduled":{"label":"Tidsplan","description":"Starter på en fast tidsplan (cron-lignende).","category":"scheduling","config":{"frequency":{"type":"enum","description":"Hvor ofte den kører","enum":["hourly","daily","weekly","monthly"],"default":"daily","storage":"node.data.config"},"dayOfWeek":{"type":"number","description":"Ugedag 0-6 (kun weekly)","storage":"node.data.config"},"dayOfMonth":{"type":"number","description":"Dag i måneden 1-28 (kun monthly)","storage":"node.data.config"},"time":{"type":"string","description":"Tidspunkt HH:mm (ved hourly bruges kun minuttet — fx 00:15 = hvert kvarter over)","default":"09:00","storage":"node.data.config"}},"placeholders":["lead.*","owner.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":"Daglig kl. 09:00: frequency=daily, time=09:00. Hver time på :00: frequency=hourly, time=00:00. Kombinér typisk med en lookup-node der finder de relevante entities."},"webhook":{"label":"Webhook","description":"Starter når en ekstern webhook kalder automationens unikke URL.","category":"scheduling","config":{"secret":{"type":"string","description":"Valgfri hemmelighed til at validere kald","storage":"node.data.config"},"entityMapping":{"type":"object","description":"Mapping af payload til entity: { entityType: Lead|People|Company|Deal|none, entityIdField }","storage":"node.data.config"}},"placeholders":["webhook.*"],"uiGuide":"Triggeren er den øverste node. Klik på den → panelet til højre viser 'Trigger type' øverst. Vælg event i dropdownen; eventuelle ekstra felter (fx tidsplan, keyword, webhook) vises under.","example":"Webhook-URL'en findes i trigger-panelet og kaldes udefra. Payload-felter bliver til {{webhook.<felt>}}.","note":"Webhook URL: POST /api/webhooks/automation/{automationId}. Payload fields available as {{webhookData.fieldName}}."}}},"actionTypes":{"description":"Action nodes perform operations. Set data.actionType and data.config on the node.","types":{"send_email":{"label":"Send email","description":"Sender en email til en kontakt på entityen.","group":"communication","config":{"subject":{"type":"string","description":"Emnelinje — kritisk indhold brugeren skal angive (medmindre template vælges)","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"body":{"type":"string","description":"Email-brødtekst (HTML) — kritisk indhold (medmindre template vælges)","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"templateId":{"type":"string","description":"Brug en eksisterende email-template i stedet for at skrive emne/body","storage":"node.data.config"},"recipientField":{"type":"enum","description":"Hvilken email-adresse: primary=Primær (første tilgængelige), secondary=Sekundær, work/privat/cvr/ai/faktura/support=type-markeret email, person/company=via forbindelse, priority=Person→Virksomhed, any=første tilgængelige, all=alle (multi-send), custom=fast adresse i feltet 'to'.","enum":["primary","secondary","work","privat","cvr","ai","faktura","support","person","company","priority","any","all","custom"],"default":"primary","storage":"node.data.config"},"recipientType":{"type":"enum","description":"KUN relevant når entityen er et Lead: 'auto'=kontakt først, ellers firma; 'contact'=personRef; 'company'=companyRef. Bestemmer om mailen går til kontakten eller firmaet.","enum":["auto","contact","company"],"default":"auto","storage":"node.data.config"},"to":{"type":"string","description":"KUN når recipientField=custom: fast email eller {{placeholder}}.","supportsPlaceholders":true,"storage":"node.data.config"},"senderAccountId":{"type":"string","description":"Afsenderkonto — auto-detekteres hvis tom; spørg ikke","storage":"node.data.config"}},"produces":["emailSent.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"Spørg ALTID om emne+indhold hvis ingen template er valgt. Slå afsender op — spørg aldrig om den. recipientType gælder kun Leads (kontakt vs. firma).","deprecated":false},"send_sms":{"label":"Send SMS","description":"Sender en SMS til et telefonnummer på entityen.","group":"communication","config":{"message":{"type":"string","description":"SMS-tekst — kritisk indhold brugeren skal angive","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"phoneField":{"type":"enum","description":"Hvilket telefonfelt der bruges","enum":["primary","mobile","work","all","custom"],"default":"primary","storage":"node.data.config"},"fromNumber":{"type":"string","description":"Afsendernummer — bruger workspace-default hvis tom","storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"Spørg om beskedteksten. Slå afsendernummer op via listTwilioNumbers.","deprecated":false},"create_task":{"label":"Opret opgave","description":"Opretter en opgave/aktivitet på entityen.","group":"crm","config":{"title":{"type":"string","description":"Opgavens titel","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"description":{"type":"string","description":"Beskrivelse","supportsPlaceholders":true,"storage":"node.data.config"},"activityType":{"type":"enum","description":"Aktivitetstype","enum":["task","call","meeting","follow_up","email","deadline","reminder"],"default":"task","storage":"node.data.config"},"priority":{"type":"enum","description":"Prioritet","enum":["low","medium","high"],"default":"medium","storage":"node.data.config"},"dueInDays":{"type":"number","description":"Antal dage til deadline (0 = i dag)","default":0,"storage":"node.data.config"},"assignTo":{"type":"string","description":"Hvem opgaven tildeles — default entity-ejer","storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"create_recall":{"label":"Opret genopkald","description":"Opretter et planlagt genopkald (recall).","group":"crm","config":{"title":{"type":"string","description":"Recall-titel","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"message":{"type":"string","description":"Noter til opkaldet","storage":"node.data.config"},"phoneField":{"type":"enum","description":"Telefonfelt","enum":["primary","mobile","work","custom"],"default":"primary","storage":"node.data.config"},"delayDays":{"type":"number","description":"Dage til genopkald","default":0,"storage":"node.data.config"},"assignTo":{"type":"string","description":"Tildeles til — default ejer","storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"create_note":{"label":"Opret note","description":"Tilføjer en note på entityen.","group":"crm","config":{"content":{"type":"string","description":"Notens indhold","required":true,"supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"create_activity":{"label":"Opret aktivitet","description":"Logger en aktivitet på tidslinjen.","group":"crm","config":{"activityType":{"type":"string","description":"Aktivitetstype","storage":"node.data.config"},"description":{"type":"string","description":"Beskrivelse af aktiviteten","required":true,"supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"update_record":{"label":"Opdater felt","description":"Opdaterer ét eller flere felter på entityen.","group":"crm","config":{"fieldPath":{"type":"string","description":"Felt der opdateres (fx status, customFields.score)","required":true,"storage":"node.data.config"},"value":{"type":"string","description":"Ny værdi","required":true,"supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"assign_user":{"label":"Tildel adgang (legacy)","description":"Legacy — brug set_access i stedet.","group":"crm","config":{"assignmentType":{"type":"enum","description":"","enum":["owner","ownerGroup","share","shareGroup"],"default":"owner","storage":"node.data.config"},"userId":{"type":"string","description":"Bruger","storage":"node.data.config"},"groupId":{"type":"string","description":"Gruppe","storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"set_access":{"label":"Tildel adgang","description":"Sæt ejer, synlighed (gruppe/privat) og deling.","group":"crm","config":{"recordType":{"type":"enum","description":"","enum":["trigger","lead","deal","company","person","project","supportTicket","customObject"],"default":"trigger","storage":"node.data.config"},"accessState":{"type":"object","description":"Adgangskonfiguration (ejer, synlighed, delinger)","required":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"move_deal_stage":{"label":"Flyt deal stage","description":"Flytter dealen til et nyt pipeline-stage.","group":"crm","config":{"stageId":{"type":"string","description":"Mål-stage","storage":"node.data.config"}},"produces":[],"consumes":["deal.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"create_lead":{"label":"Opret lead","description":"Opretter et nyt lead. (Deprecated — use create_record.)","group":"crm","config":{"title":{"type":"string","description":"Lead-titel/navn","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"email":{"type":"string","description":"Email","supportsPlaceholders":true,"storage":"node.data.config"},"phone":{"type":"string","description":"Telefon","supportsPlaceholders":true,"storage":"node.data.config"},"status":{"type":"string","description":"Status — default workspace-standard","storage":"node.data.config"}},"produces":["createdLead.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":true},"create_deal":{"label":"Opret deal","description":"Opretter en ny deal i en pipeline. (Deprecated — use create_record.)","group":"crm","config":{"title":{"type":"string","description":"Deal-titel","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"value":{"type":"number","description":"Værdi","storage":"node.data.config"},"flowRef":{"type":"string","description":"Pipeline (flowRef)","storage":"node.data.config"},"stageId":{"type":"string","description":"Start-stage","storage":"node.data.config"}},"produces":["createdDeal.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":true},"create_contact":{"label":"Opret kontakt","description":"Opretter en ny person/kontakt. (Deprecated — use create_record.)","group":"crm","config":{"firstName":{"type":"string","description":"Fornavn","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"lastName":{"type":"string","description":"Efternavn","supportsPlaceholders":true,"storage":"node.data.config"},"email":{"type":"string","description":"Email","supportsPlaceholders":true,"storage":"node.data.config"}},"produces":["createdContact.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":true},"add_to_sequence":{"label":"Tilmeld sequence","description":"Tilmelder entityen til en sequence.","group":"communication","config":{"sequenceId":{"type":"string","description":"Hvilken sequence","storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"create_offer":{"label":"Opret tilbud","description":"Opretter et tilbud. (Deprecated — use create_record.)","group":"crm","config":{"templateId":{"type":"string","description":"Tilbudsskabelon","storage":"node.data.config"},"title":{"type":"string","description":"Tilbudstitel","required":true,"supportsPlaceholders":true,"storage":"node.data.config"}},"produces":["createdOffer.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":true},"http_request":{"label":"HTTP-kald","description":"Sender et HTTP-request til et eksternt endpoint og gør svaret tilgængeligt som variabler.","group":"general","config":{"method":{"type":"enum","description":"HTTP-metode","enum":["GET","POST","PUT","PATCH","DELETE"],"default":"GET","storage":"node.data.config"},"url":{"type":"string","description":"Endpoint-URL — kritisk","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"headers":{"type":"object","description":"HTTP-headers som key/value","storage":"node.data.config"},"body":{"type":"json","description":"Request-body (JSON, kan indeholde placeholders)","supportsPlaceholders":true,"storage":"node.data.config"},"responseMapping":{"type":"object","description":"Map felter fra svaret til navngivne variabler","storage":"node.data.config"}},"produces":["httpResponse.*","httpResponse.status","httpResponse.body"],"consumes":["lead.*","deal.*","ai_json.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"Svaret tilgås som {{httpResponse.body.<felt>}}. Spørg om URL og metode; resten kan defaultes.","deprecated":false},"send_webhook":{"label":"Send webhook","description":"Sender en webhook (POST) til en URL.","group":"general","config":{"url":{"type":"string","description":"Webhook-URL — kritisk","required":true,"supportsPlaceholders":true,"storage":"node.data.config"},"payload":{"type":"json","description":"Payload (JSON)","supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"ordrestyring_create_debtor":{"label":"Opret debitor","description":"Opretter en debitor i økonomisystemet.","group":"integrations","config":{"mapping":{"type":"object","description":"Mapping af entity-felter til debitor-felter (navn, CVR, email)","storage":"node.data.config"}},"produces":["debtor.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"ordrestyring_update_debtor":{"label":"Opdater debitor","description":"Opdaterer en eksisterende debitor.","group":"integrations","config":{"mapping":{"type":"object","description":"Felter der opdateres","storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"ordrestyring_create_case":{"label":"Opret sag","description":"Opretter en sag i økonomisystemet.","group":"integrations","config":{"mapping":{"type":"object","description":"Sags-felter","storage":"node.data.config"}},"produces":["case.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"ordrestyring_create_order_confirmation":{"label":"Opret ordrebekræftelse","description":"Opretter en ordrebekræftelse i økonomisystemet.","group":"integrations","config":{"mapping":{"type":"object","description":"Ordre-felter og linjer","storage":"node.data.config"}},"produces":["orderConfirmation.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"create_record":{"label":"Opret record","description":"Opretter lead, deal, kontakt, tilbud eller brugerdefineret objekt-record i ét samlet trin.","group":"crm","config":{"recordType":{"type":"enum","description":"Hvilken record-type der oprettes","enum":["lead","deal","contact","offer","custom_object"],"default":"lead","required":true,"storage":"node.data.config"},"fieldValues":{"type":"object","description":"Standardfelter for record-typen (fx title, email, value, stageId)","supportsPlaceholders":true,"storage":"node.data.config"},"customFields":{"type":"array","description":"Brugerdefinerede felter [{ name, value, type }]","storage":"node.data.config"},"customObjectId":{"type":"string","description":"Påkrævet når recordType=custom_object — ID på objektdefinition","storage":"node.data.config"}},"produces":["createdRecord.*","createdLead.*","createdDeal.*","createdContact.*","createdOffer.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"Brug create_record i stedet for legacy create_lead/create_deal/create_contact/create_offer.","deprecated":false},"add_to_list":{"label":"Tilføj til liste","description":"Tilføjer entityen til en statisk liste.","group":"lists","config":{"listId":{"type":"string","description":"Mål-liste (statisk liste-ID)","required":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"remove_from_list":{"label":"Fjern fra liste","description":"Fjerner entityen fra en statisk liste.","group":"lists","config":{"listId":{"type":"string","description":"Liste entityen fjernes fra","required":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"billy_create_contact":{"label":"Billy: Opret kontakt","description":"Opretter en kontakt i Billy.","group":"integrations","config":{"mapping":{"type":"object","description":"Mapping af entity-felter til Billy-kontakt","storage":"node.data.config"}},"produces":["billyContact.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"apacta_create_contact":{"label":"Apacta: Opret kontakt","description":"Opretter en kontakt i Apacta.","group":"integrations","config":{"mapping":{"type":"object","description":"Mapping af entity-felter til Apacta-kontakt","storage":"node.data.config"}},"produces":["apactaContact.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"economic_create_customer":{"label":"e-conomic: Opret kunde","description":"Opretter en kunde i e-conomic.","group":"integrations","config":{"mapping":{"type":"object","description":"Mapping til e-conomic kunde-felter (navn, CVR, email)","storage":"node.data.config"}},"produces":["economicCustomer.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"economic_create_invoice":{"label":"e-conomic: Opret faktura","description":"Opretter en faktura i e-conomic.","group":"integrations","config":{"mapping":{"type":"object","description":"Fakturalinjer og kunde-reference","storage":"node.data.config"}},"produces":["economicInvoice.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"economic_book_invoice":{"label":"e-conomic: Bogfør faktura","description":"Bogfører en faktura i e-conomic.","group":"integrations","config":{"invoiceId":{"type":"string","description":"Faktura-ID eller {{placeholder}}","supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"uniconta_create_customer":{"label":"Uniconta: Opret kunde","description":"Opretter en kunde i Uniconta.","group":"integrations","config":{"mapping":{"type":"object","description":"Mapping til Uniconta kunde-felter","storage":"node.data.config"}},"produces":["unicontaCustomer.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"uniconta_create_invoice":{"label":"Uniconta: Opret faktura","description":"Opretter en faktura i Uniconta.","group":"integrations","config":{"mapping":{"type":"object","description":"Fakturalinjer og kunde-reference","storage":"node.data.config"}},"produces":["unicontaInvoice.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"uniconta_book_invoice":{"label":"Uniconta: Bogfør faktura","description":"Bogfører en faktura i Uniconta.","group":"integrations","config":{"invoiceId":{"type":"string","description":"Faktura-ID eller {{placeholder}}","supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"dinero_create_contact":{"label":"Dinero: Opret kontakt","description":"Opretter en kontakt i Dinero.","group":"integrations","config":{"mapping":{"type":"object","description":"Mapping til Dinero kontakt-felter","storage":"node.data.config"}},"produces":["dineroContact.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"dinero_create_invoice":{"label":"Dinero: Opret faktura","description":"Opretter en faktura i Dinero.","group":"integrations","config":{"mapping":{"type":"object","description":"Fakturalinjer og kunde-reference","storage":"node.data.config"}},"produces":["dineroInvoice.*"],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false},"dinero_book_invoice":{"label":"Dinero: Bogfør faktura","description":"Bogfører en faktura i Dinero.","group":"integrations","config":{"invoiceId":{"type":"string","description":"Faktura-ID eller {{placeholder}}","supportsPlaceholders":true,"storage":"node.data.config"}},"produces":[],"consumes":["lead.*","person.*","company.*","deal.*","owner.*"],"uiGuide":"Klik på action-noden → panelet til højre viser action-typen øverst og dens felter nedenunder.","example":"","deprecated":false}}},"conditionNode":{"description":"Condition nodes evaluate rules and branch the flow. Edges use sourceHandle 'true' (met) or 'false' (not met).","dataSchema":{"label":{"type":"string","description":"Display label"},"conditions":{"type":"array","description":"Array of { id, field, operator, value, dataType? }"},"logic":{"type":"string","enum":["and","or"],"description":"Combine multiple conditions"}},"operators":[{"key":"equals","label":"equals"},{"key":"not_equals","label":"not equals"},{"key":"contains","label":"contains"},{"key":"not_contains","label":"not contains"},{"key":"starts_with","label":"starts with"},{"key":"ends_with","label":"ends with"},{"key":"matches_regex","label":"matches regex"},{"key":"greater_than","label":"greater than"},{"key":"less_than","label":"less than"},{"key":"greater_than_or_equal","label":"greater than or equal"},{"key":"less_than_or_equal","label":"less than or equal"},{"key":"between","label":"between"},{"key":"is_empty","label":"is empty"},{"key":"is_not_empty","label":"is not empty"},{"key":"exists","label":"exists"},{"key":"not_exists","label":"not exists"},{"key":"is_true","label":"is true"},{"key":"is_false","label":"is false"},{"key":"array_contains","label":"array contains"},{"key":"array_length_equals","label":"array length equals"},{"key":"array_length_greater","label":"array length greater"},{"key":"date_before","label":"date before"},{"key":"date_after","label":"date after"},{"key":"date_equals","label":"date equals"},{"key":"date_within_days","label":"date within days"}],"fields":{"conditions":{"type":"array","description":"Liste af { id, field, operator, value }. field er en sti (fx lead.score, deal.value, ai_json.intent).","required":true,"storage":"node.data"},"logic":{"type":"enum","description":"Hvordan flere betingelser kombineres","enum":["and","or"],"default":"and","storage":"node.data"}},"uiGuide":"Klik på betingelses-noden → panelet 'Betingelser' åbner. Hver betingelse har felt-vælger, operator-dropdown og værdi. Husk at trække BÅDE den grønne (true) og røde (false) udgang videre."},"delayNode":{"description":"Delay nodes pause execution for a specified duration before continuing.","dataSchema":{"label":{"type":"string","description":"Display label"},"delayAmount":{"type":"number","required":true,"description":"Amount of time to wait"},"delayUnit":{"type":"string","required":true,"enum":["minutes","hours","days","weeks"],"description":"Time unit (stored in data.config)"}},"note":"Delays are rounded to 5-minute cron intervals.","fields":{"delayAmount":{"type":"number","description":"Antal tidsenheder","default":1,"storage":"node.data.config"},"delayUnit":{"type":"enum","description":"Tidsenhed","enum":["minutes","hours","days","weeks"],"default":"days","storage":"node.data.config"}}},"aiNode":{"description":"AI nodes send execution context to an AI model. Output available as {{ai_text}} and {{ai_json.*}}.","dataSchema":{"label":{"type":"string","description":"Display label"},"prompt":{"type":"string","required":true,"description":"AI prompt with {{placeholders}}"},"outputMode":{"type":"string","enum":["text","json_schema"],"required":true},"reasoningEffort":{"type":"string","enum":["none","low","medium","high"],"default":"medium"},"schema":{"type":"object","description":"JSON Schema when outputMode is json_schema"}},"outputContext":{"ai_text":"string","ai_json.*":"structured fields from schema or freeform JSON"},"fields":{"prompt":{"type":"string","description":"Instruktion til AI'en — kritisk. Kan referere {{lead.*}} osv.","required":true,"supportsPlaceholders":true,"storage":"node.data"},"outputMode":{"type":"enum","description":"'text' = fritekst, 'json_schema' = struktureret output der kan forgrenes på","enum":["text","json_schema"],"default":"text","storage":"node.data"},"reasoningEffort":{"type":"enum","description":"Hvor meget AI'en 'tænker' — højere = langsommere/dyrere","enum":["none","low","medium","high"],"default":"low","storage":"node.data"},"schema":{"type":"json","description":"JSON schema for struktureret output (kun ved json_schema). Hvert top-level felt bliver til {{ai_json.<felt>}}. Brug schema-builderen eller en SCHEMA_TEMPLATE.","storage":"node.data"}}},"lookupNode":{"description":"Lookup nodes query related records and expose results as {{lookup.<nodeId>.items}} and {{lookup.<nodeId>.count}}.","dataSchema":{"label":{"type":"string","description":"Display label"},"entityType":{"type":"string","required":true,"enum":["Lead","Deal","Company","People","Offer","Activity","Task","Booking","Event","SupportTicket","CustomObjectRecord"],"description":"Entity type to query"},"customObjectId":{"type":"string","description":"Required when entityType is CustomObjectRecord"},"filters":{"type":"array","description":"Filter rules [{ field, operator, value }] relative to trigger context"},"limit":{"type":"number","default":1,"description":"Max records returned (1 = find first)"}},"entityTypes":["Lead","Deal","Company","People","Offer","Activity","Task","Booking","Event","SupportTicket","CustomObjectRecord"],"outputPlaceholders":["lookup.<nodeId>.items","lookup.<nodeId>.count","lookup.<nodeId>.<field>"],"fields":{"entityType":{"type":"enum","description":"Hvilken type records der slås op","enum":["Lead","Deal","Company","People","Offer","Activity","Task","Booking","Event","SupportTicket","CustomObjectRecord"],"storage":"node.data.config"},"customObjectId":{"type":"string","description":"Påkrævet når entityType er CustomObjectRecord — ID på brugerdefineret objekt","storage":"node.data.config"},"filters":{"type":"array","description":"Filtre der afgrænser opslaget ({ field, operator, value })","storage":"node.data.config"},"limit":{"type":"number","description":"Maks antal records","default":50,"storage":"node.data.config"}},"uiGuide":"Klik på opslag-noden → vælg entitetstype og tilføj filtre. Resultatet refereres som {{lookup.<nodeId>.items}} eller {{lookup.<nodeId>.count}}."},"flowBuildingGuide":{"layout":"Automations flow top-down (vertical). Sequences flow left-to-right (horizontal).","nodeIds":"Use stable IDs: trigger_1, action_1, condition_1, delay_1, lookup_1, ai_1","branching":"Condition and AI condition nodes: connect sourceHandle 'true' and 'false' edges.","placeholders":"Use {{entity.field}} syntax. AI output: {{ai_json.field}}, {{ai_text}}. Lookup: {{lookup.<nodeId>.items}}.","compositeTriggers":"Prefer record_created and record_changed over legacy lead_created/deal_created/tag_added triggers.","createRecord":"Prefer create_record action over legacy create_lead/create_deal/create_contact/create_offer."},"edgeStructure":{"description":"Edges connect nodes in the flow:","schema":{"id":{"type":"string","required":true,"description":"Unique edge ID, e.g. 'edge_trigger_1-action_1'"},"source":{"type":"string","required":true,"description":"Source node ID"},"target":{"type":"string","required":true,"description":"Target node ID"},"sourceHandle":{"type":"string|null","required":false,"description":"For condition nodes: 'true' or 'false'. null for other node types."},"targetHandle":{"type":"string|null","required":false,"description":"Target handle (usually null)"}}},"executionSettings":{"description":"Configure how the automation handles failures","schema":{"failureBehavior":{"type":"string","enum":["stop","continue","retry"],"default":"stop","description":"'stop' halts the flow, 'continue' skips the failed node, 'retry' retries"},"retryMaxAttempts":{"type":"number","default":3,"min":1,"max":10},"retryIntervalMinutes":{"type":"number","default":5,"min":1,"max":1440}}},"rateLimits":{"description":"Limit how often an automation can run","schema":{"maxRunsPerHour":{"type":"number","default":0,"description":"0 = unlimited"},"maxRunsPerDay":{"type":"number","default":0,"description":"0 = unlimited"},"maxRunsPerWeek":{"type":"number","default":0,"description":"0 = unlimited"},"maxTotalRuns":{"type":"number","default":0,"description":"0 = unlimited. Auto-deactivates after this many total runs."}}},"placeholders":{"description":"Placeholders use double curly braces: {{field.path}}. They are resolved from the execution context at runtime.","categories":{"lead":["lead._id","lead.title","lead.email","lead.phone","lead.status","lead.source","lead.score","lead.value","lead.notes","lead.customFields.*"],"company":["company._id","company.name","company.cvr","company.email","company.phone","company.address","company.city","company.zip","company.industry","company.employees","company.website"],"contact":["contact._id","contact.firstName","contact.lastName","contact.fullName","contact.email","contact.phone","contact.mobile","contact.title"],"deal":["deal._id","deal.title","deal.value","deal.stage","deal.probability","deal.priority","deal.customFields.*"],"owner":["owner._id","owner.firstName","owner.lastName","owner.fullName","owner.email","owner.phone"],"call":["call._id","call.duration","call.outcome","call.direction","call.notes"],"email":["email.subject","email.from","email.fromName","email.body"],"sms":["sms.body","sms.from"],"webhook":["webhookData.* (any field from the incoming webhook payload)"],"lookup":["lookup.<nodeId>.items","lookup.<nodeId>.count","lookup.<nodeId>.<field>"],"system":["triggeredAt","entityId","entityType","workspaceId"],"previousSteps":["httpResponse.status","httpResponse.data.*","ai_text","ai_json.*","aiOutput","aiOutput.*"]}},"examples":[{"name":"New lead welcome email + follow-up task","description":"When a lead is created, send a welcome email and create a follow-up task in 3 days","flow":{"name":"Welcome & Follow-up","description":"Sends welcome email on lead creation and creates a 3-day follow-up task","nodes":[{"id":"trigger_1","type":"trigger","position":{"x":500,"y":50},"data":{"triggerType":"lead_created","label":"Lead created"}},{"id":"action_1","type":"action","position":{"x":500,"y":250},"data":{"actionType":"send_email","label":"Send welcome email","config":{"subject":"Welcome {{contact.firstName}}!","body":"<p>Hi {{contact.firstName}},</p><p>Thank you for your interest. We will be in touch soon.</p><p>Best regards,<br>{{owner.firstName}}</p>"}}},{"id":"action_2","type":"action","position":{"x":500,"y":450},"data":{"actionType":"create_task","label":"Follow-up task","config":{"taskTitle":"Follow up with {{contact.firstName}} {{contact.lastName}}","taskDescription":"New lead from {{lead.source}}. Score: {{lead.score}}","dueInDays":3,"assignTo":"owner"}}}],"edges":[{"id":"e1","source":"trigger_1","target":"action_1"},{"id":"e2","source":"action_1","target":"action_2"}]}},{"name":"Deal stage change with condition","description":"When a deal moves to 'Proposal' stage, check if value > 50000 and send different emails","flow":{"name":"High-value deal notification","description":"Notifies the owner differently based on deal value when deal reaches proposal stage","nodes":[{"id":"trigger_1","type":"trigger","position":{"x":500,"y":50},"data":{"triggerType":"deal_stage_changed","label":"Deal stage changed"}},{"id":"condition_1","type":"condition","position":{"x":500,"y":250},"data":{"label":"Deal value > 50000?","conditions":[{"id":"c1","field":"deal.value","operator":"greater_than","value":"50000"}],"logic":"and"}},{"id":"action_1","type":"action","position":{"x":300,"y":450},"data":{"actionType":"send_email","label":"High-value alert","config":{"to":"{{owner.email}}","subject":"High-value deal: {{deal.title}}","body":"<p>Deal {{deal.title}} worth {{deal.value}} has moved to proposal stage!</p>"}}},{"id":"action_2","type":"action","position":{"x":700,"y":450},"data":{"actionType":"create_task","label":"Standard follow-up","config":{"taskTitle":"Follow up on {{deal.title}}","dueInDays":2,"assignTo":"owner"}}}],"edges":[{"id":"e1","source":"trigger_1","target":"condition_1"},{"id":"e2","source":"condition_1","target":"action_1","sourceHandle":"true"},{"id":"e3","source":"condition_1","target":"action_2","sourceHandle":"false"}]}},{"name":"Webhook-triggered lead creation","description":"External system sends webhook data, automation creates a lead and notifies the team","flow":{"name":"Webhook lead import","description":"Creates leads from incoming webhook data and sends a Slack/webhook notification","nodes":[{"id":"trigger_1","type":"trigger","position":{"x":500,"y":50},"data":{"triggerType":"webhook","label":"Webhook received"}},{"id":"action_1","type":"action","position":{"x":500,"y":250},"data":{"actionType":"create_lead","label":"Create lead","config":{"title":"{{webhookData.company_name}} — {{webhookData.contact_name}}","email":"{{webhookData.email}}","phone":"{{webhookData.phone}}","source":"webhook"}}},{"id":"action_2","type":"action","position":{"x":500,"y":450},"data":{"actionType":"send_webhook","label":"Notify team","config":{"webhookUrl":"https://hooks.slack.com/services/YOUR/WEBHOOK/URL","webhookBody":"{\"text\": \"New lead from webhook: {{webhookData.company_name}}\"}"}}}],"edges":[{"id":"e1","source":"trigger_1","target":"action_1"},{"id":"e2","source":"action_1","target":"action_2"}]}},{"name":"AI-powered email response handler","description":"When an email reply is received, use AI to analyze sentiment and route accordingly","flow":{"name":"AI Email Router","description":"Analyzes email replies with AI and creates appropriate tasks based on sentiment","nodes":[{"id":"trigger_1","type":"trigger","position":{"x":500,"y":50},"data":{"triggerType":"email_replied","label":"Email replied"}},{"id":"ai_1","type":"ai","position":{"x":500,"y":250},"data":{"label":"Analyze reply","prompt":"Analyze this email reply and determine the sentiment and intent.\n\nFrom: {{email.fromName}}\nSubject: {{email.subject}}\nBody: {{email.body}}\n\nReturn JSON with sentiment (positive/negative/neutral) and intent (interested/not_interested/question/meeting_request).","outputMode":"json_schema","schema":{"type":"object","properties":{"sentiment":{"type":"string","enum":["positive","negative","neutral"]},"intent":{"type":"string","enum":["interested","not_interested","question","meeting_request"]},"summary":{"type":"string"}},"required":["sentiment","intent","summary"]}}},{"id":"condition_1","type":"condition","position":{"x":500,"y":450},"data":{"label":"Positive sentiment?","conditions":[{"id":"c1","field":"aiOutput.sentiment","operator":"equals","value":"positive"}],"logic":"and"}},{"id":"action_1","type":"action","position":{"x":300,"y":650},"data":{"actionType":"create_task","label":"Priority follow-up","config":{"taskTitle":"Priority: {{contact.firstName}} replied positively — {{aiOutput.summary}}","dueInDays":0,"assignTo":"owner"}}},{"id":"action_2","type":"action","position":{"x":700,"y":650},"data":{"actionType":"create_task","label":"Review reply","config":{"taskTitle":"Review reply from {{contact.firstName}}: {{aiOutput.intent}}","dueInDays":1,"assignTo":"owner"}}}],"edges":[{"id":"e1","source":"trigger_1","target":"ai_1"},{"id":"e2","source":"ai_1","target":"condition_1"},{"id":"e3","source":"condition_1","target":"action_1","sourceHandle":"true"},{"id":"e4","source":"condition_1","target":"action_2","sourceHandle":"false"}]}}],"webhookTriggerUrl":{"description":"To trigger a webhook-based automation externally, send a POST request to:","url":"POST /api/webhooks/automation/{automationId}","body":"Any JSON payload — all fields become available as webhookData.* placeholders","note":"The automation must be active and have a webhook trigger type configured."}},"sequences":{"overview":{"title":"Sequences","description":"Sequences are entity-centric outreach flows for personalized sales communication. Unlike automations (which are event-triggered), sequences are started by enrolling an entity (Lead, People, Deal, or Company). Each sequence has a Start node, communication nodes (email, SMS), timing nodes (wait), action nodes (tasks, recalls, field updates), logic nodes (conditions, AI), and Stop nodes.","sequencesVsAutomations":{"sequences":{"start":"Enrollment (manual or automatic)","purpose":"Outreach campaigns & nurturing","focus":"Email/SMS communication sequences","exit":"Exit conditions (reply, meeting booked, etc.)","timing":"Smart scheduling with business hours"},"automations":{"start":"Trigger (event-based)","purpose":"React to CRM events","focus":"Broad automation of any action","exit":"Runs to completion","timing":"Event-driven, immediate execution"}},"entityTypes":{"Lead":"Leads in the system — cold outreach, nurturing","People":"Contact persons — personal outreach, follow-up","Company":"Companies — account-based outreach","Deal":"Deals in pipeline — deal acceleration, engagement"}},"endpoints":[{"method":"GET","path":"/api/v1/sequences","description":"List all sequences in the workspace","queryParams":{"page":{"type":"number","default":1},"limit":{"type":"number","default":20,"max":100},"isActive":{"type":"string","enum":["true","false"],"description":"Filter by active status"}},"response":{"data":"Sequence[]","page":"number","limit":"number","total":"number"}},{"method":"POST","path":"/api/v1/sequences","description":"Create a new sequence","body":{"name":{"type":"string","required":true,"description":"Sequence name"},"description":{"type":"string","required":false},"nodes":{"type":"Node[]","required":false,"description":"Array of step nodes (see Step Types below). A default Start node is created if nodes are omitted."},"edges":{"type":"Edge[]","required":false,"description":"Array of edges connecting nodes"}},"response":{"data":"Sequence"},"statusCode":201},{"method":"GET","path":"/api/v1/sequences/:id","description":"Get a single sequence by ID","response":{"data":"Sequence"}},{"method":"PUT","path":"/api/v1/sequences/:id","description":"Update a sequence","body":{"name":{"type":"string"},"description":{"type":"string"},"nodes":{"type":"Node[]"},"edges":{"type":"Edge[]"},"allowedEntityTypes":{"type":"string[]","description":"Array of entity types that can be enrolled: 'Lead', 'People', 'Deal', 'Company'"},"exitConditions":{"type":"ExitConditions","description":"See Exit Conditions section"},"sendSettings":{"type":"SendSettings","description":"See Send Settings section"},"trackingSettings":{"type":"TrackingSettings"},"aiSettings":{"type":"AiSettings"},"executionSettings":{"type":"ExecutionSettings"},"triggers":{"type":"Trigger[]","description":"Auto-enrollment triggers"},"defaultSenderType":{"type":"string","enum":["fixed","owner"]},"defaultSenderId":{"type":"string","description":"Email account ID for fixed sender"},"defaultSmsNumber":{"type":"string","description":"Twilio number for SMS"}},"response":{"data":"Sequence"}},{"method":"DELETE","path":"/api/v1/sequences/:id","description":"Delete a sequence. Fails if there are active enrollments.","response":{"data":{"deleted":true}}},{"method":"POST","path":"/api/v1/sequences/:id/toggle","description":"Toggle sequence active/inactive. Activation requires a start node and at least one action node.","response":{"data":{"_id":"string","isActive":"boolean"}}},{"method":"POST","path":"/api/v1/sequences/:id/duplicate","description":"Duplicate a sequence (creates inactive copy)","response":{"data":"Sequence"}},{"method":"GET","path":"/api/v1/sequences/:id/enroll-eligibility","description":"Check if an entity can be enrolled before calling enroll","queryParams":{"entityType":{"type":"string","required":true,"enum":["Lead","People","Deal","Company"]},"entityId":{"type":"string","required":true}},"response":{"data":"{ eligible: boolean, reason?: string }"}},{"method":"POST","path":"/api/v1/sequences/:id/enroll","description":"Enroll one or more entities into the sequence","body":{"entityType":{"type":"string","required":true,"enum":["Lead","People","Deal","Company"]},"entityId":{"type":"string","description":"Single entity ID (for single enrollment)"},"entityIds":{"type":"string[]","description":"Array of entity IDs (for bulk enrollment)"},"source":{"type":"string","default":"api","description":"Enrollment source identifier"},"forceRestart":{"type":"boolean","default":false,"description":"Re-enroll even if entity was previously enrolled"}},"response":{"singleEnrollment":{"data":"{ ok: boolean, action: string, enrollmentId: string }"},"bulkEnrollment":{"data":"{ enrolled: number, failed: number, results: [{ entityId, success, error? }] }"}},"statusCode":201,"note":"Use entityId for single enrollment, entityIds (array) for bulk enrollment. The sequence must be active."},{"method":"GET","path":"/api/v1/sequences/:id/enrollments","description":"List enrollments for a sequence","queryParams":{"page":{"type":"number","default":1},"limit":{"type":"number","default":20,"max":100},"status":{"type":"string","enum":["active","paused","completed","exited","switched"]}},"response":{"data":"SequenceEnrollment[]","page":"number","limit":"number","total":"number"}},{"method":"GET","path":"/api/v1/sequences/:id/stats","description":"Get aggregate statistics for a sequence","response":{"data":{"stats":"Sequence.stats object (totalEnrolled, active, completed, exited, etc.)","enrollmentCounts":"[{ _id: status, count: number }]"}}},{"method":"POST","path":"/api/v1/sequences/enrollments/:enrollmentId/pause","description":"Pause an active enrollment","body":{"durationDays":{"type":"number","description":"Optional: auto-resume after X days"}},"response":{"data":{"paused":true}}},{"method":"POST","path":"/api/v1/sequences/enrollments/:enrollmentId/resume","description":"Resume a paused enrollment","response":{"data":{"resumed":true}}},{"method":"POST","path":"/api/v1/sequences/enrollments/:enrollmentId/unenroll","description":"Remove an entity from the sequence (only if active or paused)","response":{"data":{"unenrolled":true}}}],"stepTypes":{"description":"Each sequence node has a type on node.type. Settings live on node.data (not nested under config). Flows are horizontal (left to right).","nodeWidths":{"start":200,"stop":180,"wait":220,"send_email":280,"send_sms":280,"create_task":280,"create_recall":280,"update_field":280,"condition":280,"ai_analyzer":320,"ai_condition":280},"types":{"start":{"label":"Start","description":"Indgangspunktet for sequencen. Præcis én pr. flow.","dataSchema":{},"produces":["lead.*","person.*","company.*","deal.*","owner.*"],"branching":null,"uiGuide":"Start-noden er fast og kan ikke fjernes. Træk den første step ud fra dens højre udgang.","example":""},"send_email":{"label":"Send email","description":"Sender en email-step i sequencen.","dataSchema":{"subject":{"type":"string","description":"Emnelinje — kritisk (medmindre template)","required":true},"body":{"type":"string","description":"Email-brødtekst (HTML) — kritisk (medmindre template). Brug rich text med toolbar: vedhæft fil, indsæt billede, variabel, AI Composer.","required":true},"aiBlocks":{"type":"array","description":"Inline AI-blokke [{ id, prompt }] — indsættes som {{ai:id}} i body og genereres pr. modtager ved afsendelse. Prompt kan indeholde variabler."},"attachments":{"type":"array","description":"Vedhæftede filer [{ id, name, s3Key, workspaceFileId }]"},"templateId":{"type":"string","description":"Brug template i stedet for emne/body"},"recipientType":{"type":"enum","description":"Trin 1 'Hvem sender du til?': 'contact'=Person, 'company'=Virksomhed, 'auto'=prøv kontaktperson først, ellers virksomhed. KUN relevant når sequencen accepterer Lead/Deal eller en blanding (Company+People) — Company-only låses til virksomhed, People-only til person. Bekræft valget med brugeren for Lead/Deal/blandede sequences.","enum":["contact","company","auto"],"default":"contact"},"companyRecipientTarget":{"type":"enum","description":"KUN ved virksomheds-flow (recipientType company/auto eller Company-entity). 'contact_person'=send til en person tilknyttet virksomheden, 'company_direct'=send til virksomhedens egen email (fx info@, salg@).","enum":["contact_person","company_direct"],"default":"contact_person"},"companyContactSelection":{"type":"object","description":"KUN når companyRecipientTarget=contact_person. Objekt: { mode: 'first'|'beslutningstagere'|'all'|'byTitle'|'byTag', titleFilter, tagFilter, fallback: 'company_email'|'skip' }. mode vælger hvilke(n) kontaktperson(er) (byTitle kræver titleFilter, byTag kræver tagFilter); fallback bestemmer hvad der sker hvis ingen kontaktperson matcher."},"recipientField":{"type":"enum","description":"Hvilken email-adresse på den valgte modtager: primary=Første email (uanset type), work=Arbejde, cvr=CVR, privat=Privat, faktura=Faktura, support=Support, ai=AI-fundet, all=send separat til ALLE emails, custom=fast adresse/placeholder i customRecipient.","enum":["primary","work","cvr","privat","faktura","support","ai","all","custom"],"default":"primary"},"customRecipient":{"type":"string","description":"KUN når recipientField=custom: fast email eller {{placeholder}} (fx {{contact.email}} eller salg@firma.dk)."},"senderType":{"type":"enum","description":"'fixed' = bestemt konto, 'owner' = entity-ejers konto. Default = sequencens afsender","enum":["fixed","owner"]},"senderAccountId":{"type":"string","description":"Afsenderkonto — sæt via setEmailSender eller emailAccountId i updateNodeConfig (auto-resolver email-adresse)"},"emailMode":{"type":"enum","description":"'manual' = emne+body, 'template' = brug skabelon","enum":["manual","template"],"default":"manual"},"ignoreBusinessHours":{"type":"boolean","description":"Send uden for åbningstid hvis true","default":false},"sendCondition":{"type":"object","description":"Valgfrit: spring email over hvis felt matcher { enabled, field, operator: equals|not_equals, value }"},"unsubscribeLinkEnabled":{"type":"boolean","description":"Tilføj afmeldingslink i footer","default":false},"unsubscribeLinkPreset":{"type":"string","description":"Footer-preset for afmelding","default":"attio_default"}},"produces":["stepHistory.lastEmail.*"],"branching":null,"uiGuide":"Lineære sekvenser vises som vertikal trin-liste (Attio-stil): emne + rich body-kort med bund-toolbar (Vedhæft, Billede, Variabel, AI Composer). Brug AI Composer til personaliserede snippets med {{ai:id}}-markører. Modtageren konfigureres i dialogen 'Opsæt modtager' (åbnes via ⋯ → Leveringsindstillinger): trinnene er 1) 'Hvem sender du til?' (Person/Virksomhed/Auto — kun for Lead/Deal/blandet), 2) ved virksomhed 'Hvem modtager emailen?' (virksomhedens email vs. en kontaktperson), 3) 'Hvilken kontaktperson?' + fallback, 4) 'Hvilken email bruges?'. Højre side viser en live forhåndsvisning når man søger en rigtig person/virksomhed.","example":"Spørg om emne+indhold hvis ingen template. Brug aiBlocks til dynamisk tekst — ikke skriv alt manuelt. Afsender slås op — spørg ikke. Modtager: for Lead/Deal/blandede sequences, bekræft recipientType (person/virksomhed/auto) med brugeren og forklar den beregnede modtager."},"send_sms":{"label":"Send SMS","description":"Sender en SMS-step i sequencen.","dataSchema":{"message":{"type":"string","description":"SMS-tekst — kritisk. Kan indeholde {{ai:id}} AI-blokke.","required":true},"aiBlocks":{"type":"array","description":"Inline AI-blokke [{ id, prompt }] for SMS — genereres pr. modtager"},"recipientType":{"type":"enum","description":"Trin 1 'Hvem sender du til?': 'contact'=Person, 'company'=Virksomhed, 'auto'=prøv kontaktperson først, ellers virksomhed. KUN relevant for Lead/Deal/blandede sequences (Company-only=virksomhed, People-only=person). Bekræft valget med brugeren ved Lead/Deal/blandet.","enum":["contact","company","auto"],"default":"contact"},"companyRecipientTarget":{"type":"enum","description":"KUN ved virksomheds-flow. 'contact_person'=brug telefon fra en person tilknyttet virksomheden, 'company_direct'=brug virksomhedens eget telefonnummer.","enum":["contact_person","company_direct"],"default":"contact_person"},"companyContactSelection":{"type":"object","description":"KUN når companyRecipientTarget=contact_person. { mode: 'first'|'beslutningstagere'|'all'|'byTitle'|'byTag', titleFilter, tagFilter, fallback: 'company_phone'|'skip' }."},"phoneField":{"type":"enum","description":"Hvilket telefonnummer: primary=Første telefon, mobile=Mobil, work=Arbejde, privat=Privat, cvr=CVR, direkte=Direkte, all=alle numre, custom=fast nummer/placeholder i customPhone.","enum":["primary","mobile","work","privat","cvr","direkte","all","custom"],"default":"primary"},"customPhone":{"type":"string","description":"KUN når phoneField=custom: fast nummer eller {{placeholder}} (fx {{contact.phone}} eller +4512345678)."},"smsMode":{"type":"enum","description":"'manual' = besked, 'template' = SMS-skabelon","enum":["manual","template"],"default":"manual"},"templateId":{"type":"string","description":"SMS-skabelon (template mode)"},"ignoreBusinessHours":{"type":"boolean","description":"Send uden for åbningstid hvis true","default":false},"sendCondition":{"type":"object","description":"Valgfrit: spring SMS over hvis felt matcher { enabled, field, operator, value }"},"senderType":{"type":"enum","description":"Afsender-type for SMS","enum":["fixed","owner","alphanumeric"],"default":"fixed"},"fromNumber":{"type":"string","description":"Twilio-nummer (fixed sender)"},"senderId":{"type":"string","description":"Alfanumerisk afsender-ID (max 11 tegn)"}},"produces":["stepHistory.lastSms.*"],"branching":null,"uiGuide":"SMS vises som kompakt kort i trin-listen med besked + toolbar (Variabel, AI Composer — ingen vedhæftninger). Modtager konfigureres i 'Opsæt modtager (telefon)' (⋯ → Leveringsindstillinger): samme trin-flow som email, men med telefonnumre og fallback til virksomhedens telefon. Højre side viser live forhåndsvisning.","example":""},"wait":{"label":"Vent","description":"Venter et tidsrum før næste step.","dataSchema":{"delayAmount":{"type":"number","description":"Antal tidsenheder","default":1},"delayUnit":{"type":"enum","description":"Tidsenhed","enum":["minutes","hours","days","weeks"],"default":"days"}},"produces":[],"branching":null,"uiGuide":"Klik på vent-step'et → angiv antal og enhed.","example":""},"create_task":{"label":"Opret opgave","description":"Opretter en opgave/aktivitet som en step i sequencen.","dataSchema":{"taskTitle":{"type":"string","description":"Opgavens titel","required":true},"taskDescription":{"type":"string","description":"Beskrivelse"},"activityType":{"type":"enum","description":"Aktivitetstype","enum":["task","call","meeting","follow_up","email","deadline","reminder"],"default":"task"},"priority":{"type":"enum","description":"Prioritet","enum":["low","medium","high"],"default":"medium"},"dueInDays":{"type":"number","description":"Dage til deadline (0 = i dag)","default":0},"assignTo":{"type":"enum","description":"Hvem opgaven tildeles","enum":["owner","creator"],"default":"owner"}},"produces":[],"branching":null,"uiGuide":"Klik på opgave-step'et → udfyld titel, type og forfald.","example":""},"create_recall":{"label":"Opret genopkald","description":"Planlægger et genopkald som en step.","dataSchema":{"title":{"type":"string","description":"Recall-titel","required":true},"message":{"type":"string","description":"Noter"},"phoneField":{"type":"enum","description":"Telefonfelt","enum":["primary","mobile","work","custom"],"default":"primary"},"recipientType":{"type":"enum","description":"Modtagertype","enum":["contact","company","auto"],"default":"auto"},"delayDays":{"type":"number","description":"Dage til genopkald","default":0},"callTime":{"type":"string","description":"Tidspunkt HH:mm"},"assignTo":{"type":"string","description":"Tildeles til"}},"produces":[],"branching":null,"uiGuide":"Klik på genopkalds-step'et → udfyld titel, telefonfelt og forsinkelse.","example":""},"update_field":{"label":"Opdater felt","description":"Opdaterer et felt på den enrolled entity.","dataSchema":{"fieldPath":{"type":"string","description":"Feltsti","required":true},"value":{"type":"string","description":"Ny værdi","required":true}},"produces":[],"branching":null,"uiGuide":"","example":""},"condition":{"label":"Betingelse","description":"Forgrener sequencen så den udfører FORSKELLIGE handlinger (fx ud fra lead-score eller åben deal). For blot at stoppe ved svar/booking, brug exit conditions i stedet — ikke denne node.","dataSchema":{"field":{"type":"string","description":"Felt der tjekkes (fx lead.score, deal.stage)","required":true},"operator":{"type":"enum","description":"Operator","enum":["equals","not_equals","contains","not_contains","starts_with","ends_with","matches_regex","greater_than","less_than","greater_than_or_equal","less_than_or_equal","between","is_empty","is_not_empty","exists","not_exists","is_true","is_false","array_contains","array_length_equals","array_length_greater","date_before","date_after","date_equals","date_within_days"],"default":"is_true"},"value":{"type":"string","description":"Sammenligningsværdi (hvis relevant)"}},"produces":[],"branching":{"handles":["true","false"],"describe":"Begge grene bør forbindes."},"uiGuide":"Klik på betingelses-step'et → vælg felt, operator og værdi. Forbind både true- og false-grenen.","example":"field=lead.score, operator=greater_than, value=70 (forgren på score). Brug IKKE til at stoppe ved svar — det gør exit conditions automatisk."},"ai_analyzer":{"label":"AI-analyse","description":"Analyserer kontekst med AI (fx et email-svar) og producerer output til efterfølgende betingelser.","dataSchema":{"prompt":{"type":"string","description":"Analyse-prompt — kritisk","required":true},"outputMode":{"type":"enum","description":"Output-format","enum":["text","json_schema"],"default":"json_schema"},"reasoningEffort":{"type":"enum","description":"Reasoning effort","enum":["none","low","medium","high"],"default":"low"},"schema":{"type":"json","description":"Schema for struktureret output → {{ai_json.<felt>}}"}},"produces":["ai_json.*","ai_text"],"branching":null,"uiGuide":"Klik på AI-analyse-step'et → skriv prompt og byg schema. Forgren derefter med en betingelse på ai_json.<felt>.","example":""},"ai_condition":{"label":"AI-betingelse","description":"AI træffer en ja/nej-beslutning og forgrener sequencen. (Manglede tidligere helt i flow-schemas.)","dataSchema":{"prompt":{"type":"string","description":"Kriterie AI skal vurdere — kritisk","required":true},"confidenceThreshold":{"type":"number","description":"Sikkerhedstærskel (0-1)","default":0.7},"useKnowledgeBase":{"type":"boolean","description":"Brug vidensbase","default":false}},"produces":["ai_json.decision","ai_json.confidence"],"branching":{"handles":["true","false"],"describe":"Begge grene bør forbindes."},"uiGuide":"Klik på AI-betingelse-step'et → formulér kriteriet. Forbind true- og false-grenen.","example":""},"set_access":{"label":"Tildel adgang","description":"Sætter ejer, synlighed og deling på den enrolled entity.","dataSchema":{"recordType":{"type":"enum","description":"","enum":["trigger"],"default":"trigger"},"accessState":{"type":"object","description":"Adgangskonfiguration","required":true}},"produces":[],"branching":null,"uiGuide":"","example":""},"stop":{"label":"Stop","description":"Afslutter sequencen for entityen.","dataSchema":{},"produces":[],"branching":null,"uiGuide":"Forbind et step til stop-noden for eksplicit at afslutte den gren.","example":""}}},"sequenceSettingsGuide":{"exitConditions":"onEmailReply, onSmsReply, onMeetingBooked, onDealStageChange.{enabled,stages[]}, onLeadStatusChange.{enabled,statuses[]}","sendSettings":"businessHoursOnly, businessStart, businessEnd, timezone, skipWeekends, smsQuietHours*, emailIntervalSeconds","autoEnrollTriggers":"field_change | sequence_event | entity_created — see triggers[] on sequence document","duplicateHandling":"block | block_with_restart | allow_multiple"},"exitConditions":{"description":"Exit conditions automatically remove an entity from the sequence when certain events occur.","schema":{"onEmailReply":{"type":"boolean","default":true,"description":"Exit when the entity replies to a sequence email"},"onSmsReply":{"type":"boolean","default":true,"description":"Exit when the entity replies to a sequence SMS"},"onMeetingBooked":{"type":"boolean","default":true,"description":"Exit when a meeting/booking is created for the entity"},"onDealStageChange":{"enabled":{"type":"boolean","default":false},"stages":{"type":"number[]","description":"Array of stage IDs that trigger exit"}},"onLeadStatusChange":{"enabled":{"type":"boolean","default":false},"statuses":{"type":"string[]","description":"Array of status values that trigger exit (e.g. ['won', 'lost'])"}}},"exitReasons":["email_reply","sms_reply","meeting_booked","deal_stage","lead_status","manual","ai_decision"]},"sendSettings":{"description":"Control when messages are sent in the sequence","schema":{"businessHoursOnly":{"type":"boolean","default":false,"description":"Only send during business hours"},"businessStart":{"type":"string","default":"08:00","description":"Business hours start (HH:mm)"},"businessEnd":{"type":"string","default":"16:30","description":"Business hours end (HH:mm)"},"timezone":{"type":"string","default":"Europe/Copenhagen","description":"Timezone for scheduling"},"skipWeekends":{"type":"boolean","default":false,"description":"Skip Saturday and Sunday"},"smsQuietHoursEnabled":{"type":"boolean","default":false,"description":"Enforce SMS quiet hours"},"smsQuietHoursStart":{"type":"string","default":"20:00","description":"SMS quiet hours start"},"smsQuietHoursEnd":{"type":"string","default":"08:00","description":"SMS quiet hours end"}}},"trackingSettings":{"schema":{"trackOpens":{"type":"boolean","default":true,"description":"Track email opens via pixel"},"trackClicks":{"type":"boolean","default":false,"description":"Track link clicks"}}},"executionSettings":{"schema":{"failureBehavior":{"type":"string","enum":["stop","continue","retry"],"default":"stop"},"retryMaxAttempts":{"type":"number","default":3,"min":1,"max":10},"retryIntervalMinutes":{"type":"number","default":5,"min":1,"max":1440}}},"autoEnrollmentTriggers":{"description":"Sequences can automatically enroll entities when specific conditions are met. Configure via the 'triggers' array on the sequence.","triggerTypes":{"field_change":{"description":"Enroll when a field on an entity changes to a specific value","config":{"entityType":{"type":"string","enum":["Lead","People","Deal","Company"]},"field":{"type":"string","description":"Field path to watch"},"operator":{"type":"string","enum":["equals","not_equals","contains"]},"value":{"type":"string"}}},"entity_created":{"description":"Enroll when a new entity is created matching filters","config":{"entityType":{"type":"string","enum":["Lead","People","Deal","Company"]},"filters":{"type":"object","description":"Field-value filters the new entity must match"}}},"sequence_event":{"description":"Enroll when an entity completes or exits another sequence","config":{"sourceSequenceId":{"type":"string","description":"The other sequence ID"},"event":{"type":"string","enum":["completed","exited","any"],"description":"Which event to trigger on"}}}}},"duplicateHandling":{"description":"Controls what happens when an entity is already enrolled","options":{"block":"Reject the enrollment if the entity is already active in this sequence","block_with_restart":"Unenroll from the current run and start fresh (default)","allow_multiple":"Allow multiple concurrent enrollments of the same entity"}},"placeholders":{"description":"Placeholders use double curly braces: {{field.path}}. Available in subject, body, message, titles, and descriptions.","categories":{"contact":["contact.firstName","contact.lastName","contact.fullName","contact.email","contact.phone","contact.mobile","contact.title"],"company":["company.name","company.cvr","company.email","company.phone","company.address","company.city","company.zip","company.industry","company.employees","company.website"],"lead":["lead._id","lead.title","lead.email","lead.phone","lead.status","lead.source","lead.score","lead.value"],"deal":["deal._id","deal.title","deal.value","deal.stage","deal.probability","deal.priority"],"owner":["owner.firstName","owner.lastName","owner.fullName","owner.email","owner.phone"],"workspace":["workspace.name"],"system":["currentDate","currentTime","enrolledAt"],"customFields":["customFields.field_key (any custom field defined on the entity)"],"aiOutput":["aiOutput (full AI response)","aiOutput.fieldName (structured field from AI json_schema output)"],"stepHistory":["stepHistory.lastEmail.replied","stepHistory.lastEmail.opened","stepHistory.lastSms.replied"]},"formatting":{"description":"Placeholders support default values and formatting","syntax":["{{contact.firstName}} — basic placeholder","{{contact.firstName|default:Customer}} — fallback value if empty","{{deal.value|format:currency}} — format as currency","{{currentDate|format:date}} — format as date"]}},"examples":[{"name":"3-email cold outreach","description":"Send 3 emails spaced 3 days apart with a stop at the end","flow":{"name":"Cold Outreach 3-Touch","description":"3-email cold outreach sequence with 3-day intervals","nodes":[{"id":"start_1","type":"start","position":{"x":50,"y":300},"data":{"label":"Start"}},{"id":"email_1","type":"send_email","position":{"x":330,"y":300},"data":{"label":"First email","subject":"Hi {{contact.firstName}} — quick question","body":"<p>Hi {{contact.firstName}},</p><p>I noticed {{company.name}} might benefit from our solution. Would you be open to a quick chat this week?</p><p>Best,<br>{{owner.firstName}}</p>"}},{"id":"wait_1","type":"wait","position":{"x":690,"y":300},"data":{"label":"Wait 3 days","delayAmount":3,"delayUnit":"days"}},{"id":"email_2","type":"send_email","position":{"x":990,"y":300},"data":{"label":"Follow-up","subject":"Re: Hi {{contact.firstName}} — quick question","body":"<p>Hi {{contact.firstName}},</p><p>Just following up on my last email. I'd love to show you how we've helped similar companies in {{company.industry}}.</p><p>Best,<br>{{owner.firstName}}</p>"}},{"id":"wait_2","type":"wait","position":{"x":1350,"y":300},"data":{"label":"Wait 3 days","delayAmount":3,"delayUnit":"days"}},{"id":"email_3","type":"send_email","position":{"x":1650,"y":300},"data":{"label":"Final attempt","subject":"Last try — {{contact.firstName}}","body":"<p>Hi {{contact.firstName}},</p><p>I don't want to be a bother. If now isn't the right time, no worries at all. Just let me know if you'd like to connect in the future.</p><p>Best,<br>{{owner.firstName}}</p>"}},{"id":"stop_1","type":"stop","position":{"x":2010,"y":300},"data":{"label":"Stop"}}],"edges":[{"id":"e1","source":"start_1","target":"email_1"},{"id":"e2","source":"email_1","target":"wait_1"},{"id":"e3","source":"wait_1","target":"email_2"},{"id":"e4","source":"email_2","target":"wait_2"},{"id":"e5","source":"wait_2","target":"email_3"},{"id":"e6","source":"email_3","target":"stop_1"}],"exitConditions":{"onEmailReply":true,"onMeetingBooked":true},"sendSettings":{"businessHoursOnly":true,"skipWeekends":true,"timezone":"Europe/Copenhagen"}}},{"name":"Multi-channel with condition","description":"Email then SMS with a condition check for email open","flow":{"name":"Multi-channel Follow-up","description":"Sends email, waits 2 days, checks if opened, then sends SMS or second email","nodes":[{"id":"start_1","type":"start","position":{"x":50,"y":300},"data":{"label":"Start"}},{"id":"email_1","type":"send_email","position":{"x":330,"y":300},"data":{"label":"Initial email","subject":"{{contact.firstName}}, quick intro","body":"<p>Hi {{contact.firstName}},</p><p>I wanted to introduce myself and our solution for {{company.name}}.</p><p>{{owner.firstName}}</p>"}},{"id":"wait_1","type":"wait","position":{"x":690,"y":300},"data":{"label":"Wait 2 days","delayAmount":2,"delayUnit":"days"}},{"id":"condition_1","type":"condition","position":{"x":990,"y":300},"data":{"label":"Email opened?","conditions":[{"field":"stepHistory.lastEmail.opened","operator":"is_true"}],"logic":"and"}},{"id":"sms_1","type":"send_sms","position":{"x":1350,"y":150},"data":{"label":"SMS follow-up","message":"Hi {{contact.firstName}}, I sent you an email about {{company.name}}. Would love to chat briefly — {{owner.firstName}}","phoneField":"primary"}},{"id":"email_2","type":"send_email","position":{"x":1350,"y":450},"data":{"label":"Re-engage email","subject":"Did you see my email, {{contact.firstName}}?","body":"<p>Hi {{contact.firstName}},</p><p>I sent an email a couple of days ago but wanted to make sure it didn't get lost. Happy to chat whenever works for you.</p><p>{{owner.firstName}}</p>"}},{"id":"task_1","type":"create_task","position":{"x":1710,"y":300},"data":{"label":"Manual follow-up","taskTitle":"Call {{contact.firstName}} at {{company.name}}","taskDescription":"Sequence complete — time for a personal touch","dueInDays":1,"assignTo":"owner"}},{"id":"stop_1","type":"stop","position":{"x":2070,"y":300},"data":{"label":"Stop"}}],"edges":[{"id":"e1","source":"start_1","target":"email_1"},{"id":"e2","source":"email_1","target":"wait_1"},{"id":"e3","source":"wait_1","target":"condition_1"},{"id":"e4","source":"condition_1","target":"sms_1","sourceHandle":"true"},{"id":"e5","source":"condition_1","target":"email_2","sourceHandle":"false"},{"id":"e6","source":"sms_1","target":"task_1"},{"id":"e7","source":"email_2","target":"task_1"},{"id":"e8","source":"task_1","target":"stop_1"}],"exitConditions":{"onEmailReply":true,"onSmsReply":true,"onMeetingBooked":true},"sendSettings":{"businessHoursOnly":true,"skipWeekends":true}}},{"name":"AI-powered reply analysis","description":"Send email, wait for reply, use AI to analyze and route","flow":{"name":"AI Reply Analyzer","description":"Sends outreach email, waits for reply, uses AI to determine next action","nodes":[{"id":"start_1","type":"start","position":{"x":50,"y":300},"data":{"label":"Start"}},{"id":"email_1","type":"send_email","position":{"x":330,"y":300},"data":{"label":"Outreach email","subject":"{{contact.firstName}} — idea for {{company.name}}","body":"<p>Hi {{contact.firstName}},</p><p>I have an idea that could help {{company.name}} save time. Worth a 15-min call?</p><p>{{owner.firstName}}</p>"}},{"id":"wait_1","type":"wait","position":{"x":690,"y":300},"data":{"label":"Wait 5 days","delayAmount":5,"delayUnit":"days"}},{"id":"ai_1","type":"ai_condition","position":{"x":990,"y":300},"data":{"label":"Got a reply?","prompt":"Has the contact {{contact.firstName}} at {{company.name}} replied to our last email? Check the step history for any email reply.","reasoningEffort":"low"}},{"id":"ai_2","type":"ai_analyzer","position":{"x":1350,"y":150},"data":{"label":"Analyze reply","prompt":"Analyze the reply from {{contact.firstName}}. Determine if they are interested, need more info, or are declining. Reply history: {{stepHistory.lastEmail.replyBody}}","outputMode":"json_schema","schema":{"type":"object","properties":{"intent":{"type":"string","enum":["interested","needs_info","declining","out_of_office"]},"suggestedAction":{"type":"string"}},"required":["intent","suggestedAction"]}}},{"id":"task_1","type":"create_task","position":{"x":1750,"y":150},"data":{"label":"Act on reply","taskTitle":"{{contact.firstName}} replied: {{aiOutput.intent}} — {{aiOutput.suggestedAction}}","dueInDays":0,"assignTo":"owner"}},{"id":"email_2","type":"send_email","position":{"x":1350,"y":450},"data":{"label":"Bump email","subject":"Re: {{contact.firstName}} — idea for {{company.name}}","body":"<p>Hi {{contact.firstName}},</p><p>Just bumping this to the top of your inbox. Let me know if you'd like to chat.</p><p>{{owner.firstName}}</p>"}},{"id":"stop_1","type":"stop","position":{"x":2110,"y":300},"data":{"label":"Stop"}}],"edges":[{"id":"e1","source":"start_1","target":"email_1"},{"id":"e2","source":"email_1","target":"wait_1"},{"id":"e3","source":"wait_1","target":"ai_1"},{"id":"e4","source":"ai_1","target":"ai_2","sourceHandle":"true"},{"id":"e5","source":"ai_1","target":"email_2","sourceHandle":"false"},{"id":"e6","source":"ai_2","target":"task_1"},{"id":"e7","source":"task_1","target":"stop_1"},{"id":"e8","source":"email_2","target":"stop_1"}],"exitConditions":{"onEmailReply":false,"onMeetingBooked":true}}}],"completeWorkflow":{"title":"Building a sequence via API — step by step","steps":[{"step":1,"title":"Create the sequence","description":"POST /api/v1/sequences with name and the full flow (nodes + edges)","note":"Include all nodes and edges in the initial creation, or create empty and update later."},{"step":2,"title":"Configure settings","description":"PUT /api/v1/sequences/:id with exitConditions, sendSettings, allowedEntityTypes","note":"Set exit conditions (onEmailReply, onMeetingBooked) and send settings (business hours, timezone)."},{"step":3,"title":"Activate the sequence","description":"POST /api/v1/sequences/:id/toggle to activate","note":"The sequence must have a start node and at least one action node."},{"step":4,"title":"Enroll entities","description":"POST /api/v1/sequences/:id/enroll with entityType and entityId or entityIds","note":"Entities begin at the start node and progress through the flow automatically."},{"step":5,"title":"Monitor progress","description":"GET /api/v1/sequences/:id/enrollments and /api/v1/sequences/:id/stats","note":"Check enrollment statuses and aggregate statistics."}]}},"endpoints":{"overview":{"baseUrl":"/api/v1","authentication":"All endpoints require Authorization: Bearer <API_KEY> header (or ?api_key= query param)","responseFormat":{"success":"{ data: <result>, page?, limit?, total? }","error":"{ error: <message string>, ...details }"},"pagination":"Most list endpoints accept page (default 1) and limit (default 20, max 100) query params","integrationOnly":"Denne reference dækker workspace API-nøgler til integrationer. Mobilapp-, session- og platform-endpoints er ikke dokumenteret her."},"groups":{"inbound":{"title":"Inbound (unified creation)","description":"Create companies, people, leads, and deals in one request. Ideal for form submissions and integrations.","endpoints":[{"method":"POST","path":"/api/v1/inbound","description":"Create or find-and-update company/person/lead/deal from a single payload. Supports JSON, form-urlencoded, and Elementor webhook formats.","body":{"companyName":{"type":"string","description":"Company name (for company lookup/creation)"},"companyCvr":{"type":"string","description":"Danish CVR number (for exact company match)"},"companyEmail":{"type":"string"},"companyPhone":{"type":"string"},"personFirstName":{"type":"string"},"personLastName":{"type":"string"},"personEmail":{"type":"string"},"personPhone":{"type":"string"},"personTitle":{"type":"string"},"leadTitle":{"type":"string","description":"Lead title (auto-generated if not provided)"},"leadSource":{"type":"string"},"leadStatus":{"type":"string"},"leadNotes":{"type":"string"},"dealTitle":{"type":"string"},"dealValue":{"type":"number"},"dealFlowId":{"type":"string","description":"Pipeline ID"},"dealStageId":{"type":"string","description":"Stage ID within pipeline"},"customFields":{"type":"object","description":"Key-value pairs for custom fields"},"tags":{"type":"string[]","description":"Array of tag names to apply"}},"response":"{ data: { company, person, lead, deal, flow }, created: { company: bool, person: bool, lead: bool, deal: bool } }"},{"method":"GET","path":"/api/v1/inbound","description":"Returns API documentation for the inbound endpoint"}]},"search":{"title":"Search","endpoints":[{"method":"GET","path":"/api/v1/search","description":"Search across all entity types (companies, people, leads, deals)","queryParams":{"q":{"type":"string","required":true,"description":"Search query (minimum 2 characters)"},"types":{"type":"string","description":"Comma-separated entity types to search: company,person,lead,deal (default: all)"},"limit":{"type":"number","default":10,"description":"Max results per entity type (max 50)"}}}]},"companies":{"title":"Companies","endpoints":[{"method":"GET","path":"/api/v1/companies","description":"List companies","queryParams":{"page":{},"limit":{},"search":{"type":"string"}}},{"method":"POST","path":"/api/v1/companies","description":"Create a company","body":{"name":{"type":"string","required":true},"cvr":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"zip":{"type":"string"},"country":{"type":"string"},"website":{"type":"string"},"industry":{"type":"string"},"employees":{"type":"number"},"customFields":{"type":"array"},"tags":{"type":"string[]"}}},{"method":"GET","path":"/api/v1/companies/:id","description":"Get company by ID"},{"method":"PUT","path":"/api/v1/companies/:id","description":"Update company"},{"method":"DELETE","path":"/api/v1/companies/:id","description":"Delete company"},{"method":"GET","path":"/api/v1/companies/:id/people","description":"List people connected to company"},{"method":"GET","path":"/api/v1/companies/:id/deals","description":"List deals connected to company"},{"method":"GET","path":"/api/v1/companies/:id/activities","description":"List activities for company"},{"method":"GET","path":"/api/v1/companies/:id/activity-feed","description":"Unified activity feed for company"},{"method":"POST","path":"/api/v1/companies/:id/people","description":"Link person to company"},{"method":"DELETE","path":"/api/v1/companies/:id/people","description":"Unlink person from company"}]},"people":{"title":"People (contacts)","endpoints":[{"method":"GET","path":"/api/v1/people","description":"List people"},{"method":"POST","path":"/api/v1/people","description":"Create a person","body":{"firstName":{"type":"string","required":true},"lastName":{"type":"string"},"emails":{"type":"array","description":"[{ email, label }]"},"phones":{"type":"array","description":"[{ phone, label }]"},"title":{"type":"string"},"companyId":{"type":"string"},"customFields":{"type":"array"},"tags":{"type":"string[]"}}},{"method":"GET","path":"/api/v1/people/:id","description":"Get person by ID"},{"method":"PUT","path":"/api/v1/people/:id","description":"Update person"},{"method":"DELETE","path":"/api/v1/people/:id","description":"Delete person"},{"method":"GET","path":"/api/v1/people/:id/companies","description":"List companies connected to person"},{"method":"GET","path":"/api/v1/people/:id/deals","description":"List deals connected to person"},{"method":"GET","path":"/api/v1/people/:id/activities","description":"List activities for person"},{"method":"GET","path":"/api/v1/people/:id/activity-feed","description":"Unified activity feed for person"}]},"leads":{"title":"Leads","endpoints":[{"method":"GET","path":"/api/v1/leads","description":"List leads","queryParams":{"page":{},"limit":{},"status":{"type":"string"},"source":{"type":"string"},"search":{"type":"string"}}},{"method":"POST","path":"/api/v1/leads","description":"Create a lead","body":{"title":{"type":"string","required":true},"email":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string"},"source":{"type":"string"},"score":{"type":"number"},"value":{"type":"number"},"notes":{"type":"string"},"companyRef":{"type":"string","description":"Company ID"},"personRef":{"type":"string","description":"Person ID"},"customFields":{"type":"object"},"tags":{"type":"string[]"}}},{"method":"GET","path":"/api/v1/leads/:id","description":"Get lead by ID"},{"method":"PUT","path":"/api/v1/leads/:id","description":"Update lead"},{"method":"DELETE","path":"/api/v1/leads/:id","description":"Delete lead"},{"method":"GET","path":"/api/v1/leads/:id/activity-feed","description":"Unified activity feed for lead"},{"method":"GET","path":"/api/v1/leads/:id/activities","description":"List activities for lead"}]},"deals":{"title":"Deals","endpoints":[{"method":"GET","path":"/api/v1/deals","description":"List deals","queryParams":{"page":{},"limit":{},"flowId":{"type":"string","description":"Filter by pipeline"},"stageId":{"type":"string"}}},{"method":"POST","path":"/api/v1/deals","description":"Create a deal","body":{"title":{"type":"string","required":true},"value":{"type":"number"},"flowId":{"type":"string"},"stageId":{"type":"string"},"priority":{"type":"string","enum":["low","medium","high"]},"probability":{"type":"number"},"company":{"type":"string","description":"Company ID"},"personRef":{"type":"string","description":"Person ID"},"leadRef":{"type":"string","description":"Lead ID"},"customFields":{"type":"object"},"tags":{"type":"string[]"}}},{"method":"GET","path":"/api/v1/deals/:id","description":"Get deal by ID"},{"method":"PUT","path":"/api/v1/deals/:id","description":"Update deal (logs field/stage changes to activity feed, same as UI)"},{"method":"DELETE","path":"/api/v1/deals/:id","description":"Delete deal"},{"method":"POST","path":"/api/v1/deals/:id/move","description":"Move deal to a different stage","body":{"stageId":{"type":"string","required":true},"flowId":{"type":"string"}}},{"method":"GET","path":"/api/v1/deals/:id/activities","description":"List activities for deal"},{"method":"GET","path":"/api/v1/deals/:id/activity-feed","description":"Unified activity feed for deal"}]},"activities":{"title":"Activities","description":"Aktiviteter / activity feed — list and create feed rows (noter, opkald, deals m.m.)","endpoints":[{"method":"GET","path":"/api/v1/activities","description":"List activities (aktiviteter)"},{"method":"POST","path":"/api/v1/activities","description":"Create activity / aktivitet (creates a feed row). Body: type (required), summary or title, description, companyId/personId/dealId/leadId, entityType+entityId, noteRef, date, metadata"},{"method":"GET","path":"/api/v1/activities/:id","description":"Get activity by ID (aktivitet)"}]},"tasks":{"title":"Tasks","endpoints":[{"method":"GET","path":"/api/v1/tasks","description":"List tasks"},{"method":"POST","path":"/api/v1/tasks","description":"Create task"},{"method":"GET","path":"/api/v1/tasks/:id","description":"Get task"},{"method":"PUT","path":"/api/v1/tasks/:id","description":"Update task"},{"method":"DELETE","path":"/api/v1/tasks/:id","description":"Delete task"}]},"notes":{"title":"Notes","endpoints":[{"method":"GET","path":"/api/v1/notes","description":"List notes"},{"method":"POST","path":"/api/v1/notes","description":"Create note (also creates linked activity for Noter tab / activity feed). Requires entity ref: company, personRef, leadRef, dealRef, or customObjectRecord"},{"method":"GET","path":"/api/v1/notes/:id","description":"Get note"},{"method":"PUT","path":"/api/v1/notes/:id","description":"Update note (syncs linked activity)"},{"method":"DELETE","path":"/api/v1/notes/:id","description":"Delete note (removes linked activity)"}]},"calls":{"title":"Calls","endpoints":[{"method":"GET","path":"/api/v1/calls","description":"List calls"},{"method":"POST","path":"/api/v1/calls","description":"Create call record (also creates call activity in feed)"},{"method":"GET","path":"/api/v1/calls/:id","description":"Get call by ID"},{"method":"PUT","path":"/api/v1/calls/:id","description":"Update call (syncs linked activity)"},{"method":"DELETE","path":"/api/v1/calls/:id","description":"Delete call (removes linked activity)"}]},"events":{"title":"Events (calendar)","endpoints":[{"method":"GET","path":"/api/v1/events","description":"List events"},{"method":"POST","path":"/api/v1/events","description":"Create event"},{"method":"GET","path":"/api/v1/events/:id","description":"Get event"},{"method":"PUT","path":"/api/v1/events/:id","description":"Update event"},{"method":"DELETE","path":"/api/v1/events/:id","description":"Delete event"}]},"tags":{"title":"Tags","endpoints":[{"method":"GET","path":"/api/v1/tags","description":"List unique tags","queryParams":{"entityType":{"type":"string","enum":["company","person","deal","lead"]}}},{"method":"POST","path":"/api/v1/tags/bulk","description":"Bulk add/remove tags on multiple entities"}]},"customFields":{"title":"Custom Fields","endpoints":[{"method":"GET","path":"/api/v1/custom-fields","description":"List custom field definitions","queryParams":{"entityType":{"type":"string","enum":["lead","deal","company","person"]}}},{"method":"POST","path":"/api/v1/custom-fields","description":"Create custom field definition"},{"method":"GET","path":"/api/v1/custom-fields/:id","description":"Get custom field"},{"method":"PUT","path":"/api/v1/custom-fields/:id","description":"Update custom field"},{"method":"DELETE","path":"/api/v1/custom-fields/:id","description":"Delete custom field"},{"method":"POST","path":"/api/v1/custom-fields/search","description":"Search entities by custom field values"},{"method":"GET","path":"/api/v1/custom-fields/search","description":"Returns search endpoint documentation"}]},"flows":{"title":"Flows & Stages (Pipelines)","endpoints":[{"method":"GET","path":"/api/v1/flows","description":"List pipelines"},{"method":"POST","path":"/api/v1/flows","description":"Create pipeline"},{"method":"GET","path":"/api/v1/flows/:id","description":"Get pipeline"},{"method":"PUT","path":"/api/v1/flows/:id","description":"Update pipeline"},{"method":"DELETE","path":"/api/v1/flows/:id","description":"Delete pipeline"},{"method":"POST","path":"/api/v1/flows/:id/stages","description":"Create stage in pipeline"},{"method":"PUT","path":"/api/v1/flows/:id/stages","description":"Update stage","body":{"id":{"type":"string","required":true},"title":{"type":"string"},"order":{"type":"number"}}},{"method":"DELETE","path":"/api/v1/flows/:id/stages","description":"Delete stage","body":{"id":{"type":"string","required":true}}}]},"lists":{"title":"Lists & Items","endpoints":[{"method":"GET","path":"/api/v1/lists","description":"List all lists"},{"method":"POST","path":"/api/v1/lists","description":"Create list"},{"method":"GET","path":"/api/v1/lists/:id","description":"Get list"},{"method":"PUT","path":"/api/v1/lists/:id","description":"Update list"},{"method":"DELETE","path":"/api/v1/lists/:id","description":"Delete list"},{"method":"GET","path":"/api/v1/lists/:id/items","description":"List items in a list"},{"method":"POST","path":"/api/v1/lists/:id/items","description":"Add items to list"},{"method":"DELETE","path":"/api/v1/lists/:id/items","description":"Remove items from list"}]},"emails":{"title":"Emails","endpoints":[{"method":"GET","path":"/api/v1/emails","description":"List emails"},{"method":"POST","path":"/api/v1/emails","description":"Send email"},{"method":"GET","path":"/api/v1/emails/:id","description":"Get email"},{"method":"GET","path":"/api/v1/emails/threads/:threadId","description":"Get email thread"}]},"emailAccounts":{"title":"Email Accounts","endpoints":[{"method":"GET","path":"/api/v1/email-accounts","description":"List connected email accounts"}]},"emailTemplates":{"title":"Email Templates","description":"Create and manage email templates with custom HTML (compiledHtml). Supports {{contact.*}} placeholders and default filter syntax {{field | default:\"fallback\"}}.","endpoints":[{"method":"GET","path":"/api/v1/email-templates","description":"List email templates"},{"method":"POST","path":"/api/v1/email-templates","description":"Create email template (admin scope)","body":{"name":{"type":"string","required":true},"category":{"type":"string","enum":["marketing","transactional","quote","other"]},"compiledHtml":{"type":"string","description":"Full HTML body with {{placeholders}}"},"plainText":{"type":"string"},"metadata":{"type":"object","description":"{ subject, preheader }"},"layoutSettings":{"type":"object","description":"containerWidth, backgroundColor, layoutMode"},"tags":{"type":"string[]"}}},{"method":"GET","path":"/api/v1/email-templates/:id","description":"Get template by ID (includes compiledHtml, projectData)"},{"method":"PATCH","path":"/api/v1/email-templates/:id","description":"Update template (admin scope)"},{"method":"DELETE","path":"/api/v1/email-templates/:id","description":"Delete template (admin scope)"}],"aiGuide":"/api/v1/docs?section=offerTemplates"},"sms":{"title":"SMS","endpoints":[{"method":"GET","path":"/api/v1/sms","description":"List SMS messages"},{"method":"POST","path":"/api/v1/sms","description":"Send SMS","body":{"to":{"type":"string","required":true},"message":{"type":"string","required":true},"from":{"type":"string","description":"Sender number"}}},{"method":"GET","path":"/api/v1/sms/:id","description":"Get SMS by ID"},{"method":"POST","path":"/api/v1/sms/bulk","description":"Send bulk SMS"},{"method":"POST","path":"/api/v1/sms/schedule","description":"Schedule SMS for later"},{"method":"GET","path":"/api/v1/sms/scheduled","description":"List scheduled SMS"},{"method":"DELETE","path":"/api/v1/sms/scheduled/:id","description":"Cancel scheduled SMS"},{"method":"GET","path":"/api/v1/sms/threads/:phoneNumber","description":"Get SMS thread by phone number"}]},"smsTemplates":{"title":"SMS Templates","endpoints":[{"method":"GET","path":"/api/v1/sms-templates","description":"List SMS templates"}]},"webhooks":{"title":"Webhook Subscriptions","description":"Subscribe to CRM events via outbound webhooks. See the Webhooks section for available events.","endpoints":[{"method":"GET","path":"/api/v1/webhooks/subscriptions","description":"List webhook subscriptions","response":"{ data: items[], total, availableEvents: string[] }"},{"method":"POST","path":"/api/v1/webhooks/subscriptions","description":"Create webhook subscription","body":{"url":{"type":"string","required":true},"events":{"type":"string[]","required":true,"description":"Array of event names to subscribe to"},"name":{"type":"string"},"active":{"type":"boolean","default":true}},"response":"{ data: { _id, url, events, name, active, secret, createdAt }, warning: 'Store the secret...' }"},{"method":"GET","path":"/api/v1/webhooks/subscriptions/:id","description":"Get subscription (secret masked)"},{"method":"PUT","path":"/api/v1/webhooks/subscriptions/:id","description":"Update subscription"},{"method":"DELETE","path":"/api/v1/webhooks/subscriptions/:id","description":"Delete subscription"},{"method":"POST","path":"/api/v1/webhooks/zapier","description":"Zapier inbound webhook — creates person, lead, and deal in one request (Bearer API key)","body":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"leadTitle":{"type":"string"},"dealTitle":{"type":"string"},"dealValue":{"type":"number"},"source":{"type":"string","default":"zapier"}},"response":"{ data: { person, lead, deal } }"}]},"crmConnect":{"title":"CRM Connect","description":"Lookup and connect CRM data with external systems","endpoints":[{"method":"GET","path":"/api/v1/crm-connect/lookup","description":"Look up entity by phone/email"},{"method":"POST","path":"/api/v1/crm-connect/calls","description":"Log or connect call events for integration"}]},"offers":{"title":"Offers (quotes/proposals)","description":"Create draft offers linked to offer types and templates. Send creates an immutable snapshot and public link.","endpoints":[{"method":"GET","path":"/api/v1/offers","description":"List offers"},{"method":"POST","path":"/api/v1/offers","description":"Create offer","body":{"title":{"type":"string","required":true},"offerTypeId":{"type":"ObjectId"},"templateId":{"type":"ObjectId"},"companyRef":{"type":"ObjectId"},"personRef":{"type":"ObjectId"},"dealRef":{"type":"ObjectId"},"quoteInput":{"type":"object","description":"{ contact, address, facts, calculatorInputs }"},"calculatorResult":{"type":"object","description":"{ lineItems, subtotal, vatAmount, total }"},"validUntil":{"type":"Date"}}},{"method":"GET","path":"/api/v1/offers/:id","description":"Get offer (by _id or publicId)"},{"method":"PUT","path":"/api/v1/offers/:id","description":"Update draft offer","body":{"title":{"type":"string"},"templateId":{"type":"ObjectId"},"offerTypeId":{"type":"ObjectId"},"quoteInput":{"type":"object"},"calculatorResult":{"type":"object"}}},{"method":"DELETE","path":"/api/v1/offers/:id","description":"Delete draft offer"},{"method":"POST","path":"/api/v1/offers/:id/send","description":"Send offer — snapshot, activity, automations, offer.sent webhook. Returns publicId.","response":"{ data: { _id, status: 'sent', sentAt, publicId, snapshotId } }"},{"method":"POST","path":"/api/v1/offers/:id/cancel","description":"Cancel offer"},{"method":"POST","path":"/api/v1/offers/:id/send-email","description":"Send or resend offer email to customer","body":{"emailTo":{"type":"string","description":"Optional recipient override"},"senderAccountId":{"type":"ObjectId","description":"Optional sender email account"},"templateId":{"type":"ObjectId","description":"Optional email template"}}},{"method":"POST","path":"/api/v1/offers/:id/send-sms","description":"Send or resend offer link via SMS","body":{"phoneTo":{"type":"string","description":"Optional phone override"}}},{"method":"GET","path":"/api/v1/offers/:id/preview-token","description":"Preview URL for draft offers (short-lived token) or public link when sent"}],"aiGuide":"/api/v1/docs?section=offerTemplates"},"offerTemplates":{"title":"Offer Templates (tilbudsskabeloner)","description":"Visual page-builder templates with pages[], headerElements, footerElements, branding, and custom HTML elements. See ?section=offerTemplates for element types and A-Polering reference.","endpoints":[{"method":"GET","path":"/api/v1/offer-templates","description":"List templates (summary without full pages)"},{"method":"POST","path":"/api/v1/offer-templates","description":"Create template with full layout (admin scope)","body":{"name":{"type":"string","required":true},"pages":{"type":"array","description":"Page[] with elements (text, heading, html, columns, line_items, totals, video, …)"},"headerElements":{"type":"array"},"footerElements":{"type":"array"},"branding":{"type":"object","description":"colors, typography, logo"},"defaultTerms":{"type":"string"},"defaultPaymentTerms":{"type":"string"},"isDefault":{"type":"boolean"}}},{"method":"GET","path":"/api/v1/offer-templates/:id","description":"Get full template including pages and elements"},{"method":"PATCH","path":"/api/v1/offer-templates/:id","description":"Update template (admin scope)"},{"method":"DELETE","path":"/api/v1/offer-templates/:id","description":"Delete template (admin scope)"},{"method":"POST","path":"/api/v1/offer-templates/:id/duplicate","description":"Duplicate template (admin scope)"}],"aiGuide":"/api/v1/docs?section=offerTemplates"},"offerTypes":{"title":"Offer Types","endpoints":[{"method":"GET","path":"/api/v1/offer-types","description":"List offer types"},{"method":"POST","path":"/api/v1/offer-types","description":"Create offer type (admin scope)"},{"method":"GET","path":"/api/v1/offer-types/:id","description":"Get offer type"},{"method":"PATCH","path":"/api/v1/offer-types/:id","description":"Update offer type (admin scope)"},{"method":"DELETE","path":"/api/v1/offer-types/:id","description":"Delete offer type (admin scope)"}]},"products":{"title":"Products & Catalog","endpoints":[{"method":"GET","path":"/api/v1/products","description":"List products"},{"method":"POST","path":"/api/v1/products","description":"Create product"},{"method":"GET","path":"/api/v1/products/:id","description":"Get product"},{"method":"PUT","path":"/api/v1/products/:id","description":"Update product"},{"method":"DELETE","path":"/api/v1/products/:id","description":"Delete product"},{"method":"GET","path":"/api/v1/catalog","description":"List catalog items"},{"method":"POST","path":"/api/v1/catalog","description":"Create catalog item"},{"method":"GET","path":"/api/v1/catalog/:id","description":"Get catalog item"},{"method":"PUT","path":"/api/v1/catalog/:id","description":"Update catalog item"},{"method":"DELETE","path":"/api/v1/catalog/:id","description":"Delete catalog item"}]},"projects":{"title":"Projects","endpoints":[{"method":"GET","path":"/api/v1/projects","description":"List projects"},{"method":"POST","path":"/api/v1/projects","description":"Create project"},{"method":"GET","path":"/api/v1/projects/:id","description":"Get project"},{"method":"PUT","path":"/api/v1/projects/:id","description":"Update project"},{"method":"DELETE","path":"/api/v1/projects/:id","description":"Delete project"},{"method":"POST","path":"/api/v1/projects/:id/move","description":"Move project to different stage"},{"method":"GET","path":"/api/v1/projects/:id/stats","description":"Get project statistics"},{"method":"GET","path":"/api/v1/projects/:id/tasks","description":"List project tasks"},{"method":"POST","path":"/api/v1/projects/:id/tasks","description":"Create project task"},{"method":"GET","path":"/api/v1/projects/tasks/:taskId","description":"Get project task"},{"method":"PUT","path":"/api/v1/projects/tasks/:taskId","description":"Update project task"},{"method":"DELETE","path":"/api/v1/projects/tasks/:taskId","description":"Delete project task"},{"method":"POST","path":"/api/v1/projects/tasks/:taskId/move","description":"Move project task"},{"method":"GET","path":"/api/v1/projects/:id/time-entries","description":"List time entries"},{"method":"POST","path":"/api/v1/projects/:id/time-entries","description":"Create time entry"},{"method":"PUT","path":"/api/v1/projects/time-entries/:entryId","description":"Update time entry"},{"method":"DELETE","path":"/api/v1/projects/time-entries/:entryId","description":"Delete time entry"},{"method":"GET","path":"/api/v1/projects/:id/expenses","description":"List expenses"},{"method":"POST","path":"/api/v1/projects/:id/expenses","description":"Create expense"}]},"bookings":{"title":"Bookings","endpoints":[{"method":"GET","path":"/api/v1/bookings","description":"List bookings"},{"method":"POST","path":"/api/v1/bookings","description":"Create booking"},{"method":"GET","path":"/api/v1/bookings/:id","description":"Get booking by ID"},{"method":"POST","path":"/api/v1/bookings/:id/cancel","description":"Cancel booking"},{"method":"POST","path":"/api/v1/bookings/:id/approve","description":"Approve pending booking","body":{"notes":{"type":"string"}}},{"method":"POST","path":"/api/v1/bookings/:id/reject","description":"Reject pending booking","body":{"reason":{"type":"string"}}},{"method":"POST","path":"/api/v1/bookings/:id/reschedule","description":"Reschedule booking"},{"method":"GET","path":"/api/v1/bookings/available-slots","description":"Get available time slots"},{"method":"GET","path":"/api/v1/booking-configs","description":"List booking configurations"},{"method":"GET","path":"/api/v1/booking-configs/:id","description":"Get booking configuration"},{"method":"PATCH","path":"/api/v1/booking-configs/:id","description":"Update booking configuration (admin scope)"}]},"reports":{"title":"Reports","endpoints":[{"method":"GET","path":"/api/v1/reports/pipeline","description":"Pipeline report"},{"method":"GET","path":"/api/v1/reports/leads","description":"Leads report"},{"method":"GET","path":"/api/v1/reports/offers","description":"Offers report"},{"method":"GET","path":"/api/v1/reports/support","description":"Support report"},{"method":"GET","path":"/api/v1/reports/history","description":"History/activity report"},{"method":"GET","path":"/api/v1/reports/organization","description":"Organization overview"},{"method":"GET","path":"/api/v1/reports/users","description":"Users report"},{"method":"GET","path":"/api/v1/reports/users/:userId","description":"Individual user report"}]},"leadScoring":{"title":"Lead Scoring","endpoints":[{"method":"GET","path":"/api/v1/lead-scoring/rules","description":"List lead scoring rules"},{"method":"POST","path":"/api/v1/lead-scoring/rules","description":"Create scoring rule"},{"method":"PUT","path":"/api/v1/lead-scoring/rules/:id","description":"Update scoring rule"},{"method":"DELETE","path":"/api/v1/lead-scoring/rules/:id","description":"Delete scoring rule"}]},"leadRouting":{"title":"Lead Routing","endpoints":[{"method":"GET","path":"/api/v1/lead-routing/rules","description":"List lead routing rules"},{"method":"POST","path":"/api/v1/lead-routing/rules","description":"Create routing rule"},{"method":"PUT","path":"/api/v1/lead-routing/rules/:id","description":"Update routing rule"},{"method":"DELETE","path":"/api/v1/lead-routing/rules/:id","description":"Delete routing rule"}]},"importExport":{"title":"Import & Export","endpoints":[{"method":"POST","path":"/api/v1/import/companies","description":"Import companies from CSV/data"},{"method":"POST","path":"/api/v1/import/people","description":"Import people"},{"method":"POST","path":"/api/v1/import/leads","description":"Import leads"},{"method":"POST","path":"/api/v1/import/deals","description":"Import deals"},{"method":"POST","path":"/api/v1/import/validate","description":"Validate import data before importing"},{"method":"GET","path":"/api/v1/import/history","description":"List import history"},{"method":"POST","path":"/api/v1/export/leads","description":"Export leads"},{"method":"POST","path":"/api/v1/export/deals","description":"Export deals"},{"method":"POST","path":"/api/v1/export/people","description":"Export people"},{"method":"POST","path":"/api/v1/export/companies","description":"Export companies"},{"method":"POST","path":"/api/v1/export/lists/:listId","description":"Export list items"}]},"files":{"title":"Files & Folders","endpoints":[{"method":"GET","path":"/api/v1/files","description":"List files"},{"method":"POST","path":"/api/v1/files","description":"Upload file"},{"method":"GET","path":"/api/v1/files/:id","description":"Get file metadata"},{"method":"DELETE","path":"/api/v1/files/:id","description":"Delete file"},{"method":"POST","path":"/api/v1/files/:id/link","description":"Create signed download link"},{"method":"DELETE","path":"/api/v1/files/:id/link","description":"Revoke signed download link"},{"method":"GET","path":"/api/v1/folders","description":"List folders"},{"method":"POST","path":"/api/v1/folders","description":"Create folder"},{"method":"DELETE","path":"/api/v1/folders/:id","description":"Delete folder"}]},"users":{"title":"Users (Team Members)","description":"Manage workspace members","endpoints":[{"method":"GET","path":"/api/v1/users","description":"List workspace members","queryParams":{"page":{},"limit":{},"search":{"type":"string"}}},{"method":"GET","path":"/api/v1/users/:id","description":"Get user by ID"},{"method":"PUT","path":"/api/v1/users/:id","description":"Update user (name, phone)","body":{"firstName":{"type":"string"},"lastName":{"type":"string"},"phone":{"type":"string"},"defaultUserPhone":{"type":"string"}}}]},"supportTickets":{"title":"Support Tickets","description":"Manage customer support tickets with conversations","endpoints":[{"method":"GET","path":"/api/v1/support-tickets","description":"List support tickets","queryParams":{"page":{},"limit":{},"status":{"type":"string"},"priority":{"type":"string"},"assignee":{"type":"string"},"category":{"type":"string"},"search":{"type":"string"}}},{"method":"POST","path":"/api/v1/support-tickets","description":"Create support ticket","body":{"title":{"type":"string","required":true},"description":{"type":"string"},"priority":{"type":"string","enum":["low","medium","high","urgent"]},"category":{"type":"string"},"assignee":{"type":"string","description":"User ID"},"company":{"type":"string","description":"Company ID"},"personRef":{"type":"string","description":"Person ID"},"tags":{"type":"string[]"}}},{"method":"GET","path":"/api/v1/support-tickets/:id","description":"Get support ticket by ID"},{"method":"PUT","path":"/api/v1/support-tickets/:id","description":"Update support ticket","body":{"title":{"type":"string"},"description":{"type":"string"},"priority":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","waiting","resolved","closed"]},"category":{"type":"string"},"assignee":{"type":"string"},"tags":{"type":"string[]"},"resolution":{"type":"string"}}},{"method":"DELETE","path":"/api/v1/support-tickets/:id","description":"Delete support ticket"},{"method":"POST","path":"/api/v1/support-tickets/:id/reply","description":"Add reply to ticket","body":{"content":{"type":"string","required":true},"type":{"type":"string","enum":["agent_reply","internal_note"],"default":"agent_reply"},"visibility":{"type":"string","enum":["public","internal"],"default":"public"}}},{"method":"POST","path":"/api/v1/support-tickets/:id/move","description":"Move ticket to kanban stage","body":{"stageId":{"type":"number","required":true},"flowId":{"type":"string","description":"Optional support flow ID"}}},{"method":"GET","path":"/api/v1/support-tickets/:id/messages","description":"List ticket messages","queryParams":{"limit":{"type":"number","default":50},"visibility":{"type":"string","enum":["public","internal"]}}},{"method":"GET","path":"/api/v1/support-tickets/:id/time-entries","description":"List time entries on ticket"},{"method":"POST","path":"/api/v1/support-tickets/:id/time-entries","description":"Create time entry on ticket"}]},"scripts":{"title":"Scripts (Call Scripts)","description":"Manage sales/call scripts for the dialer","endpoints":[{"method":"GET","path":"/api/v1/scripts","description":"List scripts","queryParams":{"page":{},"limit":{},"search":{"type":"string"}}},{"method":"POST","path":"/api/v1/scripts","description":"Create script","body":{"name":{"type":"string","required":true},"content":{"type":"string","required":true},"description":{"type":"string"},"targetCallType":{"type":"string","enum":["cold_call","discovery","demo","closing","follow_up","other"]},"isShared":{"type":"boolean"}}},{"method":"GET","path":"/api/v1/scripts/:id","description":"Get script by ID"},{"method":"PUT","path":"/api/v1/scripts/:id","description":"Update script"},{"method":"DELETE","path":"/api/v1/scripts/:id","description":"Delete script"}]},"filterPresets":{"title":"Filter Presets","description":"Saved filter configurations for lists and views","endpoints":[{"method":"GET","path":"/api/v1/filter-presets","description":"List filter presets","queryParams":{"area":{"type":"string","description":"Filter by area (e.g. companies, leads, deals)"},"page":{},"limit":{}}},{"method":"POST","path":"/api/v1/filter-presets","description":"Create filter preset","body":{"name":{"type":"string","required":true},"area":{"type":"string"},"columnFilters":{"type":"object"},"filterTree":{"type":"object"},"filterMode":{"type":"string","enum":["and","or"]},"sorting":{"type":"array"},"visibility":{"type":"string","enum":["workspace","private","group","user"]}}},{"method":"GET","path":"/api/v1/filter-presets/:id","description":"Get filter preset"},{"method":"PUT","path":"/api/v1/filter-presets/:id","description":"Update filter preset"},{"method":"DELETE","path":"/api/v1/filter-presets/:id","description":"Delete filter preset"}]},"emailSignatures":{"title":"Email Signatures","endpoints":[{"method":"GET","path":"/api/v1/email-signatures","description":"List email signatures"},{"method":"POST","path":"/api/v1/email-signatures","description":"Create signature","body":{"name":{"type":"string","required":true},"content":{"type":"string","required":true,"description":"HTML content"},"textContent":{"type":"string"}}},{"method":"GET","path":"/api/v1/email-signatures/:id","description":"Get signature"},{"method":"PUT","path":"/api/v1/email-signatures/:id","description":"Update signature"},{"method":"DELETE","path":"/api/v1/email-signatures/:id","description":"Delete signature"}]},"clipCards":{"title":"Clip Cards (Prepaid Hours)","description":"Manage prepaid service hour cards for projects","endpoints":[{"method":"GET","path":"/api/v1/clip-cards","description":"List clip cards","queryParams":{"page":{},"limit":{},"status":{"type":"string","enum":["active","depleted","expired","cancelled"]},"projectId":{"type":"string"}}},{"method":"POST","path":"/api/v1/clip-cards","description":"Create clip card","body":{"project":{"type":"string","required":true,"description":"Project ID"},"title":{"type":"string"},"totalHours":{"type":"number","required":true},"hourlyRate":{"type":"number","required":true},"allowOverdraft":{"type":"boolean"},"overdraftRate":{"type":"number"},"expiresAt":{"type":"string","description":"ISO date"},"notes":{"type":"string"}}},{"method":"GET","path":"/api/v1/clip-cards/:id","description":"Get clip card"},{"method":"PUT","path":"/api/v1/clip-cards/:id","description":"Update clip card"},{"method":"DELETE","path":"/api/v1/clip-cards/:id","description":"Delete clip card"}]},"dashboardLayouts":{"title":"Dashboard Layouts","description":"Manage saved dashboard configurations","endpoints":[{"method":"GET","path":"/api/v1/dashboard-layouts","description":"List dashboard layouts"},{"method":"POST","path":"/api/v1/dashboard-layouts","description":"Create layout","body":{"name":{"type":"string","required":true},"layout":{"type":"object"},"visibleComponents":{"type":"string[]"},"chartWidgets":{"type":"array"},"visibility":{"type":"string","enum":["workspace","private","group","user"]}}},{"method":"GET","path":"/api/v1/dashboard-layouts/:id","description":"Get layout"},{"method":"PUT","path":"/api/v1/dashboard-layouts/:id","description":"Update layout"},{"method":"DELETE","path":"/api/v1/dashboard-layouts/:id","description":"Delete layout"}]},"customObjects":{"title":"Custom Objects","description":"Workspace-defined object types and records. Schema/field mutations require admin scope; record CRUD uses write scope.","endpoints":[{"method":"GET","path":"/api/v1/custom-objects","description":"List custom object definitions"},{"method":"POST","path":"/api/v1/custom-objects","description":"Create custom object definition (admin scope)","body":{"slug":{"type":"string","required":true},"singular":{"type":"string","required":true},"plural":{"type":"string","required":true},"description":{"type":"string"},"icon":{"type":"string"},"color":{"type":"string"}}},{"method":"GET","path":"/api/v1/custom-objects/search","description":"Search records across all searchable objects","queryParams":{"q":{"type":"string","required":true,"minLength":2},"limit":{"type":"number","default":10}}},{"method":"GET","path":"/api/v1/custom-objects/:slug","description":"Get definition with field schemas"},{"method":"PATCH","path":"/api/v1/custom-objects/:slug","description":"Update definition metadata (admin scope)"},{"method":"DELETE","path":"/api/v1/custom-objects/:slug","description":"Delete object and all records (admin scope)"},{"method":"POST","path":"/api/v1/custom-objects/:slug/fields","description":"Add field (admin scope)","body":{"slug":{"type":"string","required":true},"label":{"type":"string","required":true},"type":{"type":"string","required":true}}},{"method":"PATCH","path":"/api/v1/custom-objects/:slug/fields/:fieldSlug","description":"Update field (admin scope)"},{"method":"DELETE","path":"/api/v1/custom-objects/:slug/fields/:fieldSlug","description":"Delete field (admin scope)"},{"method":"GET","path":"/api/v1/custom-objects/:slug/records","description":"List records with pagination or cursor search","queryParams":{"page":{"type":"number","default":1},"limit":{"type":"number","default":30,"max":100},"q":{"type":"string","description":"Search query (alias: search)"},"search":{"type":"string","description":"Alias for q"},"cursor":{"type":"string","description":"Cursor for next page when searching"},"sort":{"type":"string","description":"Field slug to sort by"},"dir":{"type":"string","enum":["asc","desc"],"default":"desc"}}},{"method":"POST","path":"/api/v1/custom-objects/:slug/records","description":"Create record","body":{"type":"object","description":"Field slug keys → values"}},{"method":"POST","path":"/api/v1/custom-objects/:slug/records/bulk","description":"Bulk update records","body":{"ids":{"type":"string[]","required":true},"patch":{"type":"object","required":true}}},{"method":"GET","path":"/api/v1/custom-objects/:slug/records/:id","description":"Get record by ID"},{"method":"PATCH","path":"/api/v1/custom-objects/:slug/records/:id","description":"Partial update of record"},{"method":"PUT","path":"/api/v1/custom-objects/:slug/records/:id","description":"Replace record"},{"method":"DELETE","path":"/api/v1/custom-objects/:slug/records/:id","description":"Delete record"},{"method":"GET","path":"/api/v1/custom-objects/:slug/records/:id/activity-feed","description":"Activity feed for a record"},{"method":"GET","path":"/api/v1/custom-objects/:slug/records/:id/related","description":"Related custom object records linked via native entity refs"},{"method":"POST","path":"/api/v1/export/custom-objects/:slug","description":"Export records (export + admin scope)","body":{"from":{"type":"string"},"to":{"type":"string"},"limit":{"type":"number"}}},{"method":"POST","path":"/api/v1/import/custom-objects/:slug","description":"Import records from rows array (import + admin scope)","body":{"rows":{"type":"array","required":true}}}]},"calculators":{"title":"Calculators","description":"Read calculator templates tied to offer types and run stateless price calculations.","endpoints":[{"method":"GET","path":"/api/v1/calculator-templates","description":"List calculator templates"},{"method":"GET","path":"/api/v1/calculator-templates/:id","description":"Get template with pricing rules"},{"method":"POST","path":"/api/v1/calculator-templates/:id/calculate","description":"Run calculation without persisting","body":{"inputs":{"type":"object","required":true}}},{"method":"GET","path":"/api/v1/calculator-submissions","description":"List calculator submissions","queryParams":{"page":{},"limit":{},"templateId":{"type":"string"},"offerId":{"type":"string"}}}]},"integrations":{"title":"Integrations","description":"Read integration connection status. OAuth connect flows remain in-app only.","endpoints":[{"method":"GET","path":"/api/v1/integrations","description":"List connected providers and sync health (no secrets)"},{"method":"POST","path":"/api/v1/integrations/:provider/sync","description":"Trigger manual sync (admin scope)","body":{"fullSync":{"type":"boolean"}}}]}}},"schemas":{"overview":{"title":"Data Schemas","description":"Salesbase CRM entities and their field structures. All entities are workspace-scoped. Custom fields can be added to any entity type via the Custom Fields API."},"entities":{"Company":{"description":"A business entity. Can be linked to people, leads, and deals.","fields":{"_id":{"type":"ObjectId","description":"Unique identifier"},"name":{"type":"string","required":true,"description":"Company name"},"cvr":{"type":"string","description":"Danish CVR number (unique within workspace)"},"email":{"type":"string","description":"Primary email"},"phone":{"type":"string","description":"Primary phone"},"address":{"type":"string"},"city":{"type":"string"},"zip":{"type":"string"},"country":{"type":"string"},"website":{"type":"string"},"industry":{"type":"string"},"employees":{"type":"number"},"description":{"type":"string"},"customFields":{"type":"array","description":"Array of { name, value } objects"},"tags":{"type":"ObjectId[]","description":"Array of tag IDs"},"owner":{"type":"ObjectId","description":"Assigned user ID"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"People":{"description":"A contact person. Can be linked to companies, leads, and deals.","fields":{"_id":{"type":"ObjectId"},"firstName":{"type":"string","required":true},"lastName":{"type":"string"},"emails":{"type":"array","description":"[{ email: string, label: string }]"},"phones":{"type":"array","description":"[{ phone: string, label: string }]"},"title":{"type":"string","description":"Job title"},"description":{"type":"string"},"companyIds":{"type":"ObjectId[]","description":"Connected company IDs"},"customFields":{"type":"array","description":"Array of { name, value }"},"tags":{"type":"ObjectId[]"},"owner":{"type":"ObjectId"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"Lead":{"description":"A sales lead. Links to a company and/or person, and can have deals.","fields":{"_id":{"type":"ObjectId"},"title":{"type":"string","required":true,"description":"Lead title (typically company/person name)"},"email":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string","description":"Lead status (e.g. 'new', 'contacted', 'qualified', 'won', 'lost')"},"source":{"type":"string","description":"Where the lead came from"},"score":{"type":"number","description":"Lead score (0-100)"},"value":{"type":"number","description":"Estimated value"},"notes":{"type":"string"},"companyRef":{"type":"ObjectId","description":"Connected company"},"personRef":{"type":"ObjectId","description":"Connected person"},"customFields":{"type":"Map","description":"Map of key → value (unlike Company/People which use array format)"},"tags":{"type":"ObjectId[]"},"owner":{"type":"ObjectId"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"Deal":{"description":"A deal/opportunity in a pipeline. Linked to a company, person, and/or lead.","fields":{"_id":{"type":"ObjectId"},"title":{"type":"string","required":true},"value":{"type":"number","description":"Deal monetary value"},"flow":{"type":"ObjectId","description":"Pipeline (flow) ID"},"stage":{"type":"number","description":"Stage ID within the pipeline"},"probability":{"type":"number","description":"Win probability (0-100)"},"priority":{"type":"string","enum":["low","medium","high"]},"expectedCloseDate":{"type":"Date"},"wonAt":{"type":"Date"},"lostAt":{"type":"Date"},"lostReason":{"type":"string"},"company":{"type":"ObjectId","description":"Connected company"},"personRef":{"type":"ObjectId","description":"Connected person"},"leadRef":{"type":"ObjectId","description":"Connected lead"},"customFields":{"type":"Map","description":"Map of key → value"},"tags":{"type":"ObjectId[]"},"owner":{"type":"ObjectId"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"Automation":{"description":"An event-driven automation flow (see Automations section for full detail)","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"description":{"type":"string"},"isActive":{"type":"boolean"},"nodes":{"type":"Node[]","description":"ReactFlow nodes (see Automation docs)"},"edges":{"type":"Edge[]","description":"ReactFlow edges"},"triggers":{"type":"Trigger[]","description":"Extracted trigger configs for quick lookup"},"executionSettings":{"type":"ExecutionSettings"},"rateLimits":{"type":"RateLimits"},"stats":{"type":"Stats","description":"{ totalRuns, successfulRuns, failedRuns, lastRunAt }"},"createdBy":{"type":"ObjectId"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"Sequence":{"description":"A multi-step outreach sequence (see Sequences section for full detail)","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"description":{"type":"string"},"isActive":{"type":"boolean"},"nodes":{"type":"Node[]","description":"ReactFlow nodes (see Sequence docs)"},"edges":{"type":"Edge[]"},"allowedEntityTypes":{"type":"string[]","description":"['Lead', 'People', 'Deal', 'Company']"},"exitConditions":{"type":"ExitConditions"},"sendSettings":{"type":"SendSettings"},"trackingSettings":{"type":"TrackingSettings"},"executionSettings":{"type":"ExecutionSettings"},"stats":{"type":"Stats"},"createdBy":{"type":"ObjectId"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"Activity":{"description":"An activity log entry (call, meeting, email, note, task)","fields":{"_id":{"type":"ObjectId"},"type":{"type":"string","enum":["call","meeting","email","note","task","other"]},"title":{"type":"string"},"description":{"type":"string"},"entityType":{"type":"string","description":"Related entity type"},"entityId":{"type":"ObjectId","description":"Related entity ID"},"dueDate":{"type":"Date"},"completed":{"type":"boolean"},"owner":{"type":"ObjectId"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"}}},"Tag":{"description":"A label that can be applied to any entity","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"color":{"type":"string"},"workspaceId":{"type":"ObjectId"}}},"WebhookSubscription":{"description":"An outbound webhook subscription that fires on CRM events","fields":{"_id":{"type":"ObjectId"},"url":{"type":"string","required":true},"events":{"type":"string[]","required":true},"name":{"type":"string"},"active":{"type":"boolean"},"secret":{"type":"string","description":"HMAC signing secret (returned on creation only)"},"workspaceId":{"type":"ObjectId"},"createdAt":{"type":"Date"}}},"CustomObjectDefinition":{"description":"A workspace-defined object type (schema). Managed via admin-scoped API key.","fields":{"_id":{"type":"ObjectId"},"slug":{"type":"string","required":true,"description":"URL-safe identifier, e.g. contracts"},"singular":{"type":"string","required":true},"plural":{"type":"string","required":true},"description":{"type":"string"},"icon":{"type":"string"},"color":{"type":"string","description":"Hex accent for sidebar"},"searchable":{"type":"boolean"},"showInSidebar":{"type":"boolean"},"workspace":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"CustomObjectField":{"description":"Field definition on a custom object. Types mirror Attio-style schema fields.","fields":{"_id":{"type":"ObjectId"},"slug":{"type":"string","required":true},"label":{"type":"string","required":true},"type":{"type":"string","enum":["text","number","date","checkbox","select","multiselect","url","email","phone","textarea","record_reference","formula","rollup"]},"isRequired":{"type":"boolean"},"isUnique":{"type":"boolean"},"options":{"type":"array","description":"For select/multiselect"},"referenceObject":{"type":"string","description":"Custom object slug for record_reference"},"referenceType":{"type":"string","enum":["custom","native"]},"nativeEntity":{"type":"string","description":"company, person, deal, lead when referenceType=native"},"order":{"type":"number"}}},"CustomObjectRecord":{"description":"A record instance for a custom object. Field values live under data keyed by field slug.","fields":{"_id":{"type":"ObjectId"},"object":{"type":"ObjectId","description":"CustomObjectDefinition _id"},"recordNumber":{"type":"number","description":"Auto-increment per object type"},"data":{"type":"object","description":"Map of fieldSlug → value"},"workspace":{"type":"ObjectId"},"createdBy":{"type":"ObjectId"},"updatedBy":{"type":"ObjectId"},"createdAt":{"type":"Date"},"updatedAt":{"type":"Date"}}},"OfferTemplate":{"description":"Tilbudsskabelon with page builder layout. Mix native elements (text, line_items) and custom html blocks.","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"description":{"type":"string"},"pages":{"type":"array","description":"[{ id, order, title, elements[], settings }]"},"headerElements":{"type":"array","description":"Elements on every page header"},"footerElements":{"type":"array","description":"Elements on every page footer"},"branding":{"type":"object","description":"{ colors, typography, logo }"},"defaultTerms":{"type":"string"},"defaultPaymentTerms":{"type":"string"},"defaultValidity":{"type":"number","description":"Days"},"isDefault":{"type":"boolean"},"isActive":{"type":"boolean"},"workspaceId":{"type":"ObjectId"}},"elementTypes":["text","heading","html","columns","image","video","table","line_items","totals","divider","spacer","button"],"aiGuide":"/api/v1/docs?section=offerTemplates"},"EmailTemplate":{"description":"Email template with compiledHtml and optional GrapesJS projectData.","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"category":{"type":"string","enum":["marketing","transactional","quote","other"]},"compiledHtml":{"type":"string","description":"HTML with {{contact.firstName}} placeholders"},"plainText":{"type":"string"},"metadata":{"type":"object","description":"{ subject, preheader }"},"layoutSettings":{"type":"object"},"requiredVars":{"type":"array"},"tags":{"type":"string[]"},"workspace":{"type":"ObjectId"}},"aiGuide":"/api/v1/docs?section=offerTemplates"},"OfferType":{"description":"Tilbudstype — pricing rules, BBR mapping, default template, CRM automations on accept/submit.","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"slug":{"type":"string"},"defaultTemplateId":{"type":"ObjectId","ref":"OfferTemplate"},"requiredInputFields":{"type":"array"},"pricingRules":{"type":"object","description":"tieredPricing, conditionalRules, packages, globalSurcharges"},"offerSettings":{"type":"object","description":"OTP, deal/sequence on accept/submit"},"customPlaceholders":{"type":"array","description":"→ {{custom.fieldId}} in templates"},"isActive":{"type":"boolean"},"workspaceId":{"type":"ObjectId"}}},"OfferProduct":{"description":"Product/service for offers. pricingType: fixed | advanced (tiered pricing).","fields":{"_id":{"type":"ObjectId"},"name":{"type":"string","required":true},"unitPrice":{"type":"number"},"unit":{"type":"string","default":"stk"},"pricingType":{"type":"string","enum":["fixed","advanced"]},"tieredPricing":{"type":"array"},"conditionalRules":{"type":"array"},"variants":{"type":"array"},"category":{"type":"string"},"isActive":{"type":"boolean"},"workspaceId":{"type":"ObjectId"}}}},"customFieldTypes":{"description":"Custom fields support these data types","types":[{"type":"text","description":"Free-text string"},{"type":"number","description":"Numeric value"},{"type":"date","description":"ISO date string"},{"type":"checkbox","description":"Boolean (true/false)"},{"type":"select","description":"Single-select from predefined options"},{"type":"multi_select","description":"Multi-select from predefined options"},{"type":"url","description":"URL string"},{"type":"email","description":"Email address"},{"type":"phone","description":"Phone number (stored as text)"},{"type":"textarea","description":"Multi-line text"}],"note":"Lead and Deal custom fields use Map storage (key → value). Company and People use array storage ([{ name, value }]). When creating via API, both formats are accepted and auto-converted."}},"webhooks":{"overview":{"title":"Webhooks","description":"Subscribe to CRM events and receive HTTP POST notifications at your URL. Each webhook delivery includes an HMAC signature for verification. Manage subscriptions via the /api/v1/webhooks/subscriptions endpoints."},"events":[{"event":"company.created","description":"A company was created"},{"event":"company.updated","description":"A company was updated"},{"event":"company.deleted","description":"A company was deleted"},{"event":"person.created","description":"A person was created"},{"event":"person.updated","description":"A person was updated"},{"event":"person.deleted","description":"A person was deleted"},{"event":"deal.created","description":"A deal was created"},{"event":"deal.updated","description":"A deal was updated"},{"event":"deal.deleted","description":"A deal was deleted"},{"event":"deal.stage_changed","description":"A deal moved to a different pipeline stage"},{"event":"deal.won","description":"A deal was marked as won"},{"event":"deal.lost","description":"A deal was marked as lost"},{"event":"lead.created","description":"A lead was created"},{"event":"lead.updated","description":"A lead was updated"},{"event":"lead.deleted","description":"A lead was deleted"},{"event":"call.created","description":"A call record was created"},{"event":"call.updated","description":"A call record was updated"},{"event":"note.created","description":"A note was created"},{"event":"note.updated","description":"A note was updated"},{"event":"task.created","description":"A task was created"},{"event":"task.updated","description":"A task was updated"},{"event":"task.completed","description":"A task was marked as completed"},{"event":"activity.created","description":"An activity was logged"},{"event":"custom_object.created","description":"A custom object record was created"},{"event":"custom_object.updated","description":"A custom object record was updated"},{"event":"custom_object.deleted","description":"A custom object record was deleted"},{"event":"offer.created","description":"An offer was created"},{"event":"offer.updated","description":"An offer was updated"},{"event":"offer.deleted","description":"An offer was deleted"},{"event":"offer.sent","description":"An offer was sent to recipient"},{"event":"booking.created","description":"A booking was created"},{"event":"booking.approved","description":"A booking was approved"},{"event":"booking.rejected","description":"A booking was rejected"},{"event":"booking.cancelled","description":"A booking was cancelled"},{"event":"support_ticket.created","description":"A support ticket was created"},{"event":"support_ticket.updated","description":"A support ticket was updated"},{"event":"support_ticket.stage_changed","description":"A support ticket moved kanban stage"},{"event":"support_ticket.deleted","description":"A support ticket was deleted"}],"deliveryFormat":{"description":"Each webhook delivery sends a POST request to your URL with this JSON body:","schema":{"event":{"type":"string","description":"Event name (e.g. 'lead.created')"},"timestamp":{"type":"string","description":"ISO 8601 timestamp"},"data":{"type":"object","description":"The entity data that triggered the event"},"workspaceId":{"type":"string"}},"headers":{"Content-Type":"application/json","X-Webhook-Signature":"HMAC-SHA256 signature of the request body using your webhook secret"}},"signatureVerification":{"description":"Verify webhook authenticity by computing HMAC-SHA256 of the raw request body with your secret","example":"const crypto = require('crypto');\n\nfunction verifyWebhook(body, signature, secret) {\n  const expected = crypto\n    .createHmac('sha256', secret)\n    .update(JSON.stringify(body))\n    .digest('hex');\n  return crypto.timingSafeEqual(\n    Buffer.from(signature),\n    Buffer.from(expected)\n  );\n}"},"endpoints":{"description":"See the Webhook Subscriptions section in Endpoints for CRUD operations","quickReference":[{"method":"GET","path":"/api/v1/webhooks/subscriptions","description":"List subscriptions"},{"method":"POST","path":"/api/v1/webhooks/subscriptions","description":"Create subscription (returns secret)"},{"method":"GET","path":"/api/v1/webhooks/subscriptions/:id","description":"Get subscription"},{"method":"PUT","path":"/api/v1/webhooks/subscriptions/:id","description":"Update subscription"},{"method":"DELETE","path":"/api/v1/webhooks/subscriptions/:id","description":"Delete subscription"}]},"inboundWebhooks":{"description":"Salesbase also accepts inbound webhooks to trigger automations","endpoints":[{"method":"POST","path":"/api/webhooks/automation/:automationId","description":"Trigger a webhook-type automation. The JSON body becomes available as webhookData.* placeholders in the automation flow.","authentication":"Header x-webhook-secret must match the secret on the automation webhook trigger node."},{"method":"POST","path":"/api/v1/webhooks/zapier","description":"Zapier inbound — creates person, lead, and deal. Bearer API key with inbound scope."}]}},"offerTemplates":{"title":"Offer & Email Templates (AI Guide)","description":"How to build premium tilbudsskabeloner with custom HTML, placeholders, columns, and branding — plus email templates with compiledHtml. Reference implementation: A-Polering Standard Tilbud.","referenceDoc":"docs/OFFER-AI-PROMPT.md (full internal reference in repo)","setupOrder":["1. Workspace offer settings (companyInfo, bankInfo, defaults)","2. OfferProducts (pricingType: advanced for tiered pricing)","3. OfferTemplate (pages, headerElements, footerElements, branding)","4. OfferType (pricingRules, defaultTemplateId, offerSettings)","5. CalculatorTemplate (optional, offerTypeId)","6. Offer (templateId, offerTypeId, quoteInput, calculatorResult)","7. POST /api/v1/offers/:id/send (creates snapshot, fires automations)"],"apiEndpoints":{"offerTemplates":["GET /api/v1/offer-templates","POST /api/v1/offer-templates (admin)","GET /api/v1/offer-templates/:id","PATCH /api/v1/offer-templates/:id (admin)","DELETE /api/v1/offer-templates/:id (admin)","POST /api/v1/offer-templates/:id/duplicate (admin)"],"emailTemplates":["GET /api/v1/email-templates","POST /api/v1/email-templates (admin)","GET /api/v1/email-templates/:id","PATCH /api/v1/email-templates/:id (admin)","DELETE /api/v1/email-templates/:id (admin)"],"offerStack":["GET/POST /api/v1/offer-types, /api/v1/products","GET/POST /api/v1/offers, PUT draft fields, POST /api/v1/offers/:id/send"]},"elementTypes":{"description":"Page builder element types for offer templates (pages[].elements, headerElements, footerElements)","types":[{"type":"text","use":"Body copy with {{placeholders}}. Use \\n for line breaks. Inline styling via style object."},{"type":"heading","use":"H1-H6 via level: 1-6. Supports placeholders in content."},{"type":"html","use":"Custom HTML/CSS blocks — hero banners, info boxes, USP cards, colored dividers. Supports {{placeholders}} inside HTML."},{"type":"columns","use":"Multi-column layout. columns: [{ id, width, elements: [...] }]. Presets: 50-50, 70-30, 33-33-33."},{"type":"image","use":"url, alt, width, height. Use {{company.logo}} for workspace logo."},{"type":"video","use":"YouTube/Vimeo embed. url, provider: youtube|vimeo|direct."},{"type":"table","use":"Structured key-value data (recipient/sender, bank info). hideEmptyRows: true."},{"type":"line_items","use":"Auto-renders offer.calculatorResult.lineItems. showQuantity, showUnitPrice, showTotal."},{"type":"totals","use":"Auto-renders subtotal, VAT, total from calculatorResult."},{"type":"divider","use":"Horizontal rule with style.borderColor etc."},{"type":"spacer","use":"Vertical gap via height: '28px'|'40px' etc."},{"type":"button","use":"CTA. action: link|download. Brand-colored accept styling optional (accept handled on public /offer/[token] page)."}],"fullWidthOnly":["line_items","totals","columns"]},"placeholders":{"offer":["{{offer.number}}","{{offer.title}}","{{offer.date}}","{{offer.validUntil}}","{{offer.terms}}","{{offer.paymentTerms}}","{{offer.total}}","{{offer.subtotal}}","{{offer.vat}}"],"recipient":["{{recipient.name}}","{{recipient.firstName}}","{{recipient.email}}","{{recipient.phone}}","{{recipient.fullAddress}}","{{recipient.zip}}","{{recipient.city}}"],"company":["{{company.name}}","{{company.logo}}","{{company.phone}}","{{company.email}}","{{company.cvr}}","{{company.street}}","{{company.postalCode}}","{{company.city}}"],"bank":["{{bank.name}}","{{bank.reg}}","{{bank.account}}","{{bank.iban}}","{{bank.swift}}"],"calc":["{{calc.total}}","{{calc.subtotal}}","{{calc.vat}}","{{calc.discount}}"],"footer":["{{page}}","{{total}}","{{totalPages}}"],"email":["{{contact.firstName}}","{{contact.lastName}}","{{contact.email}}","{{company.name}}","{{offer.validUntil}}","{{sender.name}}"],"syntax":"Email templates also support {{field | default:\"fallback\"}} filter syntax."},"offerTemplateSchema":{"name":"string (required)","description":"string","branding":{"colors":{"primary":"#13143E","secondary":"#FBA212","accent":"#FBA212","background":"#ffffff","text":"#13143E","border":"#e0e0ea"},"typography":{"fontFamily":"Inter, sans-serif","headingFontFamily":"","fontSize":"base"},"logo":{"url":"","maxHeight":60,"position":"left|center|right"}},"headerElements":"Element[] shown on every page","footerElements":"Element[] shown on every page","headerSettings":{"height":80,"showOnAllPages":true,"showOnFirstPage":true},"footerSettings":{"height":40,"showPageNumbers":true,"pageNumberFormat":"Side {{page}} af {{total}}"},"pages":[{"id":"page_...","order":0,"title":"Side 1","elements":[],"settings":{"background":"#ffffff","minHeight":297,"margins":{"top":20,"right":15,"bottom":20,"left":15}}}],"defaultTerms":"string","defaultPaymentTerms":"string","defaultValidity":30,"isDefault":false,"isActive":true},"emailTemplateSchema":{"name":"string (required)","category":"marketing|transactional|reminder|follow-up|notification|quote|newsletter|other","compiledHtml":"string — full HTML body with {{placeholders}} (primary field for API-created templates)","plainText":"string (optional)","metadata":{"subject":"string with {{placeholders}}","preheader":"string"},"layoutSettings":{"layoutMode":"minimal|styled","containerWidth":600,"backgroundColor":"#ffffff","outerBackgroundColor":"#f3f4f6"},"requiredVars":[{"key":"vars.offerLink","type":"string","description":"..."}],"tags":["string[]"]},"aPoleringPattern":{"description":"Premium template mixing native elements + custom HTML (stored in production for A-Polering ApS)","techniques":["Header: columns (logo left) + html block (right-aligned company info) + html accent bar (#FBA212)","Hero: html element with dark brand background (#13143E), badge pill, headline, Trustpilot row","Meta: columns 55/45 — greeting text left, html info box right with {{offer.number}}, {{offer.date}}, {{recipient.fullAddress}}","Pricing: native line_items + totals elements","Social proof: video element (YouTube) + columns with html USP cards (border-top accent)","CTA: html dark banner + optional button element","Footer: html accent bar + columns (company | terms) + page numbers with {{page}}, {{offer.number}}"],"exampleHtmlHero":"<div style=\"background:#13143E;border-radius:10px;padding:36px;font-family:sans-serif\"><div style=\"font-size:26px;font-weight:800;color:#ffffff\">Dit personlige tilbud</div><div style=\"font-size:13px;color:rgba(255,255,255,0.75)\">Blanke ruder siden 1949</div></div>","exampleHtmlInfoBox":"<div style=\"background:#f5f5f8;border:1px solid #e0e0ea;border-radius:8px;padding:20px\"><table style=\"width:100%\"><tr><td>Tilbud nr.</td><td style=\"text-align:right;font-weight:600\">{{offer.number}}</td></tr></table></div>"},"designRules":["Mix html + native elements: html for visual design (heroes, cards, bars); text/heading for copy; line_items/totals for pricing.","Use inline CSS in html elements (flexbox, border-radius, brand colors). Placeholders work inside html content.","Vertical rhythm: spacer + divider between sections. One idea per section.","Brand colors via branding.colors AND inline html for accent bars/cards.","Do NOT put accept signature lines in templates — accept is handled on /offer/[token].","Email templates: set compiledHtml directly; subject in metadata.subject with {{contact.firstName}} etc."],"createOfferExample":{"method":"POST","path":"/api/v1/offers","body":{"title":"Tilbud vinduespolering","offerTypeId":"<OfferType _id>","templateId":"<OfferTemplate _id>","personRef":"<Person _id>","quoteInput":{"contact":{"name":"Klaus Hansen","email":"klaus@example.dk","phone":"+4512345678"},"address":{"fullAddress":"Hovedgaden 1, 2100 København Ø"}},"calculatorResult":{"lineItems":[{"name":"Vinduespolering","quantity":12,"unit":"stk","unitPrice":45,"total":540}],"subtotal":540,"vatAmount":135,"vatRate":25,"total":675}}},"sendOffer":{"method":"POST","path":"/api/v1/offers/:id/send","description":"Marks offer sent, creates immutable OfferSnapshot, logs activity, runs onOfferSent automations, dispatches offer.sent webhook. Returns publicId for customer link /offer/{publicId}.","scope":"write"}}},"integrationScope":"Workspace API key integrations. Mobile app, session, and platform endpoints are intentionally omitted."}