Draft an email
well_draft_emailShow an email draft on a card so the user can read it, edit it and send it. Nothing is sent by this call. The only thing it stores is each linked document's durable download link, which stays the same on every call.
REQUIRED: invoice_id, document_ids, transaction_id, task_id or links_no_file: true: a draft that names none of them is refused with attachment_required. links_no_file: true is for a plain email about no invoice, no document and no transaction (a question to a supplier, a reply), when the user asks to see or edit the draft first; it cannot be combined with the three ids. To send an email the user dictated, well_send_message is the tool, not this one. subject and body are required too, except with an invoice_id: leave them out and Well words them from the invoice, in the language it prints in (a credit note's email names it a credit note and the amount it credits). Optional: to, cc, bcc, purpose (a few words on what the email is for).
to holds the addresses the user gave. With an invoice_id and no to, Well fills to with the customer email the invoice prints, so do not look the address up yourself. With a task_id and no to, Well fills to with the email of the company the task names, when it knows one. When no address is known, pass to: [] and draw the card anyway: the card asks the reader for the address. Never ask for it in text first.
For an email about an invoice, pass its invoice_id: Well links that invoice's own PDF itself. Only an issued invoice can be emailed: a draft is refused with invoice_not_issued (offer Finalize instead) and a canceled one with invoice_canceled. Do not pass a document_id for an invoice: the document_id a create or extract call returned is the invoice's source data, not its PDF, and is refused. document_ids are other PDFs of this workspace to link; anything that is not a PDF is refused. An invoice with no PDF yet is refused with invoice_pdf_missing: call well_generate_document with its invoice_id, then call this tool again.
For an email about an open anomaly task (for example writing to a supplier about a detected issue with no invoice or document to link), pass its task_id: Well checks the task and fills the recipient, you write the subject and body from what the task found. A task that is not an anomaly task is refused with task_not_anomaly, and a closed one with task_closed: only an open anomaly-alert task satisfies this.
Write the body as plain paragraphs separated by a blank line. The user's own email app cannot carry a file, so Well adds each document's download link as the last paragraphs of the body, and the card shows them. The link does not expire: it stops when the document is deleted or printed again in place, or when the user asks to stop sharing it (well_revoke_document_shares). Never write that a file is attached ("Please find attached"); write for example "You can download the invoice here:" as the last line of your text, and the link follows it. Never write the link yourself. The user edits the draft on the card and presses "Send via your email app" there, which opens their email app with the message prefilled. Do not call well_send_email_draft yourself, and do not tell the user the email was sent until they say so.
When the token authorizes one workspace, call this directly — no workspace call is needed first. When it authorizes several, this read will not guess which one you mean: pass workspace_id on the call.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | ||
| to | No | The addresses the user gave. Leave it out with an invoice_id: Well fills in the email the invoice prints. Empty when no address is known: the card asks the reader for it. | |
| bcc | No | ||
| body | No | Plain text. A blank line starts a new paragraph. Leave it out with an invoice_id: Well words it from the invoice. | |
| purpose | No | What the email is for, in a few words, for example `invoice WA-2026-0148`. | |
| subject | No | Leave it out with an invoice_id: Well words it from the invoice. | |
| task_id | No | The open anomaly task this email is about. Well fills to from the company the task names, when it knows one. Refused with task_not_anomaly when the task is not an anomaly task, and task_closed when it is no longer open. | |
| invoice_id | No | The invoice this email is about. Well links that invoice's own PDF. | |
| document_ids | No | Other PDFs of this workspace to link. Never an invoice's document. | |
| 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. | |
| links_no_file | No | Set for a plain email about no invoice, no document, no transaction and no task. Never with an invoice_id, document_ids, transaction_id or task_id, and never for an email about an invoice: pass its invoice_id. | |
| transaction_id | No | The transaction this email asks a receipt for. A receipt request links no file: `transaction_id` alone satisfies the `invoice_id`/`document_ids` demand. | |
| 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. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | ||
| to | No | ||
| bcc | No | ||
| error | No | ||
| status | No | ||
| purpose | No | ||
| subject | No | ||
| success | Yes | ||
| task_id | No | On a refusal, the anomaly task the call named. | |
| draft_id | No | Minted per call. The card sends it back as the send call's idempotency key and Gmail-draft dedup key. | |
| body_lines | No | ||
| invoice_id | No | On a refusal, the invoice the call named. | |
| attachments | No | ||
| error_reason | No | ||
| transaction_id | No | The transaction a receipt-request draft names, echoed so the card can hand it to the send call. | |
| 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. | |
| resolved_workspace | No | The workspace that answered, when the caller named none and the token authorizes several. | |
| 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. |