Modules

Work Orders

Repair and service jobs with status, delivery date, down payments and payments.

Overview

A work order (wo_...) is a job you do for a customer: a repair, an installation, a custom piece. It has a title, a total, a delivery date, an assignee and a status (pending, in_progress, ready, delivered, cancelled). Customers can leave a down payment and pay the rest on delivery. Optionally it carries a product whose stock goes out when the order is delivered.

Requires the Work orders module. An owner or admin turns it on in Settings > Modules. While it is off, every endpoint on this page returns 403 with type permission_error and code module_disabled.

Every {id} in the work order endpoints accepts the id (wo_...) or the order_number (for example WO-000057).

The Work Order Object

JSON
1{
2 "id": "wo_a1b2c3d4e5f6",
3 "object": "work_order",
4 "order_number": "WO-000057",
5 "title": "Screen replacement",
6 "status": "in_progress",
7 "customer_id": "cus_a1b2c3d4e5f6g7h8",
8 "customer": { "id": "cus_a1b2c3d4e5f6g7h8", "name": "Acme Corporation" },
9 "contact_name": "Acme Corporation",
10 "contact_phone": "+1-555-0100",
11 "item_id": null,
12 "warehouse_id": null,
13 "quantity": 1,
14 "document_date": "2026-10-11",
15 "delivery_date": "2026-10-18",
16 "assigned_to": "usr_a1b2c3d4e5f6",
17 "currency": "USD",
18 "total_amount": 180,
19 "paid_amount": 50,
20 "pending_amount": 130,
21 "overdue": false,
22 "customer_instructions": "Keep the original case",
23 "item_notes": null,
24 "work_notes": null,
25 "delivered_at": null,
26 "cancelled_at": null,
27 "cancellation_reason": null,
28 "created_at": "2026-10-11T15:30:00.000Z",
29 "updated_at": "2026-10-11T15:30:00.000Z",
30 "payments": [
31 {
32 "id": "wop_a1b2c3d4e5f6",
33 "object": "work_order_payment",
34 "work_order_id": "wo_a1b2c3d4e5f6",
35 "payment_date": "2026-10-11",
36 "amount": 50,
37 "payment_method": "cash",
38 "reference": null,
39 "notes": null,
40 "is_down_payment": true,
41 "invoice_id": null,
42 "created_at": "2026-10-11T15:30:00.000Z"
43 }
44 ]
45}

pending_amount = total_amount - paid_amount (never below 0). overdue is true for active orders whose delivery_date already passed in the company time zone. payments is included in single-object responses and omitted in lists.

Endpoints

MethodPathPermissionDescription
GET/v1/work-ordersreadList orders (status, customer_id, assigned_to, query)
POST/v1/work-orderswriteCreate an order, optionally with a down payment
GET/v1/work-orders/{id}readRetrieve an order with its payments
POST/v1/work-orders/{id}writeUpdate fields (not the status)
DELETE/v1/work-orders/{id}adminDelete an order without payments
POST/v1/work-orders/{id}/statuswriteChange the status
POST/v1/work-orders/{id}/record_paymentwriteRecord a payment
POST/v1/work-orders/{id}/cancelwriteCancel (optional reason)

Create a Work Order

1curl -X POST "https://api.corebill.io/v1/work-orders" \
2 -H "Authorization: Bearer sk_live_your_api_key" \
3 -H "Content-Type: application/json" \
4 -H "Idempotency-Key: wo-acme-screen" \
5 -d '{
6 "title": "Screen replacement",
7 "customer_id": "cus_a1b2c3d4e5f6g7h8",
8 "total_amount": 180,
9 "delivery_date": "2026-10-18",
10 "assigned_to": "usr_a1b2c3d4e5f6",
11 "customer_instructions": "Keep the original case",
12 "down_payment": 50,
13 "down_payment_method": "cash"
14 }'

Only title is required. contact_name and contact_phone default to the customer, document_date to today and delivery_date to the configured delivery days. A down_payment (up to the total) is recorded as the first payment with is_down_payment: true. Emits work_order.created and, with a down payment, work_order.payment_recorded.

Status and Delivery

1curl -X POST "https://api.corebill.io/v1/work-orders/WO-000057/status" \
2 -H "Authorization: Bearer sk_live_your_api_key" \
3 -H "Content-Type: application/json" \
4 -d '{ "status": "ready" }'
  • status accepts pending, in_progress, ready or delivered, from any status except cancelled. Sending the current status changes nothing
  • Moving to delivered takes the product out of stock (Inventory); leaving delivered returns it. Without stock and with negative stock disabled it fails with 400
  • Emits work_order.status_changed, plus work_order.delivered on delivery
  • To cancel use POST /v1/work-orders/{id}/cancel: not allowed for delivered orders or orders with payments

Record a Payment

1curl -X POST "https://api.corebill.io/v1/work-orders/WO-000057/record_payment" \
2 -H "Authorization: Bearer sk_live_your_api_key" \
3 -H "Content-Type: application/json" \
4 -H "Idempotency-Key: wo-57-final" \
5 -d '{ "amount": 130, "payment_method": "credit_card", "reference": "AUTH-4411" }'

amount can be up to pending_amount. Methods: cash (default), credit_card, debit_card, bank_transfer, wallet, check, other. With the Cash module on, a cash payment goes into the open cash session of the user who created the API key. Returns 201 with the updated order and emits work_order.payment_recorded.