Use casesWorkflow
AI Invoice Collection Agent
An AI agent that monitors unpaid invoices, sends timely reminders, handles replies about payment status, and escalates overdue accounts — keeping your cash flow on track.
The Problem
Chasing unpaid invoices is one of the most tedious and important tasks in any business. Late payments are the norm — the average B2B invoice is paid 8 days late, and nearly a quarter go over 30 days past due. Every day an invoice sits unpaid is a day your cash flow suffers.
The process is maddening in its repetitiveness. Someone on your finance team has to check which invoices are approaching their due date, compose a polite reminder, send it, wait for a reply, and follow up again if nothing happens. Multiply this across dozens or hundreds of outstanding invoices and it becomes a full-time job — one that most companies handle inconsistently because nobody wants to be the person sending awkward payment reminders.
The human side matters too. Invoice follow-ups are conversational. A client might reply saying they have sent payment, ask for a copy of the invoice, dispute a line item, or request a payment plan. These replies need to be read, understood, and acted on — not just logged in a spreadsheet.
How an Agent Solves This
An AI invoice collection agent automates the entire follow-up cycle while keeping the communication personal and conversational. The agent monitors your accounts receivable, sends reminders on a schedule, and handles the back-and-forth that follows. Here is how it works:
- Agent checks your billing system daily for invoices approaching their due date or past due
- Sends a friendly reminder 3 days before the due date, with a link to the invoice and payment details
- If the client replies — confirming payment, asking a question, or disputing — the agent reads the reply and responds appropriately
- If no payment or response after the due date, the agent sends a firmer follow-up and CC's your finance team
- Severely overdue invoices are escalated to a human with the full communication history and recommended next steps
The agent maintains a professional, consistent tone across all communications. It never forgets to follow up, never sends a reminder on the wrong date, and never loses track of who said what in a payment conversation.
How It Works with Robotomail
Robotomail provides the email infrastructure for your collection agent: a dedicated billing mailbox, outbound sending with proper authentication, inbound reply handling via webhooks, and thread tracking to keep each invoice conversation organized.
1. Send payment reminders
Your agent sends reminders from a dedicated billing address like billing@yourcompany.com. Each email is properly signed with DKIM and SPF so it lands in the inbox, not spam.
# Agent sends a payment reminder
curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_billing01/messages \
-H "Authorization: Bearer rm_live_abc123" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"to": [
"ap@clientco.com"
],
"subject": "Friendly reminder: Invoice #1042 — $8,400 due March 28",
"bodyText": "Hi,\n\nThis is a friendly reminder that Invoice #1042 for $8,400.00 is due on March 28, 2026.\n\nPayment details:\n- Amount: $8,400.00\n- Due date: March 28, 2026\n- Invoice: https://billing.yourcompany.com/inv/1042\n\nIf you have already sent payment, please disregard this message. Otherwise, let me know if you have any questions about this invoice.\n\nBest regards,\nBilling Team",
"bodyHtml": "<p>Hi,</p><p>This is a friendly reminder that Invoice #1042 for $8,400.00 is due on March 28, 2026.</p>"
}
JSON
# Response (excerpt)
{
"message": {
"id": "msg_4n8k1x",
"threadId": "thr_7v2p5q",
"status": "SENT",
"sentAt": "2026-03-22T08:00:00Z"
}
}2. Handle replies
When a client replies to a reminder, Robotomail delivers the message to your agent via webhook. The agent can parse the response — did they confirm payment, ask a question, or raise a dispute? — and respond accordingly.
# Client replies — Robotomail delivers via webhook
{
"event": "message.received",
"timestamp": "2026-03-22T14:20:00Z",
"data": {
"message_id": "11111111-1111-4111-8111-111111111111",
"mailbox_id": "22222222-2222-4222-8222-222222222222",
"mailbox_address": "invoice-chasing@yourcompany.com",
"from": "ap@clientco.com",
"to": [
"invoice-chasing@yourcompany.com"
],
"cc": [],
"subject": "Re: Friendly reminder: Invoice #1042 — $8,400 due March 28",
"body_text": "Hi, we have processed the payment via wire transfer this morning. Should arrive in 2-3 business days. Can you send us a receipt once it clears?",
"thread_id": "33333333-3333-4333-8333-333333333333",
"received_at": "2026-03-22T14:20:00Z",
"attachments": []
}
}3. Continue the conversation
The agent replies in the same thread, keeping the conversation organized. It can also update your billing system — marking the invoice as "payment pending" when a client confirms they have sent a wire, for example.
# inReplyTo below stands for the fetched message.messageId; see the reply example below.
# Agent acknowledges and updates internal status
curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_billing01/messages \
-H "Authorization: Bearer rm_live_abc123" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"to": [
"ap@clientco.com"
],
"subject": "Re: Friendly reminder: Invoice #1042 — $8,400 due March 28",
"inReplyTo": "<original-message@example.com>",
"bodyText": "Thanks Lisa, I have noted the wire transfer. I will send a receipt as soon as the payment clears on our end. If it has not arrived by March 27, I will follow up.\n\nAppreciate the quick response.",
"bodyHtml": "<p>Thanks Lisa, I have noted the wire transfer. I will send a receipt as soon as the payment clears on our end...</p>"
}
JSON4. Escalate overdue invoices
For invoices that remain unpaid after multiple reminders, the agent escalates with a firmer tone and CC's your finance team. Custom headers let your systems track escalation status programmatically.
# Agent escalates overdue invoices with context
curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_billing01/messages \
-H "Authorization: Bearer rm_live_abc123" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"to": [
"ap@clientco.com"
],
"cc": [
"finance@yourcompany.com"
],
"subject": "Overdue: Invoice #1038 — $12,600 (14 days past due)",
"bodyText": "Hi,\n\nInvoice #1038 for $12,600.00 was due on March 8 and is now 14 days past due. I have sent two previous reminders on March 5 and March 12.\n\nCould you provide an update on the payment status? If there is an issue with the invoice, I am happy to help resolve it.\n\nInvoice: https://billing.yourcompany.com/inv/1038\n\nI have CC'd our finance team for visibility.\n\nBest regards,\nBilling Team",
"headers": {
"x-custom-invoice-status": "overdue",
"x-custom-days-past-due": "14"
}
}
JSONKey Benefits
- Consistent follow-up. Every invoice gets the right number of reminders at the right time. No invoices fall through the cracks because someone was on vacation or forgot.
- Conversational handling.Unlike notification-only tools, the agent reads and responds to client replies. If someone says "we sent payment yesterday," the agent acknowledges it and updates your records.
- Professional sender identity. Emails come from your company domain with proper DKIM and SPF authentication. Reminders land in the inbox, not the spam folder.
- Graduated escalation. The agent adjusts tone based on how overdue an invoice is — friendly reminders before the due date, firmer follow-ups after, and human escalation for severely past-due accounts.
- Full audit trail. Every message is stored with thread context. Your finance team can review the complete communication history for any invoice at any time via the threads API.
Check the API documentation for webhook setup, threading, and custom headers. Read why we built Robotomail, or get started and have your invoice agent running by end of day — paid plans come with a 30-day money-back guarantee.
Connect the workflow to a real reply
The webhook's data.message_id is a database ID used to retrieve or deduplicate a message. Fetch it with the GET message endpoint, then use the response's message.messageId (the RFC Message-ID) as inReplyTo. Keep data.thread_id for your application's conversation state. Do not use a database ID or thread ID as a reply header. Stop and investigate if the fetched message has no Message-ID.
Examples use illustrative IDs. Replace them with IDs from your account; never construct an email Message-ID from a database ID. These workflows email other people and need a paid plan. Test Free with your verified account email first; see plans.
Verify the webhook signature over the raw body, persist the event and deduplicate on the database message ID before acknowledging it. Run your application logic from a durable queue. The database, calendar, CRM and model functions shown above belong to your application.
This shell example fetches an incoming email and builds all required send fields. Set ROBOTOMAIL_API_KEY, ROBOTOMAIL_MAILBOX_ID and ROBOTOMAIL_MESSAGE_ID in your environment. Apply your recipient and approval rules before sending.
# Requires jq. Use mailbox_id and message_id from the verified webhook.
original=$(curl --fail --silent --show-error \
"https://api.robotomail.com/v1/mailboxes/$ROBOTOMAIL_MAILBOX_ID/messages/$ROBOTOMAIL_MESSAGE_ID" \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY") || exit 1
payload=$(printf '%s' "$original" | jq -e --arg body "Thanks, I received your message." '
.message | if (.messageId | type == "string" and length > 0) then
{to: [.fromAddress], subject: ("Re: " + .subject), bodyText: $body, inReplyTo: .messageId}
else error("Original email has no Message-ID") end
') || exit 1
curl --fail --silent --show-error \
"https://api.robotomail.com/v1/mailboxes/$ROBOTOMAIL_MAILBOX_ID/messages" \
-H "Authorization: Bearer $ROBOTOMAIL_API_KEY" \
-H "Content-Type: application/json" \
--data-binary "$payload"
Read receive and reply and webhook verification for the full setup.