Requirements for VoIP Providers

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

  1. Registration-based trunks
  2. rInstance parameter support
  3. Allowed IP address list
  4. DTMF support for RFC2833
  5. Proxy audio
  6. Error codes

Optional

  1. E164 number formatting
  2. TLS / SRTP
  3. T38 Support
  4. 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

Via: SIP/2.0/UDP 10.10.10.10:5060;branch=z9hG4bK-524287-1;rport

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

SIP/2.0 407 Proxy Authentication Required

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

Via: SIP/2.0/UDP 10.10.10.10:5060;branch=z9hG4bK-524287-1;rport

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:

Message Header

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:

Message Header

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:

Session Initiation Protocol (INVITE)

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:

  1. If the Provider needs to add the IPs of 3CX customers in their list of allowed IPs, then this needs to be clearly stated.
  2. 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.
  3. 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.
  4. 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.
  5. 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:

Authorization: Bearer <YOUR_API_KEY>

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.

curl -X POST \

  --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.

curl -X POST "https://api.generic.com/v2/messages" \

  --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

  1. Go to “Voice & Chat”.
  2. Select “Country > Generic” and choose between SIP Trunk and VoIP Provider.
  3. Configure your SIP Trunk Provider details.
  4. Go to the “SMS” tab and check the “Enable SMS”.
  5. Copy and paste the ‘Webhook’ to your provider’s portal.
  6. Add the “API Key” and “Provider URL” which can be found in your provider’s portal.

See also

Last Updated

This document was last updated on 3 March 2023

https://www.3cx.com/docs/supported-sip-trunk-requirements/