Write-back
Write-back pushes each call's intent and outcome to your external LMS/CRM. It is configured per organization and applies to all campaigns. See the Write-back UI guide for an overview.
Write-back is dispatched only for calls in a terminal status, within ~60 seconds of the intent being tagged.
The Config Object
{
"webhookEnabled": true,
"webhookUrl": "https://crm.example.com/oliai/webhook",
"webhookMethod": "POST",
"authType": "API_KEY",
"authHeaderName": "X-API-Key",
"hasCredential": true,
"csvAutoExport": true,
"shareTranscript": false
}The stored credential is never returned — hasCredential indicates whether one is set.
| Field | Type | Description |
|---|---|---|
webhookEnabled | boolean | Whether webhook write-back is active |
webhookUrl | string | Destination URL |
webhookMethod | string | POST or PATCH |
authType | string | NONE, API_KEY, or BEARER |
authHeaderName | string | Header name for API_KEY auth (e.g. X-API-Key) |
csvAutoExport | boolean | Generate the results CSV automatically on campaign completion |
shareTranscript | boolean | Include a transcript link in the webhook payload |
Get Write-back Config
GET /v1/write-back/configReturns the config (with the credential redacted to hasCredential), or null if not configured.
Update Write-back Config
PUT /v1/write-back/configRequest Body: any subset of config fields, plus a write-only credential.
| Field | Type | Description |
|---|---|---|
webhookEnabled | boolean | |
webhookUrl | string | Required (valid URL) when webhookEnabled is true |
webhookMethod | string | POST or PATCH |
authType | string | NONE, API_KEY, BEARER |
authHeaderName | string | Required for API_KEY |
credential | string | Plaintext API key / bearer token — write-only, encrypted at rest. Omit to keep the current value; ignored when authType is NONE. |
csvAutoExport | boolean | |
shareTranscript | boolean |
Credentials are encrypted with AES-256-GCM and never returned by the API. Setting authType to NONE clears the stored credential.
Webhook Payload
Each dispatch sends this JSON body to your endpoint:
{
"contact_identifier": "loan_12345",
"identifier_type": "loan_id",
"intent_label": "Interested in Paying",
"intent_source": "auto",
"intent_undetermined": false,
"call_timestamp": "2026-05-31T09:08:27.000Z",
"campaign_id": "camp_def456",
"campaign_name": "Mumbai Outreach - March",
"call_duration_seconds": 87,
"transcript_url": null
}identifier_type is the org's DataSource lookup key (e.g. loan_id) when the contact has that field, else "phone". transcript_url is null unless shareTranscript is enabled.
Delivery & retries: non-2xx 5xx/timeout responses are retried up to 5 times with backoff (30s, 2m, 10m, 30m, 2h). A 4xx response is not retried — it is marked a permanent failure.
List Failures
GET /v1/write-back/failuresReturns write-back events that exhausted retries (FAILED) or failed permanently (PERMANENT_FAILURE).
Query Parameters: page, limit
{
"data": [
{
"id": "wbe_abc123",
"contactIdentifier": "loan_12345",
"identifierType": "loan_id",
"campaignName": "Mumbai Outreach - March",
"status": "PERMANENT_FAILURE",
"attempts": 1,
"lastError": "HTTP 401",
"lastAttemptAt": "2026-05-31T09:09:00.000Z"
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
}Retry a Failed Event
POST /v1/write-back/events/:id/retryRe-queues a failed event against the current webhook target. Returns 400 if there is no active webhook configured.
Download Results CSV
GET /v1/write-back/campaigns/:campaignId/results.csvReturns an enriched CSV (text/csv) of every contact in the campaign: identifier, name, intent label, intent source, call status, call timestamp, attempts, and commitment data. Always available, regardless of the csvAutoExport setting.