In 3CX: start a trunk from the Thread template
Install the Thread Voice AI template

Keep the defaults and select Create.
Create a trunk from the template

Thread Voice AI appears as a provider once the template is installed.
In Thread: copy Thread’s SIP address and set encryption
Select Add SIP Trunk and name it

New trunk: both directions start as Optional.
Under Inbound trunk, select Set up trunk

Thread's SIP address in the inbound settings
Choose how Thread recognizes your 3CX
- Allowed addresses: list your 3CX public IP, shown next to Use this IP for Whitelisting on any 3CX trunk page.
- Username and password: pick a username unique to this trunk and a long, randomly generated password (20 or more characters from a password manager). Don’t reuse credentials from anywhere else or use defaults like admin/admin. Keep them for step 7. Choose this if your 3CX is hosted and shares an IP with other customers.
- Leave the address list empty: Thread accepts calls from any address. Anyone who knows Thread’s SIP address and your agent’s number can then call the agent with any caller number, so prefer one of the options above.

Allowed addresses: one IP or CIDR block per line. Left empty, any address is allowed.

Username and password: Thread checks these on every call from 3CX.
In 3CX: point the trunk at Thread
Name the trunk and paste Thread's SIP address
5060. Leave Outbound Proxy empty.
Name, Main Trunk Number and Registrar/Server filled in. Port stays on 5060.
Fill in authentication to match step 5

The username and password version. For allowed addresses, leave both credential fields empty.
Set encryption to match step 4, then save

SRTP Mode set to Enforced. Transport Protocol can stay on the template's setting.
Add an Outbound Rule for Thread's test number

A US trunk: prefix 999 without the country code, and Prepend +1 puts it back.
In Thread: test inbound and set up the outbound side
Test the inbound side
5060, and that no higher Outbound Rule catches the test number. Thread can only see calls it accepts, so check your 3CX logs to find out why calls are failing.
A call Thread accepted. Expand Headers to see what 3CX sent.
Set up the outbound side
yourcompany.3cx.us (port 5061 is filled in). Copy Thread’s three SIP IP ranges for step 12, and leave this page open.
Thread's SIP IP ranges for your 3CX allow list
In 3CX: allow Thread’s IP ranges
Allow Thread's SIP IP ranges
143.223.88.0/21, 161.115.160.0/19 and 153.57.128.0/18. Skip this for a trunk in Australia or New Zealand.
One entry per range, with Action set to Allow.
In Thread: skip credentials and find the transfer number
Leave Username and password empty

Optional. Leave both empty for 3CX.
Find the agent's transfer number

Without menu options: one transfer number, in Call queue and extension.

With menu options: option 1 transfers to +1 202 555 0111 and needs a DID; option 2 stays in Thread.
In 3CX: add the transfer number
Add the transfer number as a DID, then save
+1 202 555 0110, enter +12025550110), and add the row. 3CX accepts a call from Thread only when it arrives on a DID the trunk knows. Calls on the trunk go to the Default route on its General tab, so set that to the extension, ring group or queue that should answer transfers. Select Save.
The transfer number from step 14, in E.164 format.
In Thread: test transfers and finish the trunk
Skip the certificate and test the connection

Connection Successful means TLS and routing to 3CX both work.
Link the agent and save

Both sides configured and switched on, one linked agent.
In 3CX: send callers to Thread over SIP
Add an Outbound Rule for the agent's numbers
+1 202 555 0142, enter 2025550142). Set Route 1 to the Thread Voice AI trunk, Strip no digits, and Prepend the country code, +1 in the US and Canada.The agent’s numbers are in Thread under Voice > Agents: the Attendant number is under Your attendant phone number on the agent’s Attendant tab, and the Overflow number under Your overflow phone number on its Overflow tab. The trunk page also lists both next to the agent you linked in step 17. Add a rule for both the Attendant and the Overflow number, so 3CX sends every forward to the agent over SIP.Make sure no higher rule catches the number first. If a call still doesn’t match, Dashboard > Activity logs shows the number 3CX compared on a line like Looking for outbound rule: dialed = [+12025550142], processed: [2025550142]; use the processed form as the prefix. Then delete the test-number rule.
The Attendant number, on the agent's Attendant tab.

The Overflow number, on the agent's Overflow tab.

Route 1 goes to the same trunk that receives Thread's transfers.
Forward callers to the agent's number
Place a test call