Appearance
call.priced
When: The call's cost is final, about a minute after it ended (it is metered with the provider's own timing, then priced; a recording still being stored makes it wait for that too): bill your user from call.cost.amount. Sent again when pricing a period again changes it. Not sent in test mode
Extra data: call.cost: a call's cost — status PRICED or UNPRICED (with reason)
Example
Headers: X-Calloop-Event: call.priced, X-Calloop-Event-Id, X-Calloop-Signature (verifying).
json
{
"event_id": "7c0b1e0c-8a45-4c1b-9d4c-0f3a6a2f9b11",
"event_type": "call.priced",
"api_version": "2026-09-25",
"livemode": true,
"occurred_at": "2026-09-25T10:05:12.000Z",
"tenant_ref": "biz-123",
"data": {
"call": {
"callId": 42,
"callUuid": "00000000-0000-0000-0000-000000000042",
"tenantId": 1,
"tenantRef": "biz-123",
"channel": "WHATSAPP",
"channelId": 1,
"channelAddress": "+442079460000",
"channelRef": "support-line",
"queueId": 1,
"direction": "INBOUND",
"status": "TERMINATED",
"state": null,
"mediaTopology": "ROOM",
"customer": {
"address": "+447700900123",
"addressType": "E164",
"name": "Test Customer"
},
"agentId": 7,
"agentRef": "user-7",
"agentName": "Agent One",
"externalRef": "crm-call-42",
"providerCallId": "wacid.HBgL...",
"ivrFlowId": null,
"ringingAt": "2026-09-25T10:00:00.000Z",
"answeredAt": "2026-09-25T10:00:06.000Z",
"endedAt": "2026-09-25T10:05:12.000Z",
"terminationReason": "COMPLETED",
"terminatedBy": "CUSTOMER",
"durations": {
"ringing": 6,
"call": 306,
"queue": 4
},
"failureDetails": null,
"consumerMetadata": {
"crm_contact_id": 991
},
"createdAt": "2026-09-25T10:00:00.000Z",
"cost": {
"status": "PRICED",
"amount": 0.4965,
"currency": "USD",
"source": "TENANT_PLAN",
"reason": null,
"billedSeconds": 306,
"charges": {
"status": "RATED",
"amount": 0.306,
"currency": "USD",
"billedQuantity": 306,
"rate": 0.06,
"how": {
"planName": "Standard",
"method": "DECK_MARKUP",
"prefix": "44",
"destination": "United Kingdom",
"baseRate": 0.05,
"markupPercent": 20,
"initialSeconds": 1,
"incrementSeconds": 1
}
},
"tenantCharges": {
"status": "RATED",
"amount": 0.459,
"currency": "USD",
"billedQuantity": 306,
"rate": 0.09,
"how": {
"planName": "Resale",
"method": "DECK_MARKUP",
"on": "consumer price",
"baseAmount": 0.306,
"baseRate": 0.06,
"markupPercent": 50,
"prefix": "44",
"destination": "United Kingdom"
}
},
"carrierCost": null,
"recordings": [
{
"seconds": 300,
"charges": {
"status": "RATED",
"amount": 0.025,
"currency": "USD",
"billedQuantity": 300,
"rate": 0.005,
"how": {
"planName": "Standard",
"method": "FLAT"
}
},
"tenantCharges": {
"status": "RATED",
"amount": 0.0375,
"currency": "USD",
"billedQuantity": 300,
"rate": 0.0075,
"how": {
"planName": "Resale",
"method": "DECK_MARKUP",
"on": "consumer price",
"baseAmount": 0.025,
"markupPercent": 50
}
},
"carrierCost": null
}
]
}
}
}
}data.call is the full call at that moment — the same view GET /v1/calls/{callId} returns. Apply events by "latest occurred_at wins": they can arrive out of order.