MOTORAdvisorShop intelligence powered by motor.comDevelopersOpen the app →

issue_invoice

Billing · Write · account-scoped

Issue a real, payable invoice from the authenticated account's shop and get back a pay link.

Usage

A write-capable tool — and the write goes to MotorAdvisor's payment provider (Stripe), never to MOTOR. MOTOR DaaS is read-only on this server without exception.

Three properties define its safety model:

  • The shop is never an input. It resolves from the verified bearer token, so identical input from two accounts bills two different shops, and a caller cannot invoice as someone else.
  • Retry is safe. The same referenceId (or an identical request) returns the same invoice — an agent that retries cannot double-bill a customer.
  • Money is recomputed server-side in integer cents from the shop's stored rates. Totals computed by the client are ignored.

No email is sent by issuing. Relay the payUrl explicitly; never tell the user the customer has been notified.

When the work was quoted on this server, pass the approved quote's quoteId: the quote records invoiceId/invoicedAt (one money trail per job, readable via check_quote_status), and void_quote will refuse to retire it from then on.

Parameters

ParameterTypeRequiredDescription
vehicleDescriptionstringNoThe vehicle, for the invoice footer. Example: "2010 Honda Civic LX 1.8L"
customerobjectYesWho is being billed. Required — an invoice needs a recipient. Example: {"name": "Jane Rivera", "email": "jane@example.com"}
customer.namestringYesCustomer's name. Example: "Jane Rivera"
customer.emailstringYesCustomer's email — where the shop will send the pay link. Example: "jane@example.com"
customer.phonestringNoCustomer's phone, optional. Example: "(313) 555-0144"
laborarray of objectYesThe BOOKED labor selection (a completed selectedTotal choice), one entry per operation. Example: [{"name": "A/C Compressor — Remove & Replace", "bookHours": 1.2}]
labor[].namestringNoThe labor operation as MOTOR names it, from a service_advisor_lookup selection. Example: "A/C Compressor — Remove & Replace"
labor[].bookHoursnumberNoBook hours for the operation. Example: 1.2
labor[].rateCentsPerHourpositive integerNoRate for THIS line in integer cents/hour, when the answer carried a skill rate. Omit to bill at the shop's stored rate. Example: 15000
labor[].skillNamestringNoSkill tier name shown on the line. Example: "Air Conditioning"
partsarray of objectNoPriced parts to bill, if any. Every part needs unitPriceCents. Example: [{"name": "A/C Compressor", "unitPriceCents": 12500}]
parts[].namestringNoPart name as quoted. Example: "A/C Compressor"
parts[].quantitypositive integerNoHow many. Defaults to 1. Example: 1
parts[].unitPriceCentspositive integerNoSELL price in integer cents, set by the advisor — an unpriced part is refused. MOTOR provides the OEM LIST price (listPriceCents on quote parts rows) as an anchor; it is not the sell price and is never billed automatically. Example: 12500
referenceIdstringNoStable id for THIS repair order — reuse it on any retry so the same order can never be invoiced twice. When omitted, one is derived from the customer and lines, which also collapses identical retries. Example: "job_civic_ac_2026_08_12"
quoteIdstringNoThe q_… id of the approved quote this invoice bills, when one exists. Linking it closes the money trail: the quote records the invoice, check_quote_status points at it, and void_quote refuses to retire it. Example: "q_1facac2305cc6b3901077d3b"

Description advertised to clients

The exact description a fully entitled MCP client discovers — the workflow contracts travel with the tool, so a client with no system prompt still uses it correctly. An account missing a licence for content this tool reaches sees the same text behind a [Licensed content — not enabled on this account] or [Partially available] notice:

Issue a REAL invoice for completed repair work, from the shop the authenticated account belongs to, and get back a payment link to give the customer. THIS TOOL MOVES COMMERCIAL STATE: it creates a customer and a finalized invoice on the shop's own Stripe account (MotorAdvisor's payment provider), with the platform fee applied. It writes NOTHING to MOTOR — MOTOR DaaS is read-only on this server and this tool does not touch it. The shop is NEVER a parameter: it is resolved from the authenticated account, so this tool can only invoice for the caller's own shop. All money is recomputed server-side from the shop's stored rates in integer cents; totals you computed yourself are ignored. Use it AFTER a completed service_advisor_lookup selection (a selectedTotal exists) and after the advisor confirms the customer's name and email. Pass the booked labor lines as returned; do not invent operations or prices. When the work was quoted on this server, pass the approved quote's quoteId: the quote then records the invoice (one money trail per job) and void_quote refuses to retire it. Preconditions, each refused by name when unmet: the account must belong to a shop; the shop must have completed Stripe onboarding; every part must have a price; there must be at least one line. The result includes payUrl (MotorAdvisor's payment page for this invoice) and hostedInvoiceUrl (Stripe's fallback page). NO EMAIL IS SENT by issuing — relay the payUrl to the advisor explicitly, and never tell the user the customer has been emailed. Calling twice with the same referenceId returns the SAME invoice rather than a duplicate.

Example — Invoice a completed A/C job

Standing demo invoice, issued live 2026-08-12 over the MCP protocol. Pay-link token elided.

Request

{
  "vehicleDescription": "2010 Honda Civic LX 1.8L",
  "customer": {
    "name": "Jane Rivera",
    "email": "jane@example.com"
  },
  "labor": [
    {
      "name": "A/C Compressor — Remove & Replace",
      "bookHours": 1.2,
      "rateCentsPerHour": 15000
    }
  ],
  "referenceId": "job_civic_ac_2026_08_12"
}

Response

{
  "invoiceId": "in_1U3eHUR4WQPNzEYlDhYqbFHn",
  "number": "ALRVAKWA-0001",
  "status": "open",
  "totalCents": 18000,
  "total": "$180.00",
  "platformFeeCents": 450,
  "dueDate": "2026-09-11",
  "payUrl": "https://motoradvisor.app/pay/…",
  "hostedInvoiceUrl": "https://invoice.stripe.com/…",
  "delivery": "link-only — no email was sent; give the customer the payUrl"
}