Home/ Docs

Docs.

The integration surface you'll touch as a customer — webhooks, the events we emit, transcript schema, and how to wire the agent into your own stack. Sparse on purpose; we write the integration for you.

Overview

You don't have to write code to use a Triage Agent — we wire the integration on the way in. These docs are here for the moments when your team wants to: receive events into a custom CRM, replay a transcript into a downstream system, or sign requests we send you. Everything below assumes you already have an agent in production.

i

If you're reading this before signing up, you don't need to — send us your script and we'll handle the rest. These docs become useful around week three, when your team wants to plug the agent into something we didn't already build.

Quick start

Two-minute orientation. There are three primitives:

  • An agent — a configured voice persona, attached to one phone number, running one script.
  • An event — a structured fact emitted as the call progresses (call.answered, intent.captured, call.ended, …).
  • A handover — the agent's way of saying "this needs a human" (warm transfer, SMS, escalation page).

You consume events by giving us a single webhook URL. We POST every event there with an HMAC signature. That's the whole surface.

Set a webhook in the console

# in our dashboard:
Console → Agents → [your agent] → Webhooks
  └─ Endpoint: https://api.your-domain.com/triage/events
  └─ Signing secret: whsec_••••••••

Verify the signature in your handler

const crypto = require('crypto');

app.post('/triage/events', (req, res) => {
  const sig    = req.headers['x-triage-signature'];
  const body   = req.rawBody; // preserve raw bytes
  const digest = crypto
    .createHmac('sha256', process.env.TRIAGE_SECRET)
    .update(body)
    .digest('hex');

  if (digest !== sig) return res.status(401).end();

  const event = JSON.parse(body);
  // event.type === 'call.ended', etc.
  res.status(200).end();
});

You only need to handle the events you care about. The most common are call.ended (write a row in your CRM) and handover.requested (page a human).

Core concepts

Agents are not personas

One agent = one phone number, one script, one set of integrations. If you want a second persona on the same number (e.g. an after-hours flavour), that's still one agent — the persona is part of the script's branching.

Events are at-least-once

We retry failed deliveries with exponential backoff for 24 hours. Every event carries a unique id; deduplicate on it. We will never silently drop an event.

Transcripts are immutable

Once a call ends, the transcript is sealed. You can request a recording delete; the transcript still exists as a row in your account (with content nulled) for audit.

Sending events to us

Most teams don't send us events — we mostly consume them out the other end. If you do need to push state in (e.g. a customer's appointment cancelled while they were on the line), use POST /v1/context:

POST
/v1/agents/{agent_id}/context
curl https://api.triageagents.com.au/v1/agents/agt_abc/context \
  -H "Authorization: Bearer $TRIAGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key": "appointment.next", "value": "2026-05-30T11:00:00Z"}'

Receiving events

POST
[your endpoint]
{
  "id": "evt_01HQ8E5R...",
  "type": "call.ended",
  "created_at": "2026-05-26T04:58:12.310Z",
  "agent_id": "agt_abc",
  "call_id": "call_01HQ...",
  "data": {
    "duration_sec": 214,
    "caller_number": "+61421555882",
    "outcome": "booked",
    "booking_ref": "BK-08214",
    "transcript_url": "https://..."
  }
}

Request signing

Every request we POST to your endpoint carries:

  • X-Triage-Signature — HMAC-SHA256 of the raw request body, hex-encoded.
  • X-Triage-Timestamp — Unix ms when we generated the signature.
  • X-Triage-Event-Id — same as event.id in the body; use for dedup.

Reject requests where the timestamp is more than 5 minutes old.

Event types

Eight events cover ~95% of integrations. They emit in order, once per call:

  • call.answered — agent picked up.
  • call.identified — caller matched to a record (CRM, customer DB) when possible.
  • intent.captured — the agent has classified what the call is about.
  • field.extracted — emitted per field the agent fills (name, callback, symptom, etc.). May fire many times.
  • handover.requested — agent decided a human is needed; warm transfer / SMS in flight.
  • action.executed — a tool call was run (booking, ticket, notification). Includes the target system.
  • call.ended — call closed, transcript URL provided.
  • call.failed — call did not complete (carrier issue, abandoned, etc.).

Transcript schema

Transcripts are JSON files at the URL provided in call.ended.data.transcript_url. URLs are short-lived (1 hour) — fetch and store the body if you need to retain it.

{
  "call_id": "call_01HQ...",
  "agent_id": "agt_abc",
  "turns": [
    {
      "role": "agent",
      "text": "Good evening, you've reached...",
      "start_ms": 0, "end_ms": 2840
    },
    {
      "role": "caller",
      "text": "Hi, it's Carla, calling about...",
      "start_ms": 3120, "end_ms": 7340,
      "sentiment": "anxious"
    }
  ],
  "fields": { "name": "Carla N.", "postcode": "2031" }
}

Phone numbers

We provision numbers on your behalf, or port your existing number in. From your side they look like ordinary +61 numbers — there's no special configuration in your phone system. We handle:

  • Number provisioning & carrier paperwork (porting takes 3–10 business days)
  • SIP trunk into your PBX if you have one (Genesys, 3CX, Cisco, Asterisk)
  • Fallback to your human queue if the agent is unhealthy
  • Caller ID presentation (your business name, not "Unknown")

Integration catalog

~140 integrations are live in the studio. Anything with a public API can be wired up — these are the ones we've shipped most often.

Twilio
Cliniko
ServiceM8
HubSpot
Salesforce
Genesys
Zendesk
Halaxy
Xero
Calendly
Slack
Custom webhook

Monitoring & logs

Every call is observable in your console: live waveform, agent state, tool calls, integration responses. Export to your own logging stack via:

  • Datadog — we ship custom metrics on a tag per agent.
  • OpenTelemetry — OTLP endpoint, every call as a trace.
  • S3 — daily JSONL export of all events, your bucket.

Security & data

Recordings are encrypted at rest (AES-256) and in transit (TLS 1.3). Transcripts are PII-scrubbed at write time for non-clinical accounts. Retention is configurable from "never store" to "keep forever (audit)".

!

For regulated workloads (clinical, financial), enable strict mode in the console: bring-your-own KMS, IP allowlist on the agent's egress, no recording stored at our end.

SLA & status

Live status, incident history, and SLA credits are at status.triageagents.com.au. Studio tier carries 99.9% in-call uptime; Enterprise 99.96%. Both measured monthly, with auto-applied credits.