Jobs
Create and manage service jobs (instore, offsite, or remote)
Jobs are the work you do for a customer — repairs, installations, on-site visits. A job links a customer to a scheduled time window, an optional technician, and a service location.
Naming note
Jobs are exposed under the /tickets collection. The Servicebay mobile and
web apps use the term ticket internally; both terms refer to the same
resource. The endpoint paths below all begin with /tickets.
Endpoints
- GET
/organisations/{orgId}/tickets— List jobs (paginated) - POST
/organisations/{orgId}/tickets— Create job - GET
/organisations/{orgId}/tickets/{ticketId}— Get job - PUT
/organisations/{orgId}/tickets/{ticketId}— Update job - DELETE
/organisations/{orgId}/tickets/{ticketId}— Delete job - GET
/organisations/{orgId}/tickets/{ticketId}/services/ POST/organisations/{orgId}/tickets/{ticketId}/services - GET
/organisations/{orgId}/tickets/{ticketId}/inventory/ POST/organisations/{orgId}/tickets/{ticketId}/inventory - GET
/organisations/{orgId}/tickets/{ticketId}/discount/ PUT/organisations/{orgId}/tickets/{ticketId}/discount/ DELETE/organisations/{orgId}/tickets/{ticketId}/discount -
GET
/organisations/{orgId}/tickets/{ticketId}/totals - GET
/organisations/{orgId}/tickets/{ticketId}/signature/ PUT/organisations/{orgId}/tickets/{ticketId}/signature(no DELETE — signatures are never deleted) - Messages: Messages
Required scopes: tickets:read / tickets:write / tickets:delete.
Line-item and discount DELETE use tickets:write (v2 write does not
include delete of the job itself).
List supports filtering by status, customerId, and assignedTechnician,
ordered by timestamp descending. discount is
{ "isPercentage": boolean, "value": number }.
Service location
When creating or updating a job, set serviceLocation to one of:
| Value | Meaning |
|---|---|
instore | Job performed at the business premises |
offsite | Job performed at the customer's address |
remote | Job performed remotely (no physical location) |
Combined with customerId, serviceTime, and endTime, this is everything an
external intake form needs to book a job after a customer-lookup match.
Status
status is optional on create. If omitted, the job is created in the
organisation's lowest-index status (there is no implicit "Open"). If
provided, it must match an existing job status (400 with
Unknown job status '{status}' — no code). Jobs cannot be created
in a start- or completion-gated status (409 FORM_GATE_CREATE).
Moving into a gated status with outstanding forms returns 409
FORM_GATE_TRANSITION with {gate, outstanding}. Delete requires all
three form counters <= 0 (409 FORM_GATE_DELETE).
Changing status, assignedTechnician, or stationId writes a system
timeline message (status_update / assignment_update / station_update).
Calendar sync
Creating or updating a job through the API keeps the organisation calendar in sync — the same behaviour as the Servicebay mobile app.
Automatic calendar events
When both serviceTime and endTime are set, the API upserts one
calendar event linked to the job (ticketId).
Clearing serviceTime removes linked events. Setting only serviceTime
without endTime does not create an event. Deleting a job removes its linked
events too.
You do not need a separate calendar call for the standard book-a-job flow —
POST the job with customer, location, and time window. On create, the
calendar upsert runs in after() so the event appears shortly after the
201 (a failed-then-retried POST must not allocate a second ticket id).
Update sync is inline (a failure is 500).
Standalone calendar events
Use the calendar endpoints directly when you need events that are not tied to a job (internal reminders, blocked-out slots, etc.).
Machine-readable version: OpenAPI spec.