Invoices
Invoices in the BlueSuite REST API
Create and manage one-off invoices. New type: "recurring" invoices are rejected; use a recurring job schedule for repeating work. Existing legacy recurring invoices remain editable.
Sending and payment
Setting status: "sent" does not email or text the client. Use Notifications with type: "invoice_to_customer" for delivery. A scheduled invoice uses status: "scheduled" together with send_on.
To mark an invoice paid, record money received using Payments. A bare paid status write returns 409 while a balance remains. Fully covered and zero-total invoices can be marked paid. The payment settlement flow accounts for completed payments and applicable quote deposits; pending payments block settlement.
GET /invoices/:id includes payment/balance information. reminders_enabled controls reminders, and waive_credit_card_fee overrides the workspace's online processing fee. See line items.
Example: record the remaining balance as received
curl 'https://my.bluesuite.app/api/v1/payments' \
-H "Authorization: Bearer $BLUESUITE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"object_type":"invoice","object_id":101,"category":"payment","settle_remaining":true}'This records a manual payment and recalculates status. It does not charge a card or send a customer receipt.
GET /api/v1/invoices
GET /api/v1/invoicesRequired scopes: invoices:read.
Query parameters
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
page | integer | No | Page number, starting at 1. Default: 1. |
per_page | integer | No | Records per page, from 1 to 100. Default: 25. minimum: 1. maximum: 100. |
search | string | No | Search text. maxLength: 100. |
sort_by | string | No | Sort column. See the supported columns below when listed. |
sort_direction | "asc", "desc" | No | Sort direction. Default: "desc". |
contact_id | string | No | Filter by contact ID. |
job_id | string | No | Filter by job ID. |
exclude_children | string | No | Use true to exclude child invoices. |
exclude_statuses | string | No | Comma-separated statuses to exclude. |
tag_ids | string | No | Comma-separated tag IDs. Tags must match this resource type. |
Response
200 with { "success": true, "data": [...], "pagination": { "page": 1, "per_page": 25, "total_pages": 1 } }.
See response conventions and errors.
POST /api/v1/invoices
POST /api/v1/invoicesRequired scopes: invoices:write.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
name | string or null | No | |
contact_id | integer or null | No | |
property_id | integer or null | No | |
job_id | integer or null | No | |
quote_id | integer or null | No | |
salesperson_id | string or null | No | |
date | string | No | |
due_date | string | No | |
send_on | string or null | No | |
message | string or null | No | |
payment_instructions | string or null | No | |
payment_terms | "due_on_receipt", "net_7", "net_14", "net_30", "net_60", "net_90" | No | Default: "due_on_receipt". |
line_items | array of object or object | No | maxItems: 500. |
line_items[]._type | "lineItem" | No | For lineItem rows. Defaults to lineItem when omitted. |
line_items[].name | string | For this variant | For lineItem rows. Item name |
line_items[].description | string or null | No | For lineItem rows. Additional description |
line_items[].quantity | number | No | For lineItem rows. Quantity Default: 1. |
line_items[].unitPrice | number | For this variant | For lineItem rows. Unit price |
line_items[].unitCost | number | No | For lineItem rows. What this costs the business, per unit. Only used when cost tracking is enabled. minimum: 0. |
line_items[].taxable | boolean | No | For lineItem rows. Whether the item is taxable |
line_items[].optional | boolean | No | For lineItem rows. Whether the item is optional |
line_items[]._type | "image" | For this variant | For image rows. |
line_items[].image_path | string | For this variant | For image rows. Storage path returned by /uploads minLength: 1. |
line_items[].image_id | integer or null | No | For image rows. Upload link ID returned by /uploads |
line_items[].description | string or null | No | For image rows. Caption shown beneath the image |
discount | number | No | Default: 0. |
discount_unit | "%", "$" | No | Default: "%". |
deposit | number | No | Default: 0. |
deposit_unit | "%", "$" | No | Default: "%". |
tax_rate | number | No | Default: 0. |
tax_rate_id | integer or null | No | |
total | number | No | Default: 0. |
reminders_enabled | boolean | No | Default: true. |
waive_credit_card_fee | boolean | No | Skip the workspace's online processing fee for this record. Default: false. |
status | "draft", "sent", "paid", "overdue", "cancelled", "partially_paid", "scheduled" | No | Default: "draft". |
type | "one-off", "recurring" | No | Default: "one-off". |
custom_fields | JSON value or null | No | |
event_ids | array of integer | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
201 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
GET /api/v1/invoices/:id
GET /api/v1/invoices/:idRequired scopes: invoices:read.
Path parameters: id. Use positive integer record IDs from this workspace.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
PUT /api/v1/invoices/:id
PUT /api/v1/invoices/:idRequired scopes: invoices:write.
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
name | string or null | No | |
contact_id | integer or null | No | |
property_id | integer or null | No | |
job_id | integer or null | No | |
quote_id | integer or null | No | |
salesperson_id | string or null | No | |
date | string | No | |
due_date | string | No | |
send_on | string or null | No | |
message | string or null | No | |
payment_instructions | string or null | No | |
payment_terms | "due_on_receipt", "net_7", "net_14", "net_30", "net_60", "net_90" | No | Default: "due_on_receipt". |
line_items | array of object or object | No | maxItems: 500. |
line_items[]._type | "lineItem" | No | For lineItem rows. Defaults to lineItem when omitted. |
line_items[].name | string | For this variant | For lineItem rows. Item name |
line_items[].description | string or null | No | For lineItem rows. Additional description |
line_items[].quantity | number | No | For lineItem rows. Quantity Default: 1. |
line_items[].unitPrice | number | For this variant | For lineItem rows. Unit price |
line_items[].unitCost | number | No | For lineItem rows. What this costs the business, per unit. Only used when cost tracking is enabled. minimum: 0. |
line_items[].taxable | boolean | No | For lineItem rows. Whether the item is taxable |
line_items[].optional | boolean | No | For lineItem rows. Whether the item is optional |
line_items[]._type | "image" | For this variant | For image rows. |
line_items[].image_path | string | For this variant | For image rows. Storage path returned by /uploads minLength: 1. |
line_items[].image_id | integer or null | No | For image rows. Upload link ID returned by /uploads |
line_items[].description | string or null | No | For image rows. Caption shown beneath the image |
discount | number | No | Default: 0. |
discount_unit | "%", "$" | No | Default: "%". |
deposit | number | No | Default: 0. |
deposit_unit | "%", "$" | No | Default: "%". |
tax_rate | number | No | Default: 0. |
tax_rate_id | integer or null | No | |
total | number | No | Default: 0. |
reminders_enabled | boolean | No | Default: true. |
waive_credit_card_fee | boolean | No | Skip the workspace's online processing fee for this record. Default: false. |
status | "draft", "sent", "paid", "overdue", "cancelled", "partially_paid", "scheduled" | No | Default: "draft". |
type | "one-off", "recurring" | No | Default: "one-off". |
custom_fields | JSON value or null | No | |
event_ids | array of integer | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
DELETE /api/v1/invoices/:id
DELETE /api/v1/invoices/:idRequired scopes: invoices:write.
Path parameters: id. Use positive integer record IDs from this workspace.
No request body.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
PUT /api/v1/invoices/:id/status
PUT /api/v1/invoices/:id/statusRequired scopes: invoices:write.
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
status | "draft", "sent", "paid", "overdue", "cancelled", "partially_paid", "scheduled" | Yes |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.