> ## Documentation Index
> Fetch the complete documentation index at: https://docs.telzino.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payloads

> Nested and flat event formats

Every message has the same envelope. Pick the format per endpoint.

## Nested (default)

```json theme={null}
{
  "event_id": "evt_6f9c2c1e-…",
  "event_type": "account.first_agent_created",
  "api_version": "1",
  "occurred_at": "2026-10-13T09:41:07Z",
  "test": false,
  "partner_id": "a1b2…", "reseller_id": "b2c3…", "org_id": "c3d4…", "agent_id": "d4e5…",
  "account": {
    "account_id": "a1b2…", "email": "jane@acme.example", "first_name": "Jane",
    "company_name": "Acme VoIP", "pbx_type": "netsapiens", "is_test_account": false,
    "last_call_at": "2026-10-13T09:12:44Z"
  },
  "data": { "agent_name": "Front Desk", "agent_extension": "7001" }
}
```

## Flat

Every field at the top level — easiest for low-code tools such as GoHighLevel. `event` carries the event's flat name (see [Events](https://docs.telzino.com/event-webhooks/events.md)); an event with no flat name (such as `webhook.disabled`) uses its event type there instead.

```json theme={null}
{
  "event": "agent_created", "event_id": "evt_6f9c2c1e-…", "occurred_at": "2026-10-13T09:41:07Z",
  "api_version": "1", "test": false,
  "partner_id": "a1b2…", "reseller_id": "b2c3…", "org_id": "c3d4…", "agent_id": "d4e5…",
  "account_id": "a1b2…", "email": "jane@acme.example", "first_name": "Jane", "company_name": "Acme VoIP",
  "pbx_type": "netsapiens", "is_test_account": false, "last_call_at": "2026-10-13T09:12:44Z",
  "agent_name": "Front Desk", "agent_extension": "7001"
}
```

## Fields

| Field | Meaning |
| - | - |
| `event_id` | Unique per event. The same on every retry and replay — de-duplicate on it. |
| `event_type` / `event` | What happened. |
| `api_version` | Payload version your endpoint is pinned to. Every endpoint is on version `1`; a breaking change would ship as a new version. |
| `occurred_at` | When it happened in Telzino (UTC, ISO 8601). Every timestamp in a message, in the envelope or in `data`, is UTC to the whole second, ending in `Z` (for example `2026-10-13T09:41:07Z`). |
| `test` | `true` only for **Send test** messages. |
| `partner_id`, `reseller_id`, `org_id`, `agent_id` | Where it happened; `null` when not applicable. `account_id` is the same as `partner_id`. |
| `account` fields | The account's contact: email and first name of its first admin, company name, PBX type, whether it is a Telzino test account, and `last_call_at` (when any of its agents last received a call, `null` if never). Reseller- and organization-level endpoints get only `account_id`, `pbx_type` and `last_call_at`: the Partner's email, first name, company name and test flag are left out. |
| `data` | The event's own fields ([Events](https://docs.telzino.com/event-webhooks/events.md)). |
| `phi` | Only on call and survey events, and only when the organization allows it ([below](#phi-protected-health-information)). Absent otherwise, and never on **Send test** messages. |

By default payloads carry IDs, account contact details and event metadata only — never call transcripts, caller details, recordings or PBX credentials.

## Call event example

```json Nested theme={null}
{
  "event_id": "evt_0b7d4a52-…",
  "event_type": "call.completed",
  "api_version": "1",
  "occurred_at": "2026-10-13T09:46:30Z",
  "test": false,
  "partner_id": "a1b2…", "reseller_id": "b2c3…", "org_id": "c3d4…", "agent_id": "d4e5…",
  "account": { "account_id": "a1b2…", "pbx_type": "netsapiens", "last_call_at": "2026-10-13T09:42:11Z" },
  "data": {
    "call_id": "f5a6…", "direction": "inbound",
    "started_at": "2026-10-13T09:42:11Z", "ended_at": "2026-10-13T09:46:29Z", "duration_seconds": 258,
    "resolution_status": "resolved", "sentiment": "Positive",
    "transcript_url": "https://app.telzino.com/dashboard/organization/reports/call-logs?call=f5a6…"
  },
  "phi": {
    "caller_number": "+15555550123",
    "summary": "Caller booked a cleaning for Tuesday at 10 am."
  }
}
```

In the flat format `phi` stays one nested object, so a low-code tool can map it once:

```json Flat theme={null}
{
  "event": "call.completed", "event_id": "evt_0b7d4a52-…", "occurred_at": "2026-10-13T09:46:30Z",
  "api_version": "1", "test": false,
  "partner_id": "a1b2…", "reseller_id": "b2c3…", "org_id": "c3d4…", "agent_id": "d4e5…",
  "account_id": "a1b2…", "pbx_type": "netsapiens", "last_call_at": "2026-10-13T09:42:11Z",
  "call_id": "f5a6…", "direction": "inbound",
  "started_at": "2026-10-13T09:42:11Z", "ended_at": "2026-10-13T09:46:29Z", "duration_seconds": 258,
  "resolution_status": "resolved", "sentiment": "Positive",
  "transcript_url": "https://app.telzino.com/dashboard/organization/reports/call-logs?call=f5a6…",
  "phi": { "caller_number": "+15555550123", "summary": "Caller booked a cleaning for Tuesday at 10 am." }
}
```

## Survey event example

A `survey.completed` message from a CSAT survey where the caller rated the representative 4. The second question was not shown, so it is not in `answers`. `phi` carries what the organization allows: here Webhook PHI is on and redaction is off, so the caller's number and the raw answer text are in `phi`, and `open_answers` is left out because no open question was answered.

```json Nested theme={null}
{
  "event_id": "evt_3c9e1a77-…",
  "event_type": "survey.completed",
  "api_version": "1",
  "occurred_at": "2026-10-13T09:52:41Z",
  "test": false,
  "partner_id": "a1b2…", "reseller_id": "b2c3…", "org_id": "c3d4…", "agent_id": "d4e5…",
  "account": { "account_id": "a1b2…", "pbx_type": "netsapiens", "last_call_at": "2026-10-13T09:51:39Z" },
  "data": {
    "survey_version": 1,
    "call_id": "7d2f4b0e-5a1c-4e93-8b6d-2f9a0c1e3d54",
    "parent_call_id": "3a8c6e12-9f04-4b7d-a1e5-6c2d8b0f9e71",
    "rep": { "id": "8101@pbx.example.com", "name": "Jane Doe", "extension": "8101", "source": "netsapiens_api" },
    "queue": "Support",
    "transferred_at": "2026-10-13T09:50:12Z",
    "status": "completed",
    "language": "en",
    "duration_sec": 41,
    "answers": [
      { "key": "rep_csat", "type": "rating", "value": 4, "confirmed": true, "confidence": 0.97 }
    ],
    "flags": { "detractor": false, "callback_requested": false, "survey_opt_out": false },
    "transcript_url": "https://app.telzino.com/dashboard/organization/reports/call-logs?call=7d2f4b0e-5a1c-4e93-8b6d-2f9a0c1e3d54"
  },
  "phi": {
    "transfer_ani": "+15555550123",
    "answers_raw": [ { "key": "rep_csat", "raw": "four" } ]
  }
}
```

## PHI (protected health information)

Caller details and call content are sent only when the organization opts in, with the organization setting **Webhook PHI** (`org.webhook_phi`). Only an admin can change it, from the organization's settings in the dashboard: an account admin, or a Reseller Admin of its reseller. It cannot be set with an API key or the settings API. Every change is audited.

| `org.webhook_phi` | Who gets `phi` |
| - | - |
| `off` (default) | Nobody. |
| `org_only` | That organization's own endpoints. |
| `all_levels` | Its own endpoints, reseller and account endpoints that receive its events, and Telzino's own platform endpoints. |

The setting in force when the event happened decides; changing it later does not change events already recorded. Healthcare (secure access) organizations can opt in too.

| `phi` field | On |
| - | - |
| `caller_number` | `call.completed` |
| `summary` | `call.completed`, when the organization does not redact personal details (with redaction on, the redacted summary is in `data` instead) |
| `tasks_completed` | `call.completed` |
| `transfer_ani` | `call.completed`, when the call has [transfer context](https://docs.telzino.com/functions/transferred-call-context.md) (the `transfer` object in `data` never includes it); `survey.*`: the caller's number from the transfer context, or the call's own caller number when there is none |
| `answers_raw`, `open_answers` | `survey.*`, when neither the organization nor the survey agent redacts (with redaction on, the redacted text is in `data` and `phi` keeps only `transfer_ani`) |
| `escalation_reason` | `call.completed` and `call.escalated` |
| `tool_arguments`, `tool_result` | `call.outcome` (not for `tool` `reservation`) |

A field is left out when it has no value. The call transcript is never sent: open `transcript_url` to read it.

Never sent at any setting: recordings or audio, PBX credentials, API key or webhook secrets. Stored event data, `phi` included, is deleted with the delivery logs, after the retention period Telzino sets for the platform (30 days by default).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.