Workorders

Workorders

Automatically added from OpenAPI sync.

List workorders

GET /v1/workorders

A user (OAuth) without the right to view all workorders only sees the workorders he is responsible for or has hours on, like in the app. API keys see all workorders of the environment

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Query
Name Type Description
page integer
per_page integer
id string
client_id string
number string
date_from string
date_to string
due_date_from string
due_date_to string
created_from string
created_to string
search string
payment_status string Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.
sort string Sort field.
order string Sort direction.
Request body

None

Response
data array
id string
number string
title string
invoice_date string
due_date string
created_at string
subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
client_id string
payment_status string

Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.

Enum
open partial paid pending failed canceled expired authorized created chargeback refunded
paid_at string Nullable
sent_at string Nullable
project_number string Nullable
is_credit boolean
external_id string Nullable

Your reference, if set.

meta object
page integer
per_page integer
total integer
pages integer

Examples

GET /v1/workorders
curl -X GET "https://api.appficient.nl/v1/workorders" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json"

Curl, Node and response are shown to the right of this endpoint.

Create a workorder

POST /v1/workorders

Same body as create invoice. Like in the app, a workorder gets its workorder number (WB series) at once, also as a draft; it stays open (editable) until it is completed. A user who is not a member of the environment and may not view all workorders gets 403 forbidden (nothing is created): he could not see the new workorder. API keys are not affected. On `server_error` the result is unknown: do not retry before checking the list of workorders

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Headers
Name Type Description
Idempotency-Key string Optional. Replay within 24h returns the same response.
Request body
title string Required
client_id string
client_external_id string
invoice_date string
due_date string
external_id string

Your unique reference. Duplicate → `409`.

Example: inv-2026-00123
generation_mode string

`draft` (default) or `final`.

Enum
draft final
Example: draft
generate boolean

Shortcut for `final`.

rows array
name string
title string
quantity number
unit_price number
unit string
vat_rate string

VAT for this row — a `code` from `GET /v1/tax-rates` (e.g. `VAT21`, `VATINEU`, `VATNONE`) or a percentage (`21`, `21.00`, `9%`). Empty uses the environment default; an unknown value returns 422.

vat_code string

Alias of `vat_rate`.

subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
number string
payment_status string

`paid` registers a payment for the open amount, the same as marking the invoice paid in Appficient. Only on a final invoice; otherwise `422`. Other values record the provider status of an unpaid invoice; on a paid invoice they return `409 invoice_paid`. `partial` is derived from payments and cannot be set; on a partly paid invoice any non-`paid` value is returned as `partial`.

Enum
open paid pending failed canceled expired authorized created chargeback refunded
Response
data object

Document list item.

id string
number string
title string
invoice_date string
due_date string
created_at string
subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
client_id string
payment_status string

Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.

Enum
open partial paid pending failed canceled expired authorized created chargeback refunded
paid_at string Nullable
sent_at string Nullable
project_number string Nullable
is_credit boolean
external_id string Nullable

Your reference, if set.

rows array
name string
quantity number
unit string
unit_price number
vat_rate string
total_excl_vat number
total_incl_vat number
client_company_name string
client_firstname string
client_lastname string
web_url string
pdf_url string
source_id string Nullable

The document this one was created from (for example the quote of a workorder, or the workorder of an invoice); an invoice, quote, workorder or subscription id. `null` when it was not created from another document, when the source is a template or another document type the API does not return, or when the user may not see the source workorder.

meta object
generation_mode string

`draft` (default) or `final`.

Enum
draft final
Example: draft
pdf object
generated boolean
status string
message string Nullable
url string Nullable
payment_registered boolean

Only when `payment_status` was `paid`. `false` means the invoice was created but the payment could not be registered; its `payment_status` shows the actual state.

Examples

POST /v1/workorders
curl -X POST "https://api.appficient.nl/v1/workorders" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "00000000-0000-0000-0000-000000000001",
    "title": "Draft workorder",
    "generation_mode": "draft"
}'

Curl, Node and response are shown to the right of this endpoint.

Retrieve a workorder

GET /v1/workorders/{id}

`source_id` is the document the workorder was created from (for example a quote). A user (OAuth) without the right to view all workorders gets `404` for a workorder he is not responsible for and has no hours on, like in the app

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Request body

None

Response
data object

Document list item.

id string
number string
title string
invoice_date string
due_date string
created_at string
subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
client_id string
payment_status string

Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.

Enum
open partial paid pending failed canceled expired authorized created chargeback refunded
paid_at string Nullable
sent_at string Nullable
project_number string Nullable
is_credit boolean
external_id string Nullable

Your reference, if set.

rows array
name string
quantity number
unit string
unit_price number
vat_rate string
total_excl_vat number
total_incl_vat number
client_company_name string
client_firstname string
client_lastname string
web_url string
pdf_url string
source_id string Nullable

The document this one was created from (for example the quote of a workorder, or the workorder of an invoice); an invoice, quote, workorder or subscription id. `null` when it was not created from another document, when the source is a template or another document type the API does not return, or when the user may not see the source workorder.

meta object

Examples

GET /v1/workorders/{id}
curl -X GET "https://api.appficient.nl/v1/workorders/{id}" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json"

Curl, Node and response are shown to the right of this endpoint.

Update a workorder

PATCH /v1/workorders/{id}

Send at least one field. Only an open workorder can be changed: a completed or signed workorder gives `409` `workorder_locked`

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Request body
title string
invoice_date string
due_date string
payment_status string

`paid` registers a payment for the open amount, the same as marking the invoice paid in Appficient. Only on a final invoice; otherwise `422`. Other values record the provider status of an unpaid invoice; on a paid invoice they return `409 invoice_paid`. `partial` is derived from payments and cannot be set; on a partly paid invoice any non-`paid` value is returned as `partial`.

Enum
open paid pending failed canceled expired authorized created chargeback refunded
Response
data object

Document list item.

id string
number string
title string
invoice_date string
due_date string
created_at string
subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
client_id string
payment_status string

Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.

Enum
open partial paid pending failed canceled expired authorized created chargeback refunded
paid_at string Nullable
sent_at string Nullable
project_number string Nullable
is_credit boolean
external_id string Nullable

Your reference, if set.

rows array
name string
quantity number
unit string
unit_price number
vat_rate string
total_excl_vat number
total_incl_vat number
client_company_name string
client_firstname string
client_lastname string
web_url string
pdf_url string
source_id string Nullable

The document this one was created from (for example the quote of a workorder, or the workorder of an invoice); an invoice, quote, workorder or subscription id. `null` when it was not created from another document, when the source is a template or another document type the API does not return, or when the user may not see the source workorder.

meta object

Examples

PATCH /v1/workorders/{id}
curl -X PATCH "https://api.appficient.nl/v1/workorders/{id}" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "string",
    "invoice_date": "2026-07-01",
    "due_date": "2026-07-01",
    "payment_status": "open"
}'

Curl, Node and response are shown to the right of this endpoint.

Delete a workorder

DELETE /v1/workorders/{id}

Draft only

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Request body

None

Response

None

Examples

DELETE /v1/workorders/{id}
curl -X DELETE "https://api.appficient.nl/v1/workorders/{id}" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json"

Curl, Node and response are shown to the right of this endpoint.

Send a workorder

POST /v1/workorders/{id}/send

Same body and checks as sending an invoice. `send_type` is `workorder`. `404` when the id is not a workorder; `409` `workorder_draft` (no number yet) or `workorder_paid`. For a user the send right for workorders is required (`403`). The AI tool `workorders_send` (MCP) uses stricter rules: see the MCP section of the developer documentation

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Request body
to string Required

Every address must be a valid email address, otherwise `422` (`invalid_email`) and nothing is sent.

subject string Required
message string Required
cc string

Every address must be a valid email address, otherwise `422` (`invalid_email`) and nothing is sent.

send_type string

Email template for send. Allowed per endpoint: invoices `invoice` (default), `credit`, `invoice_rem1`-`3`; quotes `quote` (default), `quote_rem1`-`3`; workorders `workorder`. Another value gives `422` `invalid_value`.

Enum
invoice quote credit invoice_rem1 invoice_rem2 invoice_rem3 quote_rem1 quote_rem2 quote_rem3 workorder
Example: invoice
include_pdf boolean

With `true` the PDF is required; when it cannot be attached the send fails with `409` and nothing is sent.

Example: 1
reminder boolean

Only `true` when a reminder is asked for. The server then sends the reminder that is due for an invoice or quote that was sent before (`invoice_rem1`–`invoice_rem3`, `quote_rem1`). `409` `reminder_unavailable` when the document was never sent or has no reminder (credit invoice, workorder). On REST it cannot be combined with `send_type` (`422`).

Response
data object
success boolean
recipients array
recipients_list string
template boolean

Only via MCP. Always `true`; the official email template of the environment was sent.

send_type string

Only via MCP. The mail that was sent (`invoice`, `credit`, `invoice_rem1`–`invoice_rem3`, `quote`, `quote_rem1`, `workorder`).

subject string

Only via MCP. The subject of the mail that was sent.

meta object

Examples

POST /v1/workorders/{id}/send
curl -X POST "https://api.appficient.nl/v1/workorders/{id}/send" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "string",
    "cc": "string",
    "subject": "string",
    "message": "string",
    "send_type": "invoice",
    "include_pdf": true,
    "reminder": false
}'

Curl, Node and response are shown to the right of this endpoint.

Download workorder PDF

GET /v1/workorders/{id}/pdf
Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Request body

None

Response
data object
id string
pdf_url string
meta object

Examples

GET /v1/workorders/{id}/pdf
curl -X GET "https://api.appficient.nl/v1/workorders/{id}/pdf" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json"

Curl, Node and response are shown to the right of this endpoint.

Finalize a workorder

POST /v1/workorders/{id}/finalize

Turns a draft workorder into a final workorder: it gets its definitive number and PDF, exactly like generating it in Appficient. After this it can be sent

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Headers
Name Type Description
Idempotency-Key string Optional. Replay within 24h returns the same response.
Request body
invoice_date_mode string

`keep` keeps the invoice date of the draft; `today` sets the invoice date to today and recalculates the due date.

Enum
keep today
Example: keep
Response
data object

Document list item.

id string
number string
title string
invoice_date string
due_date string
created_at string
subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
client_id string
payment_status string

Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.

Enum
open partial paid pending failed canceled expired authorized created chargeback refunded
paid_at string Nullable
sent_at string Nullable
project_number string Nullable
is_credit boolean
external_id string Nullable

Your reference, if set.

rows array
name string
quantity number
unit string
unit_price number
vat_rate string
total_excl_vat number
total_incl_vat number
client_company_name string
client_firstname string
client_lastname string
web_url string
pdf_url string
source_id string Nullable

The document this one was created from (for example the quote of a workorder, or the workorder of an invoice); an invoice, quote, workorder or subscription id. `null` when it was not created from another document, when the source is a template or another document type the API does not return, or when the user may not see the source workorder.

meta object

Examples

POST /v1/workorders/{id}/finalize
curl -X POST "https://api.appficient.nl/v1/workorders/{id}/finalize" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "invoice_date_mode": "keep"
}'

Curl, Node and response are shown to the right of this endpoint.

Convert a workorder to an invoice

POST /v1/workorders/{id}/invoice

Creates a draft invoice from a completed workorder, like "Bill" in Appficient: the billable rows of the workorder, linked to their source rows, `source_id` is the workorder. The invoice is a draft without number; nothing is sent. The workorder becomes billed. Only a completed workorder that is not billed yet: `409` `workorder_not_completed`, or `409` `already_billed` with the existing invoice in `data.id` (use that invoice instead of creating a new one). While another request bills the same workorder, the call waits briefly and then gives `409` `busy`: try again in a moment. Returns the new invoice

Authorization: HTTP
name: httpBearer
type: http
scheme: bearer
Path
Name Type Description
id Required string
Headers
Name Type Description
Idempotency-Key string Optional. Replay within 24h returns the same response.
Request body

None

Response
data object

Document list item.

id string
number string
title string
invoice_date string
due_date string
created_at string
subtotal number
vat_rate number
vat_amount number
total_excl_vat number
total_incl_vat number
client_id string
payment_status string

Payment status of a document, the same as Appficient shows it: `paid` when the invoice is marked paid, `partial` when payments cover part of it, otherwise the last status from your payment provider (`pending`, `failed`, `canceled`, `expired`, `authorized`, `created`, `chargeback`, `refunded`) or `open`.

Enum
open partial paid pending failed canceled expired authorized created chargeback refunded
paid_at string Nullable
sent_at string Nullable
project_number string Nullable
is_credit boolean
external_id string Nullable

Your reference, if set.

rows array
name string
quantity number
unit string
unit_price number
vat_rate string
total_excl_vat number
total_incl_vat number
client_company_name string
client_firstname string
client_lastname string
web_url string
pdf_url string
source_id string Nullable

The document this one was created from (for example the quote of a workorder, or the workorder of an invoice); an invoice, quote, workorder or subscription id. `null` when it was not created from another document, when the source is a template or another document type the API does not return, or when the user may not see the source workorder.

meta object

Examples

POST /v1/workorders/{id}/invoice
curl -X POST "https://api.appficient.nl/v1/workorders/{id}/invoice" \
  -H "Authorization: Bearer apf_xxxxxxxx" \
  -H "Accept: application/json"

Curl, Node and response are shown to the right of this endpoint.