1. Reference
CallerAPI Documentation
  • Quickstart
  • Use cases
    • For carriers (MNOs/MVNOs)
    • CPaaS platforms
    • Cloud communications providers
    • SIP trunking providers
    • PBX/Cloud PBX
    • UCaaS vendors
  • Account
    • Balance and email
      GET
  • Spam protection
    • Voice firewall
      • Get started
      • Quickstart
        • What you get
        • Before you start
        • Test with a recording
        • Connect your switch
        • Switch notes
        • Twilio and Telnyx
        • Send text instead of audio
      • Verdicts
        • Read a verdict
        • What to do with a verdict
        • Block a caller
        • Events and webhooks
      • Honeypot
        • Hand a call over
        • Audio, events, and limits
      • Reference
        • Endpoints
        • Errors
        • Limits and thresholds
        • Production checklist
      • REST
        • What this deployment can do
        • List the verdict categories
        • List the honeypot personas
        • Score a transcript or a recording
        • List your recent sessions
        • Get one session with verdict and intel
        • Twilio voice URL for a screened number
        • Preview the Twilio TwiML
        • Telnyx voice URL for a screened number
        • Twilio voice URL for a honeypot number
        • Telnyx voice URL for a honeypot number
      • WebSocket
        • Live scam filter stream
        • Honeypot stream
    • Daily spam reports
      • Webhook
        • Subscribe to daily reports
        • Unsubscribe from daily reports
        • List webhook subscriptions
        • Manual dispatch of reports
        • Test webhook
      • REST
        • Fetch daily spam reports
    • 15 days spam CSV snapshot
      GET
    • Spam score + HLR
      GET
  • Mobile SDK
    • Get started
    • Quickstart
      • What you get
      • Get your keys
      • Android
      • iOS
      • Flutter
      • React Native
      • Check it works
    • Call screening
      • What each platform can do
      • Android call screening
      • iOS prerequisites
      • iOS add the extension
      • iOS test on device
    • Reference
      • Methods
      • Errors
      • Limits and billing
      • Troubleshooting
  • Data partners
    • Partner tems & docs
    • Upload spam reports
    • Upload contacts
  • Fraud prevention
    • Ported date
    • Porting history
    • Online presence
    • KYC user identity
  • Business Caller ID
    • Get started
    • Quickstart
      • Announce a call
      • Verify at INVITE
      • What you get
    • Verdicts
      • Show the name and logo
      • Read a verdict
    • REST
      • Verify the calling number
      • Fetch the logo
      • Announce a call
  • DID monitoring
    • Get started
    • Reference
      • Statuses and labels
      • Webhooks
      • Billing and limits
      • Errors
    • REST
      • Submit numbers
      • List number status
      • Read one number
      • Remove a number
      • Read the check schedule
      • Set the check schedule
      • Save the webhook URL
      • Read the webhook
      • Delete the webhook
      • Send a test event
      • Rotate the webhook secret
    • Number flagged
    • Number cleared
  • Signer reputation by SPC
    GET
  • Signers ranked by score
    GET
  • Schemas
    • Spam protection
      • Spam score request
      • Business info
      • Carrier info
      • Complaint (without number)
      • Daily spam reports request
      • Complaint (with phone)
    • Signer
    • SubmitResponse
    • Monitoring
    • Number
    • NumberListResponse
    • OneNumberResponse
    • ScheduleResponse
    • WebhookWriteResponse
    • WebhookReadResponse
    • FlaggedEvent
    • ClearedEvent
    • EventData
    • Error
    • AuthError
    • ScheduleRequest
    • WebhookRequest
    • RemovedResponse
    • WebhookTestResponse
  1. Reference

Webhooks

A webhook tells you when the status of a number changes. CallerAPI sends a POST request to your URL. Each request contains one event.
Webhooks send only changes. To get the full results for all numbers, send GET /api/did-monitoring/v1/numbers.
INFO
Webhooks are not available on the Free plan. An account has one webhook URL.

Event types#

typeWhen
number.flaggedA number becomes flagged. The previous status was pending, clean, or unknown.
number.clearedA flagged number becomes clean.
There are no other status events. A first result of clean, a change to unknown, and a change from unknown to clean do not send an event. See the Statuses and labels page.

Event fields#

FieldMeaning
idThe event ID, for example evt_8f3c2a1e9b7d4c60. Use it to find duplicate deliveries.
typenumber.flagged or number.cleared.
created_atWhen CallerAPI made the event. RFC 3339 in UTC.
data.phoneThe number in E.164 format.
data.statusThe new status.
data.previous_statusThe status before this check.
data.labelThe label of the new status.
data.checked_atWhen the check finished. Use it to put events in order.

Examples#

number.flagged:
{
  "id": "evt_8f3c2a1e9b7d4c60",
  "type": "number.flagged",
  "created_at": "2026-10-29T08:02:11Z",
  "data": {
    "phone": "+13058901598",
    "status": "flagged",
    "previous_status": "clean",
    "label": "Spam or scam risk",
    "checked_at": "2026-10-29T08:02:11Z"
  }
}
number.cleared:
{
  "id": "evt_1a7d5e0c3f9b2468",
  "type": "number.cleared",
  "created_at": "2026-11-02T08:01:47Z",
  "data": {
    "phone": "+13058901598",
    "status": "clean",
    "previous_status": "flagged",
    "label": "No flags",
    "checked_at": "2026-11-02T08:01:47Z"
  }
}

Test event#

POST /api/did-monitoring/v1/webhook/test sends one test event. It has the same headers and the same signature as a real event. It is not a status change.
{
  "id": "evt_5c0e7b2a9d4f1836",
  "type": "webhook.test",
  "created_at": "2026-10-29T08:00:00Z",
  "data": {"ok": true}
}
Reply to it with a 2xx status. Do not store it as a status change.

Headers#

HeaderValue
Content-Typeapplication/json
User-AgentCallerAPI-DID-Monitoring/1
CallerAPI-Event-IdThe event id.
CallerAPI-TimestampThe time when CallerAPI signed the request, in Unix seconds.
CallerAPI-Signaturev1=<hex>. HMAC SHA256 of <timestamp>.<raw body>. The key is your webhook secret.
The webhook secret starts with whsec_. Use the full secret as the key, with the whsec_ part.

Verify the signature#

Do these steps for each request:
1.
Read the raw bytes of the body. Do not parse the JSON first.
2.
Read CallerAPI-Timestamp. Reject the request if the time is more than 5 minutes from your clock.
3.
Make the string <timestamp>.<raw body>. Use a dot between the two parts.
4.
Calculate the HMAC SHA256 of this string with your secret. Write it as lowercase hex. Put v1= in front.
5.
Compare the result with each value in CallerAPI-Signature. Use a constant time compare.
6.
Accept the request if one value is equal.
Python:
Node.js:
In Node.js, rawBody must be the raw body as a Buffer. For example, use express.raw({ type: "application/json" }) on the webhook route.

Rotate the secret#

POST /api/did-monitoring/v1/webhook/rotate-secret returns a new secret. CallerAPI shows it one time only.
For 24 hours after a rotation, CallerAPI-Signature contains two values, separated by a comma:
CallerAPI-Signature: v1=<signature with the new secret>,v1=<signature with the old secret>
The code samples above accept the request when one value is equal. Put the new secret on your receiver in the 24 hours. After 24 hours, only the new secret signs.

Delivery rules#

1.
Reply with a 2xx status in 10 seconds. Any other status, a timeout, or a redirect is a failed delivery.
2.
CallerAPI sends each event at least one time. The same event can arrive more than one time. Use id to find duplicates.
3.
Events can arrive out of order. Use data.checked_at to put them in order.
4.
Do not depend on a fixed source IP address. Verify the signature instead.

Retries#

After a failed delivery, CallerAPI tries again after these intervals:
AttemptTime after the previous attempt
21 minute
35 minutes
430 minutes
52 hours
66 hours
712 hours
824 hours
There are 8 attempts in total, over about 45 hours. After the eighth attempt, CallerAPI stops the delivery of that event.

When CallerAPI turns off your webhook#

CallerAPI turns off the webhook after 50 failed delivery attempts in a row, or after 3 days of failures. CallerAPI then sends an email to the account email address.
GET /api/did-monitoring/v1/webhook shows "active": false and a note with the reason. To turn the webhook on again, fix your endpoint. Then save the URL again with PUT /api/did-monitoring/v1/webhook.
While the webhook is off, CallerAPI does not deliver events. Send GET /api/did-monitoring/v1/numbers to get the current status of all numbers.

URL rules#

RuleValue
Schemehttps only
Port443 or 8443
HostMust resolve to a public address. Private, loopback, link-local, and reserved addresses are not accepted.
Host nameslocalhost and names that end in .localhost, .local, or .internal are not accepted.
RedirectsNot followed. A redirect is a failed delivery.
User name or password in the URLNot accepted.
Length2,048 characters at most
CallerAPI checks these rules when you save the URL. CallerAPI checks them again before each delivery.
Modified at 2026-10-29 10:43:45
Previous
Statuses and labels
Next
Billing and limits
Built with