Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dolfinai.co/llms.txt

Use this file to discover all available pages before exploring further.

The Dolfin AP Agent lets your users review bills, correct OCR output, manage suppliers, and approve payments through natural language. You upload the bill document via the direct API, then drive the rest of the workflow through POST /agent/ap. This guide walks through the same bill flow as the AP Quick Start, but driven through the agent after the initial upload.

Prerequisites

  • A Dolfin API key
  • An organisation already provisioned (see Client Integration)
  • A valid session token or API key for authentication
  • A bill PDF or image file to upload
All requests below require the x-dolfin-api-key and x-dolfin-organisation-id headers. See Authentication for details.

How the Agent Works

Every agent turn is a single POST to /agent/ap with just two body fields:
FieldTypeNotes
messagestring, requiredThe user’s message for this turn
conversationIdUUID, optionalOmit on the first turn. Supply on every subsequent turn to continue the same thread
You do not send the full message history — Dolfin persists the conversation server-side and the agent loads it automatically from conversationId.

Response format

The response is a text/event-stream (SSE). Read events as they arrive:
EventPayloadWhen
conversation{ "id": "uuid" }Fired once, on the first turn only, before any content
(unnamed){ "content": "text chunk" }Streamed assistant text, one chunk per data frame
actionTool action objectWhen the agent runs a tool (e.g. patched a bill)
(unnamed){ "done": true }Final frame — stream is complete
On error, the final frame is { "error": "message", "done": true }.

Persisting conversationId

On the first request, read the conversation SSE event and save its data.id. Echo that UUID back as conversationId on every follow-up POST to continue the same conversation. See the AR Agent guide for an SSE parser example.
Once the first response returns a conversationId, the agent type is frozen on that conversation. Sending a request to POST /agent/ar with an AP conversation’s conversationId (or vice versa) returns 409 Conflict.

Conversation scoping

Conversations are scoped by:
  • Organisation — always. A conversation belongs to the organisation in x-dolfin-organisation-id and can’t be read or continued from another organisation.
  • User — only when the call is authenticated with a Bearer JWT. API-key calls have no user binding, so any caller with the same API key and organisation can continue an API-key conversation.

Overview

1

Upload the bill (direct API)

Bill uploads are multipart file transfers, so Step 1 uses POST /bills directly. After this, everything else runs through the agent.
2

Ask the agent to review the bill

Start a conversation by sending the bill’s ID to the agent. It loads the OCR output and walks you through it.
3

Correct any fields (optional)

Tell the agent what’s wrong in natural language; it calls the patchBill tool to save your edits.
4

Submit for review and approve

The agent submits the bill for approval and, once approved, moves it to Approved.

Step 1: Upload the Bill (Direct API)

Bill uploads happen via POST /bills as multipart/form-data. OCR runs asynchronously.
curl -X POST https://api.dolfinai.co/bills \
  -H "x-dolfin-api-key: dol_live_abc123" \
  -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
  -F "file=@./acme-invoice-2025-01.pdf"
Response (202 Accepted):
{
  "id": "b1234567-abcd-ef01-2345-6789abcdef01",
  "state": "OcrProcessing"
}
Save the bill id — you’ll hand it to the agent next. Wait for the state to move to PendingReview (poll GET /bills/{id} or subscribe to the /hubs/bills SignalR hub) before talking to the agent.

Step 2: Ask the Agent to Review the Bill

This is the first turn of the conversation, so omit conversationId. Give the agent the bill ID and ask it to walk you through the OCR output.
curl -N -X POST https://api.dolfinai.co/agent/ap \
  -H "x-dolfin-api-key: dol_live_abc123" \
  -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "message": "I just uploaded bill b1234567-abcd-ef01-2345-6789abcdef01 — walk me through what OCR extracted."
  }'
SSE stream (excerpt):
event: conversation
data: {"id":"a7e1f3b2-9c0d-4e8a-b6f5-3d2e4f7c8a91"}

event: action
data: {"type":"bill.retrieved","billId":"b1234567-abcd-ef01-2345-6789abcdef01", ...}

data: {"content":"Here's what OCR extracted from that bill:"}

data: {"content":"\n\n- **Supplier:** Acme Supplies Ltd"}

...

data: {"done":true}
The agent replies with a summary:
Here’s what OCR extracted from that bill:
  • Supplier: Acme Supplies Ltd (billing@acme.co.uk)
  • Invoice number: ACM-2025-0142
  • Invoice date: 15 Jan 2025
  • Due date: 14 Feb 2025
  • Currency: GBP
  • Subtotal: £480.00
  • Tax: £96.00
  • Total: £576.00
  • Line items:
    1. Bulk stationery order × 10 @ £48.00 (20% tax)
OCR confidence is 0.94. Anything you’d like me to correct before we submit for review?

Step 3: Correct Any Fields (Optional)

Tell the agent what’s off. It’ll call the patchBill tool for you — no need to craft a patch payload by hand.
curl -N -X POST https://api.dolfinai.co/agent/ap \
  -H "x-dolfin-api-key: dol_live_abc123" \
  -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "conversationId": "a7e1f3b2-9c0d-4e8a-b6f5-3d2e4f7c8a91",
    "message": "Invoice number should be ACM-2025-00142, and add bank details: account 12345678, sort code 20-00-00, GB/GBP."
  }'
The agent calls patchBill, emits an action event, and confirms:
Done — I’ve updated:
  • Invoice number: ACM-2025-00142
  • Bank details: Acme Supplies Ltd · Account 12345678 · Sort 20-00-00 · GB / GBP
Ready to submit for review?
The agent can only edit bills in PendingReview — matching the direct-API rule. If OCR is still running, ask again in a few seconds.

Step 4: Submit for Review and Approve

When the data looks right, have the agent submit the bill and then approve it.

Submit for review

curl -N -X POST https://api.dolfinai.co/agent/ap \
  -H "x-dolfin-api-key: dol_live_abc123" \
  -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "conversationId": "a7e1f3b2-9c0d-4e8a-b6f5-3d2e4f7c8a91",
    "message": "Yes, submit for review."
  }'
The agent confirms and calls submitBillReview:
Submitted. The bill is now in NeedsApproval — Acme Supplies Ltd is linked as the supplier. Ready for you to approve?
Supplier auto-resolution. When the agent submits a bill, Dolfin resolves the supplier in this order: an explicit supplierId you set → an existing supplier on the organisation whose tax ID or email matches → a new supplier created from the OCR data (requires at minimum supplierName and supplierEmail). If the agent doesn’t have enough data to resolve or create a supplier, submit-review returns 400 Bad Request.

Approve

curl -N -X POST https://api.dolfinai.co/agent/ap \
  -H "x-dolfin-api-key: dol_live_abc123" \
  -H "x-dolfin-organisation-id: 9a658587-fe02-402e-b1ac-bfaf53274ef8" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "conversationId": "a7e1f3b2-9c0d-4e8a-b6f5-3d2e4f7c8a91",
    "message": "Approve it."
  }'
The agent runs approveBill and confirms:
Approved. The bill is now in Approved and ready for payment scheduling. Want me to schedule the payment now?
The agent can also schedule the payment (schedulePayment) and confirm payment (confirmPaid) via further turns.
Rejecting a bill. The AP agent can’t reject bills — rejection is a direct-API-only call via POST /bills/{id}/reject. Use the AP Quick Start for that flow.

Full Conversation Flow

TurnconversationId sent?User message
1No (first turn)“I just uploaded bill {id} — walk me through what OCR extracted.”
2Yes”Invoice number should be ACM-2025-00142, and add bank details…“
3Yes”Yes, submit for review.”
4Yes”Approve it.”

Managing Conversations

EndpointPurpose
GET /agent/conversations?agentType=ApList the caller’s AP conversations
GET /agent/conversations/{id}Get metadata for a single conversation
GET /agent/conversations/{id}/messagesPaged message history
PATCH /agent/conversations/{id}Rename a conversation
DELETE /agent/conversations/{id}Delete a conversation and its messages

Agent vs Direct API

Direct APIAP Agent
UploadPOST /bills (multipart)Same — agent doesn’t handle file upload
Review / patchCraft a PATCH /bills/{id} body by handDescribe the changes in plain English
Submit / approveSequential endpoint callsSingle-turn natural language requests
RejectPOST /bills/{id}/rejectDirect API only

Next Steps

AP Quick Start (Direct API)

See the same flow using direct API calls, including rejection and re-open.

API Reference

Explore the full Bills API, including payment scheduling and file URLs.