Create ticket API

This article and the rest of the API documentation in this section are written for a technical audience — integrators and developers connecting external systems to Tickiti. Familiarity with HTTP, REST, JSON and bearer-token authentication is assumed.

The create ticket endpoint files a new ticket on behalf of a customer. Use it when an external system needs Tickiti to take ownership of a piece of work — for example a sales portal logging an enquiry, an order system creating a delivery exception ticket, or a CRM raising a contract review.

Endpoint

POST /api/v1/tickets

Headers

  1. Authorization: Bearer YOUR_TOKEN — required. Token must have the tickets:write ability.
  2. Idempotency-Key: <uuid> — required. See Idempotency.
  3. Content-Type: application/json — required.

Body

Required fields:

  1. originator_email_address — the email of the customer the ticket is filed for. Tickiti will create the user record if it does not exist.

You must provide exactly one of the following payload shapes:

  1. A) Subject + content: free-form text. Use when the integration writes its own subject and body.
  2. B) Template + data: render a Tickiti template by identifier with bound data. Use when content should follow a configured template.
  3. C) Intervention + data: drive a Tickiti intervention with bound data — the most expressive option. See Interventions guide.

Optional fields:

  1. data.queue_name — route to a non-default queue. Defaults to Inbox. Cannot be set for interventions (the intervention picks the queue).
  2. data.priority — "10" Low, "20" Normal, "30" High or "40" Urgent. Send it as a JSON string — an integer is rejected with 422. Omit to leave Tickiti’s default. An intervention configured to create urgent tickets overrides this.
  3. data.status — open (default), closed or on-hold.
  4. data.assigned_to_email — assign the ticket to a staff member as it is created. Defaults to Unassigned. An intervention that specifies an assignee overrides this.
  5. is_public — whether the first response is public (default true). Set false for staff-only initial tickets.
  6. use_passed_originator_as_responder — show the originator as the response author rather than the system account.

Example A — subject + content

curl -X POST https://support.sole-provider.example/api/v1/tickets \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "originator_email_address": "[email protected]",
    "data": {
      "queue_name": "Returns",
      "subject": "Carbon plate cracked on first marathon",
      "content": "The Vapor Pro 3 plate snapped at mile 14 of Berlin Marathon. Order SP-2412-0489."
    }
  }'

Example B — template + data

Render the warranty_acknowledgement template with order/customer data:

{
  "originator_email_address": "[email protected]",
  "template_identifier": "warranty_acknowledgement",
  "data": {
    "queue_name": "Returns",
    "order_reference": "SP-2412-0489",
    "product": "Vapor Pro 3",
    "customer_name": "Marcus Whitfield"
  }
}

Example C — intervention

Run the warranty_claim intervention. The intervention defines its own queue, templates and follow-up steps:

{
  "originator_email_address": "[email protected]",
  "intervention": "warranty_claim",
  "uid": "crm-claim-58221",
  "data": {
    "order_reference": "SP-2412-0489",
    "product": "Vapor Pro 3"
  }
}

Interventions are the recommended pattern for any workflow that recurs — see Interventions quick start.

Inline images

In the subject + content shape, embed an image in data.content as a base64 data URI — an <img src="data:image/png;base64,…"> element placed where the image should appear. Tickiti decodes it, stores it as an inline attachment, and rewrites the body to reference it, so it renders within the ticket.

Successful response

{
  "ok": true,
  "data": {
    "queue": "Returns",
    "used_template": false,
    "used_intervention": false,
    "used_private_template": false,
    "used_public_template": false
  }
}

The response confirms which queue the ticket landed in and which template / intervention path was taken. If you drive recurring workflows and need to correlate the new ticket back to your own system, use an intervention (payload shape C) with a uid — Tickiti carries the uid through the intervention’s epilog callbacks, which is the supported way to tie a Tickiti ticket to an external record. See Interventions technical reference.

Error responses

  1. 422 validation_failed — missing field, unknown queue, missing template/intervention.
  2. 409 idempotency_key_conflict — the idempotency key was already used with a different payload. See Idempotency.
  3. 401 unauthenticated — bad or missing token.
  4. 403 forbidden — token does not have the tickets:write ability, or the user it acts as lacks access to the target queue.

What happens server-side

  1. Tickiti finds or creates the user record for the originator email.
  2. It picks the queue: data.queue_name if provided, otherwise the queue named by the intervention or template, otherwise Inbox.
  3. It creates the ticket, applying data.status, data.priority and data.assigned_to_email where supplied — otherwise status Open, Tickiti’s default priority and Unassigned.
  4. It writes the first response (public or staff per is_public) using the chosen subject/content/template/intervention.
  5. It extracts any base64 data-URI images from the body, stores them as inline attachments, and rewrites the body to reference them.
  6. It dispatches the appropriate notification email to the originator (unless suppressed by the template configuration).