Pinless dial-in and SIP Interconnect allow incoming calls to trigger a webhook on your infrastructure, which then routes the call to a Daily room — no PIN required from the caller.
This pattern is common in contact centers, voice bots, and IVR flows where the destination room isn’t known at call time.
How it works
- A caller dials your purchased phone number or a static SIP URI.
- Daily places the caller on hold (hold music plays).
- Daily sends a webhook to your configured
room_creation_api URL.
- Your server creates or selects a Daily room and waits for
dialin-ready to fire.
- Your server calls
pinlessCallUpdate with the room’s sip_uri to connect the held caller.
Configure your domain with a pinless_dialin array. Each object represents one incoming number or SIP interconnect:
You can omit phone_number for SIP Interconnect (no phone number needed). Otherwise, phone_number is required and must be a number purchased from Daily.
The response is the room’s config object, including an array of pinless_dialin entries, each with a static sip_uri and the corresponding room_creation_api URL — the sip_uri is the address your SIP system dials for interconnect flows:
Daily generates each sip_uri for your domain. Copy the exact value from the API response and store it. Do not build the address by hand and do not change any part of it.Incoming calls are matched against the exact address Daily generated. If your SIP system dials an address you built yourself, or an edited version of the real one, the call will not match. Daily ends the call, your room_creation_api webhook never fires, and you see no sign of the call at all.
When you configure pinless_dialin, Daily sends a test request to your room_creation_api endpoint with the body {"test": "test"}. This test request is sent every time you configure pinless_dialin, not only the first time. It only checks that your endpoint is reachable. Your endpoint is still configured even if it does not return a 200 response, so that existing domains that do not recognize the test body keep working.Do not use “my webhook was called” as proof that call routing works. The test request looks nothing like a real call. Only a real incoming call includes callId and callDomain in the body, so check for those two fields when you want to know whether a real call reached you.
Incoming webhook payload
When a call arrives, Daily POSTs to your room_creation_api:
From: caller’s phone or SIP address
To: your Daily phone number or static SIP URI
callId + callDomain: use these to connect the held call to a Daily room. They are only sent for real calls, never for the config-time test request
sipHeaders: custom SIP headers sent to the sip_uri (e.g., for external SIP systems forwarding caller context). For example, when you receive a call on your Avaya on-premise SIP server and need to send the caller phone and called phone, the to and from fields will already be the Avaya sip addresses. In that case, you can add custom sip headers prepended with an x-. This would be something like 8a1f0c4e2b7d9351--1739943585193@daily-8a1f0c4e2b7d9351-pinless-sip.dapp.signalwire.com?x-caller=7861230000&x-called=6501230000.
Verifying the webhook signature (HMAC)
Each pinless_dialin entry has an hmac — a Base64-encoded HMAC-SHA256 secret shared between Daily and your server. Use it to verify that the webhook came from Daily.
Daily includes two headers with each webhook request:
X-Pinless-Timestamp
X-Pinless-Signature
To verify:
You can provide your own Base64-encoded secret in the hmac field when configuring. If omitted, Daily generates a new one each time you update pinless_dialin.
Keep your hmac secret private. Anyone with it can forge webhook requests.
Connecting the held call to a Daily room
Once your webhook handler has created or selected a room:
- Join the room with a Daily participant (e.g., a Pipecat bot or agent) so the room is active.
- Wait for
dialin-ready to fire.
- Call
pinlessCallUpdate with the room’s sip_uri and the callId/callDomain from the webhook:
Calling pinlessCallUpdate before dialin-ready fires may cause the call to drop.
Make sure the sip_uri you provide is not already in use by another SIP client. See multiple SIP endpoints for provisioning multiple endpoints per room.
For building voice bots with this pattern, see the Pipecat dial-in docs.