Webhook Reference
StarAgent sends a POST request to your webhook URL for missed calls, voicemails, and inbound texts. The body is always JSON.
Sign in to see customized payload examples matching your actual configuration.
Events
incoming_callSent immediately when a call arrivesFires the moment your monitored number receives a call. Contains caller identity and location data from the carrier.
voicemailSent after the voicemail is transcribedFires after the caller leaves a message and transcription completes. Contains the full transcription (or extracted data), a link to the audio recording, and all caller metadata.
incoming_smsSent when someone texts your agent numberFires when Inbound Texts is enabled and a customer texts your number (SMS, MMS, or iMessage via BlueBubbles). Includes the message body, any media URLs, and the reply status.
Request format
Every webhook is a POST with the header Content-Type: application/json. Your endpoint should return a 2xx status. The standard webhook does not retry on failure. The optional all-activity webhook below uses automatic retries.
All-activity webhook
In Setup, open Advanced JSON webhook and configure All activity to send leads, incoming messages, drafts, reviews, and other recorded activity to one destination. Its settings are independent of the standard webhook and Agent hook above; existing payloads and delivery behavior are unchanged.
Enter your receiver URL and its signing secret (at least 32 characters), enable delivery, and save. Receiver setup details provides the connection ID and business ID. Send test checks the saved destination; it sends a connection-test event rather than a customer inquiry. The status shows pending retries and the last successful delivery.
Each event includes specversion, id, source, type, time, subject, business_id, and data containing activity and record snapshots. Event types begin with activity., for example activity.yelp_lead_received or activity.review_held. The standard event examples below remain unchanged.
Verify X-Staragent-Signature as HMAC-SHA256 of the timestamp, a period, and the exact request body using your signing secret. X-Staragent-Timestamp contains Unix seconds, X-Staragent-Integration identifies the connection, and Idempotency-Key is stable across retries. Reject stale timestamps and deduplicate event IDs before processing. Return 2xx after saving the event.
Failures retry automatically with backoff. Delivery can arrive out of order. Pausing keeps queued events for when you resume, but new activity is not captured while paused. Enabling does not import history. Apply the integration database migration and configure CRON_SECRET before enabling this feature in a deployment.
incoming_call payload
{
"event": "incoming_call",
"call_id": "clxyz1234567890abcdef",
"call_sid": "CA1234567890abcdef1234567890abcd",
"timestamp": "2026-02-21T18:30:00.000Z",
"business_name": "Sunrise Dental",
"business_phone": "+15551234567",
"caller": {
"phone": "+15559876543",
"name": "Jane Smith",
"city": "San Francisco",
"state": "CA",
"country": "US"
},
"forwarded_from": "+15551111111",
"direction": "inbound"
}| Field | Type | Description |
|---|---|---|
| event | string | Always "incoming_call" |
| call_id | string | Unique StarAgent call identifier |
| call_sid | string | Twilio Call SID for cross-referencing |
| timestamp | string | ISO 8601 timestamp of when the call arrived |
| business_name | string | Your business name as configured in StarAgent |
| business_phone | string | Your monitored phone number (E.164 format) |
| caller.phone | string | Caller's phone number (E.164 format) |
| caller.name | string? | Caller ID name from the carrier, if available |
| caller.city | string? | Caller's city from the carrier |
| caller.state | string? | Caller's state or region |
| caller.country | string? | Caller's two-letter country code |
| forwarded_from | string? | The number that forwarded this call, if applicable |
| direction | string? | Call direction, typically "inbound" |
voicemail payload
Includes all fields from incoming_call plus a voicemail object.
{
"event": "voicemail",
"call_id": "clxyz1234567890abcdef",
"call_sid": "CA1234567890abcdef1234567890abcd",
"timestamp": "2026-02-21T18:31:15.000Z",
"business_name": "Sunrise Dental",
"business_phone": "+15551234567",
"caller": {
"phone": "+15559876543",
"name": "Jane Smith",
"city": "San Francisco",
"state": "CA",
"country": "US"
},
"voicemail": {
"transcription": "Hi, this is Jane. I was calling about rescheduling my cleaning appointment next Tuesday. Could you call me back? Thanks.",
"recording_url": "https://staragent.io/api/recordings/clxyz1234567890abcdef?token=a1b2c3d4e5f6...",
"recording_duration": 12,
"recording_sid": "RE1234567890abcdef1234567890abcd",
"voicemail_mode": "transcribe"
},
"forwarded_from": "+15551111111",
"direction": "inbound"
}voicemail fields
| Field | Type | Description |
|---|---|---|
| voicemail.transcription | string | Full transcription or extracted data, depending on your voicemail mode |
| voicemail.recording_url | string | Direct link to the voicemail audio (MP3 by default). Token-authenticated, valid indefinitely. Append format=wav if you need WAV. |
| voicemail.recording_duration | number? | Duration of the voicemail in seconds |
| voicemail.recording_sid | string? | Twilio Recording SID for cross-referencing |
| voicemail.voicemail_mode | string | The mode used to process this voicemail. One of "transcribe", "extract", or "prompt". |
| extracted_fields | object? | Present on voicemail events when the transcription contains Label-style lines. Keys are lowercased labels, values are the caller's answers. Omitted when empty. |
| inferred_contact | object? | Best-effort name, email, and phone from transcript analysis plus extracted lines. Fields may be null. Omitted when all values are null. |
Structured fields on voicemail webhooks
For integrations and OpenClaw-style automations, StarAgent also sends extracted_fields and inferred_contact when it can derive them, so downstream tools do not need to re-parse the transcription.
{
"event": "voicemail",
"call_id": "clxyz1234567890abcdef",
"call_sid": "CA1234567890abcdef1234567890abcd",
"timestamp": "2026-02-21T18:31:15.000Z",
"business_name": "Sunrise Dental",
"business_phone": "+15551234567",
"caller": {
"phone": "+15559876543",
"name": "Jane Smith",
"city": "San Francisco",
"state": "CA",
"country": "US"
},
"voicemail": {
"transcription": "Name: Jane Smith\nPhone: 555-987-6543\nReason: Boarding inquiry",
"recording_url": "https://staragent.io/api/recordings/clxyz1234567890abcdef?token=a1b2c3d4e5f6...",
"recording_duration": 18,
"recording_sid": "RE1234567890abcdef1234567890abcd",
"voicemail_mode": "extract"
},
"extracted_fields": {
"name": "Jane Smith",
"phone": "555-987-6543",
"reason": "Boarding inquiry"
},
"inferred_contact": {
"name": "Jane Smith",
"email": null,
"phone": "555-987-6543"
},
"forwarded_from": null,
"direction": "inbound"
}Voicemail modes and transcription output
The content of voicemail.transcription depends on which voicemail mode you configured in Setup.
transcribePlain-text transcription of the voicemail, word for word.
extractStructured extraction using your template. The transcription field contains the filled-in template fields (e.g. Name, Phone, Reason, Urgency). This is ideal for feeding directly into a CRM or form.
promptCustom prompt applied to the audio. The transcription field contains whatever your prompt instructs the model to return, such as a summary, sentiment analysis, or action items.
Example with extract mode
If your template is "Name / Phone / Reason / Preferred time / Urgency", the transcription field in the webhook will look like this.
{
"event": "voicemail",
"call_id": "clxyz1234567890abcdef",
"call_sid": "CA1234567890abcdef1234567890abcd",
"timestamp": "2026-02-21T18:31:15.000Z",
"business_name": "Sunrise Dental",
"business_phone": "+15551234567",
"caller": {
"phone": "+15559876543",
"name": "Jane Smith",
"city": "San Francisco",
"state": "CA",
"country": "US"
},
"voicemail": {
"transcription": "Name: Jane Smith\nPhone: 555-987-6543\nReason: Reschedule cleaning\nPreferred time: Tuesday morning\nUrgency: Not urgent",
"recording_url": "https://staragent.io/api/recordings/clxyz1234567890abcdef?token=a1b2c3d4e5f6...",
"recording_duration": 18,
"recording_sid": "RE1234567890abcdef1234567890abcd",
"voicemail_mode": "extract"
},
"forwarded_from": null,
"direction": "inbound"
}incoming_sms payload
Sent when Inbound Texts is enabled in Setup and a customer texts your agent number.
{
"event": "incoming_sms",
"call_id": "clxyz1234567890abcdef",
"message_sid": "SMS:SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"timestamp": "2026-02-21T18:35:00.000Z",
"business_name": "Sunrise Dental",
"business_phone": "+15551234567",
"from": {
"phone": "+15559876543"
},
"body": "Do you have boarding open this weekend?",
"media_urls": [],
"channel": "twilio",
"reply": {
"status": "sent",
"body": "Yes, we have boarding open Saturday and Sunday. What size dog?"
}
}| Field | Type | Description |
|---|---|---|
| event | string | Always "incoming_sms" |
| call_id | string | StarAgent record ID (also shown on the dashboard) |
| message_sid | string | Synthetic ID such as SMS:SM… or BB:… |
| timestamp | string | ISO 8601 timestamp |
| business_name | string | Your business name |
| business_phone | string | Your monitored phone number |
| from.phone | string | Sender phone number |
| body | string | Message text (may be empty for media-only MMS) |
| media_urls | string[] | Attachment URLs when present |
| channel | string | "twilio" or "bluebubbles" |
| reply.status | string | sent, held, failed, or skipped |
| reply.body | string|null | Generated reply when available |
Recording URL
The voicemail.recording_url is a signed URL that serves the audio file without requiring login. You can use it to play the recording in your app, attach it to a support ticket, or store it in your own system. The URL does not expire, but it is unique per call and cannot be guessed.
GET request to the URL. The response is audio/mpeg (MP3) by default, which plays cleanly in SMS and on iPhone. Pass ?format=wav if you need WAV.Tips for integration builders
- Use the event field to route payloads. You may receive
incoming_callfirst, followed byvoicemailseconds later for the same call. Match oncall_idto correlate them. - Nullable fields like
caller.namemay benullif the carrier does not provide caller ID data. Always handle nulls gracefully. - Phone numbers use E.164 format (e.g.
+15551234567). Most CRMs and automation tools accept this format natively. - Respond quickly. Your endpoint should return within 5 seconds. StarAgent sends webhooks fire-and-forget, so a timeout will not block call processing, but your data will be lost if your endpoint is down.
Ready to connect?
See step-by-step guides for popular platforms.