We want to configure FreePBX to forward inbound calls to a PSTN number via a Twilio Elastic SIP Trunk while attempting to preserve the original caller ID (CID). Currently, Twilio replaces the original caller ID with the Twilio trunk number. We need an expert VoIP engineer to implement a solution that complies with Twilio’s requirements and maximizes preservation of original caller information in SIP headers.
Current Setup
-
PBX: FreePBX 17.x
-
Trunk: Twilio Elastic SIP Trunk
- Verified Twilio number: +1954833XXXX
-
Original caller: Arbitrary external numbers (e.g., +12342713563)
-
Destination: External PSTN number (e.g., +1954737XXXX)
-
Goal: Forward calls from FreePBX → Twilio → PSTN, showing the correct caller information.
Problem Statement
When forwarding calls through the Twilio trunk, the displayed Caller ID on the PSTN side always shows the Twilio number (+19548338586), not the original caller number (+1234271XXXX).
Twilio reply :
1. Allowed Caller ID Numbers in Termination Calls
For outbound (termination) calls through Twilio Elastic SIP Trunking:
-
The Caller ID Number (From header) must be either a Twilio phone number (DID) on your account or a number that has been verified in the Twilio Console or via the Outgoing Caller ID API.
-
If a Caller ID Number is not specified in the SIP INVITE’s From field, Twilio will use the value from the Remote-Party-ID or P-Asserted-Identity header (if present) as the Caller ID, provided it is a Twilio-verified number.
Allowed Caller ID Numbers in Termination calls
2. Supported SIP Headers for Original Caller Information
Twilio Elastic SIP Trunks support the following headers for passing caller information:
-
From: This must always be a Twilio number or a Twilio-verified number for outbound PSTN calls.
-
P-Asserted-Identity (PAI): Twilio will forward this header to downstream carriers if present.
-
Diversion: If your call is a forwarded call, you can include a Diversion header. Twilio will forward this header to the PSTN.
-
Remote-Party-ID: This header is also supported for identifying the originator of the call, but is not always honoured by all carriers.
3. Best Practices for Compliance and Header Handling
-
Set the From header to your Twilio-verified number (+1 770 637 9587) to ensure compliance and call acceptance.
-
Place the original caller’s number in the P-Asserted-Identity or Diversion header. Twilio will attempt to pass this information downstream, but the final display depends on the terminating carrier and regulatory requirements.
-
Ensure your FreePBX is configured to populate these headers correctly.
4. Forwarding Original Caller Information to PSTN
-
Twilio will forward the PAI and Diversion headers to the PSTN where possible, but the number displayed to the called party is typically the one in the From header.
-
The original caller information may still be available in call logs or for compliance purposes.
5. Caller ID Flags and Feature Deprecation
-
Previous flags that allowed more flexibility with caller ID presentation have been deprecated to align with industry regulations and prevent spoofing.
-
There is no current flag or setting to override the requirement for a Twilio-verified number in the From header for PSTN calls.
6. Twilio Trunk Configuration
- No additional configuration or flags are available on the Twilio side to change this behaviour. The key is to ensure your PBX is sending the correct headers as described above.
Next Steps:
-
If you can provide a SIP trace of a sample call, I can review the headers to confirm everything is being sent as expected.
-
I’m happy to arrange a call with our technical team to walk through your setup and answer any further questions. Please let me know your availability or preferred times.
Thank you for your patience and for working with us on this. If you have any additional details or questions, please share them and I’ll be glad to assist further.
I tried forward using misc destenation and below is my dial plan :
exten => _00015X.,1,NoOp(Forward to Twilio with correct headers)
same => n,Set(ORIGCID=${CALLERID(num)})
; Twilio verified outbound CLI
same => n,Set(CALLERID(num)=1954833XXXX)
; IMPORTANT: inherit into outbound channel
same => n,Set(__PJSIP_HEADER(remove,P-Asserted-Identity)=)
;same => n,Set(__PJSIP_HEADER(add,P-Asserted-Identity)=sip:[email protected])
same => n,Set(__PJSIP_HEADER(remove,Remote-Party-ID)=)
;same => n,Set(__PJSIP_HEADER(add,Remote-Party-ID)=sip:+${ORIGCID}<@sip-usa-05.rinXXXXX.com>;party=calling;screen=yes;privacy=off)
same => n,Dial(PJSIP/+${EXTEN:5}@1954833XXXX-infra-test-1500)