Link or unlink what an invoice bills
const url = 'https://app.buildworkpro.com/api/v1/invoices/1/billing-source';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"sourcePayAppId":1,"paymentTermInstallmentId":1,"sourceBidId":1,"dryRun":true}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://app.buildworkpro.com/api/v1/invoices/1/billing-source \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "sourcePayAppId": 1, "paymentTermInstallmentId": 1, "sourceBidId": 1, "dryRun": true }'Attach an existing invoice to the pay application, payment-schedule installment and/or bid it bills, or detach it (send null). Allowed in every status except voided, so an imported, manual or already-paid invoice can be linked after the fact; only the link columns and the derived sourceType change — never lines, totals or status — and nothing is pushed to QuickBooks. The pay app must be on the invoice’s own project, live (submitted, sent, approved or paid) and not already claimed by another live invoice; the installment must be on the project’s bid’s payment term and not billed by another live invoice. An invoice bills a pay app or an installment, not both. The response carries the project’s billed figures before and after; dryRun: true returns them without saving.
Authorizations
Section titled “ Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “ Path Parameters ”Header Parameters
Section titled “ Header Parameters ”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.
Request Body
Section titled “ Request Body ”object
Pay application this invoice bills (same project, submitted/sent/approved/paid, not claimed by another live invoice). null unlinks.
Payment-schedule installment this invoice bills (on the project’s bid’s payment term, not billed by another live invoice). null unlinks.
The project’s bid, printed on the invoice PDF. null unlinks.
Validate and return the billed-figure preview without saving.
Example generated
{ "sourcePayAppId": 1, "paymentTermInstallmentId": 1, "sourceBidId": 1, "dryRun": true}Responses
Section titled “ Responses ”Linked
object
object
object
object
object
object
object
object
object
Server-generated request identifier
object
Opaque cursor for the next page; null when no more results
Whether more pages are available after this one
Items in this page
Example
{ "data": { "invoice": { "status": "draft" }, "before": { "sourceType": "bid" }, "after": { "sourceType": "bid" } }}Error
object
URL identifying the problem type
Short human-readable summary
HTTP status code
Human-readable explanation
Server-generated request identifier
Validation error array (422 only)
object
Field path that failed validation
Validation error code
Human-readable validation message
Example generated
{ "type": "https://example.com", "title": "example", "status": 1, "detail": "example", "request_id": "example", "errors": [ { "field": "example", "code": "example", "message": "example" } ]}Error
object
URL identifying the problem type
Short human-readable summary
HTTP status code
Human-readable explanation
Server-generated request identifier
Validation error array (422 only)
object
Field path that failed validation
Validation error code
Human-readable validation message
Example generated
{ "type": "https://example.com", "title": "example", "status": 1, "detail": "example", "request_id": "example", "errors": [ { "field": "example", "code": "example", "message": "example" } ]}Error
object
URL identifying the problem type
Short human-readable summary
HTTP status code
Human-readable explanation
Server-generated request identifier
Validation error array (422 only)
object
Field path that failed validation
Validation error code
Human-readable validation message
Example generated
{ "type": "https://example.com", "title": "example", "status": 1, "detail": "example", "request_id": "example", "errors": [ { "field": "example", "code": "example", "message": "example" } ]}