Developers · Reference

Every route, in the order the controllers serve it.

148 routes under /api/v1, plus health and metrics. Each one is grouped by the controller that owns it, with the permission it requires and what it does in a sentence.

On this page

Jump to a group

Auth, then a controller for each part of the phone system, then the operator-only platform surface at the end.

Auth

modules/auth/auth.controller.ts

Session cookie or bearer token. See the authentication section above for how the token works.

MethodPathWhat it doesPermission
POST/api/v1/auth/loginSign in and receive a session.public, no session
POST/api/v1/auth/mfa/verifyComplete the multi-factor challenge.MFA-exempt: this is how MFA itself gets satisfied.session only
POST/api/v1/auth/mfa/enrolStart authenticator enrolment.MFA-exempt.session only
POST/api/v1/auth/mfa/enrol/confirmConfirm enrolment and receive recovery codes.MFA-exempt.session only
GET/api/v1/auth/meThe signed-in user, their active tenant and role, every tenant they belong to, and their sorted permission list. The one call a portal makes on load.session only
POST/api/v1/auth/switch-tenantChange the active account for this session.Refuses without a membership or an open support session in the target account.session only
POST/api/v1/auth/portal-modeSwitch the active tenant membership between Simple and Advanced mode.session only
POST/api/v1/auth/passwordChange the signed-in user's password.Every other session for this user is signed out.session only
POST/api/v1/auth/logoutEnd the session and clear the cookie.MFA-exempt.session only
GET/api/v1/auth/rolesThe permission set for every tenant role, for a portal that explains what a role can do.session only

Extensions

modules/extensions/extensions.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/extensionsList the lines on this account.Offset pagination: `?page=&pageSize=`, capped at 100.extension.read
GET/api/v1/extensions/next-numberSuggest the next free extension number.extension.read
POST/api/v1/extensionsAdd a line: the Add Line wizard, executed server-side, in one call.Takes `idempotencyKey` (8-120 chars); a repeat with the same key replays the recorded result rather than creating a second line.extension.manage
GET/api/v1/extensions/:idGet one line, with its site, voicemail box, devices, assigned numbers, emergency location and dial permission.extension.read
GET/api/v1/extensions/:id/sip-credentialsThe live SIP username, password and server settings a phone needs to register this line.Reading it is audited by name every time; the extension record itself never carries the password.extension.manage
GET/api/v1/extensions/:id/dependenciesWhat breaks if this line is removed.extension.read
PATCH/api/v1/extensions/:idUpdate a line's settings.extension.manage
DELETE/api/v1/extensions/:idRemove a line, choosing what happens to its number.extension.manage

Numbers

modules/numbers/numbers.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/numbersList the numbers on this account.Offset pagination, capped at 200.number.read
GET/api/v1/numbers/territoriesWhere the platform can supply a number right now.number.read
GET/api/v1/numbers/searchSearch carrier inventory for numbers available to buy.Returns `{ numbers, notes }`. `notes` carries the reasons a territory or capability came back empty, so keep it: it is how a customer learns emergency calling is unavailable before buying, not after.number.read
POST/api/v1/numbers/purchaseBuy a number from a carrier and add it to inventory.Idempotent on `idempotencyKey`; a concurrent retry gets `409 This number order is already in progress.`number.purchase
POST/api/v1/numbers/:e164/assignRoute a number to an extension, ring group, queue, IVR or call flow.number.manage
POST/api/v1/numbers/:e164/unassignStop routing a number anywhere.number.manage
POST/api/v1/numbers/:e164/caller-idSet the outbound caller ID name (CNAM) for a number.number.manage
GET/api/v1/numbers/:e164One number, with its routing and emergency state.number.read

Devices

modules/devices/devices.controller.ts, branding.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/devicesList enrolled phones with their registration state.device.read
GET/api/v1/devices/catalogPhone models we can provision, and hardware we sell.device.read
POST/api/v1/devicesEnrol a phone by MAC address and issue its provisioning URL.device.manage
POST/api/v1/devices/:id/assign-extensionPut an extension on a line key of this phone.device.manage
POST/api/v1/devices/:id/reissue-tokenIssue a fresh provisioning URL; the previous one stops working.device.manage
DELETE/api/v1/devices/:idRemove a phone from the account.device.manage
GET/api/v1/devices/provisioning-settingsWhere phones should look for their configuration.device.read
GET/api/v1/devices/brandingThe logo and idle text handsets are showing.device.read
PUT/api/v1/devices/brandingSet the logo and idle text for every handset on the account.device.manage
DELETE/api/v1/devices/brandingPut the handsets back to the default screen.device.manage

Emergency (E911)

modules/emergency/emergency.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/emergency/locationsEmergency (911) addresses on this account.emergency.read
POST/api/v1/emergency/locationsAdd an emergency address; it is validated immediately.emergency.manage
POST/api/v1/emergency/locations/:id/validateRe-run carrier validation on an address.emergency.manage
POST/api/v1/emergency/numbers/:e164/registerRegister a validated address against a number with the carrier.emergency.manage
GET/api/v1/emergency/unprotected-linesLines that would dial 911 without a usable address.emergency.read

Call handling

modules/ring-groups, queues, ivrs, call-flows, schedules, sites, dial-permissions

Ring groups, queues, auto attendants (IVRs), call flows, schedules, sites and dialling permissions each follow the same list / get / create / update / delete shape, with one or two operations of their own.

MethodPathWhat it doesPermission
GET/api/v1/ring-groupsList ring groups.routing.read
GET/api/v1/ring-groups/:idGet one ring group with its members.routing.read
POST/api/v1/ring-groupsCreate a ring group.routing.manage
PATCH/api/v1/ring-groups/:idUpdate a ring group.routing.manage
DELETE/api/v1/ring-groups/:idDelete a ring group.routing.manage
POST/api/v1/ring-groups/:id/membersAdd an extension to a ring group.routing.manage
PATCH/api/v1/ring-groups/:id/members/:extensionIdChange a member's ring delay, order, or enabled state.routing.manage
DELETE/api/v1/ring-groups/:id/members/:extensionIdRemove an extension from a ring group.routing.manage
PUT/api/v1/ring-groups/:id/members/orderSet the ring order for every member of the group.routing.manage
GET/api/v1/queuesList call queues.routing.read
GET/api/v1/queues/:idGet one queue with its agents.routing.read
POST/api/v1/queuesCreate a call queue.routing.manage
PATCH/api/v1/queues/:idUpdate a call queue.routing.manage
DELETE/api/v1/queues/:idDelete a call queue.routing.manage
POST/api/v1/queues/:id/agentsAdd an agent to a queue.routing.manage
PATCH/api/v1/queues/:id/agents/:extensionIdChange an agent's tier, position, or enabled state.routing.manage
DELETE/api/v1/queues/:id/agents/:extensionIdRemove an agent from a queue.routing.manage
GET/api/v1/ivrsList auto attendants.routing.read
GET/api/v1/ivrs/:idGet one auto attendant with its menu.routing.read
POST/api/v1/ivrsCreate an auto attendant.routing.manage
PATCH/api/v1/ivrs/:idUpdate an auto attendant.routing.manage
DELETE/api/v1/ivrs/:idDelete an auto attendant.routing.manage
POST/api/v1/ivrs/:id/optionsAdd a menu key.routing.manage
PUT/api/v1/ivrs/:id/optionsReplace the whole menu in one call.routing.manage
PATCH/api/v1/ivrs/:id/options/:optionIdChange one menu key.routing.manage
DELETE/api/v1/ivrs/:id/options/:optionIdRemove a menu key.routing.manage
GET/api/v1/call-flowsList call flows.routing.read
GET/api/v1/call-flows/:idGet one call flow with its recent versions.routing.read
GET/api/v1/call-flows/:id/versionsList saved versions of a call flow.routing.read
GET/api/v1/call-flows/:id/versions/:versionIdGet the full graph of one version.routing.read
POST/api/v1/call-flowsCreate a call flow as a draft.routing.manage
PATCH/api/v1/call-flows/:idRename a call flow.routing.manage
POST/api/v1/call-flows/:id/versionsSave a new draft version; returns the validation report.routing.manage
POST/api/v1/call-flows/:id/validateCheck a graph without saving or publishing it.routing.read
POST/api/v1/call-flows/:id/publishMake a version live.routing.manage
POST/api/v1/call-flows/:id/rollbackRepublish an earlier version.routing.manage
DELETE/api/v1/call-flows/:idDelete a call flow.routing.manage
GET/api/v1/schedulesList schedules.routing.read
GET/api/v1/schedules/:idGet one schedule with its holidays.routing.read
GET/api/v1/schedules/:id/stateWhether this schedule is open right now, and why.routing.read
POST/api/v1/schedulesCreate a schedule.schedule.manage
PATCH/api/v1/schedules/:idUpdate a schedule.schedule.manage
DELETE/api/v1/schedules/:idDelete a schedule.schedule.manage
POST/api/v1/schedules/:id/holidaysAdd a holiday.schedule.manage
PATCH/api/v1/schedules/:id/holidays/:holidayIdUpdate a holiday.schedule.manage
DELETE/api/v1/schedules/:id/holidays/:holidayIdRemove a holiday.schedule.manage
POST/api/v1/schedules/:id/close-nowClose the office temporarily, with a reason and an expiry.schedule.manage
DELETE/api/v1/schedules/:id/close-nowLift a temporary closure and go back to the normal schedule.schedule.manage
GET/api/v1/sitesList the sites in this account.tenant.read
GET/api/v1/sites/:idGet one site.tenant.read
POST/api/v1/sitesCreate a site.site.manage
PATCH/api/v1/sites/:idUpdate a site.site.manage
DELETE/api/v1/sites/:idDelete a site.site.manage
GET/api/v1/dial-permissionsList dialling permissions.tenant.read
GET/api/v1/dial-permissions/:idGet one dialling permission.tenant.read
POST/api/v1/dial-permissionsCreate a dialling permission.advanced.access
PATCH/api/v1/dial-permissions/:idUpdate a dialling permission.advanced.access
DELETE/api/v1/dial-permissions/:idDelete a dialling permission.advanced.access

Analytics

modules/analytics/analytics.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/analytics/summaryCall analytics for a date range.analytics.read
GET/api/v1/analytics/call-volumeDaily call volume series only.analytics.read
GET/api/v1/analytics/busiest-extensionsExtensions ranked by call count.analytics.read

Call history (CDR)

modules/cdr/cdr.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/cdrList calls.Call detail is regulated as CPNI.cdr.read
GET/api/v1/cdr/:idOne call, with its quality metrics.cdr.read

Billing and plans

modules/billing/billing.controller.ts, plans.controller.ts

MethodPathWhat it doesPermission
GET/api/v1/billing/subscriptionCurrent subscription, plan, seats and period.billing.read
GET/api/v1/billing/invoicesInvoices with their lines, most recent first.billing.read
GET/api/v1/billing/usageMinutes, numbers and storage this period, with the projected charge.billing.read
POST/api/v1/billing/previewMonthly cost delta for a proposed change (the Add Line wizard Review step).A POST because the proposed change is a structured request body, not because it changes anything.billing.read
PATCH/api/v1/billing/planMove the account to a different plan.billing.manage
PATCH/api/v1/billing/seatsChange the number of paid users.billing.manage
GET/api/v1/plansList the publicly available plans and their features.public, no session
GET/api/v1/plans/:codeOne plan, by its stable code.public, no session

Signup

modules/signup/signup.controller.ts

Public, because every one of these runs before the customer has an account. No endpoint takes a price from the client; every figure comes from the Plan, PlanFeature and HardwareSku rows on the server.

MethodPathWhat it doesPermission
POST/api/v1/signup/quotePrice a basket. No side effects: nothing is created, reserved, or charged.public, no session
POST/api/v1/signupCreate a pending tenant, an owner, an incomplete subscription and a draft number order.Guarded by an `idempotencyKey` unique constraint; a repeat submission cannot create a second account.public, no session
GET/api/v1/signup/:idWhere a signup got to, for a browser that came back.public, no session
POST/api/v1/signup/:id/confirmCapture payment, then activate, buy numbers and run guided setup, in that order.public, no session

Webhooks

modules/webhooks/webhook-endpoint.controller.ts

Managing your own outbound webhook subscriptions. See the webhooks section above for the delivery, signing and payload details.

MethodPathWhat it doesPermission
GET/api/v1/webhooks/endpointsList webhook endpoints. Signing secrets are never returned here.webhook.manage
GET/api/v1/webhooks/endpoints/:idGet one webhook endpoint.webhook.manage
GET/api/v1/webhooks/endpoints/:id/deliveriesRecent delivery attempts for one endpoint.Filter with `?status=PENDING|SUCCEEDED|FAILED`.webhook.manage
POST/api/v1/webhooks/endpointsCreate a webhook endpoint.The response carries the signing secret in cleartext. This is the only time it is ever returned.webhook.manage
PATCH/api/v1/webhooks/endpoints/:idUpdate a webhook endpoint.webhook.manage
POST/api/v1/webhooks/endpoints/:id/rotate-secretIssue a new signing secret; returned in cleartext once.Deliveries already in flight keep signing with the old secret.webhook.manage
DELETE/api/v1/webhooks/endpoints/:idDelete a webhook endpoint.webhook.manage

Enquiries

modules/enquiries/enquiries.controller.ts

MethodPathWhat it doesPermission
POST/api/v1/enquiriesSend an enquiry from the public website.Rate limited to 3 per minute per IP; see the rate limits section.public, no session
GET/api/v1/platform/enquiriesThe enquiry pipeline from the public website.platform.tenant.read
PATCH/api/v1/platform/enquiries/:idMove an enquiry through the pipeline.platform.tenant.manage

Platform (operator-only)

modules/platform/platform.controller.ts, teams/teams.controller.ts

Held by platform roles, not by a tenant role. This is how wiTech itself runs the service, included here for completeness rather than as a customer integration surface.

MethodPathWhat it doesPermission
GET/api/v1/platform/tenantsList every account on the platform.platform.tenant.read
GET/api/v1/platform/tenants/:idOne account, with its limits and open support sessions.platform.tenant.read
POST/api/v1/platform/tenantsCreate an account.platform.tenant.manage
POST/api/v1/platform/tenants/:id/suspendSuspend an account; calls in progress are not cut.platform.tenant.manage
POST/api/v1/platform/tenants/:id/reactivateReturn a suspended account to service.platform.tenant.manage
PATCH/api/v1/platform/tenants/:id/limitsChange concurrency, international, recording and advanced-mode limits.platform.tenant.manage
POST/api/v1/platform/tenants/:id/support-sessionOpen a time-boxed, logged support session into an account.platform.support.impersonate
DELETE/api/v1/platform/tenants/:id/support-session/:sessionIdEnd a support session immediately.platform.support.impersonate
GET/api/v1/platform/carriersCarriers, their routes, and what each is verified to do.platform.carrier.manage
POST/api/v1/platform/carriersAdd a carrier and optionally its credentials.platform.carrier.manage
PATCH/api/v1/platform/carriers/:idUpdate a carrier or rotate its credentials.platform.carrier.manage
PUT/api/v1/platform/carriers/:id/routesReplace a carrier routing table.platform.carrier.manage
POST/api/v1/platform/carriers/health-checkProbe every carrier now and record the result.platform.health.read
GET/api/v1/platform/healthDatabase, Redis, carrier and PBX node health.platform.health.read
GET/api/v1/platform/audit-logsPlatform-wide audit log.Offset pagination, capped at 200.platform.audit.read
GET/api/v1/platform/tenants/:tenantId/teams-trunkA tenant's Microsoft Teams Direct Routing trunk configuration.platform.carrier.manage
PUT/api/v1/platform/tenants/:tenantId/teams-trunkPair a tenant to Teams Direct Routing.platform.carrier.manage
PATCH/api/v1/platform/tenants/:tenantId/teams-trunkChange a tenant's Teams Direct Routing trunk settings.platform.carrier.manage
DELETE/api/v1/platform/tenants/:tenantId/teams-trunkRemove a Teams Direct Routing trunk.platform.carrier.manage

Health and metrics

modules/health/health.controller.ts

MethodPathWhat it doesPermission
GET/healthLiveness. Answers as long as the process is running.public, no session
GET/health/readyReadiness. Fails while the database is unreachable.503 when the database does not answer.public, no session
GET/metricsPrometheus metrics.Gated on an `x-metrics-token` header when `METRICS_TOKEN` is set.public, no session

Not built

What is not here yet, said plainly

No controller exists for voicemail, recordings, user invitations, API tokens, generic SIP trunk management, port requests, or fraud events, even though the underlying data models exist for several of them. If your integration needs one of these, ask; it tells us where to build next.