Tickiti Intervention Integrator’s Guide

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.

1. Overview

Interventions are Tickiti’s building block for helpdesk and ticket workflow automation: they let an external system drive a structured, human-in-the-loop step inside a ticket.

1.1 What is an intervention?

An intervention in Tickiti is a ticket-based workflow step initiated by an external (remote) system. It creates a ticket in Tickiti that:

  1. Displays structured UI fields (defined in Tickiti, populated by the remote system’s data).
  2. Allows Tickiti staff to review / edit those fields and then accept (or otherwise act).
  3. Sends the final structured data back to the remote system via a remote epilog callback.
  4. Optionally records completion inside Tickiti and adds a “final” response on the ticket.

Think of interventions as: “remote system asks Tickiti to make a human decision, with a structured UI, and return a structured decision.”

1.2 When to use interventions

Typical examples:

  1. Discount request approval (remote commerce system asks staff to approve/adjust a discount).
  2. VAT / compliance checks (remote system wants staff to confirm a decision).
  3. Account details review (staff confirms or edits proposed values).
  4. Location or entitlement verification.

Interventions are most useful when:

  1. You need human decision-making / audit trail.
  2. You want the decision embedded in a ticket conversation.
  3. You need consistent UI + consistent remote callback behaviour.

2. User-facing workflow (high-level)

  1. Remote system detects an event that needs a human decision (e.g., “customer requested discount”).
  2. Remote system calls Tickiti Create Ticket API with an intervention name + uid + data bag.
  3. Tickiti creates/opens a ticket and posts intervention template responses:
  4. A staff/private response (required): {intervention}.private
  5. An optional public response: {intervention}.public
  6. Tickiti staff open the ticket and see:
  7. the normal ticket thread
  8. an Intervention panel with structured fields (checkbox/text/labels/etc).
  9. Staff updates fields and “Send” (ticket update).
  10. Tickiti posts the ticket update and also dispatches the InterventionTicketEpilogJob containing the intervention payload + response_id.
  11. Tickiti calls the remote system epilog endpoint with a concise payload: ticket_id, response_id, uid, intervention, action, data.
  12. Remote system processes it and (optionally) responds with a final object.
  13. Tickiti marks the intervention payload as accepted/completed and optionally posts a final response rendered from {intervention}.final.

3. Data model summary (Tickiti side)

3.1 Intervention definition (interventions table)

Each intervention is configured in Tickiti with:

  1. name (unique identifier / contract name)
  2. title (display)
  3. queue_name (where created tickets land)
  4. remote integration settings:
  5. remote_enabled
  6. remote_name
  7. remote_epilog_url
  8. remote_bearer_token
  9. remote_timeout_seconds
  10. notification flags:
  11. notify_inbox_managers
  12. fma_inbox_managers

3.2 Intervention UI fields (intervention_fields)

Each intervention has a fixed set of UI fields with:

  1. type: text | checkbox | label | hr
  2. name: field key (not used for label/hr)
  3. label: optional string, may contain token placeholders
  4. width_px: for text fields
  5. required: validation intent (Tickiti currently treats this as schema-level metadata)
  6. ordinal: field ordering

Token placeholders in labels (resolved from the remote data bag):

  1. Labels support tokens like <span class="font-mono">{{'{{currency}}'}}</span> which are resolved from the client data bag.

3.3 Intervention instances (intervention_payloads)

When an intervention ticket is created, Tickiti stores an InterventionPayload:

  1. ticket_id
  2. name (intervention name)
  3. uid (remote unique identifier used to correlate)
  4. accepted (boolean)
  5. payload (JSON string, contains the remote data bag and remote settings as needed)

This record is what the UI loads and what the remote epilog job references.

4. Remote integration: high-level contract

A remote system must implement:

  1. Create intervention ticket (call Tickiti API)
  2. Epilog endpoint (receive acceptance/update decision from Tickiti)

Optionally:

3. Return a final payload to Tickiti to mark completion + add a final ticket response.

5. Step-by-step technical integration

5.1 Authentication

Tickiti uses a bearer token (Sanctum personal access token style) for API access.

  1. The remote system stores a token issued by Tickiti.
  2. Tickiti stores a remote token for calling the remote epilog endpoint (separately).

There are two directions:

A) Remote → Tickiti (creating tickets)

Remote calls Tickiti with:

  1. Authorization: Bearer <tickiti_api_token>
  2. Idempotency-Key: <uuid>

Token abilities must include: create-ticket.

B) Tickiti → Remote (epilog callback)

Tickiti calls the remote epilog URL using:

  1. Authorization: Bearer <remote_bearer_token> (stored per intervention)

5.2 Creating an intervention ticket (Remote → Tickiti)

Endpoint (example):

  1. POST /api/create_ticket

Required headers:

  1. Authorization: Bearer <token>
  2. Idempotency-Key: <string>

Body shape (intervention mode):

{
"originator_email_address": "someone@client-system.example",
"intervention": "discount_request",
"uid": "remote-unique-id-123",
"data": {
"data": {
"currency": "GBP",
"order_price": 100,
"accept": false
},

"title": "Optional override title if used by your payload conventions"
}
}

Notes:

  1. intervention must exist in Tickiti’s interventions table.
  2. Tickiti requires {intervention}.private template to exist (public is optional).
  3. uid is required for interventions and is used to dedupe/reopen the same intervention ticket if resent.
  4. Remote should treat uid as immutable and globally unique per intervention instance.

Response:

Tickiti returns { ok: true, data: {... used_intervention flags ...} }.

5.3 How Tickiti renders the intervention UI

The intervention UI is built from:

  1. InterventionFields schema (from DB) to decide what controls to show
  2. InterventionPayload JSON to provide the data bag and any label tokens

Flow:

  1. Ticket loads interventions via Ticket::interventions():
  2. Finds unaccepted InterventionPayloads
  3. Loads the matching Intervention and its InterventionFields (ordered by ordinal)
  4. Decodes JSON payload and attaches title, accepted flag, ticket_id
  5. Resolves label tokens: {{token}} is replaced with values found in payload.data

The Vue component (Intervention.vue) renders:

  1. checkbox → binds to payload.data[field.name]
  2. text → binds to payload.data[field.name]
  3. label → rendered label only
  4. hr → divider

5.4 Submitting an intervention decision (Tickiti → Remote)

When a staff user posts a ticket update, the UI includes:

  1. interventions: [...] (array of intervention payload objects)
  2. This is passed to TicketUpdateController::update_actual.

At the end of update processing:

  1. Tickiti dispatches InterventionTicketEpilogJob for each submitted intervention.
  2. The job composes an outbound payload and POSTs it to the intervention’s remote_epilog_url.

Outbound epilog request payload

Tickiti sends something like:

{
"ticket_id": 12345,
"response_id": 67890,
"uid": "remote-unique-id-123",
"intervention": "discount_request",
"action": "submit",
"data": {
"currency": "GBP",
"order_price": 95,
"accept": true
}
}

Key points:

  1. uid is the remote correlation id.
  2. data is the structured decision data bag (what the UI edited).
  3. response_id identifies the Tickiti response that initiated the epilog call (useful for audit).

5.5 Remote epilog endpoint behaviour (what you must implement)

The remote system must implement an HTTP endpoint that:

  1. Verifies bearer token.
  2. Parses the payload.
  3. Locates the remote domain object using uid (or uses additional keys inside data if your design requires it).
  4. Applies business rules.
  5. Returns HTTP 200 JSON.
  6. Optionally returns a final object if Tickiti should mark completion and post a final message.

Minimum response:

{ "ok": true }

Response with completion (final)

If you return a final object, Tickiti will:

  1. append audit text to the initiating Tickiti response
  2. mark the intervention payload as accepted/completed
  3. optionally render {intervention}.final template into a new response

Example:

{
"ok": true,
"ticket_id": 12345,
"uid": "remote-unique-id-123",
"intervention": "discount_request",
"final": {
"response_id": 67890,
"ticket_audit": "Discount approved at 95 GBP, remote order updated: ORD-10021",
"remote_reference": "ORD-10021",
"applied_price": 95
}
}

Tickiti expects:

  1. ticket_id
  2. uid
  3. intervention
  4. final.response_id (must match ticket + initiating response)
  5. final.ticket_audit (string appended to Tickiti response audit trail)

6. Configuring an intervention in Tickiti

Interventions are configured in the InterventionLibrary settings page:

  1. Create intervention:
  2. name: contract name, used for templates {name}.private/public/final
  3. title
  4. queue_name
  5. notification flags
  6. Define UI fields:
  7. Add/edit/reorder fields
  8. Choose field types
  9. Set labels, including tokens like {{currency}}
  10. Set width for text fields
  11. Configure remote interface:
  12. remote_enabled
  13. remote_name (used when generating a token label)
  14. remote_epilog_url
  15. remote_timeout_seconds
  16. remote_bearer_token (stored securely, never displayed)
  17. Generate remote token (optional):
  18. Generates a new bearer token for the configured remote name
  19. Shows plaintext token once for copying

7. Templates used by interventions

Tickiti uses templates to render the ticket messages around the intervention:

  1. {name}.private (required)
  2. Staff-only content. Usually includes explanation, context, and may embed values from the data bag.
  3. {name}.public (optional)
  4. Public content shown to the requestor/customer. Often a sanitized summary.
  5. {name}.final (optional)
  6. Posted when the remote epilog returns final. Typically confirms what happened.

Template binding:

  1. On create_ticket: Tickiti calls setData($request->input('data')) for private/public.
  2. On completion: Tickiti calls setData(['final' => (array)$payload->final]) for final.

This means:

  1. Private/public templates usually read from data.* (remote bag).
  2. Final template usually reads from final.*.

8. Operational guidance and best practices

  1. Use idempotency: Always send Idempotency-Key on create_ticket so retries do not create duplicate tickets.
  2. Stable UID: Your uid should be stable and unique for the intervention instance. Use it as your primary correlation key.
  3. Keep the data bag minimal: Include only what Tickiti needs to render and what you need back on acceptance.
  4. Treat Tickiti as the UI/audit system: The remote system remains the source of truth for domain state.
  5. Return meaningful final.ticket_audit: This becomes part of the ticket record and is helpful for staff.

9. Quick reference

Required on Tickiti

  1. Intervention exists in DB
  2. Fields exist for UI
  3. {name}.private template exists
  4. Remote config set if remote callback required

Required on Remote

  1. API token to call Tickiti create_ticket
  2. Epilog endpoint that accepts Tickiti callback
  3. Correlation by uid