Workflows
Workflows are workspace automations: when something happens (a trigger), Campbooks runs an ordered list of actions — optionally only if a condition holds. Build them at /workflows with a Zapier-style editor; every run is recorded so you can see exactly what happened.
Triggers
A workflow starts from one of three triggers:
| Trigger | Fires when |
|---|---|
| Email received | A new email finishes processing (after scanning and AI triage) |
| Webhook | An external service POSTs to the workflow's unique URL, <your-app-url>/webhooks/<token> |
| Event | An internal event is published (e.g. a document is approved) |
The webhook URL is minted automatically and can be rotated; it needs no authentication, which is what lets other services call it.
Conditions
A trigger can carry a condition, and the workflow only runs if it passes — for example, "only when the email's document type is invoice," or a generic field check like payload.status == "paid" on a webhook body. A failing condition halts the run cleanly.
Actions
Each step performs one action. Built-in actions:
| Action | What it does |
|---|---|
| Send email | Send a message from one of your connected accounts |
| HTTP request | Make an outbound API call |
| Slack message | Post to a Slack incoming webhook |
| Discord message | Post to a Discord incoming webhook |
| Custom action | Call a saved Connection (reusable base URL + auth) |
| Email action | Act on the triggering email — tag, archive, or snooze it |
| Create calendar event | Turn the triggering email into a calendar event |
| Send to Google Drive | Create a folder or upload the email's attachments |
| Send to Notion | Create a page or a database item |
| Emit event | Publish an internal event (which can trigger other workflows) |
Templating with Liquid
Every field in a step is a Liquid template rendered against the trigger's data, so actions can use real values from what fired them:
- Email triggers expose
emailanddocuments— e.g.{{ email.subject }},{{ email.from }}. - Webhook triggers expose
payload,headers, andquery— e.g.{{ payload.invoice_id }}.
Missing variables render empty rather than erroring, so templates stay forgiving.
Connections
A Connection is a saved, reusable integration target: a base URL plus encrypted auth (bearer, header, or basic). The Custom action resolves the connection server-side and injects its auth header at run time, so your secrets never live inside a step's template. Manage them under Settings → Integrations → Connections.
Outbound calls are guarded. Every HTTP-backed action runs through a safety layer that blocks requests to loopback, private, link-local, and cloud-metadata addresses (local hosts are allowed only in development), with request size and time caps. This prevents a workflow from being turned into a tool to reach your internal network.
Run history
Open a workflow's Executions tab to see each run: its status (running, completed, failed), when it started and finished, any error, and the input/output captured for every step — so debugging an automation is a matter of reading the trail, not guessing.
Triggering from the API
Webhook workflows can also be triggered programmatically through the public API with a workflows:trigger scope, which is the authenticated equivalent of POSTing to the webhook URL.