Requirements for VoIP Providers
- Introduction
- Mandatory
- Optional
- Mandatory
- Registration-based
- rInstance Parameter
- How is it used by 3CX?
- The parameter
- Allowed IP address list
- RFC2833 Support
- Proxy of audio
- Error Codes
- Optional
- E164 number format
- Inbound calls:
- Outbound calls:
- TLS / SRTP Support
- T38 Support
- SMS/MMS API
- Requirements
- Authorization
- Send SMS/MMS request
- Webhook notifications
- How to Configure your Trunk
- See also
Introduction
A SIP Trunk provider may be added to the 3CX Phone System by meeting the following technical requirements. These requirements can be divided into 2 categories, mandatory and optional:
Mandatory
- Registration-based trunks
- rInstance parameter support
- Allowed IP address list
- DTMF support for RFC2833
- Proxy audio
- Error codes
Optional
- E164 number formatting
- TLS / SRTP
- T38 Support
- SMS / MMS Support
We explain each of these technical requirements below.
Mandatory
Registration-based
3CX will only support registration based trunks as those offer greater versatility and features when combined with a 3CX phone system. Registration based trunks are also required for implementing rinstance. More on rinstance later.
When a trunk is added, the 3CX Phone System will initiate a registration request without including authentication details. If then challenged by a “407 proxy authentication” or a “401 Unauthorized” message, the 3CX Phone System will respond with another registration message that includes the appropriate authentication header with all necessary information for registration.
Note: 3-way authentication is also supported.
Initial Registration Example
Max-Forwards: 70 Contact: <sip:[email protected]:5060;rinstance=2622c879b98cfd93> To: <sip:[email protected]:5060> From: <sip:[email protected]:5060>;tag=6f679b75 Call-ID: TCoqe2Yl3wT50ot1-dSZYAQS.. CSeq: 1 REGISTER Expires: 120 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE, UPDATE Supported: replaces, timer Content-Length: 0
Provider Challenge Example
Via: SIP/2.0/UDP 10.10.10.10:5060;branch=z9hG4bK-524287-1;rport=5060 Proxy-Authenticate: Digest nonce="XXXX",algorithm=MD5,realm="XXXX" To: <sip:[email protected]:5060>;tag=2fe09c7f From: <sip:[email protected]:5060>;tag=6f679b75 Call-ID: TCoqe2Yl3wT50ot1-dSZYAQS.. CSeq: 1 REGISTER Content-Length: 0
Registration with Authorization Example
Max-Forwards: 70 Contact: <sip:[email protected]:5060;rinstance=2622c879b98cfd93> To: <sip:[email protected]:5060> From: <sip:[email protected]:5060>;tag=6f679b75 Call-ID: TCoqe2Yl3wT50ot1-dSZYAQS.. CSeq: 2 REGISTER Expires: 120 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE, UPDATE Proxy-Authorization: Digest username="XXXX",realm="XXXX",nonce="XXXX",uri="XXXX",response="XXX",algorithm=MD5 Supported: replaces, timer Content-Length: 0
rInstance Parameter
How is it used by 3CX?
The 3CX Phone System uses this parameter for Call Source Identification to match an incoming call with a SIP trunk. This is only possible for registration-based trunks since there is no registration for IP-based trunks. 3CX Phone System performs Call Source identification as described here. In short, when the 3CX Phone System receives a call, it first tries to match the rInstance value to a trunk. This ensures that calls will always be routed to the correct destination since each rInstance value is unique per SIP Trunk.
This allows for multiple SIP Trunks of the same provider to exist on the same 3CX installation even if all other parameters are the same between the trunks. A 3CX Phone System assumes the role of a UAC (User Agent Client) to register with a UAS (User Agent Server, usually a SIP Trunk provider). While doing so, 3CX includes a parameter called rInstance in the registration message sent to the UAS.
The parameter
This parameter is included in the “Contact” header and is unique for each SIP Trunk the 3CX Phone System is registered to. The parameter must remain unchanged as long as the registration is active. If the registration between the 2 User Agents expires or is terminated from either side, the next time the 3CX Phone System will try to register it will generate a new rInstance value.
Registration Example:
Via: SIP/2.0/UDP 10.10.10.10:5060;branch=z9hG4bK-524287-1---36545f783a0e7b00;rport Max-Forwards: 70 Contact: <sip:[email protected]:5060;rinstance=187128bdfcec4b74> To: " "<sip:[email protected]> From: " "<sip:[email protected]>;tag=c97b4f35 Call-ID: MPdDeqSR7zUFRYpbvEfQ3wrt.. CSeq: 2555 REGISTER Expires: 600 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE, UPDATE Supported: replaces, timer User-Agent: 3CXPhoneSystem Content-Length: 0
The 3CX Phone System expects to see the same rInstance parameter and value in the 200 OK returned for the registration attempt. This parameter must be included in the “Contact” header.
Registration Reply Example:
Via: SIP/2.0/UDP 10.10.10.10:5060; branch=z9hG4bK-524287-1---36545f783a0e7b00; From: " " <sip:[email protected]>;tag=c97b4f35 To: " " <sip:[email protected]> Call-ID: MPdDeqSR7zUFRYpbvEfQ3wrt.. CSeq: 2555 REGISTER Contact: <sip:[email protected]:5060;rinstance=187128bdfcec4b74>;expires=60 Content-Length: 0
The 3CX Phone System expects to see the same rInstance parameter and value during inbound calls so it can match the Invite to the correct SIP trunk. The parameter must be included in the “Request-Line ” header.
If the trunk has multiple DID (Direct Inward Dialing) numbers then the rInstance value must be present regardless of the DID number called.
Invite Example:
Request-Line: INVITE sip:[email protected]:5060;rinstance=187128bdfcec4b74 SIP/2.0 Message Header Via: SIP/2.0/UDP 1.1.1.1:5080;branch=z9hG4bK-f61ce555f5248ee834b54d1e1d541acf From: " " <sip:[email protected]>;tag=5878966a To: " " <sip:[email protected]> Call-ID: 3v1Vw8SxET87TOpNAZ9JYg.. CSeq: 2 INVITE Max-Forwards: 13 Contact: <sip:[email protected]:5080;transport=udp> Supported: replaces, timer Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, INFO, MESSAGE, UPDATE Content-Length: 321
Allowed IP address list
To avoid issues with customers not being able to register their Trunks, the Provider will need to make sure of the following:
- If the Provider needs to add the IPs of 3CX customers in their list of allowed IPs, then this needs to be clearly stated.
- The Provider should also be able to receive from 3CX a list of IP addresses to add in their allowed IP list at short notice.
- If possible the Provider should be able to whitelist a system using its FQDN. The TTL of the FQDN must be followed to ensure that any IP changes are updated promptly.
- The Provider should also specify an email address that will be used by them to receive email updates from 3CX with regards to IPs that they will need to add to their allowed list.
- If no whitelisting of IP addresses is required by the Provider (no blocking of IPs) then this should be stated as well.
RFC2833 Support
RFC2833 should be the default DTMF method used for delivering and accepting DTMF tones.
This must be indicated by the support of the “telephone-event” media attribute in the SDP of any call. The sample rate can vary depending on the codec used.
Proxy of audio
The Provider must be able to proxy the audio between 2 endpoints and not pass through the SDP to the other end. This prevents issues with audio not being delivered because of some firewalls not supporting hairpin traffic. This also enables transcoding in case the 2 endpoints don’t support common codecs.
Error Codes
If a 3CX Phone System fails to register a trunk due to incorrect credentials the error code sent back to the 3CX Phone System must be either “403 Forbidden”, “404 Not Found” or “603 Declined”. “401 Unauthorized” and “407 Proxy Authentication Required” are also allowed but not preferred. This allows the 3CX Phone System to understand that the credentials sent were wrong and stop the registration attempts until a change is made to the credentials or the user manually decides to retry.
Optional
E164 number format
E164 support is optional for providers unless the same Provider supports SMS / MMS. Then it is mandatory for Providers to support it.
Inbound calls:
Calls arriving at the 3CX Phone System must be in full globalized E164 number format (leading with‘+’). The 3CX Phone System can be set up to read the number format from a number of different SIP headers. The most common however are the “To: UserPart” and the “Request-Line URI: UserPart”.
Outbound calls:
Customers should be able to dial out using E164 number format (with ‘+’) as well. They should also preferably be able to present their caller ID in E164 number format (with ‘+’) too. So the “From” and “To” numbers should be accepted in E164.
TLS / SRTP Support
TLS and SRTP support is nice to have and demand from customers keeps increasing. It is not mandatory to have and it is currently not supported in 3CX StartUP but we are considering adding support for it in the future.
All technical requirements for TLS / SRTP in 3CX can be found here.
T38 Support
Fax support is optional but nice to have as some customers and markets still depend on it.
3CX supports T38 and G711 fax, however T38 is the preferred method.
All technical requirements for Fax can be found here.
SMS/MMS API
Requirements
- E164 support
- Good documentation of the interface
- HTTPs REST API for outbound message delivery
- HTTPs Webhooks for inbound message delivery and status reports
- Ability to generate an API Key and set Webhooks via the Provider Customer Portal
- SIP Trunking (voice) on the same number
Authorization
Providers should provide an API KEY (random, long enough string, unique per user account) to their users. 3CX GenericVoipProvider should be provisioned with this API KEY, so the 3CX Phone System can use it for authorization to the Provider. 3CX Phone System will pass the key in the Authorization header as follows:
This is for the Provider to be able to authenticate and authorize users’ requests that come from 3CX Phone System.
Send SMS/MMS request
The following is an example of sending an SMS from 3CX Phone System to the Provider's phone number.
--header "Content-Type: application/json" \ --header "Authorization: Bearer YOUR_API_KEY" \ --data '{ "from": "+10987654321", "to": "+11234567890", "text": "Hello John, how are you?", }'\ https://api.generic.com/v2/messages
All fields are required. Fields ‘to’, ‘from’ must be in E.164 format.
The following is an example of sending multiple MMS from 3CX Phone System to the Provider's phone number.
--header "Content-Type: application/json" \ --header "Authorization: Bearer YOUR_API_KEY" \ --data '{ "from": "+10987654321", "to": "+11234567890", "subject": "Picture", "text": "Hello John, how are you?", "media_urls": [ "https://3cx.com/path/123qweasd456rtg954mdf.png", ] }
Webhook notifications
The Provider should send incoming SMS/MMS messages and delivery receipts to 3CX Phone System in order to configure webhook using POST method.
The following is an example of sending a new incoming SMS message:
"data": { "event_type": "message.received", "id": "b301ed3f-1490-491f-995f-6e64e69674d4", "occurred_at": "2019-12-09T20:16:07.588+00:00", "payload": { "completed_at": null, "cost": null, "direction": "inbound", "encoding": "GSM-7", "errors": [], "from": { "carrier": "T-Mobile USA", "line_type": "long_code", "phone_number": "+1312500000", "status": "webhook_delivered" }, "id": "84cca175-9755-4859-b67f-4730d7f58aa3", "media": [], "messaging_profile_id": "740572b6-099c-44a1-89b9-6c92163bc68d", "organization_id": "47a530f8-4362-4526-829b-bcee17fd9f7a", "parts": 1, "received_at": "2019-12-09T20:16:07.503+00:00", "record_type": "message", "sent_at": null, "tags": [], "text": "Hello from Generic!", "to": [ { "carrier": "Generic", "line_type": "Wireless", "phone_number": "+1773005000", "status": "webhook_delivered" } ], "type": "SMS", "valid_until": null, "webhook_failover_url": null, "webhook_url": "http://webhook.site/04bbd2e3-09b5-4c9e-95de-a1debeb9e675" }, "record_type": "event" }, "meta": { "attempt": 1, "delivered_to": "http://webhook.site/04bbd2e3-09b5-4c9e-95de-a1debeb9e675" } }
Providers may extend this message with other data if needed. However, these are the required fields to be specified:
- data.id
- data.event_type
- data.payload.from.phone_number
- data.payload.to.phone_number
- data.payload.text
- data.payload.received_at
Field ‘data.id’ is the Provider's message ID (internal). Fields ‘phone_number’, ‘from’ and ‘to’ are phone numbers in E.164 format.
The following is an example of sending a new incoming MMS message:
"data": { "record_type": "message", "direction": "outbound", "id": "403186a2-4d6e-47a5-98c1-6eeba8fd1b4c", "type": "MMS", "organization_id": "9d69fdbd-c169-4bd1-903d-0db81d4550cf", "messaging_profile_id": "40017f96-ea51-4377-96d0-c84df8026ec9", "from": { "phone_number": "+17869412345", "carrier": "Generic", "line_type": "Wireless" }, "to": [ { "phone_number": "+18135712345", "status": "queued", "carrier": "....", "line_type": "Wireline" } ], "cc": [], "text": "", "media": [ { "url": "https://somedomain.com:5001/myphone/downloadchatfile/3f68b2835f9f8d1de5f2192ee95bfc849a36ed356d3a864baa4f0b875cfe94c5.png", "content_type": null, "sha256": null, "size": null } ], "webhook_url": "https://somedomain.com:5001/sms/generic/2c2970fa-235e-4679-b0f0-3bac71faec2c", "webhook_failover_url": "", "encoding": "GSM-7", "parts": 1, "tags": [], "cost": { "amount": "0.0150", "currency": "USD" }, "received_at": "2023-03-02T12:30:28.997+00:00", "sent_at": null, "completed_at": null, "valid_until": "2023-03-02T13:30:28.997+00:00", "errors": [] } }
The following is an example of an SMS delivery report which is sent by 3CX Phone System to the Provider when the SMS message is delivered successfully:
"data": { "event_type": "message.finalized", "id": "4ee8c3a6-4995-4309-a3c6-38e3db9ea4be", "occurred_at": "2019-12-09T21:32:14.148+00:00", "payload": { "completed_at": "2019-12-09T21:32:14.148+00:00", "cost": null, "direction": "outbound", "encoding": "GSM-7", "errors": [], "from": { "carrier": "T-Mobile USA", "line_type": "Wireless", "phone_number": "+13125000000", "status": "webhook_delivered" }, "id": "ac012cbf-5e09-46af-a69a-7c0e2d90993c", "media": [], "messaging_profile_id": "83d2343b-553f-4c5f-b8c8-fd27004f94bf", "organization_id": "9d76d591-1b7d-405d-8c64-1320ee070245", "parts": 1, "received_at": "2019-12-09T21:32:13.552+00:00", "record_type": "message", "sent_at": "2019-12-09T21:32:13.596+00:00", "tags": [], "text": "Hello there!", "to": [ { "carrier": "T-MOBILE USA, INC.", "line_type": "Wireless", "phone_number": "+13125000000", "status": "delivered" } ], "type": "SMS", "valid_until": "2019-12-09T22:32:13.552+00:00", "webhook_failover_url": "", "webhook_url": "http://webhook.site/af3a92e7-e150-442c-9fe6-61658ce26b1a" }, "record_type": "event" }, "meta": { "attempt": 1, "delivered_to": "http://webhook.site/af3a92e7-e150-442c-9fe6-61658ce26b1a" } }
The required fields to specify are:
- data.event_type (value should be ‘message.finalized’ or ‘message.sent’
- data.payload.id (id of delivered message)
- data.payload.to.status (could be ‘delivered’ or ‘sent’)
If the delivery of the message has failed then the ‘data.payload.to.status’ will change to “sending_failed” or “delivery_failed”.
How to Configure your Trunk
- Go to “Voice & Chat”.
- Select “Country > Generic” and choose between SIP Trunk and VoIP Provider.
- Configure your SIP Trunk Provider details.
- Go to the “SMS” tab and check the “Enable SMS”.
- Copy and paste the ‘Webhook’ to your provider’s portal.
- Add the “API Key” and “Provider URL” which can be found in your provider’s portal.
See also
- Application form to become a certified SIP Trunk provider.
- List of supported SIP Trunk providers.
- DNS Resolution - Explains how 3CX resolves FQDN to Registrar and SIP Server.
- Registration / Authentication - How 3CX registers/authenticates to a VoIP Provider.
- 3CX Trunk TLS and SRTP Functionality - Explains the TLS and SRTP functionality.
- SIP Trunk Failover - How 3CX handles multiple SIP Servers.
Last Updated
This document was last updated on 3 March 2023