Connect your PBX
Once you have created your trunk, you configure your PBX to use it. The PBX needs to know four things: where to send calls, how to prove who it is, which addresses to accept calls and audio from, and which codecs to use. This page gives those settings for Asterisk with PJSIP, FreePBX and 3CX, the firewall rules to open, and a troubleshooting guide.
The examples use the trunk from the quickstart: office-pbx, a PBX at
203.0.113.10 that accepts SIP over TLS on port 5061.
Collect your values
Read the platform values from GET /v1/platform/endpoints and the trunk values from
GET /v1/trunks/{trunk_id}. Do not copy the values below into production without checking them
against the API: PressOne can change platform addresses, and the response's version and as_of
tell you when.
| Setting | Example value | Where it comes from |
|---|---|---|
| SIP server | sip.trunk.pressone.co | signaling_fqdn in platform endpoints |
| Trunk SIP domain | office-pbx.sip.trunk.pressone.co | signaling_fqdn on the trunk |
| Signalling addresses | The addresses in signaling_nodes | signaling_nodes |
| SIP ports | 5061 for TLS, 5060 for UDP or TCP | signaling_ports |
| TLS name | sip.trunk.pressone.co | tls.realm |
| Media addresses | The ranges in media_cidrs | media_cidrs |
| Signals RTP ports | UDP 10000 to 20000 | rtp_ports |
| Codecs | G.711 A-law (PCMA) and mu-law (PCMU), 20 ms, plus any of G729, G722 and OPUS you added | codecs on the trunk; G.711 is always offered |
| DTMF | RFC 4733 telephone events | |
| Number format | E.164 with a leading +, for example +2348034128890 | |
| Caller ID | A number routed to the trunk, for example +2342013300100 | Numbers and routing |
| Authentication | Your PBX's public address, or a digest username, password and realm | Authentication and security |
Open your firewall
Your firewall must let SIP and audio pass between your PBX and Signals. TLS runs over TCP, so the TLS port is a TCP port.
| Direction | Protocol and ports | From | To | Why |
|---|---|---|---|---|
| Out | TCP 5061 (TLS), or UDP and TCP 5060 | Your PBX | signaling_nodes | Your PBX sends calls to Signals. |
| In | The port in your termination target, such as TCP 5061 | signaling_nodes | Your PBX | Signals delivers inbound calls. |
| Out | UDP, your PBX's RTP ports | Your PBX | media_cidrs, UDP 10000 to 20000 | Audio to Signals. |
| In | UDP 10000 to 20000 from Signals, to your PBX's RTP ports | media_cidrs | Your PBX | Audio from Signals. |
UDP 10000 to 20000 is the range of ports Signals sends audio from and receives audio on, so it is the range to allow from the Signals media address. It does not limit how many calls you can run. Concurrency is set by your trunk and outbound policy limits.
If your PBX sits behind NAT, it must advertise its public address in SIP and SDP, and keep audio flowing through itself rather than directly between phones and Signals. The settings below cover both.
Asterisk with PJSIP
These settings target Asterisk 18 or later with chan_pjsip. They define a TLS transport, the
Signals endpoint, its address of record (AOR) and an identify section that matches calls coming
from Signals.
IP allow list trunk
Add this to pjsip.conf. Replace the certificate paths and 203.0.113.10 with your own:
Code
bind = 0.0.0.0:5061with your certificate lets Signals deliver inbound calls over TLS, matching thetlstermination target.direct_media = nokeeps audio on the PBX, which NAT and the Signals media address require.identifywithmatchtells Asterisk that SIP from the Signals signalling address belongs to this endpoint. Add onematchline per address insignaling_nodes.- There is no registration. Signals reaches your PBX through the termination targets on the trunk.
If your trunk does not require TLS, use a UDP transport on port 5060 instead and set
contact = sip:sip.trunk.pressone.co:5060.
Digest trunk
For a digest trunk, add an auth section with the credential Signals generated, and point the
endpoint at it with outbound_auth. Keep the transport, AOR and identify sections from above:
Code
When you rotate the credential, replace username and password and run
pjsip reload before the old credential's previous_retires_at.
Encrypted audio
If the trunk uses "media_security": "sdes_srtp_required", add this line to the endpoint:
Code
Use it only with the TLS transport. SDES sends the audio keys inside SIP messages.
Dialplan
Send outbound calls in E.164 format with a caller ID routed to the trunk. This example also turns a
Nigerian national number such as 08034128890 into +2348034128890:
Code
Inbound calls arrive in the from-signals context with the called number in the request URI. This
example rings extension 1001 for any number. Place a test call and check the Asterisk console for
the exact format of the called number, then match it per number:
Code
FreePBX
FreePBX builds the same PJSIP configuration from its web interface. Menu and field names below follow recent FreePBX releases and may differ in yours.
- In Settings, open the SIP settings for
chan_pjsip. Set your external (public) address and your local networks so FreePBX rewrites addresses behind NAT. If your trunk requires TLS, enable the TLS transport on port 5061 with a certificate from the certificate manager. - In Connectivity, add a PJSIP trunk named
signals. - On the trunk's general settings, set the outbound caller ID to a routed number, such as
+2342013300100. - On the PJSIP settings:
- Set the SIP server to
sip.trunk.pressone.coand the port to5061for TLS, or5060for UDP. - Choose the transport that matches the port.
- Turn registration off.
- For an IP allow list trunk, set authentication to none. For a digest trunk, set outbound authentication with the username and password Signals generated.
- Set the inbound context to your inbound routes context (FreePBX uses
from-pstn).
- Set the SIP server to
- On the advanced PJSIP settings, set the match or permit address to the ranges in
signaling_nodesandmedia_cidrs, turn direct media off, turn RTP symmetric and rewrite contact on, and set the from domain to the trunk'ssignaling_fqdn. If the trunk requires SRTP, set media encryption to SDES (SRTP via in-SDP). - On the codecs tab, allow only
alawandulaw. - Create an outbound route that sends numbers in E.164 format through the
signalstrunk. Add a dial pattern that prefixes+234and strips the leading0from national numbers. - Create inbound routes for the numbers you routed to the trunk.
- Apply the configuration.
3CX
3CX menu names change between versions, so this section lists the settings rather than the exact screens. Add a SIP trunk using a generic SIP trunk template, then set:
| 3CX setting | Value |
|---|---|
| Registrar, server or proxy | sip.trunk.pressone.co |
| Port | 5061 for TLS, 5060 for UDP or TCP |
| Transport | TLS if your 3CX version offers it for SIP trunks; otherwise UDP, with require_tls set to false on the trunk |
| Authentication | IP-based (no registration) for an IP allow list trunk; username and password for a digest trunk |
| Authentication ID and password | The digest username and password, for digest trunks only |
| Main trunk number | A number routed to the trunk, such as +2342013300100 |
| Allowed codecs | G.711 A-law and G.711 U-law only |
| Outbound caller ID | A number routed to the trunk |
Then create outbound rules that send calls through the trunk in E.164 format with a +, and inbound
rules (DID rules) for each routed number or range. Allow the Signals signalling and media addresses
in any firewall in front of 3CX, as listed in Open your firewall.
If your 3CX cannot use TLS for SIP trunks, create the trunk with "require_tls": false, a udp or
tcp termination target, and "media_security": "rtp". SRTP with SDES is not safe without TLS.
Verify the connection
- Wait a minute after your last change so it has taken effect.
- Run a configuration test:
POST /v1/trunks/{trunk_id}/testswith{ "kind": "config_validation" }, then read the test. - Place an outbound call to a Nigerian mobile number from an extension.
- Call one of your routed numbers from a mobile phone and confirm it rings the PBX.
- Check
GET /v1/trunks/{trunk_id}/diagnosticsand the trunk'sendpoint_evidenceafter a few calls.
Troubleshooting
Start with the API. It tells you how the trunk is configured and what the network saw on real calls.
Outbound calls are rejected before they ring
- The change is very recent. A saved change takes effect within a minute. If a change cannot be applied, PressOne staff are alerted and the previous configuration keeps serving, so a call can still follow your earlier settings for a short time.
- Your address is not allowed. Calls must come from an address in the trunk's IP allow list. Behind NAT, your traffic may leave from a different public address than you expect.
Compare it with
GET /v1/trunks/{trunk_id}/ip-credentials. - Digest fails. Check the username, password and realm. A new credential works once the network
has accepted it (
new_applied_atis set), within a minute. A rotated credential stops atprevious_retires_at, and a revoked one stops within a minute of the revoke. - TLS fails. Confirm the PBX connects to port 5061 over TLS and trusts the Signals certificate.
Outbound calls are refused after authentication
- No policy. The trunk's
policymust be set. A trunk without a policy refuses every outbound call. - Destination not allowed. The number must match an allow rule in the policy, and no more specific deny rule. Send numbers in E.164 format.
- Caller ID not allowed. The caller ID must be a number routed to the trunk, with its route
statusapplied. A trunk'snumberscount of 0 means it has none. - A limit was reached. Check
concurrency,cpsand the daily spend cap on the trunk, the policy and any subtrunk.ceilings.daily_spend.used_today_minoron the policy shows today's spend. - The trunk is suspended.
statusissuspended. CallPOST /v1/trunks/{trunk_id}/resume.
Inbound calls do not arrive
- The route is not applied.
GET /v1/numbers/blocks/{block_id}/routesshould show the number's slice with the trunk as itseffectivetarget andstatusapplied. - The trunk does not take inbound calls. Its
directionmust beinboundorboth, with at least one enabled termination target. - Signals cannot reach your PBX. Allow SIP from the Signals signalling address to the port in
your termination target. For a
tlstarget, your PBX needs a valid certificate on that port. - Target health. The trunk's
endpoint_evidenceshows each target ashealthy,degraded,idleorunknown, with the last failure code. Signals does not probe targets, so a target showsidleuntil real calls reach it.
One-way audio or no audio
- Allow UDP in both directions between your PBX's RTP ports and the Signals media address on ports 10000 to 20000.
- Set your public address for media (
external_media_addressin Asterisk) and keep direct media off. GET /v1/trunks/{trunk_id}/diagnosticscountsone_way_callsandno_media_callsover the last 24 hours, alongside MOS, packet loss and jitter.
Calls fail when the trunk requires SRTP
With "media_security": "sdes_srtp_required", your PBX must offer SRTP with SDES keys. In Asterisk,
set media_encryption = sdes on the endpoint and use the TLS transport.
Calls end at the same length every time
A call ends when it reaches max_call_duration_seconds. The shortest value across the trunk, the
policy and any subtrunk applies.
Contacting support
Every API error is an application/problem+json body with a code and a request_id, and every
response carries an X-Request-ID header. Include the request ID, the trunk ID and the time of the
call when you contact PressOne support.