Skip to main content
Glama

Create invoice from data

well_create_invoice_from_data

Load the draft-invoice skill with well_get_skill before you call this.

Create an invoice in Well from data you extracted by reading an invoice (your own OCR) — you send the structured fields, not the file.

Never call it to add a product or a service to the catalog, or to change a product's price ("Ajoute le produit Audit SEO à 1 200 € HT", "Passe Audit SEO à 1 400 €"): those are well_create_product and well_update_product, and they make no invoice.

Well persists the invoice + its line items + payment means using the same pipeline as uploaded documents. Fill every field you can read from the document:

  • issuer / receiver: { name (required), company_id?, domain?, tax_id? }

  • A draft may be saved before it is complete: with status "draft", leave out the issuer, the receiver, issue_date, currency or line_items you do not know yet, and never invent one. On such a draft a party you do send carries its company_id, currency is required as soon as there is a line, and payment_means is left out. The answer's missing_fields names every part the draft still lacks before it can be issued, the issuer's own details included; the draft is complete only when it is empty. Any other status needs every part

  • invoice_number (the invoice's own number, read from the document; leave it out for a draft, Well numbers drafts itself), reference_number? (a reference printed apart from the invoice number; never the invoice number itself; ignored on a draft), issue_date (YYYY-MM-DD), due_date? (YYYY-MM-DD; leave it out on a draft the person gave no due date: Well sets the customer's usual terms, else 30 days after the issue date), currency (ISO 4217)

  • line_items[]: { line_id?, parent_line_id?, name, line_kind?, ordinal?, printed_subtotal?, product_id?, quantity?, unit_price, currency?, tax_rate? }. A section uses line_kind "section", unit_price null and an ordinal; its printed_subtotal must equal the billed descendants it closes. It prints as a heading and never changes invoice totals. A product_id can name a live product from well_list_products or an exact SKU match returned in well_define_line_items. When product_id is absent, Well links the line only if exactly one active product in this workspace has the exact line name or SKU and the same unit price and currency. Zero or multiple matches stay unlinked. Well does not create or change a product, and a stated price applies to this invoice only. The result's line_catalogue_attribution says which saved line has a product link and whether its exact price came from the catalogue. Never send totals: Well computes them from billed lines, each line held to the currency's minor units

  • printed_grand_total? — the grand total printed on a document you read. Well still stores the computed total; when the printed one differs by more than rounding, the answer carries printed_total_mismatch { printed_grand_total, computed_grand_total }: tell the user both figures

  • payment_means?[]: { type, iban?, bic?, scheme? }

  • status?: draft | issued | paid | canceled — create an invoice the user is still reviewing as "draft", then issue it with well_issue_invoice once the user confirms; issuing gives it the next invoice number and locks it. "paid" is an "issued" request that also records the source's claim that the invoice was settled; it is never a lifecycle word of its own

  • document_type_code?: "380" invoice | "381" credit note (state it: an invoice with no document type cannot post); corrects_invoice_id? — the issued invoice a credit note corrects, required for a credit note. An issued invoice cannot be edited: correct it with a credit note, then create a new invoice

ONE CALL IS THE WHOLE WRITE. This tool takes the invoice's status and both parties' company ids, so a create never needs a well_update_invoice after it:

  • The user asked to DRAFT an invoice → pass status: "draft" here.

  • You already found the company (well_query_records, well_get_entity) → pass its company_id on that party. Naming the party without its id re-resolves it, which can attach the invoice to the wrong company or create a duplicate one.

Creating and then patching the same invoice writes twice and shows the user two confirmations for one action. Put the intent in this call.

The answer carries the saved invoice's status, customer_name, customer_siren (absent while the customer has none), currency, grand_total, issue_date, design_layout (null until a design is chosen) and lines. line_catalogue_attribution marks each line as catalogue only when the exact active catalogue product is linked and its unit price and currency match; otherwise it says not_catalogue. The card shows the invoice summary, so the reply does not list those fields again.

Input Schema

NameRequiredDescriptionDefault
issuerNoThe company that issues the invoice. Leave it out only on a draft whose issuer is not known yet.
statusNoThe invoice's lifecycle status. Set it here when the user asked for one ("draft an invoice") — do NOT create and then call well_update_invoice to change it. Omitted, Well derives one only where the document type decides it; otherwise the invoice has no status.
currencyNoISO 4217 (3 letters). Required as soon as the invoice has a line; never guessed by Well.
due_dateNoISO 8601 YYYY-MM-DD.
receiverNoThe customer: a company, or a private individual named by person_id. Leave it out only on a draft whose customer is not known yet.
issue_dateNoISO 8601 YYYY-MM-DD. Leave it out only on a draft whose date is not set yet.
line_itemsNoThe lines. Leave them out only on a draft whose lines are not known yet.
workspace_idNoTarget 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.
payment_meansNo
invoice_numberNoThe invoice's own number, read from the document. Required unless the invoice is a draft or created to be issued: Well numbers those when they are issued. Never make one up.
conversation_idNoThe 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_keyNoOptional client-supplied key. A retried write with the same key returns the original result instead of re-applying the operation.
workspace_scopeNoRestrict 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.
reference_numberNoA reference printed apart from the invoice's own number. Never the invoice number itself. Leave it out for a draft: Well gives each draft its own reference (DRAFT-0007) at its first save, even while it still lacks parts, takes the invoice number only when the draft is issued, and ignores any value sent.
document_type_codeNo"380" is an invoice; "381" is a credit note that corrects an invoice already issued. Omitted, the invoice has no document type and cannot post. An issued invoice cannot be edited, so a correction is a credit note with its own number, then a new invoice.
corrects_invoice_idNoThe UUID of the issued invoice a credit note corrects. Required for a credit note (381); refused otherwise.
printed_grand_totalNoThe grand total printed on a document you read, as printed. Leave it out for an invoice Well drafts. Well still stores the total it computes from the lines; when the two differ by more than rounding, the answer carries printed_total_mismatch.

Output Schema

NameRequiredDescriptionDefault
codeNo
errorNo
linesNo
statusNo
sourcesNoThe tools that hold a copy of the invoice, highest source precedence first. Empty when no tool holds it.
successYes
currencyNo
tax_totalNo
invoice_idNo
issue_dateNo
grand_totalNo
items_totalNo
source_countNoHow many tools hold the invoice; sources may list fewer.
customer_nameNo
design_layoutNo
payment_meansNo
customer_sirenNoThe SIREN the invoice prints for its customer. Absent while the customer has none.
missing_fieldsNoOn a draft, every part the person gives that it still lacks before it can be issued. The draft is complete only when this list is empty.
card_line_countNo
conversation_idNoThe conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.
newly_connectedNoTools 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_numberNo
invoice_item_countNo
conversation_id_noteNoPresent only when the server opened a fresh lane, stating that no choice recorded earlier was read.
conversation_id_sourceNoWhere the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.
printed_total_mismatchNoThe document's printed grand total differs from the total Well computed from the lines and stored. Tell the user both figures; a document-level discount or charge belongs on its own line.
next_invoice_number_stateNoWhether the workspace's next invoice number lets the issue go ahead. Well settles it when the invoice is issued: it is never named to the person and never makes the draft incomplete.
line_catalogue_attributionNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedOutput schema / properties / customer_siren
      Added value: +{
      +  "description": "The SIREN the invoice prints for its customer. Absent while the customer has none.",
      +  "type": "string"
      +}
  2. Changed32 schema fields changed
    • removedInput schema / properties / line_items / items / properties / unit_price / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / line_items / items / properties / unit_price / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / currency / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / currency / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / design_layout / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / design_layout / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / grand_total / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / grand_total / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / issue_date / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / issue_date / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / items_total / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / items_total / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / line_catalogue_attribution / items / properties / product_id / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / line_catalogue_attribution / items / properties / product_id / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / lines / items / properties / line_total / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / lines / items / properties / line_total / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / lines / items / properties / quantity / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / lines / items / properties / quantity / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / lines / items / properties / tax_amount / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / lines / items / properties / tax_amount / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / lines / items / properties / tax_rate / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / lines / items / properties / tax_rate / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / lines / items / properties / unit_price / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / lines / items / properties / unit_price / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / reference_number / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / reference_number / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / sources / items / properties / domain / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / sources / items / properties / domain / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / status / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / status / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedOutput schema / properties / tax_total / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / tax_total / type
      Added value: +[
      +  "number",
      +  "null"
      +]
  3. Changed9 schema fields changed
    • changedInput schema / properties / line_items / items / properties / product_id / description
      Previous value: -"A live catalogue product in this workspace, from well_list_products or an exact SKU match in well_define_line_items."New value: +"A live catalogue product in this workspace, from well_list_products or an exact SKU match in well_define_line_items. When omitted, Well links the line only if exactly one active product has the exact line name or SKU and the same unit price and currency."
    • addedOutput schema / properties / items_total
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / line_catalogue_attribution
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "line_id": {
      +        "type": "string"
      +      },
      +      "price_source": {
      +        "enum": [
      +          "catalogue",
      +          "not_catalogue"
      +        ],
      +        "type": "string"
      +      },
      +      "product_id": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "line_id",
      +      "product_id",
      +      "price_source"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / lines / items / properties / line_total
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / lines / items / properties / tax_amount
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / missing_fields / description
      Added value: +"On a draft, every part the person gives that it still lacks before it can be issued. The draft is complete only when this list is empty."
    • changedOutput schema / properties / missing_fields / items / enum
      Previous value: -[
      -  "customer_address",
      -  "due_date",
      -  "line_price",
      -  "line_tax_rate",
      -  "issuer",
      -  "receiver",
      -  "line_items",
      -  "currency",
      -  "issue_date"
      -]New value: +[
      +  "customer_address",
      +  "buyer_siren",
      +  "due_date",
      +  "line_price",
      +  "line_tax_rate",
      +  "issuer",
      +  "legal_name",
      +  "postal_address",
      +  "siren",
      +  "vat_number",
      +  "legal_form",
      +  "receiver",
      +  "line_items",
      +  "currency",
      +  "issue_date"
      +]
    • addedOutput schema / properties / next_invoice_number_state
      Added value: +{
      +  "description": "Whether the workspace's next invoice number lets the issue go ahead. Well settles it when the invoice is issued: it is never named to the person and never makes the draft incomplete.",
      +  "enum": [
      +    "ready",
      +    "missing",
      +    "without_digits",
      +    "in_use"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / tax_total
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  4. Changed13 schema fields changed
    • addedInput schema / properties / line_items / items / properties / is_price_included_in_parent
      Added value: +{
      +  "type": "boolean"
      +}
    • addedInput schema / properties / line_items / items / properties / line_id
      Added value: +{
      +  "maxLength": 50,
      +  "type": "string"
      +}
    • addedInput schema / properties / line_items / items / properties / line_kind
      Added value: +{
      +  "enum": [
      +    "billed",
      +    "optional",
      +    "alternative",
      +    "section"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / line_items / items / properties / offer_subscription_id
      Added value: +{
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedInput schema / properties / line_items / items / properties / ordinal
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / line_items / items / properties / parent_line_id
      Added value: +{
      +  "maxLength": 50,
      +  "type": "string"
      +}
    • addedInput schema / properties / line_items / items / properties / printed_subtotal
      Added value: +{
      +  "type": "number"
      +}
    • addedInput schema / properties / line_items / items / properties / return_reason_category_id
      Added value: +{
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedInput schema / properties / line_items / items / properties / subscription_id
      Added value: +{
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedOutput schema / properties / card_line_count
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / lines / items / properties / covered_lines
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "line_id": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / properties / lines / items / properties / line_kind / enum
      Previous value: -[
      -  "billed",
      -  "optional",
      -  "alternative"
      -]New value: +[
      +  "billed",
      +  "optional",
      +  "alternative",
      +  "section"
      +]
    • addedOutput schema / properties / lines / items / properties / section_path
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  5. Changed8 schema fields changed
    • addedInput schema / properties / line_items / items / properties / product_id
      Added value: +{
      +  "description": "A live catalogue product in this workspace, from well_list_products or an exact SKU match in well_define_line_items.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • changedInput schema / properties / line_items / items / properties / tax_rate / description
      Previous value: -"Tax rate as a percentage 0-100."New value: +"Tax rate as a percentage 0-100, as the document or the person states it. On a draft, leave it out when the person stated none: Well saves the rate it assumes and the answer names it."
    • addedInput schema / properties / line_items / maxItems
      Added value: +50
    • changedInput schema / properties / receiver / description
      Previous value: -"The customer. Leave it out only on a draft whose customer is not known yet."New value: +"The customer: a company, or a private individual named by person_id. Leave it out only on a draft whose customer is not known yet."
    • changedInput schema / properties / receiver / properties / name / description
      Previous value: -"Legal/company name of the party."New value: +"Legal/company name of the customer, or the full name of a private individual."
    • addedInput schema / properties / receiver / properties / person_id
      Added value: +{
      +  "description": "A private individual of the workspace billed directly (B2C): the `entity_id` of a `customer_kind: \"person\"` row of well_list_customers, or the person_id well_create_person returned. Never with company_id, domain or tax_id.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • changedInput schema / properties / reference_number / description
      Previous value: -"A reference printed apart from the invoice's own number. Never the invoice number itself. Leave it out for a draft: Well names a draft by the number it will take when issued (DRAFT-061 while the next invoice number is INV-061) and ignores any value sent."New value: +"A reference printed apart from the invoice's own number. Never the invoice number itself. Leave it out for a draft: Well gives each draft its own reference (DRAFT-0007) at its first save, even while it still lacks parts, takes the invoice number only when the draft is issued, and ignores any value sent."
    • changedOutput schema / properties / missing_fields / items / enum
      Previous value: -[
      -  "customer_address",
      -  "due_date",
      -  "line_price",
      -  "issuer",
      -  "receiver",
      -  "line_items",
      -  "currency",
      -  "issue_date"
      -]New value: +[
      +  "customer_address",
      +  "due_date",
      +  "line_price",
      +  "line_tax_rate",
      +  "issuer",
      +  "receiver",
      +  "line_items",
      +  "currency",
      +  "issue_date"
      +]
  6. Changed2 schema fields changed
    • addedOutput schema / properties / source_count
      Added value: +{
      +  "description": "How many tools hold the invoice; sources may list fewer.",
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / sources
      Added value: +{
      +  "description": "The tools that hold a copy of the invoice, highest source precedence first. Empty when no tool holds it.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "domain": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "kind": {
      +        "enum": [
      +          "accounting_tool",
      +          "connector",
      +          "mail_extraction"
      +        ],
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "service_id": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "kind",
      +      "service_id",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  7. Changed9 schema fields changed
    • changedInput schema / properties / currency / description
      Previous value: -"ISO 4217 (3 letters)."New value: +"ISO 4217 (3 letters). Required as soon as the invoice has a line; never guessed by Well."
    • changedInput schema / properties / issue_date / description
      Previous value: -"ISO 8601 YYYY-MM-DD."New value: +"ISO 8601 YYYY-MM-DD. Leave it out only on a draft whose date is not set yet."
    • addedInput schema / properties / issuer / description
      Added value: +"The company that issues the invoice. Leave it out only on a draft whose issuer is not known yet."
    • addedInput schema / properties / line_items / default
      Added value: +[]
    • addedInput schema / properties / line_items / description
      Added value: +"The lines. Leave them out only on a draft whose lines are not known yet."
    • removedInput schema / properties / line_items / minItems
      Removed value: -1
    • addedInput schema / properties / receiver / description
      Added value: +"The customer. Leave it out only on a draft whose customer is not known yet."
    • removedInput schema / required
      Removed value: -[
      -  "issuer",
      -  "receiver",
      -  "issue_date",
      -  "currency",
      -  "line_items"
      -]
    • addedOutput schema / properties / missing_fields
      Added value: +{
      +  "items": {
      +    "enum": [
      +      "customer_address",
      +      "due_date",
      +      "line_price",
      +      "issuer",
      +      "receiver",
      +      "line_items",
      +      "currency",
      +      "issue_date"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  8. Changed1 schema field changed
    • changedOutput schema / properties / newly_connected / description
      Previous value: -"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. Start the reply with 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."New value: +"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."
  9. Changed1 schema field changed
    • addedOutput schema / properties / code
      Added value: +{
      +  "type": "string"
      +}
  10. Changed3 schema fields changed
    • addedInput schema / properties / line_items / items / properties / unit_price / anyOf
      Added value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / line_items / items / properties / unit_price / description
      Previous value: -"Unit price (number, not string)."New value: +"Unit price (number, not string). null for a line with no price of its own, included in another line's price; never 0 for that, which bills the line at nothing."
    • removedInput schema / properties / line_items / items / properties / unit_price / type
      Removed value: -"number"
  11. Changed5 schema fields changed
    • addedInput schema / properties / printed_grand_total
      Added value: +{
      +  "description": "The grand total printed on a document you read, as printed. Leave it out for an invoice Well drafts. Well still stores the total it computes from the lines; when the two differ by more than rounding, the answer carries printed_total_mismatch.",
      +  "type": "number"
      +}
    • removedInput schema / properties / totals
      Removed value: -{
      -  "description": "The invoice's totals. grand_total is required; Well never computes it for you.",
      -  "properties": {
      -    "grand_total": {
      -      "description": "The invoice's total including tax, as printed.",
      -      "type": "number"
      -    },
      -    "items_total": {
      -      "type": "number"
      -    },
      -    "tax_total": {
      -      "type": "number"
      -    }
      -  },
      -  "required": [
      -    "grand_total"
      -  ],
      -  "type": "object"
      -}
    • addedInput schema / properties / workspace_scope
      Added value: +{
      +  "description": "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.",
      +  "enum": [
      +    "family"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "issuer",
      -  "receiver",
      -  "issue_date",
      -  "currency",
      -  "totals",
      -  "line_items"
      -]New value: +[
      +  "issuer",
      +  "receiver",
      +  "issue_date",
      +  "currency",
      +  "line_items"
      +]
    • addedOutput schema / properties / printed_total_mismatch
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The document's printed grand total differs from the total Well computed from the lines and stored. Tell the user both figures; a document-level discount or charge belongs on its own line.",
      +  "properties": {
      +    "computed_grand_total": {
      +      "type": "number"
      +    },
      +    "printed_grand_total": {
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "printed_grand_total",
      +    "computed_grand_total"
      +  ],
      +  "type": "object"
      +}
  12. Changed5 schema fields changed
    • changedInput schema / properties / document_type_code / description
      Previous value: -"\"380\" (the default) is an invoice; \"381\" is a credit note that corrects an invoice already issued. An issued invoice cannot be edited, so a correction is a credit note with its own number, then a new invoice."New value: +"\"380\" is an invoice; \"381\" is a credit note that corrects an invoice already issued. Omitted, the invoice has no document type and cannot post. An issued invoice cannot be edited, so a correction is a credit note with its own number, then a new invoice."
    • addedInput schema / properties / invoice_number
      Added value: +{
      +  "description": "The invoice's own number, read from the document. Required unless the invoice is a draft or created to be issued: Well numbers those when they are issued. Never make one up.",
      +  "maxLength": 255,
      +  "minLength": 1,
      +  "type": "string"
      +}
    • changedInput schema / properties / reference_number / description
      Previous value: -"The invoice's own number, read from the document. Leave it out for a draft: Well names a draft by the number it will take when issued (DRAFT-061 while the next invoice number is INV-061) and ignores any value sent. Never make one up."New value: +"A reference printed apart from the invoice's own number. Never the invoice number itself. Leave it out for a draft: Well names a draft by the number it will take when issued (DRAFT-061 while the next invoice number is INV-061) and ignores any value sent."
    • changedInput schema / properties / status / description
      Previous value: -"The invoice's lifecycle status. Set it here when the user asked for one (\"draft an invoice\") — do NOT create and then call well_update_invoice to change it. Omitted, the status is derived from the document type."New value: +"The invoice's lifecycle status. Set it here when the user asked for one (\"draft an invoice\") — do NOT create and then call well_update_invoice to change it. Omitted, Well derives one only where the document type decides it; otherwise the invoice has no status."
    • addedOutput schema / properties / newly_connected
      Added value: +{
      +  "description": "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. Start the reply with 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.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "name": {
      +        "type": "string"
      +      },
      +      "service_id": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "service_id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  13. Changed1 schema field changed
    • addedOutput schema / properties / lines / items / properties / line_kind
      Added value: +{
      +  "description": "Whether the line is charged. Only a billed line counts toward grand_total; an optional or alternative line is printed with its price but not charged. Its line_id still names it in an edit.",
      +  "enum": [
      +    "billed",
      +    "optional",
      +    "alternative"
      +  ],
      +  "type": "string"
      +}
  14. Changed14 schema fields changed
    • addedInput schema / properties / corrects_invoice_id
      Added value: +{
      +  "description": "The UUID of the issued invoice a credit note corrects. Required for a credit note (381); refused otherwise.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedInput schema / properties / document_type_code
      Added value: +{
      +  "description": "\"380\" (the default) is an invoice; \"381\" is a credit note that corrects an invoice already issued. An issued invoice cannot be edited, so a correction is a credit note with its own number, then a new invoice.",
      +  "enum": [
      +    "380",
      +    "381"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / reference_number / description
      Added value: +"The invoice's own number, read from the document. Leave it out for a draft: Well names a draft by the number it will take when issued (DRAFT-061 while the next invoice number is INV-061) and ignores any value sent. Never make one up."
    • addedInput schema / properties / totals / description
      Added value: +"The invoice's totals. grand_total is required; Well never computes it for you."
    • addedInput schema / properties / totals / properties / grand_total / description
      Added value: +"The invoice's total including tax, as printed."
    • changedInput schema / required
      Previous value: -[
      -  "issuer",
      -  "receiver",
      -  "reference_number",
      -  "issue_date",
      -  "currency",
      -  "line_items"
      -]New value: +[
      +  "issuer",
      +  "receiver",
      +  "issue_date",
      +  "currency",
      +  "totals",
      +  "line_items"
      +]
    • addedOutput schema / properties / currency
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / customer_name
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / design_layout
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • removedOutput schema / properties / document_id
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / grand_total
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / issue_date
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / lines
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "line_id": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "quantity": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "tax_rate": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "unit_price": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "quantity",
      +      "unit_price",
      +      "tax_rate"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / status
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  15. Changed4 schema fields changed
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "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.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation this result belongs to. Pass it back as the conversation_id argument on every later Well call in the same conversation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_note
      Added value: +{
      +  "description": "Present only when the server opened a fresh lane, stating that no choice recorded earlier was read.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / conversation_id_source
      Added value: +{
      +  "description": "Where the conversation id came from: the host's own request meta, the caller's argument, or a fresh lane the server opened.",
      +  "enum": [
      +    "host_meta",
      +    "argument",
      +    "minted"
      +  ],
      +  "type": "string"
      +}
  16. Changed4 schema fields changed
    • addedInput schema / properties / issuer / properties / name / maxLength
      Added value: +255
    • addedInput schema / properties / line_items / items / properties / name / maxLength
      Added value: +255
    • addedInput schema / properties / receiver / properties / name / maxLength
      Added value: +255
    • addedInput schema / properties / reference_number / maxLength
      Added value: +100
  17. Changed1 schema field changed
    • changedInput schema / properties / workspace_id / description
      Previous value: -"Target workspace. Omit to use the only authorized workspace, or (for read tools) to query all authorized workspaces grouped by workspace. Required for write tools when the token authorizes more than one workspace."New value: +"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."
  18. Changed3 schema fields changed
    • addedInput schema / properties / issuer / properties / company_id
      Added value: +{
      +  "description": "An existing company in the workspace, bound directly — ALWAYS send this when you already know the company (e.g. you found it with well_query_records). Without it the party is re-resolved from name/domain/tax_id, which can attach the invoice to a different company or mint a duplicate.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedInput schema / properties / receiver / properties / company_id
      Added value: +{
      +  "description": "An existing company in the workspace, bound directly — ALWAYS send this when you already know the company (e.g. you found it with well_query_records). Without it the party is re-resolved from name/domain/tax_id, which can attach the invoice to a different company or mint a duplicate.",
      +  "format": "uuid",
      +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      +  "type": "string"
      +}
    • addedInput schema / properties / status
      Added value: +{
      +  "description": "The invoice's lifecycle status. Set it here when the user asked for one (\"draft an invoice\") — do NOT create and then call well_update_invoice to change it. Omitted, the status is derived from the document type.",
      +  "enum": [
      +    "draft",
      +    "issued",
      +    "paid",
      +    "canceled"
      +  ],
      +  "type": "string"
      +}
  19. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare it is a non-read-only, non-destructive, closed-world write. The description goes far beyond: it explains that one call is the whole write and that a create+update pattern produces two confirmations, that Well auto-numbers drafts and assigns invoice numbers on issue, that missing_fields is the completeness contract, that a printed/computed total discrepancy surfaces as printed_total_mismatch, that company_id omission risks duplicate company creation, and that issued invoices are immutable and corrected via credit notes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the prerequisite and the negative routing, and the bullet structure maps to the payload, but the text is very long for a tool description and repeats itself: the company_id/duplicate warning appears both in the field list and again in the 'ONE CALL' section, and line_catalogue_attribution is explained twice (mid-text and in the closing paragraph), alongside a closing summary of answer fields that duplicates the earlier result discussion.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 17-parameter, deeply nested, mutation-heavy tool with an output schema, the description covers the draft-vs-issued lifecycle, the credit-note correction path, payment means, currency/minor-unit handling, and idempotency-adjacent retry behaviour. Nothing an agent needs in order to invoke it correctly appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 94%, so the baseline is 3; the description still adds real semantics the schema does not carry, notably the draft field-omission rules, the section line_kind behaviour (unit_price null, printed_subtotal must equal billed descendants, never affects totals), and the exact-one-active-product matching rule for product_id. It loses a point for restating several things the schema already says verbatim (company_id re-resolution, reference_number draft behaviour).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+mechanism: 'Create an invoice in Well from data you extracted by reading an invoice (your own OCR) — you send the structured fields, not the file.' It also names the confusable siblings by name (well_create_product, well_update_product) and excludes them, so an agent can distinguish this from catalogue and document-upload tools without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use (user asked to draft → pass status: 'draft'; already found the company → pass company_id), explicit when-not (never for adding a product or changing a price, with quoted example utterances and the correct alternatives), and it names the neighbouring lifecycle tool (well_issue_invoice) plus the required prerequisite (well_get_skill loading the draft-invoice skill).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources