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.

  • Email
  • Vault
  • Audit

What you need

  1. 1An Anima API key — start free at console.useanima.sh
  2. 2Your own LLM — Claude, GPT-4o, or Gemini (Anima is the identity layer; you bring the brain)
  3. 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

  1. Received an invoice by emailEmail
  2. Extracted vendor, amount, due dateAgent
  3. Matched it to an open POAgent
  4. Emailed it for approvalEmail

Capabilities used

  • Email
  • Vault
  • Audit

Give your agent an identity.