FinanceWorks with any LLM
Invoice processor
Invoices land in the agent's inbox — it extracts the details, matches a PO, and routes for one-click approval.
- Vault
- Audit
What you need
- 1An Anima API key — start free at console.useanima.sh
- 2Your own LLM — Claude, GPT-4o, or Gemini (Anima is the identity layer; you bring the brain)
- 3Capabilities enabled on the identity: email, vault
System prompt
Paste this into your agent
The full prompt that drives the recipe. Fill in the {{variables}} and give it to your own LLM — Anima handles the channels underneath.
You are an accounts-payable agent for {{COMPANY}}. Invoices arrive at your own Anima inbox {{INBOX_EMAIL}}. You extract the details, match each to an open purchase order, and route it for approval — every step logged.
Today is {{TODAY}}.
Workflow:
1. When an invoice arrives, extract: vendor, invoice number, amount, currency, due date, and line items.
2. Match it to an open PO in {{PO_SYSTEM}}. If the amounts differ by more than {{TOLERANCE}}, flag the mismatch.
3. If a vendor portal login is needed to fetch the invoice, use the credential from the Anima vault — you can use it without seeing it.
4. Email the invoice with your extracted summary to {{APPROVER}} for one-click approval, including the PO match and any flags.
5. On approval, mark it paid-pending and log the transaction with a correlation ID.
Rules:
- Never approve or pay an invoice yourself — you extract and route; a human approves.
- Never accept an amount over the PO without flagging it explicitly.
- If an invoice looks fraudulent or duplicated, hold it and alert {{APPROVER}}.
- Every extraction, match, and routing is logged to one correlation ID.Wire it up
Provision the identity
Give the agent its identity, then it runs the workflow above on real channels.
Bring your own LLM — Anima is the identity and the channels.
import os, requests
API = "https://api.useanima.sh/v1"
H = {
"Authorization": f"Bearer {os.environ['ANIMA_API_KEY']}", # from console.useanima.sh
"Content-Type": "application/json",
}
AGENT_ID = os.environ["ANIMA_AGENT_ID"]
# 1. Run the recipe
# Email from the agent's own inbox
requests.post(f"{API}/messages/email", headers=H, json={
"agentId": AGENT_ID,
"to": ["approver@company.com"],
"subject": "Invoice #4471 from Acme — $4,200, matches PO-8891",
"body": "Extracted and matched to PO-8891 (within tolerance). Approve to schedule payment.",
})
# 2. Get inbound replies in real time with a webhook — no polling. Register once.
# Webhooks are org-wide: one endpoint receives the events for every agent you run.
requests.post(f"{API}/webhooks", headers=H, json={
"url": "https://your-app.com/hooks/anima",
"events": ["message.received"],
})
# Then handle each event. The payload carries ids ({"event", "messageId",
# "agentId", "channel", "direction"}), so fetch the message, then reply.
def on_message(event):
msg = requests.get(f"{API}/messages/{event['messageId']}", headers=H).json()
reply = run_your_llm(SYSTEM_PROMPT, msg["body"]) # bring your own model
requests.post(f"{API}/messages/email", headers=H, json={
"agentId": msg["agentId"],
"to": [msg["fromAddress"]],
"subject": f"Re: {msg['subject'] or ''}",
"body": reply,
})How it works
One agent, every channel
- Received an invoice by emailEmail
- Extracted vendor, amount, due dateAgent
- Matched it to an open POAgent
- Emailed it for approvalEmail
Capabilities used
- Vault
- Audit