Empire Telecom · Empire Unified
Empire Unified SIP trunks run on the same platform as EmpireUC, so you can read and manage your trunks, numbers, call records, recordings, 911 addresses and live events through the NetSapiens API v2.
Empire Unified is Empire Telecom's SIP trunking service for sites that keep their own phone system (PBX) and want Empire to carry their calls. It runs on the same platform as EmpireUC, Empire's cloud phone system, which is built on NetSapiens. That means Empire Unified customers use the same NetSapiens API v2: a JSON REST API with bearer-token authentication. For a SIP trunk customer, the useful parts are your domain, your SIP connections (trunks), your phone numbers and where they route, call detail records, recordings, emergency (911) addresses and event subscriptions. In short: everything you need to monitor and report on a trunk is available, while core routing changes are normally made by Empire Telecom.
This article covers only the parts of the API that matter for SIP trunking. For authentication, error codes, paging and the full endpoint list, see the companion article "EmpireUC: API specification".
Tip: You do not need code to see your calls and numbers. Empire Unified customers can view them in the Phones section of the Empire Telecom customer portal. Use the API when you want to feed call data into your PBX reporting, billing or monitoring tools.
| Item | Detail |
|---|---|
| API type | REST over HTTPS (OpenAPI 3.1) |
| API version | NetSapiens API v2, platform release 44.x |
| Base URL | https://<your-EmpireUC-API-server>/ns-api/v2 (Empire Telecom provides the server address) |
| Authentication | Token from POST /tokens (client ID + secret + login), or an API key; sent as Authorization: Bearer <token>. Details in "EmpireUC: API specification" |
| Data format | JSON, kebab-case field names |
| Your account | A domain with a numeric ID; ~ means "my domain" |
| Trunks | SIP connections under your domain |
| Sandbox | No public sandbox; test against a quiet period or test number arranged with Empire Telecom |
| Rate limits | Not published; poll gently and use event subscriptions for live data |
| Webhooks / events | Event subscriptions (POST /subscriptions), near-real-time (about every 3 seconds) |
| SDKs | None official; any HTTP client, or generate one from the OpenAPI file |
| Developer portal | docs.ns-api.com (version 44.4) |
| Status page | No public status page; contact Empire Telecom support |
| How to get access | Ask Empire Telecom for API access; we request the client ID and secret and set the scope |
| 1 | Ask Empire Telecom for API access and say it is for an Empire Unified (SIP trunk) account. Empire requests an API client (client ID and client secret) for you and delivers it securely. |
| 2 | Agree a scope. Tell Empire Telecom what you need to do. Office Manager scope covers your own domain - its connections, numbers, call records and recordings. For reporting and monitoring tools, a read-only API key is the safer choice. |
| 3 | Get the server address from Empire Telecom. Your base URL is https://<your-EmpireUC-API-server>/ns-api/v2. |
| 4 | Get a token with POST /tokens (JSON body, grant_type password, then refresh_token to renew). The client ID and secret are two separate fields; putting both in one field returns Invalid_client. |
| 5 | Test with a read call, such as GET /domains/~ and GET /domains/~/connections. |
| 6 | For unattended servers, consider a read-only API key restricted to your server's IP addresses. Creating one needs a bearer token first; Empire Telecom can arrange it. |
Same as EmpireUC. In brief:
| POST https://<your-EmpireUC-API-server>/ns-api/v2/tokens Content-Type: application/json { "grant_type": "password", "client_id": "<client_id>", "client_secret": "<client_secret>", "username": "<user>@<domain>", "password": "<password>" } |
Use the returned access_token as Authorization: Bearer <access_token>. When it expires, call POST /tokens again with "grant_type": "refresh_token" and the refresh_token. API keys (60 characters, prefixed nsd_ for Office Manager scope) are also sent as a bearer token. Full details, MFA and JWT options are in "EmpireUC: API specification".
Paths are relative to https://<your-EmpireUC-API-server>/ns-api/v2. {domain} is your numeric domain ID or ~.
| Method | Path | What it does |
|---|---|---|
| GET | /version | API version and server time (a good health check) |
| GET | /domains/~ | Your own domain |
| GET | /domains/{domain} | Read domain settings |
| GET | /domains/{domain}/billing | Domain with billing summary |
A connection is the SIP trunk between the platform and your PBX or SBC. It holds the match pattern that identifies your traffic, your PBX address, optional SIP registration credentials, transport (UDP, TCP or TLS), media and caller ID handling, and call limits.
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/connections | List the trunks on your domain |
| GET | /domains/{domain}/connections/{connection-id} | Read one trunk |
| PUT | /domains/{domain}/connections/{connection-orig-match-pattern} | Update a trunk |
| DELETE | /domains/{domain}/connections/{connection-id} | Delete a trunk |
| POST | /connections | Create a connection (requires connection-orig-match-pattern and domain) |
| GET | /connections | All connections visible to your token |
| GET | /connections/count | Count connections |
Useful connection fields:
| Field | Meaning |
|---|---|
connection-orig-match-pattern | Pattern that identifies calls from your PBX |
connection-term-match-pattern | Pattern used for calls to your PBX (defaults to the originating pattern) |
connection-address | Your PBX or SBC address |
description | Free-text label |
connection-orig-enabled, connection-term-enabled | Whether calls from and to your PBX are allowed (yes/no) |
connection-sip-transport-protocol | UDP (default), TCP or TLS |
connection-sip-registration-username, -password, -realm | Credentials if your PBX registers to the platform |
connection-require-encrypted-audio-enabled | Require SRTP: yes, no or optional |
connection-audio-relay-enabled | Whether media is relayed through the platform |
limits-max-active-calls-orig, -term, -total | Call path (concurrent call) limits |
dial-plan, dial-policy | Dial plan and dialling permissions applied to the trunk |
time-zone | Time zone for the trunk |
Important: Changing a connection's address, transport or match pattern can stop calls immediately. Ask Empire Telecom to make trunk changes, or test them in a maintenance window. Concurrent call limits are tied to the number of call paths on your Empire Unified plan.
Carrier-side routes (/routes and /routes/{route-id}/routecon) are platform-level objects above your domain; ask Empire Telecom if a carrier route needs to change.
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/phonenumbers | List your numbers and their routing |
| GET | /domains/{domain}/phonenumbers/count | Count numbers |
| GET | /domains/{domain}/phonenumbers/{phonenumber} | Read one number |
| PUT | /domains/{domain}/phonenumbers/{phonenumber} | Change where a number is delivered |
For a SIP trunk, numbers are normally delivered to your connection. The routing is in dial-rule-application; the trunk-related values include to-connection, to-connection-or-user-no-failover, to-connection-no-timeout, to-connection-block-caller-id, to-connection-add-header and to-connection-add-header-force-caller-id. The destination is dial-rule-translation-destination-user (and -host). Other values such as to-user, to-callqueue and to-voicemail send the number to EmpireUC features instead, which is handy as a failover.
| PUT /domains/~/phonenumbers/12015550100 { "dial-rule-application": "to-connection", "dial-rule-translation-destination-user": "[*]", "dial-rule-description": "Main line to on-site PBX" } |
New numbers and porting are ordered through Empire Telecom.
Dial rules translate and route numbers inside a dial plan (for example, a short code that goes to a particular destination).
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/dialplans/{dialplan}/dialrules | Read the dial rules in a dial plan |
| POST | /domains/{domain}/dialplans/{dialplan}/dialrules | Add a dial rule |
| PUT | /domains/{domain}/dialplans/{dialplan}/dialrules/{dialrule} | Update a dial rule |
| DELETE | /domains/{domain}/dialplans/{dialplan}/dialrules/{dialrule} | Delete a dial rule |
| POST | /domains/{domain}/dialplans | Create a dial plan for the domain |
Rules use fields such as dial-rule-matching-to-uri and dial-rule-translation-destination-user. Most trunk customers never need to change these; ask Empire Telecom first.
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/cdrs | Call records for your domain (datetime-start, datetime-end required) |
| GET | /domains/{domain}/cdrs/count | Count calls and total minutes |
Filters: datetime-start, datetime-end, type (Inbound, Outbound, On-net, Off-net, Missed, Received), dialled, caller, start, limit (up to 1,000 per page). Fields that matter for trunk reporting: id, call-direction, call-start-datetime, call-answer-datetime, call-disconnect-datetime, call-orig-caller-id, call-orig-to-user, call-term-user, call-talking-duration-seconds, call-total-duration-seconds, call-disconnect-reason-text, call-audio-codec, call-orig-ip-address, call-term-ip-address, call-orig-call-id and call-term-call-id. The IP address and codec fields are useful when troubleshooting a trunk.
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/calls | Calls in progress on your domain |
| GET | /domains/{domain}/calls/count | Number of calls in progress (compare with your call path limit) |
Recordings are fetched by call ID from the CDR (call-orig-call-id):
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/recordings/{callid} | Recording for a call; the response includes file-access-url, file-duration-seconds and call-recording-status |
A recording exists only if recording is turned on for that traffic; ask Empire Telecom. Many PBX sites record locally on the PBX instead.
Every location that can dial 911 needs a validated address. Keep addresses current when phones or buildings change.
| Method | Path | What it does |
|---|---|---|
| GET | /domains/{domain}/addresses | List your emergency addresses |
| POST | /domains/{domain}/addresses/validate | Check an address before saving |
| POST | /domains/{domain}/addresses | Create an address |
| PUT | /domains/{domain}/addresses/{emergency-address-id} | Update an address |
| DELETE | /domains/{domain}/addresses/{emergency-address-id} | Delete an address |
| GET | /domains/{domain}/addresses/count | Count addresses |
| GET | /domains/{domain}/addresses/endpoints | Address endpoints (named locations, optionally with a callback number) |
| POST | /domains/{domain}/addresses/endpoints | Create an address endpoint |
Required fields: address-name, caller-name, address-line-1, address-city, address-state-province-abbreviation, address-postal-code, address-country-abbreviation, address-location-description.
Important: With a SIP trunk, your PBX decides which caller ID is sent on a 911 call. Make sure each building's outbound caller ID matches a number whose 911 address is that building. Ask Empire Telecom to review your 911 setup when you add a site.
Use event subscriptions to have the platform push changes to your HTTPS URL.
| Method | Path | What it does |
|---|---|---|
| POST | /subscriptions | Create a subscription |
| GET | /subscriptions | List subscriptions |
| GET | /subscriptions/{id} | Read one |
| PUT | /subscriptions/{id} | Update one |
| DELETE | /subscriptions/{id} | Delete one |
| GET | /domains/{domain}/subscriptions | Subscriptions for your domain |
The most useful models for trunks are cdr (one event per completed call, ideal for billing and reporting) and call (changes to calls in progress, for live dashboards). Example:
| POST /ns-api/v2/subscriptions { "model": "cdr", "post-url": "https://hooks.example.org/empire-unified/cdr", "domain": "<domain>" } |
Events are JSON arrays sent by HTTP POST. Each post includes an X-Correlation-ID header with the subscription ID. Delivery is near-real-time: the platform checks for changes about every 3 seconds. Subscriptions created with a timed token expire with it unless you set subscription-expires-datetime.
start and limit on collection reads; CDRs return up to 1,000 per page.cdr model, rather than polling every few seconds.| 1 | Get a token with POST /tokens. |
| 2 | Call GET /domains/~/cdrs/count?datetime-start=2026-09-01 00:00:00&datetime-end=2026-09-30 23:59:59 for the total calls and minutes. |
| 3 | For call-by-call detail, call GET /domains/~/cdrs with the same dates, paging with start and limit=1000. |
| 1 | Call GET /domains/~/calls/count. |
| 2 | Compare with limits-max-active-calls-total on your connection (GET /domains/~/connections). |
| 3 | If you regularly reach the limit, ask Empire Telecom about adding call paths. |
| 1 | Call GET /domains/~/phonenumbers/{phonenumber}. |
| 2 | Check dial-rule-application (for example to-connection) and dial-rule-translation-destination-user. |
| 1 | Find the call with GET /domains/~/cdrs using caller or dialled and a narrow time window. |
| 2 | Note call-disconnect-reason-text, call-audio-codec and the IP address fields. |
| 3 | Send the call ID and time to Empire Telecom support for a full trace. |
| 1 | Create a subscription: POST /subscriptions with "model": "cdr" and your HTTPS post-url. |
| 2 | Verify the X-Correlation-ID header on each post. |
| 3 | Store each record keyed on id so a repeated post is not counted twice. |
| 1 | Validate it: POST /domains/~/addresses/validate. |
| 2 | Create it: POST /domains/~/addresses. |
| 3 | Ask Empire Telecom to link the building's outbound numbers to the new address. |
start and limit.Need a hand? Call Empire Telecom support at (732) 363-9898, email support@empiretelecomnj.com, or open a ticket in the customer portal.