Files

3.1 KiB
Raw Permalink Blame History

Ticket Time Entries, Notes & Status Changes — Working Payloads

Verified request/response shapes for documenting work on tickets via scripts/cw_api.py.

Response shape normalization (do this FIRST in every script)

cw_api.cw_request returns (data, http_status) tuples, and list endpoints may wrap the payload one list deeper. Normalize before any .get() or loop, or scripts fail with AttributeError: 'tuple' object has no attribute 'get':

def norm(resp):
    data = resp[0] if isinstance(resp, tuple) and len(resp) == 2 else resp
    if isinstance(data, list) and data and isinstance(data[0], list):
        data = data[0]
    return [x for x in (data if isinstance(data, list) else [data]) if isinstance(x, dict)]

Create a time entry on a ticket

POST /time/entries. Convert local Pacific time to UTC by adding 7 hours (1:30–3:30 PM PDT → 20:30–22:30Z):

{
  "company": {"id": <companyId>},
  "member": {"id": 147},
  "chargeToId": <ticketId>,
  "chargeToType": "ServiceTicket",
  "locationId": 11,
  "businessUnitId": 1,
  "workType": {"id": 3},
  "workRole": {"id": 4},
  "timeStart": "<ISO UTC>",
  "timeEnd": "<ISO UTC>",
  "actualHours": 2.0,
  "billableOption": "Billable",
  "notes": "<work note text>",
  "addToDetailDescriptionFlag": true
}
  • addToDetailDescriptionFlag does NOT produce a ticket note on this instance — post the note separately if the text must appear on the ticket.
  • Verify with GET /time/entries/{id}: check member.identifier, timeStart/timeEnd, actualHours, and notes (top level; _info.notes only appears on the ticket timeEntries list view).
  • billableOption: "Billable" or "NoCharge".

Add a ticket note

POST /service/tickets/{id}/notes:

{
  "text": "<note text>",
  "detailDescriptionFlag": true,
  "internalAnalysisFlag": false,
  "resolutionFlag": false
}
  • Do NOT include customerVisibleFlag (or any field not on ServiceNote) — the API 400s the entire request: "Could not find member 'customerVisibleFlag' on object of type 'ServiceNote'".
  • Notes are attributed to the API member (TinMan), not an arbitrary author.
  • Verify with GET /service/tickets/{id}/notes.

Change ticket status

  1. Resolve the numeric status ID: GET /service/boards/{boardId}/statuses, match on name (VistaNet Help Desk board = 1; "In Progress" = id 1; names starting with > are closed-type statuses).
  2. PATCH /service/tickets/{id} with a JSON Patch ARRAY:
[{"op": "replace", "path": "status/id", "value": 1}]
  1. Verify: GET /service/tickets/{id}?fields=id,status.

Documentation audit of a scheduled day

# UTC bounds: Pacific day 00:00–24:00 PDT → add 7 hours
params = {"conditions": f"member/id={memberId} AND dateStart >= [{startUtc}] AND dateStart <= [{endUtc}]",
          "pageSize": 100}
entries = norm(cw_api.cw_request("GET", "schedule/entries", params=params))
# per entry: objectId = ticket id → GET /service/tickets/{id}/notes AND /service/tickets/{id}/timeEntries
# count only notes where note["member"]["identifier"] matches the member — time entries do NOT count as notes
# report per ticket: notes present / time-entry-only / nothing