Webhooks let SIP Caller notify your systems in real time when something happens in your account, such as a campaign being activated or a call ending. Instead of polling the REST API for changes, your application exposes an HTTPS endpoint, and SIP Caller sends it an HTTP POST request with a JSON payload every time a subscribed event occurs.
To start receiving webhooks, create a webhook in the Web Console, select the events you're interested in, and assign it to your campaigns. See Webhooks for a step-by-step guide.
Every webhook request has a JSON body with the same envelope, where the data field contains the details of the event:
{
"id": "01928321-9129-7f25-8ad3-80c57b16d3ed",
"object": "event",
"apiVersion": 2,
"createdAt": "2024-10-12T23:47:48.133",
"type": "CampaignActivated",
"data": {
...
}
}| Field | Description |
|---|---|
id | Unique identifier of the event. If the same event is delivered more than once (for example, after a retry), it keeps the same id, so you can use it to discard duplicates. |
object | Always event. |
apiVersion | Version of the payload format, as configured in the webhook. |
createdAt | Date and time when the event occurred. |
type | Type of the event, such as CampaignActivated or CallEnded. |
data | Details of the event. Its content depends on the event type, as described in each event's page. |
Every webhook is configured with a payload version. When SIP Caller introduces changes to the payloads that aren't backward compatible, it releases them under a new version, so existing integrations keep receiving the format they expect. We recommend using the latest version for new integrations. Each event's page includes a version selector that shows the payload of each version.
| Event | Type | Sent when |
|---|---|---|
| Campaign Activated | CampaignActivated | A campaign is activated. |
| Campaign Paused | CampaignPaused | An active campaign is paused. |
| Campaign Resumed | CampaignResumed | A paused campaign is resumed. |
| Campaign Canceled | CampaignCanceled | A campaign is canceled. |
| Campaign Finished | CampaignFinished | A campaign finishes. |
| Call Ended | CallEnded | A call made by a campaign ends. |
Every webhook request includes a Sip-Caller-Signature header, which lets you verify that the request was sent by SIP Caller and wasn't modified:
Sip-Caller-Signature: t=1728776932,v1=df9da282f3ffe9a7d855cc11589d86d33852ee0bbc1abaacab854c7f52e6efaeThe t value is the timestamp when the event was signed, and the v1 value is the signature. To verify it:
.), and the raw JSON body of the request, exactly as received.v1 value. Process the event only if both values match.For example, in Python:
import hashlib
import hmac
def is_valid_signature(header: str, body: bytes, secret: str) -> bool:
parts = dict(item.split("=", 1) for item in header.split(","))
message = parts["t"].encode() + b"." + body
expected = hmac.new(secret.encode(), message, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])Complete examples are available for Python and .NET. The signing secret can be regenerated from the Web Console; when you do so, update your application right away, since signatures made with the new secret won't validate with the old one.
Your endpoint should reply with a 2xx status code as soon as it receives the event, and do any time-consuming processing afterwards (for example, in a background job). If your endpoint doesn't reply in time, or replies with an error, SIP Caller retries the delivery according to the timeout and retry settings of the webhook. Since an event can be delivered more than once, make your processing idempotent by using the event id.