Empire Telecom · net2phone
What net2phone's public APIs cover, how to get an API key or OAuth credentials, the main endpoints, and how webhooks work.
net2phone is a cloud business phone system (UCaaS) with a public developer portal at developer.net2phone.com. It offers two REST APIs: the older API V1 (OAuth, mainly users, call detail records, click-to-call and basic call webhooks) and the newer API V2 (API key or OpenID Connect, covering call detail records, recordings, voicemail, call queues, presence, phone numbers, messaging, webhooks and AI virtual agents). Verdict: a solid, modern API for reporting, wallboards, CRM call logging and event-driven integrations. It is not a full provisioning API. Most PBX configuration is still done in the net2phone admin console.
Important: net2phone publishes its API reference as an interactive explorer that changes over time. This article lists what we verified in the published V1 and V2 OpenAPI specifications in October 2026. Always confirm field names and parameters in the API V2 explorer before you build.
| Item | Detail |
|---|---|
| API type | REST over HTTPS, JSON |
| Base URL (V2, current) | https://api.n2p.io/v2 |
| Base URL (V1, legacy) | https://api.n2p.io/v1 |
| Authentication | V2: API key (X-API-Key header) or OpenID Connect, scope public_api.v2. V1: OAuth 2.0 password grant at https://api.n2p.io/v1/oauth/token/ |
| Format | JSON. V1 responses use the media type application/vnd.integrate.v1.10.0+json |
| Versioning | Major version in the path (/v1, /v2). V1 also checks the version in the Accept header |
| Machine-readable spec | https://api.n2p.io/v1/openapi.json and https://api.n2p.io/v2/openapi.json (OpenAPI 3) |
| Sandbox | No public sandbox. Testing is done against a real net2phone account |
| Rate limits | V2: per-operation quotas, reported in RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers, HTTP 429 when exceeded. V1: published per endpoint (for example 1 request per second and 15 per minute for user endpoints) |
| Webhooks / events | Yes. V2: /webhook-subscriptions with 29 event types (calls, queues, recordings, voicemail, SMS, AI agent). V1: /subscriptions/ for call, CDR and recording events |
| SDKs | Dialer SDK (@net2phone/dialer-sdk on npm) for embedding a softphone in a web page. No official REST client libraries |
| No-code | net2phone Integrate (integrate.net2phone.com) and a Zapier app |
| Developer portal | developer.net2phone.com |
| Status page | net2phone does not link an official status page from its developer portal. Ask Empire Telecom if you suspect an outage |
| How to get access | An account Admin creates an API key in the net2phone admin console. OAuth credentials are requested through the form on the developer portal |
| 1 | Confirm you have an Admin login. API keys can only be created by a user with Admin rights on the net2phone account. Ask Empire Telecom to grant or confirm admin access for the person who will manage the integration. |
| 2 | Create an API key (V2). In the net2phone web app go to the profile icon, then Admin Settings, then API Setup, and open the API Keys tab. Select Create New API Key and copy it straight away. net2phone shows a new key only once. |
| 3 | Store the key safely. Treat it like a password. Keep it in a secrets manager or server-side configuration, never in browser code or a public repository. |
| 4 | Request OAuth credentials if you need them. For apps that act as individual users (or for V1), fill in the credential request form on developer.net2phone.com (personal details, integration details, additional details). Existing customers should use their net2phone email address. net2phone then issues development credentials. |
| 5 | Check permissions. What the API returns depends on the user behind the key or token. Admins see the whole account. Regular users see only their own calls, their departments' calls and their own settings. |
| 6 | Rotate and revoke. Revoke a key straight away if it is lost or exposed, rotate keys regularly, and remove keys you no longer use (same API Keys tab). |
Tip: Some V2 features, such as SMS and AI virtual agents, need the matching service on the account. If an endpoint returns 402 (feature unavailable), ask Empire Telecom to enable the feature.
Send the key in the X-API-Key header on every request.
| GET https://api.n2p.io/v2/users/@me X-API-Key: <your-api-key> Accept: application/json |
The V2 specification lists two security schemes on every operation: n2pApiKeyAuth (API key) and n2pOpenIdConnect (OpenID Connect bearer token), both with the scope public_api.v2. Use the API key for server-to-server integrations. Use OpenID Connect only if net2phone has issued you OAuth credentials for a user-facing app.
V1 uses the OAuth 2.0 resource-owner password grant. You send your developer client ID, the user's net2phone email and password, and the grant type to the token endpoint. The response contains an access token and a refresh token. Access tokens expire, so refresh them with the refresh token before they run out.
| POST https://api.n2p.io/v1/oauth/token/ Content-Type: application/x-www-form-urlencoded grant_type=password&client_id=<client-id>&username=<email>&password=<password> |
The form field names above follow the standard OAuth password grant; confirm them in the V1 explorer before use.
Then call the API with the bearer token:
| GET https://api.n2p.io/v1/users/current/ Authorization: Bearer <access-token> Accept: application/vnd.integrate.v1.10.0+json |
Important: Build new integrations on V2 with an API key. V1 depends on a user's password, and V1 features differ by account platform generation (see below).
V1 responses include a generation value on the account: gen_v, gen_p, gen_x or gen_u. Many V1 parameters only work on some generations. For example, GET /users/ returns every user on Gen V (net2phone Canada) accounts but only the current user on Gen P, U and X. The V2 specification marks its operations for the unite and unite3 account backends.
All V2 paths below are relative to https://api.n2p.io/v2. Paths containing a colon (for example :search) are custom actions and are part of the path.
| Method | Path | What it does |
|---|---|---|
| GET | /users/@me | Returns the user who owns the API key or token |
| GET | /users/{user_id}/call-forwarding-settings | Read a user's call forwarding settings |
| PUT | /users/{user_id}/call-forwarding-settings | Update call forwarding. Regular users can change only their own; Admins can change anyone's |
| GET | /sip-registrations | Recent SIP device registrations against extensions, newest first |
| Method | Path | What it does |
|---|---|---|
| POST | /call-detail-records:search | Search call detail records (calls, plus their voicemails and recordings), newest first, cursor-paged |
The search is a POST with a JSON filter body (for example by date range, direction, answered or not, department, unread voicemail or recording). Admins see every call in the account; regular users see their own calls, calls to their departments and some voicemail fallbacks. Check the explorer for the current filter fields.
| Method | Path | What it does |
|---|---|---|
| GET | /call-recordings/{call_recording_id}:generate-audio-download-link | Get a temporary download link for a recording's audio |
| POST | /call-recordings:batch-set-view-status | Mark several recordings as viewed or not viewed |
| POST | /call-recordings:batch-delete | Delete several recordings and their audio |
The download-link endpoint behaves differently depending on the Accept header: with Accept: application/json it returns 200 and a JSON object containing the link; with any other or no Accept it returns 302 with the temporary URL in the Location header. It returns 409 if the audio is not ready. Recording IDs come from call detail records and from the CallRecorded webhook.
| Method | Path | What it does |
|---|---|---|
| DELETE | /voicemails/{voicemail_id} | Mark a voicemail deleted and remove its audio |
Voicemails themselves are found through /call-detail-records:search and the VoicemailReceived webhook.
| Method | Path | What it does |
|---|---|---|
| GET | /call-queues | List call queues |
| GET | /call-queues/{call_queue_id}/statistics | Live statistics for a queue |
| GET | /call-queues/{call_queue_id}/statistics/supervisor | Queue statistics from the supervisor view |
| POST | /call-queues/{call_queue_id}/queue-report | Build a historical report for the queue |
| POST | /call-queues/{call_queue_id}/agents-report | Build a report on the queue's agents |
These are the endpoints to use for wallboards. Statistics return 422 if the queue type does not support them.
| Method | Path | What it does |
|---|---|---|
| GET | /extension-presences | List extension presence (available, on a call and so on), ordered by extension number, cursor-paged |
Filters include presence status, extension and presence owner. Admins see every extension; regular users see only their own.
| Method | Path | What it does |
|---|---|---|
| GET | /phone-numbers | List the account's phone numbers, newest first. include_counters=true adds usage counters |
| POST | /available-phone-numbers:lookup | Search net2phone's pool of available numbers (Admin only) |
| POST | /phone-numbers:batch-create | Add available numbers to the account (Admin only) |
| POST | /phone-numbers/{phone_number_id}:unassign | Unassign a number from its current user or feature |
| POST | /porting/port-out-requests | Record a request to port numbers away and get the port-out PIN |
Tip: Ordering numbers adds billable services. For Empire Telecom customers, ask Empire Telecom to order or port numbers so billing stays correct.
| Method | Path | What it does |
|---|---|---|
| GET | /blocked-callers | List blocked callers (account-level and user-level) |
| POST | /blocked-callers | Block a caller |
| GET | /anonymous-callers-blocking-settings | Read anonymous-caller blocking settings |
| PUT | /anonymous-callers-blocking-settings:set-for-current-user | Set anonymous-caller blocking for the current user |
| Method | Path | What it does |
|---|---|---|
| GET | /messaging-enabled-phone-numbers | List numbers enabled for SMS. current_user_access filters by messaging_allowed (default) or reference_only |
| POST | /channel-conversations/{channel_conversation_id}/items | Post an item (message) into a channel conversation |
| POST | /direct-user-conversations/{direct_user_conversation_id}/items | Post a message into a one-to-one conversation |
| POST | /direct-group-conversations/{direct_group_conversation_id}/items | Post a message into a group conversation |
| GET | /campaign-registry-campaigns/{campaign_registry_campaign_id}/sharing-rejection-reasons | Reasons a 10DLC campaign share was rejected |
Business texting in the US requires 10DLC brand and campaign registration (The Campaign Registry). Ask Empire Telecom to arrange registration before you send SMS through the API. Incoming and outgoing texts are delivered as MessageReceived and MessageSent webhooks.
| Method | Path | What it does |
|---|---|---|
| POST | /huddle-rooms | Create a Huddle (video meeting) room |
net2phone's V2 API also manages its AI voice agents. Verified operations include:
| Method | Path | What it does |
|---|---|---|
| GET, POST | /virtual-agent/virtual-agents | List or create virtual agents |
| GET, POST | /virtual-agent/knowledge-bases | List or create knowledge bases |
| GET, PUT, DELETE | /virtual-agent/knowledge-bases/{knowledge_base_id} | Read, update or delete a knowledge base |
| GET, POST | /virtual-agent/knowledge-bases/{knowledge_base_id}/data-imports | List or start knowledge-base data imports |
| GET, POST | /virtual-agent/mcp-servers | List or register MCP tool servers for agents |
| POST | /virtual-agent/virtual-agents/{virtual_agent_id}/mcp-servers | Attach an MCP server to an agent |
| GET | /virtual-agent/virtual-agents/{virtual_agent_id}/voice-conversation-templates | List an agent's voice conversation templates |
| GET, PUT, DELETE | /virtual-agent/virtual-agents/{virtual_agent_id}/voice-conversation-templates/{voice_conversation_template_id} | Manage one template |
| GET, PUT | /virtual-agent/virtual-agents/{virtual_agent_id}/pbx-directory-configuration | Read or set the agent's PBX directory settings |
| GET | /virtual-agent/phone-numbers | Numbers assigned to virtual agents |
| POST, DELETE | /virtual-agent/phone-numbers/{phone_number_id}/voice-conversation-template-assignment | Set or clear the template on a number |
| GET | /virtual-agent/conversations:export | Export agent conversations |
| GET | /virtual-agent/tts-voices | List text-to-speech voices |
| GET | /virtual-agent/voice-languages | List supported voice languages |
| GET | /virtual-agent/usage | Current virtual agent usage |
| Method | Path | What it does |
|---|---|---|
| GET | /webhook-event-types | List the event types available to your account |
| GET | /webhook-subscriptions | List webhook subscriptions |
| POST | /webhook-subscriptions | Create a subscription (events are sent to endpoint_url) |
| GET | /webhook-subscriptions/{webhook_subscription_id} | Read a subscription |
| PUT | /webhook-subscriptions/{webhook_subscription_id} | Update a subscription |
| DELETE | /webhook-subscriptions/{webhook_subscription_id} | Delete a subscription |
| PUT | /webhook-subscriptions/{webhook_subscription_id}/secret | Regenerate the subscription's secret |
All paths are relative to https://api.n2p.io/v1. Note the trailing slashes.
| Method | Path | What it does | Published limit |
|---|---|---|---|
| GET | /accounts/current/ | The current account (domain, generation, package, account number) | 1/s, 15/min |
| GET | /users/ | Users on the account (all users on Gen V; current user only on other generations) | 1/s, 15/min |
| GET | /users/current/ | The authenticated user | 1/s, 15/min |
| GET | /users/{userId}/ | One user | 1/s, 15/min |
| GET | /cdrs/users/ | Call detail records for users | 5/s, 15/min |
| GET | /cdrs/users/current/ | CDRs for the authenticated user | 5/s, 15/min |
| GET | /cdrs/users/{userId}/ | CDRs for one user | 5/s, 15/min |
| POST | /calls/ | Click-to-call: place a call (to required; from, auto_answer optional). Returns 201 | 1/s, 15/min |
| POST | /subscriptions/ | Create a webhook subscription. Returns 202 | 1/s, 5/min |
| GET | /subscriptions/{subscriptionId}/ | Read a subscription | 1/s, 5/min |
| DELETE | /subscriptions/{subscriptionId}/ | Delete a subscription. Returns 204 | 1/s, 5/min |
| GET | /available/endpoint/ | List available endpoints | Not published |
V1 CDR queries take start_date (required), end_date, user (repeatable), type (Incoming, Outgoing, On Net), cursor, and either limit (1-100, default 20; Gen P, X, U) or page_size (1-100, default 10; Gen V). Gen V also supports recording_available, min_duration, max_duration and phone_number. Results come back as { "more": true|false, "cursor": "...", "result": [ ... ] }. On Gen V each CDR's from and to can include a recordings array with recording_id, url (download link) and status.name (Processing, Available, No Recording, Deleted, Archived, Ignored).
Create a subscription with POST /webhook-subscriptions, giving the endpoint_url that should receive events and the event types you want. Call GET /webhook-event-types first: it returns the event types your account can use (each with an id such as call_ringing, a display_name and a platform). The V2 specification lists these 29 callback events:
| Area | Events |
|---|---|
| Call progress | CallRinging, CallAnswered, CallCompleted, CallMissed, CallBusy, CallBlocked, CallForward |
| Call handling | CallHold, CallResume, CallPark, CallUnpark, CallPickup, CallBlindTransfer, CallConsultativeTransfer |
| Ring groups and queues | CallRgQueueEntered, CallRgQueueTier, CallRgQueueCompleted |
| Recordings | CallRecorded, CallRecordingFailed, CallRecordingAnalyticsResults |
| Voicemail | VoicemailReceived, VoicemailNotify, VoicemailMissed |
| Messaging | MessageReceived, MessageSent |
| Click-to-call | ClickToCallResult |
| Emergency | EmergencyCall |
| AI virtual agent | AiAgentConversationEnded, AiAgentConversationSummaryFinished |
Each subscription has a secret, which you can regenerate with PUT /webhook-subscriptions/{id}/secret. Use it to confirm that events really come from net2phone; the exact signing method is described in the Webhooks section of the developer portal.
POST /subscriptions/ takes post_uri (your HTTPS URL), the booleans calls, cdrs and recordings to choose event families, an optional user (default * for all users) and expires_in in seconds (default 7200, maximum 604800, which is 7 days). Re-create subscriptions before they expire. V1 call events are CallRinging, CallAnswered, CallWithAutoAttendant and CallCompleted. Each carries from and to objects (number or extension, call_id, state of progressing, ringing, active or ended), time_start, time_answer, duration in seconds, on_net and by_call_id for transfers.
Important: net2phone's V1 specification states that webhook responses are discarded and V1 webhook requests are never retried. If your endpoint is down, those events are lost. Reconcile with a CDR query afterwards.
2xx and do the heavy work in the background.| Status | Meaning |
|---|---|
| 200 / 201 / 202 / 204 | Success (read / created / accepted / deleted) |
| 302 | Redirect to a temporary file URL (recording download without a JSON Accept) |
| 400 / 422 | Invalid request or unsupported operation. In V1, 422 can also mean an invalid version in the Accept header |
| 401 | Missing or invalid API key or token |
| 402 | Feature not available on the account |
| 403 | The user behind the key lacks permission |
| 404 | Resource not found |
| 409 | Conflict (for example, recording audio not ready) |
| 429 | Rate limit exceeded |
| 500 | Server error |
RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset on every response, slow down as Remaining approaches zero, and after a 429 wait until the reset time before retrying.limit with before and after cursors. V1 CDRs use cursor and the more flag.{ "status": <code>, "message": "..." }. Log the full body.429 and 5xx with exponential backoff. Do not retry 400, 401, 403 or 422 without fixing the request.| 1 | Create or reuse an Admin API key. |
| 2 | Call POST /call-detail-records:search with a filter body covering yesterday's start and end times (UTC). |
| 3 | Store the records, then keep requesting the next page with the returned cursor until there are no more. |
| 4 | Respect the RateLimit-* headers between pages. |
| 1 | Find the recording ID in a call detail record or a CallRecorded webhook. |
| 2 | Call GET /call-recordings/{call_recording_id}:generate-audio-download-link with Accept: application/json. |
| 3 | Download the audio from the returned link straight away, because it is temporary. |
| 4 | If you get 409, the audio is still processing; try again later. |
| 1 | Call GET /webhook-event-types to confirm CallCompleted is available. |
| 2 | Call POST /webhook-subscriptions with your HTTPS endpoint_url and the CallCompleted event (add CallMissed and VoicemailReceived if needed). |
| 3 | Save the subscription ID and secret, and verify incoming requests. |
| 4 | Use GET /webhook-subscriptions to audit, and DELETE to remove old ones. |
| 1 | List queues with GET /call-queues. |
| 2 | Poll GET /call-queues/{call_queue_id}/statistics for each queue on a modest interval, within the rate limit. |
| 3 | Add agent status from GET /extension-presences. |
| 4 | For live changes, subscribe to CallRgQueueEntered, CallRgQueueTier and CallRgQueueCompleted. |
| 1 | Subscribe to ClickToCallResult so you know the outcome. |
| 2 | Place the call through the click-to-call endpoint shown under "Click-to-Call" in the V2 explorer, or legacy POST /v1/calls/ with to (and from where your generation needs it). |
| 3 | To embed a full softphone in a web page instead, use the Dialer SDK (npm install @net2phone/dialer-sdk, then new Net2PhoneDialer({ rootHtmlElement }) and placeCall({ to })). |
| 1 | Call GET /extension-presences with an Admin key. |
| 2 | Filter by presence status if you only want busy or available extensions. |
| 3 | Page through with the after cursor. |
| 1 | Call POST /blocked-callers with the number to block. |
| 2 | Confirm with GET /blocked-callers. |
Need a hand? Call Empire Telecom support at (732) 363-9898, email support@empiretelecomnj.com, or open a ticket in the customer portal.