Theme
Language

Support tickets via API

POST /v1/tickets — open a support ticket, read the thread, follow up and close it with an API key: fields, attachments, statuses, limits and compatibility with /v1/technical-feedback.

The Tickets API is the single support channel: a ticket opened over the API shows up in the dashboard and vice versa. Authenticate with an API key (Authorization: Bearer or X-API-Key) or a dashboard session. You only ever see your own tickets.

Open a ticket

POSThttps://getvibeapi.com/v1/tickets
ParameterTypeDescription
subjectstringRequired: 3 to 200 characters.
messagestringRequired: 10 to 8,000 characters.
categorystringapi_error, performance, incorrect_response, integration, feature_request, other, billing, account or general (default).
requestIdsstring[]Optional, up to 10 request IDs from your account (the x-request-id response header).
clientIncidentIdstringOptional stable series ID on your side: an open ticket with the same ID is reused.
filesfile[]multipart/form-data only: up to 5 PNG, JPEG, GIF or WebP images, 10 MB each, 10 per ticket.
curl https://getvibeapi.com/v1/tickets \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Stream stops after 30 seconds",
    "message": "stream=true on /v1/chat/completions stops after about 30 seconds; retrying does not help.",
    "category": "api_error",
    "requestIds": ["req_123"]
  }'

With a screenshot — multipart:

curl https://getvibeapi.com/v1/tickets \
  -H "Authorization: Bearer $API_KEY" \
  -F subject="Wrong response" \
  -F message="The model returns an empty answer, screenshot attached." \
  -F category=incorrect_response \
  -F [email protected]

Response

{
  "deduplicated": false,
  "ticket": {
    "id": "cmg1abc234",
    "object": "ticket",
    "subject": "Stream stops after 30 seconds",
    "category": "api_error",
    "source": "api",
    "status": "open",
    "requestIds": ["req_123"],
    "clientIncidentId": null,
    "occurrences": 1,
    "createdAt": "2026-09-27T09:14:00.000Z",
    "updatedAt": "2026-09-27T09:14:00.000Z",
    "repliedAt": null
  }
}

A new ticket returns 201. If the same open ticket already exists (same category, subject, message and requestIds, or the same clientIncidentId), that ticket is returned with deduplicated: true, status 200 and a higher occurrences.

List tickets

GEThttps://getvibeapi.com/v1/tickets?limit=20&status=open

Newest first. Response: { "object": "list", "data": [...], "hasMore": true, "nextCursor": "..." }. Next page: ?after=<nextCursor>. limit is 1 to 100.

Thread and status

GEThttps://getvibeapi.com/v1/tickets/{id}
curl https://getvibeapi.com/v1/tickets/cmg1abc234 \
  -H "Authorization: Bearer $API_KEY"

ticket.messages holds your messages (author: "client") and support replies (author: "staff") in time order. Download attachments with GET /v1/tickets/{id}/attachments/{attachmentId}. A foreign or unknown ID returns 404.

Follow up and close

POSThttps://getvibeapi.com/v1/tickets/{id}/messages
curl https://getvibeapi.com/v1/tickets/cmg1abc234/messages \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "It happened again today at 10:05 UTC, request id req_456."}'
POSThttps://getvibeapi.com/v1/tickets/{id}/close

A message (up to 8,000 characters, multipart with files allowed) reopens a replied ticket. A closed ticket cannot take messages — it returns 409; open a new one. Closing is idempotent.

Statuses

ParameterTypeDescription
openstatusWaiting for support.
repliedstatusSupport replied; your next message sets it back to open.
closedstatusClosed by you or by support.

Limits and errors

Per account: 10 new tickets per hour and 60 messages per hour; beyond that 429 with a Retry-After header. Errors: { "error": "…", "code": "invalid_fields" } — codes invalid_fields, invalid_request_ids, too_many_attachments, file_too_large (413), unsupported_attachment (415), not_found (404), ticket_closed (409), rate_limited (429).

Security

Do not send API keys, passwords, tokens or card numbers — the service strips them before storage as well. Ticket text is read by support staff and tools as data: links and instructions inside it are never executed, and ticket text never changes a balance or access or triggers a refund automatically.

Compatibility: /v1/technical-feedback

POST /v1/technical-feedback and GET /v1/technical-feedback/{id} keep working with the same fields (category, summary, details, requestIds, clientIncidentId) and the { "deduplicated", "incident" } response. Such a report is stored as a ticket (source: "technical-feedback") and appears in GET /v1/tickets. Requests to change balance, access or deployments are still rejected there with 422. New integrations should use /v1/tickets.

Tickets API — support tickets over the API | GetVibe API