> For the complete documentation index, see [llms.txt](https://docs.shortcutco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shortcutco.com/developers/api-reference/reference/invoices.md).

# Invoices

What customers owe, and its delivery.

Read invoices with their lines, send drafts, remind customers, void unpaid invoices, and record offline payments. No endpoint charges a card.

Fields: [The invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice) · [The invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery).

## List invoices

> Invoices newest first, or by last change when \`updatedSince\` is set. Every kind is listed, as in the app's invoice list: standard, prepay, and project invoices. A status turns \`overdue\` on its own when \`dueAt\` passes; that does not change \`updatedAt\`.\
> \
> Returns a list of \[invoice objects]\(<https://docs.shortcutco.com/developers/reference/objects/invoice>).

```json
{"openapi":"3.1.0","info":{"title":"Shortcut API","version":"v1"},"tags":[{"name":"Invoices","description":"Read invoices with their lines, send drafts, remind customers, void unpaid invoices, and record offline payments. No endpoint charges a card.\n\nFields: [The invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice) · [The invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery)."}],"servers":[{"url":"https://api.shortcutco.com","description":"Production"}],"security":[{"bearerAuth":["invoices:read"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"scut_<env>_<id>_<secret>","description":"A workspace API token. Each operation lists the scopes it needs; `write` implies `read`, and `send`/`complete` are never implied."}},"headers":{"RateLimitLimit":{"schema":{"type":"integer"},"description":"Requests allowed in the tightest window."},"RateLimitRemaining":{"schema":{"type":"integer"},"description":"Requests left in that window."},"RateLimitReset":{"schema":{"type":"integer"},"description":"Seconds until that window resets."}},"schemas":{"Invoice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The invoice's id."},"object":{"type":"string","const":"invoice","description":"Always `invoice`."},"number":{"type":"integer","description":"The invoice number the customer sees."},"kind":{"type":"string","enum":["standard","prepay","project"],"description":"`standard` invoices bill completed visits or manual lines. `prepay` invoices bill a coverage period in advance (see `coverageStartDate`). `project` invoices bill a project (deposit, progress, or final)."},"status":{"type":"string","enum":["draft","unpaid","overdue","paid","void"],"description":"`draft` invoices have not been sent to the customer. `unpaid` invoices are sent and not yet due (or have no due date). `overdue` invoices are past `dueAt`. `paid` and `void` invoices are closed. These match the app's invoice list, except that the app shows a draft as Unpaid or Overdue."},"paymentActivity":{"anyOf":[{"type":"string","enum":["processing","verification"]},{"type":"null"}],"description":"`processing` while a bank payment is in flight, `verification` while the bank needs the customer to verify; otherwise null. The invoice stays `unpaid` or `overdue` until the payment settles."},"customerId":{"type":"string","format":"uuid","description":"The customer billed."},"propertyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The property (service address) billed, when there is one."},"propertyAddress":{"type":["string","null"],"description":"The property's address as printed on the invoice when it was created."},"propertyLabel":{"type":["string","null"],"description":"The property's label as printed on the invoice when it was created."},"subtotal":{"type":"number","description":"Sum of the lines before tax and fees, in US dollars."},"salesTax":{"type":"number","description":"Sales tax charged, in US dollars."},"processingFee":{"type":"number","description":"The processing fee in `total`. With `processingFeeScope` `card_only` it is 0 until a credit card pays the invoice with the fee, then equals `cardProcessingFee`; it stays 0 when the invoice is paid without the fee (bank, debit, offline, or a card-fee payment review settled at the total), in US dollars."},"processingFeeScope":{"type":"string","enum":["all_payments","card_only"],"description":"Which payments carry the processing fee, fixed when the invoice was created: `all_payments` (in `total`) or `card_only` (only a credit-card payment adds `cardProcessingFee`)."},"cardProcessingFee":{"type":"number","description":"With `card_only`, the fee a credit-card payment adds on top of `total`; bank, debit, check and cash payments never pay it. 0 for `all_payments`, in US dollars."},"lateFees":{"type":"number","description":"Late fees applied and not removed, in US dollars."},"total":{"type":"number","description":"What the customer owes in all: `subtotal + salesTax + processingFee + lateFees`, in US dollars."},"dueDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"The due date as the customer's invoice prints it, `YYYY-MM-DD`: the calendar date of `dueAt` in UTC (the app stores a due date chosen as a date at midnight UTC). Null when there is none."},"dueAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"The stored due instant. The invoice is `overdue` once this moment passes, as in the app, ISO 8601 in UTC, or null."},"coverageStartDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"First day a prepay invoice covers, `YYYY-MM-DD`, or null."},"coverageEndDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"Last day a prepay invoice covers, `YYYY-MM-DD`, or null."},"sentAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was first sent, ISO 8601 in UTC, or null."},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was paid in full, ISO 8601 in UTC, or null."},"createdAt":{"type":"string","format":"date-time","description":"When the invoice was created, ISO 8601 in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"When the invoice last changed, ISO 8601 in UTC."}},"required":["id","object","number","kind","status","paymentActivity","customerId","propertyId","propertyAddress","propertyLabel","subtotal","salesTax","processingFee","processingFeeScope","cardProcessingFee","lateFees","total","dueDate","dueAt","coverageStartDate","coverageEndDate","sentAt","paidAt","createdAt","updatedAt"],"additionalProperties":false,"description":"An invoice: a bill to a customer."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","description":"Error family, such as `invalid_request` or `permission`."},"code":{"type":"string","description":"Specific error code; see the errors page."},"message":{"type":"string","description":"A human-readable explanation."},"param":{"type":"string","description":"The input the error is about, such as `query.limit`."},"requiredScope":{"type":"string","description":"The scope the token is missing."},"requestId":{"type":"string","description":"Quote this id to support."},"docs":{"type":"string","description":"Link to the error's documentation."}},"required":["type","code","message","requestId","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}},"responses":{"BadRequest":{"description":"The request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthenticated":{"description":"The token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubscriptionRequired":{"description":"The workspace's subscription needs attention.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The token is missing a required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such object in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limited; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/invoices":{"get":{"operationId":"invoices.list","tags":["Invoices"],"summary":"List invoices","description":"Invoices newest first, or by last change when `updatedSince` is set. Every kind is listed, as in the app's invoice list: standard, prepay, and project invoices. A status turns `overdue` on its own when `dueAt` passes; that does not change `updatedAt`.\n\nReturns a list of [invoice objects](https://docs.shortcutco.com/developers/reference/objects/invoice).","parameters":[{"name":"limit","in":"query","required":false,"description":"How many items to return, 1-200. Defaults to 50.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","required":false,"description":"The `meta.nextCursor` from the previous page. Omit it for the first page.","schema":{"type":"string","minLength":1,"maxLength":4096}},{"name":"status","in":"query","required":false,"description":"Only invoices with this status, as the invoice's `status` field reports it.","schema":{"type":"string","enum":["draft","unpaid","overdue","paid","void"]}},{"name":"customerId","in":"query","required":false,"description":"Only this customer's invoices.","schema":{"type":"string","format":"uuid"}},{"name":"dueBefore","in":"query","required":false,"description":"`YYYY-MM-DD`. Only invoices whose `dueDate` is before this date (not on it).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"updatedSince","in":"query","required":false,"description":"ISO 8601 timestamp. Returns objects changed at or after it, oldest change first. Keep the largest `updatedAt` you have seen, subtract five minutes, and pass it on the next sync; deduplicate by `id`.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"meta":{"type":"object","properties":{"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` to get the next page; null on the last page."},"hasMore":{"type":"boolean","description":"Whether another page exists."}},"required":["nextCursor","hasMore"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthenticated"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/Unavailable"}}}}}}
```

## Get an invoice

> One invoice with its lines, as the customer's invoice shows them: products included in a visit's price are part of that visit's line.\
> \
> Returns \[the invoice object]\(<https://docs.shortcutco.com/developers/reference/objects/invoice>).

```json
{"openapi":"3.1.0","info":{"title":"Shortcut API","version":"v1"},"tags":[{"name":"Invoices","description":"Read invoices with their lines, send drafts, remind customers, void unpaid invoices, and record offline payments. No endpoint charges a card.\n\nFields: [The invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice) · [The invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery)."}],"servers":[{"url":"https://api.shortcutco.com","description":"Production"}],"security":[{"bearerAuth":["invoices:read"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"scut_<env>_<id>_<secret>","description":"A workspace API token. Each operation lists the scopes it needs; `write` implies `read`, and `send`/`complete` are never implied."}},"headers":{"RateLimitLimit":{"schema":{"type":"integer"},"description":"Requests allowed in the tightest window."},"RateLimitRemaining":{"schema":{"type":"integer"},"description":"Requests left in that window."},"RateLimitReset":{"schema":{"type":"integer"},"description":"Seconds until that window resets."}},"schemas":{"InvoiceWithLines":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The invoice's id."},"object":{"type":"string","const":"invoice","description":"Always `invoice`."},"number":{"type":"integer","description":"The invoice number the customer sees."},"kind":{"type":"string","enum":["standard","prepay","project"],"description":"`standard` invoices bill completed visits or manual lines. `prepay` invoices bill a coverage period in advance (see `coverageStartDate`). `project` invoices bill a project (deposit, progress, or final)."},"status":{"type":"string","enum":["draft","unpaid","overdue","paid","void"],"description":"`draft` invoices have not been sent to the customer. `unpaid` invoices are sent and not yet due (or have no due date). `overdue` invoices are past `dueAt`. `paid` and `void` invoices are closed. These match the app's invoice list, except that the app shows a draft as Unpaid or Overdue."},"paymentActivity":{"anyOf":[{"type":"string","enum":["processing","verification"]},{"type":"null"}],"description":"`processing` while a bank payment is in flight, `verification` while the bank needs the customer to verify; otherwise null. The invoice stays `unpaid` or `overdue` until the payment settles."},"customerId":{"type":"string","format":"uuid","description":"The customer billed."},"propertyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The property (service address) billed, when there is one."},"propertyAddress":{"type":["string","null"],"description":"The property's address as printed on the invoice when it was created."},"propertyLabel":{"type":["string","null"],"description":"The property's label as printed on the invoice when it was created."},"subtotal":{"type":"number","description":"Sum of the lines before tax and fees, in US dollars."},"salesTax":{"type":"number","description":"Sales tax charged, in US dollars."},"processingFee":{"type":"number","description":"The processing fee in `total`. With `processingFeeScope` `card_only` it is 0 until a credit card pays the invoice with the fee, then equals `cardProcessingFee`; it stays 0 when the invoice is paid without the fee (bank, debit, offline, or a card-fee payment review settled at the total), in US dollars."},"processingFeeScope":{"type":"string","enum":["all_payments","card_only"],"description":"Which payments carry the processing fee, fixed when the invoice was created: `all_payments` (in `total`) or `card_only` (only a credit-card payment adds `cardProcessingFee`)."},"cardProcessingFee":{"type":"number","description":"With `card_only`, the fee a credit-card payment adds on top of `total`; bank, debit, check and cash payments never pay it. 0 for `all_payments`, in US dollars."},"lateFees":{"type":"number","description":"Late fees applied and not removed, in US dollars."},"total":{"type":"number","description":"What the customer owes in all: `subtotal + salesTax + processingFee + lateFees`, in US dollars."},"dueDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"The due date as the customer's invoice prints it, `YYYY-MM-DD`: the calendar date of `dueAt` in UTC (the app stores a due date chosen as a date at midnight UTC). Null when there is none."},"dueAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"The stored due instant. The invoice is `overdue` once this moment passes, as in the app, ISO 8601 in UTC, or null."},"coverageStartDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"First day a prepay invoice covers, `YYYY-MM-DD`, or null."},"coverageEndDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"Last day a prepay invoice covers, `YYYY-MM-DD`, or null."},"sentAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was first sent, ISO 8601 in UTC, or null."},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was paid in full, ISO 8601 in UTC, or null."},"createdAt":{"type":"string","format":"date-time","description":"When the invoice was created, ISO 8601 in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"When the invoice last changed, ISO 8601 in UTC."},"lines":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLine"},"description":"The lines in the order the customer's invoice shows them. Sales tax is the invoice's `salesTax`, computed by the app on the underlying lines."}},"required":["id","object","number","kind","status","paymentActivity","customerId","propertyId","propertyAddress","propertyLabel","subtotal","salesTax","processingFee","processingFeeScope","cardProcessingFee","lateFees","total","dueDate","dueAt","coverageStartDate","coverageEndDate","sentAt","paidAt","createdAt","updatedAt","lines"],"additionalProperties":false,"description":"An invoice with its lines."},"InvoiceLine":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The line's id."},"type":{"type":"string","enum":["service","product","add_on","discount","manual","project"],"description":"`service` bills a visit, `product` a product used on it, `add_on` an add-on to it, `discount` a visit discount (negative), `manual` a line entered by hand, `project` a project milestone, labor, material, change order, credit, or adjustment."},"name":{"type":"string","description":"What the line is for, as the customer sees it."},"description":{"type":["string","null"],"description":"More detail, as the customer sees it."},"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The service date of the line, `YYYY-MM-DD`."},"amount":{"type":"number","description":"The line amount; a visit's amount includes the products shown as included in its price, in US dollars."},"taxable":{"type":"boolean","description":"Whether sales tax applies to the line."},"quantity":{"type":["number","null"],"description":"Quantity, for product and project lines that have one."},"unitPrice":{"type":["number","null"],"description":"Price per unit in US dollars, when the line has a quantity."},"unitLabel":{"type":["string","null"],"description":"The unit, such as `bag`, when the line has one."},"visitId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The visit the line bills, when there is one."},"serviceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The service the line bills, when there is one."}},"required":["id","type","name","description","date","amount","taxable","quantity","unitPrice","unitLabel","visitId","serviceId"],"additionalProperties":false,"description":"One line of an invoice, as the customer sees it."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","description":"Error family, such as `invalid_request` or `permission`."},"code":{"type":"string","description":"Specific error code; see the errors page."},"message":{"type":"string","description":"A human-readable explanation."},"param":{"type":"string","description":"The input the error is about, such as `query.limit`."},"requiredScope":{"type":"string","description":"The scope the token is missing."},"requestId":{"type":"string","description":"Quote this id to support."},"docs":{"type":"string","description":"Link to the error's documentation."}},"required":["type","code","message","requestId","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}},"responses":{"BadRequest":{"description":"The request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthenticated":{"description":"The token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubscriptionRequired":{"description":"The workspace's subscription needs attention.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The token is missing a required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such object in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limited; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/invoices/{id}":{"get":{"operationId":"invoices.get","tags":["Invoices"],"summary":"Get an invoice","description":"One invoice with its lines, as the customer's invoice shows them: products included in a visit's price are part of that visit's line.\n\nReturns [the invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice).","parameters":[{"name":"id","in":"path","required":true,"description":"The object's id.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/InvoiceWithLines"},"meta":{"type":"object","properties":{},"additionalProperties":true,"description":"Facts about this request beside the object, such as `alreadyReminded` on a repeated reminder. Present only when there is something to report."}},"required":["data"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthenticated"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/Unavailable"}}}}}}
```

## Remind a customer about an invoice

> Sends the customer a payment reminder for an unpaid or overdue invoice, exactly as Remind does in the app: email under the customer's email preferences (a placeholder address is never emailed) and SMS unless the customer opted out. Drafts, paid and void invoices, invoices in import review, and invoices with a bank payment in progress are refused. At most one reminder per invoice in ten minutes through the API (\`429 invoice\_recently\_reminded\`). Repeating a request with the same \`Idempotency-Key\` returns the first reminder with \`meta.alreadyReminded: true\` once it was sent, however late. While the first attempt is still sending, the repeat gets a retryable \`409 reminder\_in\_progress\` with \`Retry-After\`; if that attempt stopped before finishing, a repeat five minutes after it started sends the reminder, so a reminder interrupted mid-send can reach the customer twice. Needs \`invoices:send\` and \`invoices:read\`.\
> \
> Returns \[the invoice delivery object]\(<https://docs.shortcutco.com/developers/reference/objects/invoice-delivery).\\>
> \
> A workspace that delivers invoices by the channels each customer chose lists a channel it did not use in \`skippedChannels\`, such as "SMS skipped: channel not selected."\
> \
> \*\*Errors specific to this endpoint:\*\* \[\`dependency\_unavailable\`]\(<https://docs.shortcutco.com/developers/concepts/errors#dependency\\_unavailable>), \[\`invoice\_recently\_reminded\`]\(<https://docs.shortcutco.com/developers/concepts/errors#invoice\\_recently\\_reminded>), \[\`no\_recipient\`]\(<https://docs.shortcutco.com/developers/concepts/errors#no\\_recipient>), \[\`reminder\_in\_progress\`]\(<https://docs.shortcutco.com/developers/concepts/errors#reminder\\_in\\_progress>), \[\`rule\_violation\`]\(<https://docs.shortcutco.com/developers/concepts/errors#rule\\_violation>), \[\`state\_conflict\`]\(<https://docs.shortcutco.com/developers/concepts/errors#state\\_conflict>). Every endpoint can also return the \[common errors]\(<https://docs.shortcutco.com/developers/concepts/errors>).

```json
{"openapi":"3.1.0","info":{"title":"Shortcut API","version":"v1"},"tags":[{"name":"Invoices","description":"Read invoices with their lines, send drafts, remind customers, void unpaid invoices, and record offline payments. No endpoint charges a card.\n\nFields: [The invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice) · [The invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery)."}],"servers":[{"url":"https://api.shortcutco.com","description":"Production"}],"security":[{"bearerAuth":["invoices:send","invoices:read"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"scut_<env>_<id>_<secret>","description":"A workspace API token. Each operation lists the scopes it needs; `write` implies `read`, and `send`/`complete` are never implied."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Any string up to 255 characters. Retrying with the same key returns the first response instead of repeating the write, for 24 hours.","schema":{"type":"string","maxLength":255}}},"headers":{"RateLimitLimit":{"schema":{"type":"integer"},"description":"Requests allowed in the tightest window."},"RateLimitRemaining":{"schema":{"type":"integer"},"description":"Requests left in that window."},"RateLimitReset":{"schema":{"type":"integer"},"description":"Seconds until that window resets."}},"schemas":{"InvoiceDelivery":{"type":"object","properties":{"object":{"type":"string","const":"invoice_delivery","description":"Always `invoice_delivery`."},"purpose":{"type":"string","enum":["invoice","reminder"],"description":"`invoice` when the invoice was sent, `reminder` for a reminder."},"queuedChannels":{"type":"array","items":{"type":"string","enum":["email","sms"]},"description":"Channels handed to delivery. Queued is not delivered: the customer's email preferences and SMS opt-out still apply when it sends."},"skippedChannels":{"type":"array","items":{"type":"string"},"description":"Channels not sent, each with the reason the app gives, such as no email on file or the customer opted out."},"failedChannels":{"type":"array","items":{"type":"string"},"description":"Channels that could not be queued; retry later."},"invoice":{"$ref":"#/components/schemas/Invoice","description":"The invoice after the send."}},"required":["object","purpose","queuedChannels","skippedChannels","failedChannels","invoice"],"additionalProperties":false,"description":"What sending an invoice or a reminder queued."},"Invoice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The invoice's id."},"object":{"type":"string","const":"invoice","description":"Always `invoice`."},"number":{"type":"integer","description":"The invoice number the customer sees."},"kind":{"type":"string","enum":["standard","prepay","project"],"description":"`standard` invoices bill completed visits or manual lines. `prepay` invoices bill a coverage period in advance (see `coverageStartDate`). `project` invoices bill a project (deposit, progress, or final)."},"status":{"type":"string","enum":["draft","unpaid","overdue","paid","void"],"description":"`draft` invoices have not been sent to the customer. `unpaid` invoices are sent and not yet due (or have no due date). `overdue` invoices are past `dueAt`. `paid` and `void` invoices are closed. These match the app's invoice list, except that the app shows a draft as Unpaid or Overdue."},"paymentActivity":{"anyOf":[{"type":"string","enum":["processing","verification"]},{"type":"null"}],"description":"`processing` while a bank payment is in flight, `verification` while the bank needs the customer to verify; otherwise null. The invoice stays `unpaid` or `overdue` until the payment settles."},"customerId":{"type":"string","format":"uuid","description":"The customer billed."},"propertyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The property (service address) billed, when there is one."},"propertyAddress":{"type":["string","null"],"description":"The property's address as printed on the invoice when it was created."},"propertyLabel":{"type":["string","null"],"description":"The property's label as printed on the invoice when it was created."},"subtotal":{"type":"number","description":"Sum of the lines before tax and fees, in US dollars."},"salesTax":{"type":"number","description":"Sales tax charged, in US dollars."},"processingFee":{"type":"number","description":"The processing fee in `total`. With `processingFeeScope` `card_only` it is 0 until a credit card pays the invoice with the fee, then equals `cardProcessingFee`; it stays 0 when the invoice is paid without the fee (bank, debit, offline, or a card-fee payment review settled at the total), in US dollars."},"processingFeeScope":{"type":"string","enum":["all_payments","card_only"],"description":"Which payments carry the processing fee, fixed when the invoice was created: `all_payments` (in `total`) or `card_only` (only a credit-card payment adds `cardProcessingFee`)."},"cardProcessingFee":{"type":"number","description":"With `card_only`, the fee a credit-card payment adds on top of `total`; bank, debit, check and cash payments never pay it. 0 for `all_payments`, in US dollars."},"lateFees":{"type":"number","description":"Late fees applied and not removed, in US dollars."},"total":{"type":"number","description":"What the customer owes in all: `subtotal + salesTax + processingFee + lateFees`, in US dollars."},"dueDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"The due date as the customer's invoice prints it, `YYYY-MM-DD`: the calendar date of `dueAt` in UTC (the app stores a due date chosen as a date at midnight UTC). Null when there is none."},"dueAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"The stored due instant. The invoice is `overdue` once this moment passes, as in the app, ISO 8601 in UTC, or null."},"coverageStartDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"First day a prepay invoice covers, `YYYY-MM-DD`, or null."},"coverageEndDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"Last day a prepay invoice covers, `YYYY-MM-DD`, or null."},"sentAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was first sent, ISO 8601 in UTC, or null."},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was paid in full, ISO 8601 in UTC, or null."},"createdAt":{"type":"string","format":"date-time","description":"When the invoice was created, ISO 8601 in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"When the invoice last changed, ISO 8601 in UTC."}},"required":["id","object","number","kind","status","paymentActivity","customerId","propertyId","propertyAddress","propertyLabel","subtotal","salesTax","processingFee","processingFeeScope","cardProcessingFee","lateFees","total","dueDate","dueAt","coverageStartDate","coverageEndDate","sentAt","paidAt","createdAt","updatedAt"],"additionalProperties":false,"description":"An invoice: a bill to a customer."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","description":"Error family, such as `invalid_request` or `permission`."},"code":{"type":"string","description":"Specific error code; see the errors page."},"message":{"type":"string","description":"A human-readable explanation."},"param":{"type":"string","description":"The input the error is about, such as `query.limit`."},"requiredScope":{"type":"string","description":"The scope the token is missing."},"requestId":{"type":"string","description":"Quote this id to support."},"docs":{"type":"string","description":"Link to the error's documentation."}},"required":["type","code","message","requestId","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}},"responses":{"BadRequest":{"description":"The request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthenticated":{"description":"The token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubscriptionRequired":{"description":"The workspace's subscription needs attention.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The token is missing a required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such object in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Conflict with the current state or an in-flight request with the same idempotency key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"The request cannot be applied, or its idempotency key was used for a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limited; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/invoices/{id}/remind":{"post":{"operationId":"invoices.remind","tags":["Invoices"],"summary":"Remind a customer about an invoice","description":"Sends the customer a payment reminder for an unpaid or overdue invoice, exactly as Remind does in the app: email under the customer's email preferences (a placeholder address is never emailed) and SMS unless the customer opted out. Drafts, paid and void invoices, invoices in import review, and invoices with a bank payment in progress are refused. At most one reminder per invoice in ten minutes through the API (`429 invoice_recently_reminded`). Repeating a request with the same `Idempotency-Key` returns the first reminder with `meta.alreadyReminded: true` once it was sent, however late. While the first attempt is still sending, the repeat gets a retryable `409 reminder_in_progress` with `Retry-After`; if that attempt stopped before finishing, a repeat five minutes after it started sends the reminder, so a reminder interrupted mid-send can reach the customer twice. Needs `invoices:send` and `invoices:read`.\n\nReturns [the invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery).\n\nA workspace that delivers invoices by the channels each customer chose lists a channel it did not use in `skippedChannels`, such as \"SMS skipped: channel not selected.\"\n\n**Errors specific to this endpoint:** [`dependency_unavailable`](https://docs.shortcutco.com/developers/concepts/errors#dependency_unavailable), [`invoice_recently_reminded`](https://docs.shortcutco.com/developers/concepts/errors#invoice_recently_reminded), [`no_recipient`](https://docs.shortcutco.com/developers/concepts/errors#no_recipient), [`reminder_in_progress`](https://docs.shortcutco.com/developers/concepts/errors#reminder_in_progress), [`rule_violation`](https://docs.shortcutco.com/developers/concepts/errors#rule_violation), [`state_conflict`](https://docs.shortcutco.com/developers/concepts/errors#state_conflict). Every endpoint can also return the [common errors](https://docs.shortcutco.com/developers/concepts/errors).","parameters":[{"name":"id","in":"path","required":true,"description":"The object's id.","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sendEmail":{"type":"boolean","default":true,"description":"Email the reminder. Defaults to true."},"sendSms":{"type":"boolean","default":true,"description":"Text the reminder. Defaults to true; the customer's SMS opt-out still applies."}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/InvoiceDelivery"},"meta":{"type":"object","properties":{},"additionalProperties":true,"description":"Facts about this request beside the object, such as `alreadyReminded` on a repeated reminder. Present only when there is something to report."}},"required":["data"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthenticated"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/Unavailable"}}}}}}
```

## Send a draft invoice

> Sends a draft invoice to the customer exactly as Send does in the app: the invoice becomes unpaid (or overdue), its email is queued under the customer's email preferences, and it syncs to QuickBooks when connected. The invoice's delivery always goes out. Your invoice-created automations, which may email or text the customer, and Automations rules that start when an invoice is sent, run only if the token has \`automations:trigger\`. A draft whose customer pays by autopay is refused (\`autopay\_charge\_required\`), because sending it would charge their saved card and the API never starts a charge; send those from the app. To send a sent invoice again, use remind. Needs \`invoices:send\` and \`invoices:read\`.\
> \
> Returns \[the invoice delivery object]\(<https://docs.shortcutco.com/developers/reference/objects/invoice-delivery).\\>
> \
> A workspace that delivers invoices by the channels each customer chose lists a channel it did not use in \`skippedChannels\`, such as "SMS skipped: channel not selected."\
> \
> \*\*Errors specific to this endpoint:\*\* \[\`autopay\_charge\_required\`]\(<https://docs.shortcutco.com/developers/concepts/errors#autopay\\_charge\\_required>), \[\`dependency\_unavailable\`]\(<https://docs.shortcutco.com/developers/concepts/errors#dependency\\_unavailable>), \[\`rule\_violation\`]\(<https://docs.shortcutco.com/developers/concepts/errors#rule\\_violation>), \[\`state\_conflict\`]\(<https://docs.shortcutco.com/developers/concepts/errors#state\\_conflict>). Every endpoint can also return the \[common errors]\(<https://docs.shortcutco.com/developers/concepts/errors>).

```json
{"openapi":"3.1.0","info":{"title":"Shortcut API","version":"v1"},"tags":[{"name":"Invoices","description":"Read invoices with their lines, send drafts, remind customers, void unpaid invoices, and record offline payments. No endpoint charges a card.\n\nFields: [The invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice) · [The invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery)."}],"servers":[{"url":"https://api.shortcutco.com","description":"Production"}],"security":[{"bearerAuth":["invoices:send","invoices:read"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"scut_<env>_<id>_<secret>","description":"A workspace API token. Each operation lists the scopes it needs; `write` implies `read`, and `send`/`complete` are never implied."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Any string up to 255 characters. Retrying with the same key returns the first response instead of repeating the write, for 24 hours.","schema":{"type":"string","maxLength":255}}},"headers":{"RateLimitLimit":{"schema":{"type":"integer"},"description":"Requests allowed in the tightest window."},"RateLimitRemaining":{"schema":{"type":"integer"},"description":"Requests left in that window."},"RateLimitReset":{"schema":{"type":"integer"},"description":"Seconds until that window resets."}},"schemas":{"InvoiceDelivery":{"type":"object","properties":{"object":{"type":"string","const":"invoice_delivery","description":"Always `invoice_delivery`."},"purpose":{"type":"string","enum":["invoice","reminder"],"description":"`invoice` when the invoice was sent, `reminder` for a reminder."},"queuedChannels":{"type":"array","items":{"type":"string","enum":["email","sms"]},"description":"Channels handed to delivery. Queued is not delivered: the customer's email preferences and SMS opt-out still apply when it sends."},"skippedChannels":{"type":"array","items":{"type":"string"},"description":"Channels not sent, each with the reason the app gives, such as no email on file or the customer opted out."},"failedChannels":{"type":"array","items":{"type":"string"},"description":"Channels that could not be queued; retry later."},"invoice":{"$ref":"#/components/schemas/Invoice","description":"The invoice after the send."}},"required":["object","purpose","queuedChannels","skippedChannels","failedChannels","invoice"],"additionalProperties":false,"description":"What sending an invoice or a reminder queued."},"Invoice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The invoice's id."},"object":{"type":"string","const":"invoice","description":"Always `invoice`."},"number":{"type":"integer","description":"The invoice number the customer sees."},"kind":{"type":"string","enum":["standard","prepay","project"],"description":"`standard` invoices bill completed visits or manual lines. `prepay` invoices bill a coverage period in advance (see `coverageStartDate`). `project` invoices bill a project (deposit, progress, or final)."},"status":{"type":"string","enum":["draft","unpaid","overdue","paid","void"],"description":"`draft` invoices have not been sent to the customer. `unpaid` invoices are sent and not yet due (or have no due date). `overdue` invoices are past `dueAt`. `paid` and `void` invoices are closed. These match the app's invoice list, except that the app shows a draft as Unpaid or Overdue."},"paymentActivity":{"anyOf":[{"type":"string","enum":["processing","verification"]},{"type":"null"}],"description":"`processing` while a bank payment is in flight, `verification` while the bank needs the customer to verify; otherwise null. The invoice stays `unpaid` or `overdue` until the payment settles."},"customerId":{"type":"string","format":"uuid","description":"The customer billed."},"propertyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The property (service address) billed, when there is one."},"propertyAddress":{"type":["string","null"],"description":"The property's address as printed on the invoice when it was created."},"propertyLabel":{"type":["string","null"],"description":"The property's label as printed on the invoice when it was created."},"subtotal":{"type":"number","description":"Sum of the lines before tax and fees, in US dollars."},"salesTax":{"type":"number","description":"Sales tax charged, in US dollars."},"processingFee":{"type":"number","description":"The processing fee in `total`. With `processingFeeScope` `card_only` it is 0 until a credit card pays the invoice with the fee, then equals `cardProcessingFee`; it stays 0 when the invoice is paid without the fee (bank, debit, offline, or a card-fee payment review settled at the total), in US dollars."},"processingFeeScope":{"type":"string","enum":["all_payments","card_only"],"description":"Which payments carry the processing fee, fixed when the invoice was created: `all_payments` (in `total`) or `card_only` (only a credit-card payment adds `cardProcessingFee`)."},"cardProcessingFee":{"type":"number","description":"With `card_only`, the fee a credit-card payment adds on top of `total`; bank, debit, check and cash payments never pay it. 0 for `all_payments`, in US dollars."},"lateFees":{"type":"number","description":"Late fees applied and not removed, in US dollars."},"total":{"type":"number","description":"What the customer owes in all: `subtotal + salesTax + processingFee + lateFees`, in US dollars."},"dueDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"The due date as the customer's invoice prints it, `YYYY-MM-DD`: the calendar date of `dueAt` in UTC (the app stores a due date chosen as a date at midnight UTC). Null when there is none."},"dueAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"The stored due instant. The invoice is `overdue` once this moment passes, as in the app, ISO 8601 in UTC, or null."},"coverageStartDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"First day a prepay invoice covers, `YYYY-MM-DD`, or null."},"coverageEndDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"Last day a prepay invoice covers, `YYYY-MM-DD`, or null."},"sentAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was first sent, ISO 8601 in UTC, or null."},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was paid in full, ISO 8601 in UTC, or null."},"createdAt":{"type":"string","format":"date-time","description":"When the invoice was created, ISO 8601 in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"When the invoice last changed, ISO 8601 in UTC."}},"required":["id","object","number","kind","status","paymentActivity","customerId","propertyId","propertyAddress","propertyLabel","subtotal","salesTax","processingFee","processingFeeScope","cardProcessingFee","lateFees","total","dueDate","dueAt","coverageStartDate","coverageEndDate","sentAt","paidAt","createdAt","updatedAt"],"additionalProperties":false,"description":"An invoice: a bill to a customer."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","description":"Error family, such as `invalid_request` or `permission`."},"code":{"type":"string","description":"Specific error code; see the errors page."},"message":{"type":"string","description":"A human-readable explanation."},"param":{"type":"string","description":"The input the error is about, such as `query.limit`."},"requiredScope":{"type":"string","description":"The scope the token is missing."},"requestId":{"type":"string","description":"Quote this id to support."},"docs":{"type":"string","description":"Link to the error's documentation."}},"required":["type","code","message","requestId","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}},"responses":{"BadRequest":{"description":"The request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthenticated":{"description":"The token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubscriptionRequired":{"description":"The workspace's subscription needs attention.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The token is missing a required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such object in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Conflict with the current state or an in-flight request with the same idempotency key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"The request cannot be applied, or its idempotency key was used for a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limited; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/invoices/{id}/send":{"post":{"operationId":"invoices.send","tags":["Invoices"],"summary":"Send a draft invoice","description":"Sends a draft invoice to the customer exactly as Send does in the app: the invoice becomes unpaid (or overdue), its email is queued under the customer's email preferences, and it syncs to QuickBooks when connected. The invoice's delivery always goes out. Your invoice-created automations, which may email or text the customer, and Automations rules that start when an invoice is sent, run only if the token has `automations:trigger`. A draft whose customer pays by autopay is refused (`autopay_charge_required`), because sending it would charge their saved card and the API never starts a charge; send those from the app. To send a sent invoice again, use remind. Needs `invoices:send` and `invoices:read`.\n\nReturns [the invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery).\n\nA workspace that delivers invoices by the channels each customer chose lists a channel it did not use in `skippedChannels`, such as \"SMS skipped: channel not selected.\"\n\n**Errors specific to this endpoint:** [`autopay_charge_required`](https://docs.shortcutco.com/developers/concepts/errors#autopay_charge_required), [`dependency_unavailable`](https://docs.shortcutco.com/developers/concepts/errors#dependency_unavailable), [`rule_violation`](https://docs.shortcutco.com/developers/concepts/errors#rule_violation), [`state_conflict`](https://docs.shortcutco.com/developers/concepts/errors#state_conflict). Every endpoint can also return the [common errors](https://docs.shortcutco.com/developers/concepts/errors).","parameters":[{"name":"id","in":"path","required":true,"description":"The object's id.","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/InvoiceDelivery"},"meta":{"type":"object","properties":{},"additionalProperties":true,"description":"Facts about this request beside the object, such as `alreadyReminded` on a repeated reminder. Present only when there is something to report."}},"required":["data"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthenticated"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/Unavailable"}}}}}}
```

## Void an invoice

> Voids an unpaid or overdue invoice with the same rules as Void in the app. Refused (\`409 state\_conflict\`, with the app's reason) for drafts, paid or already void invoices, prepay invoices, and invoices with any payment, refund, or credit memo. While an online payment is in progress (a bank payment awaiting confirmation, or an open checkout link) it is refused before anything happens, as the app hides Void then. The reason is recorded on the customer's notes. When QuickBooks is connected and the invoice is linked, the void is synced to QuickBooks. Automations rules that start on an invoice change run only if the token has \`automations:trigger\`. This cannot be undone.\
> \
> Returns \[the invoice object]\(<https://docs.shortcutco.com/developers/reference/objects/invoice).\\>
> \
> \*\*Errors specific to this endpoint:\*\* \[\`dependency\_unavailable\`]\(<https://docs.shortcutco.com/developers/concepts/errors#dependency\\_unavailable>), \[\`rule\_violation\`]\(<https://docs.shortcutco.com/developers/concepts/errors#rule\\_violation>), \[\`state\_conflict\`]\(<https://docs.shortcutco.com/developers/concepts/errors#state\\_conflict>), \[\`token\_creator\_unavailable\`]\(<https://docs.shortcutco.com/developers/concepts/errors#token\\_creator\\_unavailable>). Every endpoint can also return the \[common errors]\(<https://docs.shortcutco.com/developers/concepts/errors>).

```json
{"openapi":"3.1.0","info":{"title":"Shortcut API","version":"v1"},"tags":[{"name":"Invoices","description":"Read invoices with their lines, send drafts, remind customers, void unpaid invoices, and record offline payments. No endpoint charges a card.\n\nFields: [The invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice) · [The invoice delivery object](https://docs.shortcutco.com/developers/reference/objects/invoice-delivery)."}],"servers":[{"url":"https://api.shortcutco.com","description":"Production"}],"security":[{"bearerAuth":["invoices:write"]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"scut_<env>_<id>_<secret>","description":"A workspace API token. Each operation lists the scopes it needs; `write` implies `read`, and `send`/`complete` are never implied."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Any string up to 255 characters. Retrying with the same key returns the first response instead of repeating the write, for 24 hours.","schema":{"type":"string","maxLength":255}}},"headers":{"RateLimitLimit":{"schema":{"type":"integer"},"description":"Requests allowed in the tightest window."},"RateLimitRemaining":{"schema":{"type":"integer"},"description":"Requests left in that window."},"RateLimitReset":{"schema":{"type":"integer"},"description":"Seconds until that window resets."}},"schemas":{"Invoice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The invoice's id."},"object":{"type":"string","const":"invoice","description":"Always `invoice`."},"number":{"type":"integer","description":"The invoice number the customer sees."},"kind":{"type":"string","enum":["standard","prepay","project"],"description":"`standard` invoices bill completed visits or manual lines. `prepay` invoices bill a coverage period in advance (see `coverageStartDate`). `project` invoices bill a project (deposit, progress, or final)."},"status":{"type":"string","enum":["draft","unpaid","overdue","paid","void"],"description":"`draft` invoices have not been sent to the customer. `unpaid` invoices are sent and not yet due (or have no due date). `overdue` invoices are past `dueAt`. `paid` and `void` invoices are closed. These match the app's invoice list, except that the app shows a draft as Unpaid or Overdue."},"paymentActivity":{"anyOf":[{"type":"string","enum":["processing","verification"]},{"type":"null"}],"description":"`processing` while a bank payment is in flight, `verification` while the bank needs the customer to verify; otherwise null. The invoice stays `unpaid` or `overdue` until the payment settles."},"customerId":{"type":"string","format":"uuid","description":"The customer billed."},"propertyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The property (service address) billed, when there is one."},"propertyAddress":{"type":["string","null"],"description":"The property's address as printed on the invoice when it was created."},"propertyLabel":{"type":["string","null"],"description":"The property's label as printed on the invoice when it was created."},"subtotal":{"type":"number","description":"Sum of the lines before tax and fees, in US dollars."},"salesTax":{"type":"number","description":"Sales tax charged, in US dollars."},"processingFee":{"type":"number","description":"The processing fee in `total`. With `processingFeeScope` `card_only` it is 0 until a credit card pays the invoice with the fee, then equals `cardProcessingFee`; it stays 0 when the invoice is paid without the fee (bank, debit, offline, or a card-fee payment review settled at the total), in US dollars."},"processingFeeScope":{"type":"string","enum":["all_payments","card_only"],"description":"Which payments carry the processing fee, fixed when the invoice was created: `all_payments` (in `total`) or `card_only` (only a credit-card payment adds `cardProcessingFee`)."},"cardProcessingFee":{"type":"number","description":"With `card_only`, the fee a credit-card payment adds on top of `total`; bank, debit, check and cash payments never pay it. 0 for `all_payments`, in US dollars."},"lateFees":{"type":"number","description":"Late fees applied and not removed, in US dollars."},"total":{"type":"number","description":"What the customer owes in all: `subtotal + salesTax + processingFee + lateFees`, in US dollars."},"dueDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"The due date as the customer's invoice prints it, `YYYY-MM-DD`: the calendar date of `dueAt` in UTC (the app stores a due date chosen as a date at midnight UTC). Null when there is none."},"dueAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"The stored due instant. The invoice is `overdue` once this moment passes, as in the app, ISO 8601 in UTC, or null."},"coverageStartDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"First day a prepay invoice covers, `YYYY-MM-DD`, or null."},"coverageEndDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"description":"Last day a prepay invoice covers, `YYYY-MM-DD`, or null."},"sentAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was first sent, ISO 8601 in UTC, or null."},"paidAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invoice was paid in full, ISO 8601 in UTC, or null."},"createdAt":{"type":"string","format":"date-time","description":"When the invoice was created, ISO 8601 in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"When the invoice last changed, ISO 8601 in UTC."}},"required":["id","object","number","kind","status","paymentActivity","customerId","propertyId","propertyAddress","propertyLabel","subtotal","salesTax","processingFee","processingFeeScope","cardProcessingFee","lateFees","total","dueDate","dueAt","coverageStartDate","coverageEndDate","sentAt","paidAt","createdAt","updatedAt"],"additionalProperties":false,"description":"An invoice: a bill to a customer."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","description":"Error family, such as `invalid_request` or `permission`."},"code":{"type":"string","description":"Specific error code; see the errors page."},"message":{"type":"string","description":"A human-readable explanation."},"param":{"type":"string","description":"The input the error is about, such as `query.limit`."},"requiredScope":{"type":"string","description":"The scope the token is missing."},"requestId":{"type":"string","description":"Quote this id to support."},"docs":{"type":"string","description":"Link to the error's documentation."}},"required":["type","code","message","requestId","docs"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}},"responses":{"BadRequest":{"description":"The request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthenticated":{"description":"The token is missing, invalid, expired, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubscriptionRequired":{"description":"The workspace's subscription needs attention.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The token is missing a required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"No such object in this workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Conflict with the current state or an in-flight request with the same idempotency key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"The request cannot be applied, or its idempotency key was used for a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limited; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unavailable":{"description":"Temporarily unavailable; retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/v1/invoices/{id}/void":{"post":{"operationId":"invoices.void","tags":["Invoices"],"summary":"Void an invoice","description":"Voids an unpaid or overdue invoice with the same rules as Void in the app. Refused (`409 state_conflict`, with the app's reason) for drafts, paid or already void invoices, prepay invoices, and invoices with any payment, refund, or credit memo. While an online payment is in progress (a bank payment awaiting confirmation, or an open checkout link) it is refused before anything happens, as the app hides Void then. The reason is recorded on the customer's notes. When QuickBooks is connected and the invoice is linked, the void is synced to QuickBooks. Automations rules that start on an invoice change run only if the token has `automations:trigger`. This cannot be undone.\n\nReturns [the invoice object](https://docs.shortcutco.com/developers/reference/objects/invoice).\n\n**Errors specific to this endpoint:** [`dependency_unavailable`](https://docs.shortcutco.com/developers/concepts/errors#dependency_unavailable), [`rule_violation`](https://docs.shortcutco.com/developers/concepts/errors#rule_violation), [`state_conflict`](https://docs.shortcutco.com/developers/concepts/errors#state_conflict), [`token_creator_unavailable`](https://docs.shortcutco.com/developers/concepts/errors#token_creator_unavailable). Every endpoint can also return the [common errors](https://docs.shortcutco.com/developers/concepts/errors).","parameters":[{"name":"id","in":"path","required":true,"description":"The object's id.","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":500,"description":"Why the invoice is being voided. It is recorded on the customer's notes, as in the app."}},"required":["reason"],"additionalProperties":false}}}},"responses":{"200":{"description":"Success.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Invoice"},"meta":{"type":"object","properties":{},"additionalProperties":true,"description":"Facts about this request beside the object, such as `alreadyReminded` on a repeated reminder. Present only when there is something to report."}},"required":["data"],"additionalProperties":false}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthenticated"},"402":{"$ref":"#/components/responses/SubscriptionRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/Unavailable"}}}}}}
```
