Engagements

An engagement is an agreed total and the schedule it will be billed off. Record it once, and Billr keeps track of what has been billed, what is still owed to the agreement, and what is ready to invoice right now.

The problem it solves

You agree 12,000 for a rebuild, half up front and half on delivery. The deposit goes out as an invoice the same day. Four months later the work ships, and the second invoice is the one everybody forgets, or worse, sends twice. An engagement is where that second half lives in the meantime.

An estimate is a price you are proposing. An invoice is money you are asking for now. An engagement is the agreement in between: the number you both settled on, and the plan for turning it into invoices.

Nothing is ever sent

No engagement tool emails anybody. Creating one, starting it, marking a milestone complete and completing the whole thing all change what Billr knows, not what your client receives. A schedule entry becoming ready to bill is a status, and turning it into an invoice, and sending that invoice, stay separate steps that you or an agent take deliberately.

The model

An engagement has a client, a total, a currency, a status and a billing mode. Under it sits its schedule: one entry per payment, each with a label, an amount, a rule for when it becomes billable, and a status.

Two rules are enforced by the database rather than by the app, because both are money. The entries always add up to exactly the total: a schedule that does not balance cannot be saved, by anyone, through any route. And once an entry has been invoiced it is frozen: its amount cannot change and it cannot be deleted, so a billed engagement never quietly rewrites its own history.

Billing modes

Percentage splitpercent_split

Each entry carries a percent and the percentages add up to 100. The classic 50/50 deposit and balance, or 30/70.

Equal installmentsequal_installments

The total is divided into equal parts. Ten monthly payments on a retainer, or three phases of a build.

Milestonesmilestones

You state each amount yourself, and the amounts must add up to the total. Use it when the parts are uneven.

Manualmanual

The amounts are yours and nothing fires on its own. Every entry waits for a person to say it is billable.

Rounding is decided in one place and never left to chance: each entry is rounded to the cent and the last entry absorbs the remainder. Splitting 100 three ways gives 33.33, 33.33 and 33.34, so the schedule adds up to 100 rather than to 99.99.

Each business also carries a few saved shapes to start from: 50/50, 30/70, a three phase split, and ten equal installments.

When money becomes billable

Every entry carries a due rule, which is the only thing that moves it to ready to bill.

on_start

Becomes billable when the engagement is started. This is a deposit.

on_complete

Becomes billable when the engagement is completed.

on_milestone

Becomes billable when you mark that entry complete.

on_date

Becomes billable once its date has passed.

manual

Waits for a person to decide, and is never fired by a rule.

Dated entries are swept whenever somebody reads their engagements, which means opening the page or asking an agent. There is no background job to fail quietly.

Billing an entry

An entry that is ready to bill goes onto an ordinary invoice. In the app, the new invoice page shows a “From engagements” section listing everything that client has ready, and the engagement itself has a button that opens that page with the ready entries already ticked. Over MCP it is create_invoice with engagement_entry_ids, which is a list of entry ids from list_ready_to_bill.

Each entry becomes one line, labelled with the engagement and its own label, at the agreed amount. The line and the claim are written in the same transaction, so an invoice that exists always has its entries marked billed: an entry cannot be on two invoices, and an entry that is already invoiced refuses the whole call rather than quietly billing the rest. The entry must belong to the same client and be in the same currency as the invoice, because Billr never converts money on its own.

Sending or paying the invoice changes nothing further about the schedule. Deleting the invoice while it is still a draft hands its entries back to ready to bill, so a draft raised by mistake is simply undone.

Example
Invoice the deposit on the Harbor and Lane rebuild, but do not send it yet.

From an accepted estimate

A quote that was accepted but will be billed in parts becomes an engagement rather than an invoice. The accepted estimate page offers both, and the conversion carries the client, the total and the currency across exactly as quoted: all you choose is how the total is split. An estimate can become an invoice or an engagement, never both, and that rule is enforced in the database from either direction, so the same quote cannot be billed twice by taking two different routes.

The new engagement is a draft. Accepting a quote is not the same event as starting the work, and starting an engagement is what makes its deposit billable, so that stays a separate deliberate step.

The lifecycle

A new engagement is a draft. Starting it makes any deposit billable. It can be paused and started again while the work is on hold. Completing it fires everything waiting on completion, and tells you if money is still unbilled rather than closing quietly. Cancelling it stops anything further being billed against it at all. Completed and cancelled are both final.

What agents can read

list_engagements

Every engagement with its agreed total, how much has been billed, how much is left, and how many schedule entries are ready to bill. Filter by client, by status, or to only the ones with billable work waiting.

get_engagement

One engagement in full, including every schedule entry with its status, its due rule and the invoice it became.

list_ready_to_bill

The "what should I invoice today" list, across every client at once. Nothing on it has been invoiced yet.

Example
What is ready to bill across all my clients, and how much is it worth?

What agents can change

These need a key with the write permission. Every one of them takes a request_id, so a retry after a dropped connection returns the original answer instead of writing twice.

create_engagement

Records the agreement and its schedule. The split is worked out on the server, so the entries always add up to exactly the total and the last one absorbs any rounding.

update_engagement

Corrects the name, the dates or the internal notes. The agreed total and the schedule are deliberately not editable, because changing an agreed number after work has been billed against it is a renegotiation rather than an edit.

mark_milestone_complete

Records that a piece of work was delivered. An entry waiting on a milestone becomes ready to bill.

complete_engagement

Closes the engagement, fires anything waiting on completion, and reports any money still unbilled rather than swallowing it.

waive_engagement_entry

Writes off an entry that will not be charged, with a reason. It stays in the schedule and stops counting towards what is left.

convert_estimate_to_engagement

Turns an accepted quote into the agreement it was quoting, carrying the client, the total and the currency across unchanged. An estimate becomes an invoice or an engagement, never both.

create_invoice (engagement_entry_ids)

Not an engagement tool, but the one that bills them. Pass the entry ids and each becomes a line at its agreed amount, marked invoiced in the same step.

Example
Record the Harbor and Lane rebuild: 12,000 agreed, 50% deposit and 50% on delivery, and start it today.

Quoting work that has not been agreed yet? Estimates and items covers that. Already delivered and want paying? Getting paid picks up from the invoice.