Cases API
Create, manage, and comment on cases programmatically, and log time against them — with a pointer to the interactive API reference for the full spec.
Cases API
The Cases API lets you create and manage cases programmatically — assign them to a user, link them to a device and customer, add comments, track every change in a built-in audit history, and log time spent as time entries.
Cases are addressed under the /api/tickets path — "ticket" is the platform's internal name for a case — and time entries under /api/time-entries.
Authentication and permissions
Every request needs a valid bearer token in the Authorization header — see API Authentication. Reading cases requires the tickets.view permission; creating, updating, commenting, and deleting them require tickets.manage. Time entries follow their own permission split — see Time entries below.
What you can do
- List, search, and read cases, including their comments and audit history.
- Create a case and assign it to a user, device, or customer.
- Update a case — every change is recorded in its history automatically.
- Add comments.
- Delete a case (permanent — the case and its history cannot be recovered).
- Log, link, annotate, and list time entries against a case.
Worth knowing before you call it
- The linked device decides the customer. When a case is linked to a device, its customer is always taken from that device — any customer you send in the same request is ignored.
- Updates wrap each value. Each updatable field is sent as
{ "hasValue": true, "value": … }; to leave a field unchanged, omit it entirely. Only wrapped fields are applied. - Status and priority are fixed sets — for example
Open,InProgress, andClosedfor status, andLowthroughCriticalfor priority.
Bulk actions
These endpoints require user authentication and tickets.manage:
POST /api/tickets/bulk-close
POST /api/time-entries/manual/bulk
Both accept 1 to 100 IDs per request and process duplicate IDs only once. If any case is missing or inaccessible, the entire request is rejected with 404 without making changes. An empty or oversized selection returns 400.
For bulk time entries, endedAt must follow startedAt. Each entry belongs to the calling user and the corresponding case's customer, has status Closed, and has no device or site assignment. The same period and note are copied to every case; the duration is not divided. Repeating a successful request creates additional entries — after an uncertain response, check existing entries before retrying.
Comments and audit history
Adding a comment requires the tickets.manage permission. Each comment is appended to the case's comments array and also recorded as a history entry.
A comment can also come from the person sitting at a managed device — the octoja agent posts it on their behalf, authenticated as the device rather than as a user. Those comments carry createdByAssetId, createdByDeviceName, and createdByDisplayName in place of createdByUserId.
Every case carries a history array (full case shape only) whose changeType tells you what happened: Created when the case was opened, FieldChanged for an edited field (with fieldName, oldValue, and newValue set), StatusChanged for a status transition, and Comment for an added comment.
Time entries
Time entries record effort against a case. They live under /api/time-entries, and a case keeps its tracked time as a separate collection of entries rather than a field on the case object. An entry can be linked to a device, to a case, or to both. An entry linked to a case with no device is a case-only entry. A few behaviours and validations are not visible in the schema:
- Permissions split — creating a manual entry requires
tickets.manage. Listing entries requires user authentication and returns only entries within your access scope. Linking, updating the note, and deleting an entry are scoped to the user who owns the entry: the caller must be authenticated as that user. - Manual entries are created as
Closed— and the end (endedAt) must be after the start (startedAt). OmittingassetId(or sending it asnull) makes a case-only entry. - Note updates need an open entry —
PUT /api/time-entries/{id}/notereturns410 Gonewhen the entry is already closed. - Deleting needs an open entry —
DELETE /api/time-entries/{id}returns400 Bad Requestwhen the entry is no longerOpen. Manual entries are createdClosed, so deletion applies to an entry whose timer is still running. - Unlinking keeps the entry — sending
nulltoPUT /api/time-entries/{id}/ticketleaves the entry on its device but no longer counts it toward any case. - List a case's entries with the general endpoint — use
GET /api/time-entries?ticketId=<case-id>. It returns{ items, total, totalDurationSeconds }. See Time Entries API for filters, pagination, and the scope of the duration total.
Fields worth knowing
The full case, comment, and time-entry objects are documented field-by-field in Swagger. A few fields carry meaning that is easy to miss:
status— a case isOpen,InProgress, orClosed; a time entry isOpen,Closed, orAutoClosed.priority— one ofLow,Medium,High, orCritical.displayIdvsticketNumber—ticketNumberis the raw sequential number;displayIdis its human-friendly form, such as#42.createdBySystemand the creator fields —createdBySystemistruewhen octoja opened the case automatically. Otherwise the case was opened either by a user (createdByUserIdandcreatedByUserNameare set) or by the person sitting at a managed device, in which casecreatedByUserIdisnullandcreatedByAssetId,createdByDeviceName, andcreatedByDisplayNamename the device and the person instead. These three creator fields appear on the full case and on each comment.- List shape vs full shape — the list endpoint omits
description,comments, andhistory, and addscommentCountandlastCommentAt(the number of comments and the timestamp of the most recent one). CallGET /api/tickets/{id}for the full case.
Full endpoint reference
For the exact endpoints, query parameters, request bodies, and response fields — generated from the running platform, so it never goes out of date — use octoja's interactive API reference. See API Design Principles for how to open it.
Related articles
Was this helpful?
More in API Reference
API AuthenticationAPI Design PrinciplesError CodesAbout APIStill need help? Ask the team