Tickets
The helpdesk endpoints cover support areas (the departments tickets are routed
to) and the tickets themselves, including every action an agent can take.
All paths below are relative to https://api-v1.zingasuite.com/papi/v1.
Support areas
A support area (Billing, Technical, Installation…) carries the SLA clocks, the
default priority and the escalation ceiling for its tickets.
| Method | Path | Purpose |
|---|---|---|
GET |
/solve/support-domains |
List support areas |
POST |
/solve/support-domains |
Create one |
PATCH |
/solve/support-domains/{id} |
Update one |
DELETE |
/solve/support-domains/{id} |
Delete one |
curl -X POST https://api-v1.zingasuite.com/papi/v1/solve/support-domains \
-H "Authorization: Bearer zk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Technical",
"defaultPriority": "high",
"slaResponseMinutes": 60,
"slaResolutionMinutes": 480,
"maxLevel": 3
}'
defaultPriority is low, normal, high or urgent. maxLevel (1–5) caps
escalation. PATCH is a partial update — only the fields you send change.
Deleting an area keeps its tickets and their history — they fall back to the
entity-level SLA defaults.
Use a support area id as domainId when opening a ticket.
Listing tickets
GET /solve/tickets
| Parameter | Purpose |
|---|---|
status |
A ticket status, or open_active for everything not resolved/closed |
domainId |
One support area |
assigneeUserId |
A user id, or unassigned for the queue |
priority |
low | normal | high | urgent |
q |
Subject substring, or an exact ticket number |
limit / offset |
Paging (default 50) |
Statuses are open, pending, on_hold, resolved, closed. Results are
ordered by last activity, newest first, and wrapped in the standard
{data, total, limit, offset} envelope.
curl "https://api-v1.zingasuite.com/papi/v1/solve/tickets?status=open_active&assigneeUserId=unassigned" \
-H "Authorization: Bearer zk_live_xxx"
Opening a ticket
curl -X POST https://api-v1.zingasuite.com/papi/v1/solve/tickets \
-H "Authorization: Bearer zk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"subject": "Pump trips on start-up",
"description": "Unit 4 trips the breaker two seconds after start.",
"domainId": "<support-area-id>",
"priority": "high",
"requesterContactId": "<contact-id>"
}'
Opening a ticket runs the full intake path: it is numbered, its SLA due times are
computed from the support area, it is auto-assigned to the best available agent
at level 1, a created event is logged, and the requester is emailed (when the
contact has an address). source defaults to api; priority defaults to the
area's default.
requesterContactId links the ticket to a contact in the shared contact spine,
which is what puts it on that customer's timeline.
Reading a ticket
GET /solve/tickets/{id}
Returns the ticket fields plus:
events— the append-only timeline (created, assigned, status/priority/domain
changes, escalations, notes), withisInternaldistinguishing agent-only notes.messages— the conversation thread, when the ticket has one.
Updating a ticket
PATCH /solve/tickets/{id}
Accepts subject, status, priority and domainId. Each change is logged to
the timeline. Two behaviours worth knowing:
- Setting
statustoresolvedorclosedstamps the resolution time and stops
the SLA clock; reopening increments the reopen count. - Changing
domainIdrecomputes the SLA against the new area (already-recorded
breaches stay) and re-runs auto-assignment.
Actions
| Method | Path | Effect |
|---|---|---|
POST |
/solve/tickets/{id}/assign |
Assign to userId, or omit it to let routing pick |
POST |
/solve/tickets/{id}/escalate |
Raise the level and hand to a higher-expertise agent |
POST |
/solve/tickets/{id}/notes |
Append a timeline note |
POST |
/solve/tickets/{id}/reply |
Send an agent reply into the ticket's conversation |
# Let routing choose the best available agent
curl -X POST https://api-v1.zingasuite.com/papi/v1/solve/tickets/<id>/assign \
-H "Authorization: Bearer zk_live_xxx" -H "Content-Type: application/json" -d '{}'
# Escalate two levels with a reason
curl -X POST https://api-v1.zingasuite.com/papi/v1/solve/tickets/<id>/escalate \
-H "Authorization: Bearer zk_live_xxx" -H "Content-Type: application/json" \
-d '{"toLevel": 3, "reason": "Needs a field engineer"}'
# Internal note (invisible to the customer)
curl -X POST https://api-v1.zingasuite.com/papi/v1/solve/tickets/<id>/notes \
-H "Authorization: Bearer zk_live_xxx" -H "Content-Type: application/json" \
-d '{"note": "Spare part ordered, ETA Friday", "isInternal": true}'
Escalation caps at the area's maxLevel; an attempt at the ceiling is still
recorded on the timeline so the history shows it. Notes are internal unless you
pass isInternal: false.
A reply returns 202 Accepted and is queued for delivery — the requester's chat
widget and the shared inbox both pick it up. A ticket with no conversation thread
(for example one you opened via the API without a chat) returns
400 no_conversation; use a note, or reply from the console once a thread exists.