Recipe: Invoice and expense processing
2min read
TL;DR: When an invoice or expense arrives (email or upload), this playbook extracts the key fields, validates them against rules and budgets, then parks with metaphor.waitForInput for human approval when needed. On Continue / Slack reply it creates the bill. Trigger is a webhook or inbox; outputs are a structured record and a durable approval gate.
Who this is for
Finance and ops teams processing invoices and expenses by hand.
What you'll need
- Connectors: Email/inbox or upload source, accounting/AP system (HTTP), Slack (optional notifier).
- Secrets: Accounting system API key, Slack token (if notifying).
- Trigger: Webhook on new invoice/expense, or an inbox integration.
How to build it with Ask Ballet
- Open the Console on Home.
- Paste the prompt below; set your validation rules and approvers.
- Review the plan and confirm.
- Connect the inbox/AP system and Slack, then register the webhook.
Build a playbook that triggers when a new invoice arrives via webhook with a PDF link.
Extract vendor, invoice number, line items, amount, currency, and due date. Validate:
amount under the auto-approve threshold, vendor exists in our AP system, and no
duplicate invoice number. If valid and under threshold, create the bill in the AP system
and notify #finance. If over threshold or failing a check, call metaphor.waitForInput
with prompt, details (extracted fields + PDF link), and Approve/Reject choices — do not
busy-wait or poll Slack. After wake: on approve create the bill; on reject stop and notify.
Optionally post a Slack message from a notifier that wakes via POST /api/runs/:id/reply.
What the playbook does
- Webhook trigger — receives the invoice/expense.
- Code/HTTP step (extract) — parses fields from the document.
- Code step (validate) — checks thresholds, vendor, and duplicates.
- Code step (approve or auto-post) — under threshold: create the bill; over threshold:
await metaphor.waitForInput({ prompt, details, schema })so the run parks as Paused on the samerunId. - On wake — Studio Continue or a Slack notifier
POST /replyreturns the choice; approve creates the bill, reject aborts. - HTTP step (notify) — confirms the outcome in Slack.
Variations and tips
- Set a clear auto-approve threshold so only exceptions need a human.
- Always check for duplicate invoice numbers before creating a bill.
- Pass full extracted fields as
detailsonwaitForInputso reviewers see the payload in Studio. - Slack is a notifier for the same park — wake with
requestIdfromstate.resume, not a custom pause API. See pause and resume. - Send approved records into Reconciliation downstream.
