# Support tickets (/api-v2/support)



The support portal is a first-party ticketing surface. A project opens a ticket, exchanges a message thread with the Zumik team, and tracks status. The **SLA** - first-response target and whether the ticket jumps the queue - is derived from the project's billing plan, so a Pilot or Enterprise contract gets a faster, prioritized response. Support is available to every customer; the tier is what scales with the plan.

The console **Support** tab is the same API with a UI.

## SLA by plan [#sla-by-plan]

| Plan       | Tier       | First response                  | Priority queue |
| ---------- | ---------- | ------------------------------- | -------------- |
| Free       | community  | Best effort, community support  | —              |
| Base       | standard   | 1 business day                  | —              |
| Pilot      | priority   | 4 business hours                | Yes            |
| Enterprise | enterprise | 4 hours, 24/7 for urgent issues | Yes            |

The SLA is snapshotted onto the ticket at creation, so a later plan change doesn't retroactively weaken an open ticket's commitment.

## Open a ticket [#open-a-ticket]

```bash
curl https://api.zumik.ai/v2/support/tickets \
  -H "Authorization: Bearer $ZUMIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Streaming cuts off mid-response",
    "body": "When I set stream:true the connection drops after ~30s.",
    "priority": "high",
    "contact_email": "dev@acme.io"
  }'
```

`priority` is one of `low`, `normal` (default), `high`, `urgent`. `contact_email` is optional - the console prefills it from your session. The response is the full ticket, including its `sla` and the opening message:

```json
{
  "id": "spt_...",
  "object": "support_ticket",
  "subject": "Streaming cuts off mid-response",
  "priority": "high",
  "status": "open",
  "plan_tier": "enterprise",
  "sla": { "tier": "enterprise", "first_response_target": "4 hours, 24/7 for urgent issues", "priority_queue": true },
  "contact_email": "dev@acme.io",
  "messages": [
    { "id": "spm_...", "author": "customer", "body": "When I set stream:true ...", "created_at": "..." }
  ]
}
```

## Read and reply [#read-and-reply]

| Action       | Request                                  |
| ------------ | ---------------------------------------- |
| List tickets | `GET /v2/support/tickets`                |
| Get one      | `GET /v2/support/tickets/{id}`           |
| Reply        | `POST /v2/support/tickets/{id}/messages` |
| Set status   | `PATCH /v2/support/tickets/{id}`         |

A reply appends to the thread:

```bash
curl https://api.zumik.ai/v2/support/tickets/spt_.../messages \
  -H "Authorization: Bearer $ZUMIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Here is the full request body and a HAR file." }'
```

Replying to a `resolved` ticket reopens it. A `closed` ticket is final - open a new ticket instead.

`PATCH` sets the status to one of `open`, `pending`, `resolved`, or `closed`:

```bash
curl -X PATCH https://api.zumik.ai/v2/support/tickets/spt_... \
  -H "Authorization: Bearer $ZUMIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "resolved" }'
```

## Notifications and privacy [#notifications-and-privacy]

New ticket activity best-effort-notifies the Zumik team (a Resend email when configured, plus the shared ops webhook); a notification failure never fails your request. Tickets are scoped strictly to the owning project - you can never read another tenant's ticket. They carry contact emails and message bodies (personal data), so they are included in a [data export](/api-v2/data-rights) and erased by a deletion request.
