Skip to content

Create an invoice

POST
/invoices
curl --request POST \
--url https://app.buildworkpro.com/api/v1/invoices \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "invoice": { "invoiceNumber": "example", "projectId": 1, "contactId": 1, "sourceBidId": 1, "sourcePayAppId": 1, "sourceType": "bid", "issueDate": "example", "dueDate": "example", "taxRate": "example", "discountType": "fixed", "discount": "example", "notesToCustomer": "example", "terms": "example", "paymentTermsText": "example", "paymentTermId": 1, "paymentTermInstallmentId": 1, "percentOfBid": "example" }, "lines": [ { "position": 1, "productId": 1, "description": "example", "quantity": "example", "unitPrice": "example", "isTaxable": true, "deletedAt": "example" } ] }'

Creates a draft invoice together with its line items.

Idempotency-Key
string format: uuid
<= 255 characters

Idempotent retry key for mutating operations. The first request with a given key executes normally and BuildWorkPro caches the response. Replaying the same key with the same request body (method + path + JSON body, SHA-256 hashed) returns the cached response without re-executing the mutation. Replaying with a DIFFERENT body returns 409 idempotency_key_reused. The cache TTL is 24 hours; after expiry the key is treated as a new operation. Keys are tenant-scoped. Recommended: a fresh UUID v4 per logical operation.

Media type application/json
object
invoice
required
object
invoiceNumber
string
projectId
required
integer
>= -2147483648 <= 2147483647
contactId
required
integer
>= -2147483648 <= 2147483647
sourceBidId
integer | null
>= -2147483648 <= 2147483647
sourcePayAppId
integer | null
>= -2147483648 <= 2147483647
sourceType
string
Allowed values: bid pay_app ad_hoc
issueDate
required
string | null
dueDate
string | null
taxRate
string
discountType
string
Allowed values: fixed percentage
discount
string
notesToCustomer
string | null
terms
string | null
paymentTermsText
string | null
paymentTermId
integer | null
>= -2147483648 <= 2147483647
paymentTermInstallmentId
integer | null
> 0
percentOfBid
string | null
lines
Array<object>
object
position
integer
>= -2147483648 <= 2147483647
productId
integer | null
>= -2147483648 <= 2147483647
description
required
string
quantity
string
unitPrice
string
isTaxable
boolean
deletedAt
string | null

Created

Media type application/json
object
data
required
object
id
required
integer
tenantId
required
integer
invoiceNumber
required
string
projectId
required
integer | null
contactId
required
integer | null
status
required
string
Allowed values: draft sent partial paid voided
issueDate
required
string | null format: date-time
dueDate
required
string | null format: date-time
subtotal
required
string
taxAmount
required
string
total
required
string
amountPaid
required
string
balanceDue
required
string
notesToCustomer
required
string | null
createdAt
required
string format: date-time
updatedAt
required
string format: date-time
lineItems
Array<object>
object
id
required
integer
invoiceId
required
integer
description
required
string
quantity
required
string
unitPrice
required
string
amount
required
string
order
required
integer
meta
required
object
request_id

Server-generated request identifier

string
pagination
object
cursor
required

Opaque cursor for the next page; null when no more results

string | null
has_more
required

Whether more pages are available after this one

boolean
count
required

Items in this page

integer
Example
{
"data": {
"status": "draft"
}
}

Error

Media type application/problem+json
object
type
required

URL identifying the problem type

string format: uri
title
required

Short human-readable summary

string
status
required

HTTP status code

integer
detail

Human-readable explanation

string
request_id

Server-generated request identifier

string
errors

Validation error array (422 only)

Array<object>
object
field
required

Field path that failed validation

string
code
required

Validation error code

string
message
required

Human-readable validation message

string
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"request_id": "example",
"errors": [
{
"field": "example",
"code": "example",
"message": "example"
}
]
}

Error

Media type application/problem+json
object
type
required

URL identifying the problem type

string format: uri
title
required

Short human-readable summary

string
status
required

HTTP status code

integer
detail

Human-readable explanation

string
request_id

Server-generated request identifier

string
errors

Validation error array (422 only)

Array<object>
object
field
required

Field path that failed validation

string
code
required

Validation error code

string
message
required

Human-readable validation message

string
Example generated
{
"type": "https://example.com",
"title": "example",
"status": 1,
"detail": "example",
"request_id": "example",
"errors": [
{
"field": "example",
"code": "example",
"message": "example"
}
]
}