Invoices API
REST endpoints for invoices in SKUFlow: 8 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
| Operation | Endpoint | Risk |
|---|---|---|
| List invoices | GET /organizations/{organizationId}/invoices | read |
| Create a draft invoice | POST /organizations/{organizationId}/invoices | write |
| Get an invoice with its lines and payments | GET /organizations/{organizationId}/invoices/{invoiceId} | read |
| Update an invoice's status, notes or dates | PATCH /organizations/{organizationId}/invoices/{invoiceId} | sensitive |
| Delete an invoice | DELETE /organizations/{organizationId}/invoices/{invoiceId} | sensitive |
| Update an invoice's tax | POST /organizations/{organizationId}/invoices/{invoiceId}/tax | write |
| Get or create the invoice's customer link | POST /organizations/{organizationId}/invoices/{invoiceId}/link | sensitive |
| Replace the invoice's customer link | POST /organizations/{organizationId}/invoices/{invoiceId}/link/regenerate | sensitive |
List invoices
GET /organizations/{organizationId}/invoices
Invoices newest first, filtered by text (INV-n, customer), status or customer, paged with a total. Each item carries amountPaidCents, balanceDueCents and partiallyPaid. Read-only.
| Permission | invoices.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | invoices_list (toolset invoices, in the default set) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
query | query | string | No | Free-text search over the list's names, numbers and contact details. Up to 200 characters. |
status | query | enum | No | One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
customerId | query | string | No | |
businessUnitId | query | string | No | Only this business unit (GET /business-units), or "none" for records without one. Up to 100 characters. |
limit | query | integer | No | Page size, 1–200. Default 50. |
offset | query | integer | No | Rows to skip; the answer's total counts every match. Default 0. |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
items | array of object | |
items[].id | string | Invoice id. |
items[].organizationId | string | |
items[].identifier | string | INV-n, unique per organization. |
items[].customerId | string | |
items[].status | enum | DRAFT (not issued), SENT (issued, money due), PAID, OVERDUE (past dueDate) or CANCELLED. One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
items[].subtotalCents | integer | Lines total before tax, in integer cents. |
items[].taxRate | number | Tax rate in percent. |
items[].taxClothingRate | number or null | Percent on CLOTHING lines; null = taxRate (some states tax apparel less). |
items[].taxShippingRate | number or null | Percent on SHIPPING lines; null = taxRate (0 where shipping is not taxed). |
items[].taxDetails | any | How the rate was decided: source EXEMPT (tax-exempt customer), MANUAL (typed), ADDRESS (the address's own rate), RULES (the business's tax rules for the ship-to address; rules lists them), UNIT, DEFAULT or NONE. Null on older records. |
items[].taxCents | integer | Tax, in integer cents. |
items[].totalCents | integer | Total with tax, in integer cents. |
items[].propertyId | string or null | The ship-to address (a property of the customer); its tax rules decide the rate. |
items[].notes | string or null | |
items[].dueDate | string or null | YYYY-MM-DD |
items[].paidDate | string or null | YYYY-MM-DD |
items[].amountPaidCents | integer | Paid so far, net of refunds, tips excluded, in integer cents. |
items[].financingDisabled | boolean | |
items[].importLocked | boolean | Imported paid history: read-only, its amounts never change. |
items[].businessUnitId | string or null | |
items[].customFields | any | Custom field values by key (definitions: GET /custom-fields?entity=INVOICE). |
items[].createdAt | string (date-time) | |
items[].updatedAt | string (date-time) | |
items[].customer | object | |
items[].customer.id | string | |
items[].customer.name | string | |
items[].businessUnit | object or null | The business unit. |
items[].businessUnit.id | string | |
items[].businessUnit.name | string | |
items[].property | object or null | The ship-to address. |
items[].property.id | string | Property id. |
items[].property.name | string or null | |
items[].property.address | string or null | |
items[].property.city | string or null | |
items[].property.county | string or null | |
items[].property.state | string or null | |
items[].property.zip | string or null | |
items[].property.country | string or null | |
items[].balanceDueCents | integer | Still due, in integer cents. |
items[].partiallyPaid | boolean | |
total | integer | How many match the filters, across all pages. |
Create a draft invoice
POST /organizations/{organizationId}/invoices
Creates a DRAFT invoice (INV-n) for a customer with the given lines; amounts are fixed once created. Tax is 0 for tax-exempt customers, else taxRate when given, else decided for the ship-to address propertyId by the business's tax rules, else the business default. Apparel lines take the clothing rate and not-taxable pricebook items none. Nothing is sent: share it with POST /invoices/{invoiceId}/link and mark it SENT with PATCH. To bill an approved quote use POST /quotes/{quoteId}/invoice instead.
| Permission | invoices.write (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | invoices_create (toolset invoices, in the default set) |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Yes | From GET /customers. |
taxRate | number | No | Percent, e.g. 8.25, typed instead of the tax rules. Ignored for tax-exempt customers. -1000–1000. |
propertyId | string or null | No | The ship-to address (GET /customers/{customerId} properties): its tax rules decide the rate. |
notes | string or null | No | Printed on the invoice; the customer sees it. |
dueDate | empty string or string or null | No | Defaults from the customer's payment terms. |
lines | array of object | Yes | Up to 500 items. |
lines[].description | string | Yes | |
lines[].quantity | number | Yes | -1000000–1000000. |
lines[].unitPriceCents | integer | Yes | Money in integer cents; negative for a discount or credit line. -100000000–100000000. |
lines[].pricebookItemId | string or null | No | The pricebook item the line was picked from (GET /pricebook/items): the server snapshots its cost; pricebook edits never change the invoice. |
businessUnitId | string or null | No | Business unit (GET /business-units): its branding shows on the invoice and its accounting class or tracking applies. Omitted: none (null). Up to 100 characters. |
customFields | object | No | Invoice custom field values (GET /custom-fields?entity=INVOICE); those marked visibleToCustomer print on the invoice, its emails and pages. Required ones are checked here. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customerId":"customer_id","lines":[{"description":"string","quantity":1,"unitPriceCents":12500}]}'Response
201: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | Invoice id. |
organizationId | string | |
identifier | string | INV-n, unique per organization. |
customerId | string | |
status | enum | DRAFT (not issued), SENT (issued, money due), PAID, OVERDUE (past dueDate) or CANCELLED. One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
subtotalCents | integer | Lines total before tax, in integer cents. |
taxRate | number | Tax rate in percent. |
taxClothingRate | number or null | Percent on CLOTHING lines; null = taxRate (some states tax apparel less). |
taxShippingRate | number or null | Percent on SHIPPING lines; null = taxRate (0 where shipping is not taxed). |
taxDetails | any | How the rate was decided: source EXEMPT (tax-exempt customer), MANUAL (typed), ADDRESS (the address's own rate), RULES (the business's tax rules for the ship-to address; rules lists them), UNIT, DEFAULT or NONE. Null on older records. |
taxCents | integer | Tax, in integer cents. |
totalCents | integer | Total with tax, in integer cents. |
propertyId | string or null | The ship-to address (a property of the customer); its tax rules decide the rate. |
notes | string or null | |
dueDate | string or null | YYYY-MM-DD |
paidDate | string or null | YYYY-MM-DD |
amountPaidCents | integer | Paid so far, net of refunds, tips excluded, in integer cents. |
financingDisabled | boolean | |
importLocked | boolean | Imported paid history: read-only, its amounts never change. |
businessUnitId | string or null | |
customFields | any | Custom field values by key (definitions: GET /custom-fields?entity=INVOICE). |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
customer | object | |
customer.id | string | |
customer.name | string | |
businessUnit | object or null | The business unit. |
businessUnit.id | string | |
businessUnit.name | string | |
property | object or null | The ship-to address. |
property.id | string | Property id. |
property.name | string or null | |
property.address | string or null | |
property.city | string or null | |
property.county | string or null | |
property.state | string or null | |
property.zip | string or null | |
property.country | string or null | |
balanceDueCents | integer | Still due, in integer cents. |
partiallyPaid | boolean |
Get an invoice with its lines and payments
GET /organizations/{organizationId}/invoices/{invoiceId}
Includes payments (with refunds), amountPaidCents (net of refunds, tips excluded), balanceDueCents, tipsCents, partiallyPaid and publicToken (the /i/{token} link, null until made). Read-only.
| Permission | invoices.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | invoices_get (toolset invoices, in the default set) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | Invoice id. |
organizationId | string | |
identifier | string | INV-n, unique per organization. |
customerId | string | |
status | enum | DRAFT (not issued), SENT (issued, money due), PAID, OVERDUE (past dueDate) or CANCELLED. One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
subtotalCents | integer | Lines total before tax, in integer cents. |
taxRate | number | Tax rate in percent. |
taxClothingRate | number or null | Percent on CLOTHING lines; null = taxRate (some states tax apparel less). |
taxShippingRate | number or null | Percent on SHIPPING lines; null = taxRate (0 where shipping is not taxed). |
taxDetails | any | How the rate was decided: source EXEMPT (tax-exempt customer), MANUAL (typed), ADDRESS (the address's own rate), RULES (the business's tax rules for the ship-to address; rules lists them), UNIT, DEFAULT or NONE. Null on older records. |
taxCents | integer | Tax, in integer cents. |
totalCents | integer | Total with tax, in integer cents. |
propertyId | string or null | The ship-to address (a property of the customer); its tax rules decide the rate. |
notes | string or null | |
dueDate | string or null | YYYY-MM-DD |
paidDate | string or null | YYYY-MM-DD |
amountPaidCents | integer | Paid so far, net of refunds, tips excluded, in integer cents. |
financingDisabled | boolean | |
importLocked | boolean | Imported paid history: read-only, its amounts never change. |
businessUnitId | string or null | |
customFields | any | Custom field values by key (definitions: GET /custom-fields?entity=INVOICE). |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
customer | object | |
customer.id | string | |
customer.name | string | |
customer.email | string or null | |
customer.phone | string or null | |
customer.address | string or null | |
customer.city | string or null | |
customer.state | string or null | |
customer.zip | string or null | |
businessUnit | object or null | The business unit. |
businessUnit.id | string | |
businessUnit.name | string | |
property | object or null | The ship-to address. |
property.id | string | Property id. |
property.name | string or null | |
property.address | string or null | |
property.city | string or null | |
property.county | string or null | |
property.state | string or null | |
property.zip | string or null | |
property.country | string or null | |
balanceDueCents | integer | Still due, in integer cents. |
partiallyPaid | boolean | |
lines | array of object | |
lines[].id | string | |
lines[].invoiceId | string | |
lines[].description | string | |
lines[].quantity | number | |
lines[].unitPriceCents | integer | Unit price, in integer cents. |
lines[].totalCents | integer | Line total, in integer cents. |
lines[].sortOrder | integer | |
lines[].pricebookItemId | string or null | |
lines[].costCents | integer or null | Our unit cost in cents (costing.read only). |
lines[].kind | enum | STANDARD (typed or pricebook), PRODUCT (sizes priced alike of a product line), LARGE_FORMAT or DECORATION_FEE (a one-time fee of a decorated line). One of STANDARD, PRODUCT, LARGE_FORMAT, DECORATION_FEE. |
lines[].groupKey | string or null | A decorated line's lines share it; send the line's product input once instead of them. |
lines[].productId | string or null | |
lines[].productVariantId | string or null | |
lines[].designId | string or null | |
lines[].pricing | any | The pricing snapshot: on the first line of a group, input (the product line to send back to keep or change it) and result (sizes, decoration per location, fees). |
lines[].taxClass | enum | Which rate taxes the line: STANDARD, CLOTHING (apparel), SHIPPING or EXEMPT (set by the server). One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
quotes | array of object | Quotes invoiced here (Q-n). |
quotes[].id | string | |
quotes[].identifier | string | Q-n |
quotes[].status | enum | DRAFT → SENT (customer can answer at /q/{publicToken}) → APPROVED / CHANGES_REQUESTED / DECLINED; APPROVED → CONVERTED (invoice made). SENT past validUntil becomes EXPIRED. One of DRAFT, SENT, APPROVED, CHANGES_REQUESTED, DECLINED, CONVERTED, EXPIRED, ARCHIVED. |
payments | array of object | Payments on the invoice, with their refunds. |
payments[].id | string | |
payments[].identifier | string | PAY-n |
payments[].amountCents | integer | |
payments[].tipCents | integer | |
payments[].refundedCents | integer | |
payments[].method | enum | One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
payments[].paidOn | string | YYYY-MM-DD |
payments[].status | enum | One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
tipsCents | integer | Tips collected, net of refunds, in integer cents. |
publicToken | string or null | The customer link token (/i/{token}); null until one is made. |
Update an invoice's status, notes or dates
PATCH /organizations/{organizationId}/invoices/{invoiceId}
Amounts are fixed once created. MONEY: setting status: PAID while a balance is due records that balance as a payment (method OTHER, dated paidDate or today) so payments and status agree; prefer POST /invoices/{invoiceId}/payments to record the real method. An invoice paid in full cannot be set back to DRAFT/SENT/OVERDUE (refund a payment instead, 409), and one holding payments cannot be CANCELLED (409). paidDate is only for paid invoices. Marking SENT does not email anything.
| Permission | invoices.write (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | invoices_update (toolset invoices, in the default set) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
status | enum | No | One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
notes | string or null | No | |
dueDate | empty string or string or null | No | |
paidDate | empty string or string or null | No | |
businessUnitId | string or null | No | Move the invoice to another business unit (GET /business-units), or null for none. Up to 100 characters. |
propertyId | string or null | No | The ship-to address (one of the customer's properties), or null. A draft without payments is taxed again for it. |
financingDisabled | boolean | No | Exposes to customers: true hides Affirm and Klarna on this invoice's pay page even when the business offers financing. |
today | string | No | The business's today (YYYY-MM-DD), for the paid date and reopened-overdue checks. |
customFields | object | No | Custom field values by key (definitions: GET /custom-fields?entity=INVOICE); merged into the saved values on an update, null clears one. Checked against each field's type and options; unknown keys are refused. |
Example
curl -X PATCH "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"DRAFT","notes":"string","dueDate":"2026-11-03"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | Invoice id. |
organizationId | string | |
identifier | string | INV-n, unique per organization. |
customerId | string | |
status | enum | DRAFT (not issued), SENT (issued, money due), PAID, OVERDUE (past dueDate) or CANCELLED. One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
subtotalCents | integer | Lines total before tax, in integer cents. |
taxRate | number | Tax rate in percent. |
taxClothingRate | number or null | Percent on CLOTHING lines; null = taxRate (some states tax apparel less). |
taxShippingRate | number or null | Percent on SHIPPING lines; null = taxRate (0 where shipping is not taxed). |
taxDetails | any | How the rate was decided: source EXEMPT (tax-exempt customer), MANUAL (typed), ADDRESS (the address's own rate), RULES (the business's tax rules for the ship-to address; rules lists them), UNIT, DEFAULT or NONE. Null on older records. |
taxCents | integer | Tax, in integer cents. |
totalCents | integer | Total with tax, in integer cents. |
propertyId | string or null | The ship-to address (a property of the customer); its tax rules decide the rate. |
notes | string or null | |
dueDate | string or null | YYYY-MM-DD |
paidDate | string or null | YYYY-MM-DD |
amountPaidCents | integer | Paid so far, net of refunds, tips excluded, in integer cents. |
financingDisabled | boolean | |
importLocked | boolean | Imported paid history: read-only, its amounts never change. |
businessUnitId | string or null | |
customFields | any | Custom field values by key (definitions: GET /custom-fields?entity=INVOICE). |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
customer | object | |
customer.id | string | |
customer.name | string | |
businessUnit | object or null | The business unit. |
businessUnit.id | string | |
businessUnit.name | string | |
property | object or null | The ship-to address. |
property.id | string | Property id. |
property.name | string or null | |
property.address | string or null | |
property.city | string or null | |
property.county | string or null | |
property.state | string or null | |
property.zip | string or null | |
property.country | string or null | |
balanceDueCents | integer | Still due, in integer cents. |
partiallyPaid | boolean |
Delete an invoice
DELETE /organizations/{organizationId}/invoices/{invoiceId}
Destructive: deletes the invoice and its lines. Refused (409) while the invoice holds any payment; cancel it instead.
| Permission | invoices.delete (Owner, Admin) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | invoices_delete (toolset invoices) |
| Approval | Over MCP, this tool always waits for your approval in SKUFlow. See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Example
curl -X DELETE "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
ok | true |
Update an invoice's tax
POST /organizations/{organizationId}/invoices/{invoiceId}/tax
Taxes a DRAFT invoice without payments again: for its ship-to address under the business's current tax rules, or at taxRate when given. Changes its tax and total; 409 once it is issued, paid or imported (amounts are fixed). Answers the invoice with taxDetails (how the rate was decided).
| Permission | invoices.write (Owner, Admin, Staff) |
| Risk | write, OAuth scope skuflow.write. Write: creates or changes records inside the business; nothing leaves it. |
| MCP tool | invoices_refreshTax (toolset invoices) |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
taxRate | number | No | Percent typed instead of the tax rules. 0–100. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}/tax" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"taxRate":1}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
id | string | Invoice id. |
organizationId | string | |
identifier | string | INV-n, unique per organization. |
customerId | string | |
status | enum | DRAFT (not issued), SENT (issued, money due), PAID, OVERDUE (past dueDate) or CANCELLED. One of DRAFT, SENT, PAID, OVERDUE, CANCELLED. |
subtotalCents | integer | Lines total before tax, in integer cents. |
taxRate | number | Tax rate in percent. |
taxClothingRate | number or null | Percent on CLOTHING lines; null = taxRate (some states tax apparel less). |
taxShippingRate | number or null | Percent on SHIPPING lines; null = taxRate (0 where shipping is not taxed). |
taxDetails | any | How the rate was decided: source EXEMPT (tax-exempt customer), MANUAL (typed), ADDRESS (the address's own rate), RULES (the business's tax rules for the ship-to address; rules lists them), UNIT, DEFAULT or NONE. Null on older records. |
taxCents | integer | Tax, in integer cents. |
totalCents | integer | Total with tax, in integer cents. |
propertyId | string or null | The ship-to address (a property of the customer); its tax rules decide the rate. |
notes | string or null | |
dueDate | string or null | YYYY-MM-DD |
paidDate | string or null | YYYY-MM-DD |
amountPaidCents | integer | Paid so far, net of refunds, tips excluded, in integer cents. |
financingDisabled | boolean | |
importLocked | boolean | Imported paid history: read-only, its amounts never change. |
businessUnitId | string or null | |
customFields | any | Custom field values by key (definitions: GET /custom-fields?entity=INVOICE). |
createdAt | string (date-time) | |
updatedAt | string (date-time) | |
customer | object | |
customer.id | string | |
customer.name | string | |
customer.email | string or null | |
customer.phone | string or null | |
customer.address | string or null | |
customer.city | string or null | |
customer.state | string or null | |
customer.zip | string or null | |
businessUnit | object or null | The business unit. |
businessUnit.id | string | |
businessUnit.name | string | |
property | object or null | The ship-to address. |
property.id | string | Property id. |
property.name | string or null | |
property.address | string or null | |
property.city | string or null | |
property.county | string or null | |
property.state | string or null | |
property.zip | string or null | |
property.country | string or null | |
balanceDueCents | integer | Still due, in integer cents. |
partiallyPaid | boolean | |
lines | array of object | |
lines[].id | string | |
lines[].invoiceId | string | |
lines[].description | string | |
lines[].quantity | number | |
lines[].unitPriceCents | integer | Unit price, in integer cents. |
lines[].totalCents | integer | Line total, in integer cents. |
lines[].sortOrder | integer | |
lines[].pricebookItemId | string or null | |
lines[].costCents | integer or null | Our unit cost in cents (costing.read only). |
lines[].kind | enum | STANDARD (typed or pricebook), PRODUCT (sizes priced alike of a product line), LARGE_FORMAT or DECORATION_FEE (a one-time fee of a decorated line). One of STANDARD, PRODUCT, LARGE_FORMAT, DECORATION_FEE. |
lines[].groupKey | string or null | A decorated line's lines share it; send the line's product input once instead of them. |
lines[].productId | string or null | |
lines[].productVariantId | string or null | |
lines[].designId | string or null | |
lines[].pricing | any | The pricing snapshot: on the first line of a group, input (the product line to send back to keep or change it) and result (sizes, decoration per location, fees). |
lines[].taxClass | enum | Which rate taxes the line: STANDARD, CLOTHING (apparel), SHIPPING or EXEMPT (set by the server). One of STANDARD, CLOTHING, SHIPPING, EXEMPT. |
quotes | array of object | Quotes invoiced here (Q-n). |
quotes[].id | string | |
quotes[].identifier | string | Q-n |
quotes[].status | enum | DRAFT → SENT (customer can answer at /q/{publicToken}) → APPROVED / CHANGES_REQUESTED / DECLINED; APPROVED → CONVERTED (invoice made). SENT past validUntil becomes EXPIRED. One of DRAFT, SENT, APPROVED, CHANGES_REQUESTED, DECLINED, CONVERTED, EXPIRED, ARCHIVED. |
payments | array of object | Payments on the invoice, with their refunds. |
payments[].id | string | |
payments[].identifier | string | PAY-n |
payments[].amountCents | integer | |
payments[].tipCents | integer | |
payments[].refundedCents | integer | |
payments[].method | enum | One of CASH, CHECK, CARD, BANK_TRANSFER, OTHER. |
payments[].paidOn | string | YYYY-MM-DD |
payments[].status | enum | One of SUCCEEDED, PENDING, FAILED, REFUNDED, PARTIALLY_REFUNDED. |
tipsCents | integer | Tips collected, net of refunds, in integer cents. |
publicToken | string or null | The customer link token (/i/{token}); null until one is made. |
Get or create the invoice's customer link
POST /organizations/{organizationId}/invoices/{invoiceId}/link
Exposes to the customer: returns the token for /i/{token}, the customer's page for this one invoice (no sign-in; anyone with the link can read it). Made on first call and then reused, so calling it again is safe. Drafts and cancelled invoices are not shown on that page until issued. Nothing is emailed.
| Permission | invoices.send (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | invoiceLinks_ensure (toolset invoices) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}/link" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
token | string | Open the invoice at /i/{token} on the web app. |
createdAt | string (date-time) |
Replace the invoice's customer link
POST /organizations/{organizationId}/invoices/{invoiceId}/link/regenerate
Destructive: issues a new token; the previous /i/{token} link stops working at once.
| Permission | invoices.send (Owner, Admin, Staff) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | invoiceLinks_regenerate (toolset invoices) |
| Approval | Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in SKUFlow). See Approvals. |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invoiceId | path | string | Yes |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/invoices/{invoiceId}/link/regenerate" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
token | string | Open the invoice at /i/{token} on the web app. |
createdAt | string (date-time) |