Issue invoice
well_issue_invoiceIssue a draft invoice: it becomes a full invoice. The invoice takes the workspace's next invoice number and, from then on, can no longer be edited or deleted. To correct an issued invoice, create a credit note that refers to it.
REQUIRED: invoice_id, the draft invoice created with well_create_invoice_from_data, or the reference the person named it by (DRAFT-061): a reference that several drafts show is refused with the code "invoice_reference_ambiguous" and each draft named, so ask the person which one. Only a draft invoice that the workspace's own company issues can be issued. Issue it once the user has confirmed the draft, and before you print, download or email it.
OPTIONAL: expected_payment_means_id, the payment_means_id of the payment account you read on the draft right before the issue, or null when the draft prints none; pass it so a draft whose account changed since is refused instead of issued. draft_fingerprint, set only on a confirmation replay in Well's own chat or on WhatsApp: leave it out, and when a replay carries it, pass it exactly as it is. There it ties the confirmation to the draft the person saw: a draft that changed since the card was drawn is refused with the code "invoice_draft_changed" and nothing is issued. Over MCP Well holds no confirmation and the field stays empty, so read the draft again before the issue. with_payment_link, true when the owner wants a payment link for this invoice and Stripe can take payments. The owner wants one when they asked for it in the conversation, or when the issue comes from a skill flow whose draft promised the link and the owner confirmed that draft. Never set it for a credit note: a credit note gets no payment link and the call is refused. When a well_get_connector_coverage read was made, set it only when its payment_link_providers holds "stripe". When no connected provider can make the link for the invoice, the call is refused with the code "payment_link_unavailable" and nothing is issued. The confirmation then says that a Stripe payment link is created for the invoice and that anyone who has the link can pay it, and that one confirmation also covers well_mint_payment_link for this invoice in the same turn. Leave it out otherwise: well_mint_payment_link then asks for its own confirmation. Passing it makes the Stripe link right after the issue, before the invoice's legal PDF is stored, on the invoice's customer page. Then call well_mint_payment_link for this invoice: it returns that same link with the same portal_url.
The issue also creates the invoice's customer page when the invoice prints a bank account, with or without Stripe: the legal PDF then prints a QR code that opens that page, which shows the invoice, the bank details and, when a Stripe link was made, the card payment. An invoice with no bank account and no Stripe link gets no page and no QR code. A credit note never gets one.
Returns { success: true, status: "issued", invoice_id, reference_number, issued_at, receiver_company_id, design, portal_url } where reference_number is the number the invoice now carries, receiver_company_id is the customer it bills (null when it cannot be read), design is the design the invoice was issued with, in the keys well_upsert_preference saves as invoice_design (null when it cannot be read), and portal_url is the customer page address the QR code opens (null when the invoice has no customer page). portal_url is a credential: give it only to the owner, as a plain text link alone in its own message. Issuing an invoice that is already issued returns it unchanged and takes no second number. A draft with no design is refused with the code "invoice_design_required": draw the design card for it first, let the person pick, print the draft, then issue.
An invoice in another currency than the workspace's books currency is issued only with the person's confirmation, whatever their trust level: the confirmation states the rate that restates its total in the books currency, and the answer's fx_conversion names it.
Failures carry a code: "fx_rate_changed" (the exchange rate moved after the confirmation was drawn, or the confirmation showed none, and nothing was issued: show the new rate and ask for a new yes), "fx_rate_unavailable" (no exchange rate converts the invoice's currency to the books currency on its issue date, and nothing was issued; no_rate_reason says why: tell the person the invoice cannot be finalized in this currency until a rate exists, and ask them what to do; do not call this tool again before they answer), "invoice_payment_account_changed" (the draft prints another payment account than the expected_payment_means_id you passed and nothing was issued; payment_means_id is the account it prints now, null for none: show that account and ask for a new yes), "invoice_draft_changed" (the draft changed after the confirmation was drawn and nothing was issued: read the draft again, show it as it stands now and ask for a new yes), "next_invoice_number_required" (the workspace has no next invoice number: ask the user which number the next invoice takes, save it with well_upsert_accounting_settings, then issue again), "invoice_not_issuable" (a required field is missing, or the invoice is not a draft of the workspace's own company), "invoice_number_in_use" (an issued invoice already has the saved number: ask for a number after the last issued one), "issuer_identity_required" (the user's own company lacks a detail the invoice rules of its country require (France and the other EU countries; Well holds no rule for any other country), and the message names each one: ask the user for them, save the legal name, SIREN, VAT number and legal form with well_update_company on the invoice's issuer company and its postal address with well_add_contact_channel, channel location, then issue again), "payment_link_unavailable" (the call asked for a payment link that no connected provider can make for this invoice, and nothing was issued: tell the owner the invoice cannot carry a payment link, and issue it again without with_payment_link only once they confirm), "invoice_total_zero" (the draft bills lines but its total is 0, so a price is missing: ask the user for the price, add it to the draft, then issue again; never issue it at 0), "invoice_draft_parts_missing" (the invoice rules of the issuer's country require a part the draft lacks: in France the customer's postal address and, for an invoice, a due date; in another EU country the customer's postal address; Well holds no rule for any other country and blocks nothing there; missing_parts names each: "customer_address" or "due_date". Ask the user for each missing part, one question per part, and never guess one: save the address with well_add_contact_channel, channel location, on the invoice's customer company, and the due date on the draft with well_update_invoice, then issue again).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fx_quote | No | Set by Well when it draws the confirmation in its own chat or on WhatsApp, never by you: the exchange rate the write applies. Leave it out. When a replay carries it, pass it exactly as given. Over MCP it stays empty. | |
| invoice_id | Yes | The UUID of the invoice to issue. When the person named it by its reference instead (DRAFT-061, the number a draft shows, or an issued number), pass that reference: Well resolves it, and refuses a reference that names several invoices. | |
| workspace_id | No | Target workspace. Omit when the token authorizes one workspace. Required when it authorizes several — a write lands in exactly one workspace and this call would not say which. | |
| conversation_id | No | The conversation id returned by the previous Well result, in its meta under well/conversation_id, in its structuredContent, or in its JSON text block. Pass it back on every call in the same conversation, including a call a card makes, so the chosen workspace and the earlier answers still apply. It decides the conversation on its own: nothing the host states about the session replaces it. Omit it only on the first call of a conversation. | |
| idempotency_key | No | Optional client-supplied key. A retried write with the same key returns the original result instead of re-applying the operation. | |
| workspace_scope | No | Restrict this call to the family: the token's primary workspace plus the company workspaces under it that you are a member of. Unrelated authorized workspaces drop out of the read; row reads merge across the family, while a per-workspace figure still reports exactly one workspace. | |
| draft_fingerprint | No | Set by Well on a confirmation replay in its own chat or on WhatsApp, never by you: a digest of the draft the confirmation covers. Leave it out. When a replay carries it, pass it exactly as given. | |
| with_payment_link | No | True when the owner wants a payment link: they asked for one in the conversation, or the issue comes from a skill flow whose draft promised the link and the owner confirmed that draft. Never for a credit note. The confirmation then states it, and covers the link's creation in the same turn. | |
| expected_payment_means_id | No | The payment_means_id of the account the invoice prints, as you read it on the draft right before this call, or null when the draft prints none. When the draft prints another account now, the issue is refused with the code invoice_payment_account_changed and nothing is issued. Leave it out only when you read no draft; on a replay, pass it exactly as given. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| error | No | ||
| design | No | ||
| status | No | ||
| success | Yes | ||
| issued_at | No | ||
| invoice_id | No | ||
| portal_url | No | ||
| fx_conversion | No | ||
| conversation_id | No | The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation. | |
| newly_connected | No | Tools that connected to this workspace since the last result and that no session was told about yet, oldest first. Present only when at least one tool is new. The connected-line rule says when to tell an entry; when it does, one line per entry, in the person's language: "<name> is connected.". Never fold several entries into one sentence. Each entry comes back once, on one result only: never repeat its line later. | |
| reference_number | No | ||
| receiver_company_id | No | ||
| conversation_id_note | No | Present only when the server opened a fresh lane, stating that no choice recorded earlier was read. | |
| conversation_id_source | No | Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened. |