How-to guidesView as Markdown ↗

Personalise a staged send

In plain terms

Your assistant can add a short personal note and subject line to an invoice, proposal or statement email before it goes. It shows you the exact email first, and the note changes that one email only. It can't change who receives it or what is attached; for that it cancels and starts again.

Call update_pending_send between the propose and approve legs to set cover_message and subject on any staged send. The note renders between the template greeting and the boilerplate line, so write it with no greeting and no sign-off. The returned preview is exactly what will send.

At a glance

Who it's for:
AI assistants working in a Biloh business

Answer first

Every outbound document — invoice, proposal, work order, statement, credit note, quote request, contractor agreement — travels inside a branded email built from a tenant template. update_pending_send lets you overwrite two slots on a single staged send without touching that template:

  • cover_message — a personal note, plain text, up to 2000 characters
  • subject — the email subject line, up to 200 characters

Both are per-send. Neither changes the tenant's boilerplate for anyone else.

Where it sits in the send chain

Sends your assistant starts are staged, never one-shot. The personalisation slot only exists in the middle of the chain:

propose_send_invoice(invoice_id)
  → returns operation_id, recipients[], email_preview
update_pending_send(operation_id, cover_message, subject?)
  → returns the re-rendered email_preview
confirm_pending_operation(operation_id)
approve_send_invoice(operation_id, confirmed: true)
  → email dispatched

You may call update_pending_send as many times as you like before approving. Nothing has left the building until the approve leg returns send_ok: true.

How the note renders

The composed email is assembled in this order:

  1. Template greeting — Hi <resolved name>,
  2. your cover_message, as a single paragraph
  3. Template boilerplate — e.g. Please find your invoice from <business>.
  4. Amount / due date / terms table, payment CTA, bank details
  5. Template sign-off and footer

Three rules follow directly from that ordering, and each one is a real mistake people make:

Write no greeting. The template already opened with one. A cover_message starting Hi Sam — produces a visible double greeting.

Write no sign-off. The template already closes. Adding Thanks, Sam gives the email two endings.

Write one paragraph. The slot renders inside a single HTML paragraph element, so newlines you type do not survive into the delivered email. Two or three sentences that flow is the right shape.

Check the resolved greeting name before you write

The greeting is not always a person. It resolves to the contact name when the client has a contact flagged to receive that document type, and falls back to the client's legal name otherwise — which can be a company name in block capitals.

The recipients array returned by the propose leg tells you which you got:

"recipients": [
  { "email": "...", "name": "Sam Whitfield", "resolved_from": "receives_invoices" }
]

If the resolved name is a company rather than a person, and you know the individual, drop their first name into the first sentence of your note instead of the greeting — "Thanks for the payment you made last week, Sam — that one was against...". You get the personal touch without fighting the template.

Read the array for a second reason: it is the exact fan-out the approve leg will email. An unexpected address here is a contact-configuration problem to fix before sending, not after.

The preview is the email

update_pending_send returns a fresh email_preview containing subject, body_html and body_text. This is not an approximation — it is what will be dispatched. Read it, not your intent.

Worth confirming every time: your note landed above the payment CTA, the recipients are right, and the amount and due date match what you expect.

Changing recipients or attachments

You cannot. update_pending_send edits wording only. To change who receives the email or what is attached, cancel the operation with cancel_pending_operation and propose it again against corrected records.

The staging window

A staged operation expires if it is not approved — tenant-tunable via finance.sends.pending_operation_ttl_minutes (default 60, clamped 5–240). An expired operation sent nothing and changed nothing; stage it again.

Because cancelling is free and non-destructive, staging a send purely to read the preview and then cancelling is a legitimate way to inspect an email before committing to it.

Related

Under the hood

Tools this page uses, in the order used:

Raw markdown: /docs-md/how-to/personalise-a-staged-send

Last updated 2026-08-28