Docs

Tickets

API reference for tickets, ticket replies and technicians - raising, updating, replying to, resolving and closing tickets, and the time worked on them.

These endpoints need the Support area of the key's role. See Keys and permissions.

Tickets

EndpointDoes
GET tickets/read.phpLists tickets, or gets one
POST tickets/create.phpRaises a ticket
POST tickets/update.phpChanges a ticket
POST tickets/resolve.phpResolves a ticket
POST tickets/close.phpCloses a ticket

Tickets can't be deleted through the API.

Read

ParameterDoes
ticket_idJust this ticket, with its status's name and colour
client_idJust this client's tickets
limit, offsetPaging

The list has every ticket - new, open, resolved and closed. ticket_status is the status's number: 1 New, 2 Open, 3 On Hold, 4 Resolved and 5 Closed, then any you've added in Admin > Ticket Statuses.

curl -G https://itflow.example.com/api/v1/tickets/read.php \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "ticket_id=93"
{
  "success": "True",
  "count": 1,
  "data": [
    {
      "ticket_id": "93",
      "ticket_prefix": "TCK-",
      "ticket_number": "93",
      "ticket_source": "Email",
      "ticket_subject": "Site internet dropping intermittently",
      "ticket_priority": "High",
      "ticket_status": "2",
      "ticket_status_name": "Open",
      "ticket_billable": "1",
      "ticket_created_at": "2026-10-15 11:25:00",
      "ticket_resolution_due_at": "2026-10-15 19:25:00",
      "ticket_assigned_to": "1",
      "ticket_contact_id": "4",
      "ticket_asset_id": "1",
      "ticket_client_id": "1",
      "tags": [ { "tag_id": 116, "tag_name": "Waiting on Vendor", "tag_kind": "ticket", "tag_color": "#ffc107", "tag_icon": "hourglass-half" } ]
    }
  ]
}

ticket_id is the record's id, and what other endpoints take. ticket_prefix and ticket_number make the number people see, such as TCK-93.

Fields: ticket_id, ticket_prefix, ticket_number, ticket_source, ticket_category, ticket_subject, ticket_details, ticket_priority, ticket_status, ticket_sla_id, ticket_billable, ticket_schedule, ticket_onsite, ticket_vendor_ticket_number, ticket_feedback, ticket_url_key, ticket_created_at, ticket_updated_at, ticket_due_at, ticket_first_response_at, ticket_response_due_at, ticket_resolution_due_at, ticket_response_sla_met, ticket_resolution_sla_met, ticket_response_sla_alert_stage, ticket_resolution_sla_alert_stage, ticket_resolved_at, ticket_closed_at, ticket_archived_at, ticket_created_by, ticket_assigned_to, ticket_closed_by, ticket_vendor_id, ticket_client_id, ticket_contact_id, ticket_location_id, ticket_asset_id, ticket_quote_id, ticket_invoice_id, ticket_project_id, ticket_recurring_ticket_id, ticket_template_id, ticket_order, tags. With ticket_id, also its status's ticket_status_name, ticket_status_color, ticket_status_active, ticket_status_pauses_sla and ticket_status_order.

Create

FieldNotes
ticket_subjectRequired
client_idThe client. Leave it out for an internal ticket that isn't for any client.
ticket_detailsThe description. HTML is kept.
ticket_priorityLow, Medium, High or Urgent. Anything else is Medium.
ticket_contact_idWho it's for - one of the client's contacts. Leave it out for the client's primary contact.
ticket_asset_idOne of the client's assets
ticket_vendor_id, ticket_vendor_ticket_numberA vendor it's with - the client's or yours - and their reference for it
ticket_assigned_toAn active agent's technician_id. An assigned ticket starts Open, and an unassigned one starts New.
ticket_billable1 if the time on it is billable

A contact, asset or vendor that isn't the client's is left off. The ticket gets its number and SLA as any other ticket does, and its source is API. No email goes to the contact.

curl -X POST https://itflow.example.com/api/v1/tickets/create.php \
  -H "Content-Type: application/json" \
  -d '{"api_key": "YOUR_API_KEY", "client_id": 1, "ticket_subject": "Backup job failed on RDG-SRV-01", "ticket_details": "Veeam reported the 01:00 job failed: repository unreachable.", "ticket_priority": "High", "ticket_asset_id": 8}'
{ "success": "True", "count": "1", "data": [ { "insert_id": 1880 } ] }

Update

Send ticket_id, client_id (the ticket's own client), and any of the fields under Create apart from client_id. Only what you send changes, and a closed ticket can't be changed. To change a ticket's status, add a reply with ticket_status, or resolve or close it.

{ "api_key": "YOUR_API_KEY", "client_id": 1, "ticket_id": 1880, "ticket_assigned_to": 2, "ticket_priority": "Urgent" }

Resolve and close

Both take ticket_id and client_id, the ticket's own client.

  • Resolve sets the ticket to Resolved and records whether its resolution SLA was met. A ticket that hadn't had a first response gets one now.
  • Close resolves the ticket if it isn't already, then closes it, as the key's agent. A closed ticket can't be changed any more.

To say why when you resolve, add a reply with "ticket_status": 4 instead. See Replies.

Ticket replies

EndpointDoes
GET ticket_replies/read.phpLists replies, or gets one
POST ticket_replies/create.phpAdds a reply or note to a ticket

Read

ParameterDoes
ticket_reply_idJust this reply
ticket_idJust this ticket's replies, oldest first
typeInternal (notes), Public (replies to the client) or Client (the client's own replies)
include_archived1 to include archived replies
client_idJust replies on this client's tickets
limit, offsetPaging
{
  "success": "True",
  "count": 1,
  "data": [
    {
      "ticket_reply_id": "2553",
      "ticket_reply": "Repository share was offline after a NAS update. Remounted and re-ran the job - it completed.",
      "ticket_reply_type": "Internal",
      "ticket_reply_time_worked": "00:25:00",
      "ticket_reply_created_at": "2026-10-22 00:37:54",
      "ticket_reply_by": "1",
      "ticket_reply_by_name": "Alex Morgan",
      "ticket_reply_ticket_id": "1880",
      "ticket_prefix": "TCK-",
      "ticket_number": "1868",
      "ticket_subject": "Backup job failed on RDG-SRV-01",
      "ticket_client_id": "1"
    }
  ]
}

ticket_reply_by is an agent's id on Internal and Public replies, and a contact's id on Client replies. ticket_reply_by_name is their name either way.

Fields: ticket_reply_id, ticket_reply, ticket_reply_type, ticket_reply_time_worked, ticket_reply_created_at, ticket_reply_updated_at, ticket_reply_archived_at, ticket_reply_by, ticket_reply_by_name, ticket_reply_ticket_id, and the ticket's ticket_prefix, ticket_number, ticket_subject and ticket_client_id.

Create

FieldNotes
ticket_idRequired
ticket_replyRequired. HTML is kept.
ticket_reply_typeInternal, a note only your team sees - the default - or Public, which emails the contact and anyone watching, and counts as the first response
ticket_reply_time_workedTime to log, as HH:MM:SS. None if you leave it out.
ticket_statusAlso set the ticket's status, by number. 4 resolves it.
client_idThe ticket's client. Needed when the key's agent can see only some clients.

The reply is from the key's agent.

curl -X POST https://itflow.example.com/api/v1/ticket_replies/create.php \
  -H "Content-Type: application/json" \
  -d '{"api_key": "YOUR_API_KEY", "ticket_id": 1880, "ticket_reply": "Repository share was offline after a NAS update. Remounted and re-ran the job - it completed.", "ticket_reply_time_worked": "00:25:00", "ticket_status": 4}'

Technicians

EndpointDoes
GET technicians/read.phpLists your agents, with their role
GET technicians/time.phpTime worked, by ticket and technician

Read

ParameterDoes
technician_idJust this agent
archived1 to include archived agents
limit, offsetPaging
{
  "success": "True",
  "count": 1,
  "data": [
    { "technician_id": "2", "technician_name": "Jordan Lee", "technician_email": "jordan@summitit.example", "technician_status": "1", "role_id": "2", "role_name": "Technician", "role_is_admin": "0", "technician_created_at": "2026-10-21 19:41:45", "technician_archived_at": null }
  ]
}

technician_status is 1 for active and 0 for disabled. Passwords and sign-in details are never included. Use technician_id for ticket_assigned_to.

Time worked

ParameterDoes
yearThe year. This year if you leave it out.
month1 to 12. Every month of the year if you leave it out.
technician_idJust this agent's time
client_idJust time on this client's tickets
limit, offsetPaging

Each row is one technician's total on one ticket, from the time on their replies in that month or year. Tickets that aren't for a client are left out.

curl -G https://itflow.example.com/api/v1/technicians/time.php \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "year=2026" --data-urlencode "month=10"
{
  "success": "True",
  "count": 2,
  "data": [
    { "ticket_id": "1863", "ticket_number": "TCK-1863", "ticket_subject": "Backup job reporting failures overnight", "client_id": "20", "company": "Ashford Legal Services", "technician_id": "1", "technician": "Alex Morgan", "time_worked": "01:25:00" },
    { "ticket_id": "820", "ticket_number": "TCK-820", "ticket_subject": "Outlook stuck on disconnected after password reset", "client_id": "8", "company": "Aurora Wellness Center", "technician_id": "1", "technician": "Alex Morgan", "time_worked": "00:30:00" }
  ]
}
↑↓ to pickEnter to open