Migrate from API v1/v2/v3 to v4
This article explains how to migrate existing
Who should read this
Use this guide if you currently integrate with any
v1v2v3
Legacy API endpoints will be supported only until March 31, 2027. To avoid disruption, migrate your integration to v4 before that date.
New customers can only use v4.
What changes in v4
API v4 introduces a more consistent API structure so future API development can build on a unified foundation.
Compared with the legacy API surface, v4 generally:
-
Standardizes endpoint paths under
/api/v4/... -
Groups resources by domain, such as:
/voice/users/routing/messaging/reporting/campaigns/billing/contact_center/tasks
-
Separates collection, detail, and sub-resource endpoints more clearly
-
Replaces several action-style or product-specific legacy paths with resource-oriented endpoints
-
Uses a standardized Bearer token authentication model instead of relying on user-specific or contact-center-specific keys
For a detailed breakdown of all changes between the v1/2/3 endpoints and v4, download Endpoint migration (v1/v2/v3 → v4).
Authentication changes
In v4, authentication uses a standardized Bearer token approach instead of passing the API key in the request path. This makes requests more consistent and aligns
Authorization header for every request, like this:
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
Accept: application/jsonGenerate a scoped API key for v4
Before migrating to v4, admins must create an API key in the API keys page in the
Authorization header. When creating a key, admins can assign only the scopes required for the integration, which helps limit access to specific API domains (scopes) and operations. We recommend selecting the minimum required scopes and reviewing them carefully before going live. For instructions, see API keys and Authentication.
For example:
curl --request GET \
--url https://api.voiso.com/api/v4/users \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'| Group | Endpoint | Scope/Domain |
|---|---|---|
| Messaging | POST /api/v4/messaging/conversations | messaging.conversations.manage |
| GET /api/v4/messaging/whatsapp_templates | messaging.whatsapp_templates.read | |
| GET /api/v4/messaging/canned_messages | messaging.canned_messages.read | |
| POST /api/v4/messaging/sms | messaging.sms.send | |
| GET /api/v4/messaging/conversations/{conversation_id}/messages | messaging.conversations.read | |
| POST /api/v4/messaging/conversations/{conversation_id}/messages | messaging.conversations.manage | |
| Users | GET /api/v4/users | users.read |
| GET /api/v4/users/{user_id} | users.read | |
| GET /api/v4/users/deleted | users.read | |
| GET /api/v4/users/teams | users.teams.read | |
| Campaigns | GET /api/v4/campaigns | campaigns.read |
| POST /api/v4/campaigns | campaigns.manage | |
| GET /api/v4/campaigns/{campaign_id} | campaigns.read | |
| PATCH /api/v4/campaigns/{campaign_id} | campaigns.manage | |
| POST /api/v4/campaigns/{campaign_id}/leads | campaigns.manage | |
| PATCH /api/v4/campaigns/{campaign_id}/leads | campaigns.manage | |
| POST /api/v4/campaigns/{campaign_id}/start | campaigns.manage | |
| POST /api/v4/campaigns/{campaign_id}/stop | campaigns.manage | |
| POST /api/v4/campaigns/{campaign_id}/pause | campaigns.manage | |
| Reporting | GET /api/v4/reporting/cdrs | reporting.cdrs.read |
| GET /api/v4/reporting/cdrs/{cdr_id} | reporting.cdrs.read | |
| Routing | GET /api/v4/routing/queues | routing.queues.read |
| Contact center | GET /api/v4/contact_center/wrapup_codes | contact_center.wrapup_codes.read |
| Voice | POST /api/v4/voice/calls | voice.call.manage |
| POST /api/v4/voice/calls/{call_id/hangup | voice.call.manage | |
| Numbers | GET /api/v4/numbers | numbers.read |
| Tasks | POST /api/v4/tasks/scheduled_callbacks | tasks.scheduled_callbacks.manage |
| GET /api/v4/tasks/webhook_failures | tasks.webhooks.read | |
| POST /api/v4/tasks/webhook_failures/{webhook_failure_id}/retrigger | tasks.webhooks.manage | |
| Billing | GET /api/v4/billing/balance | billing.balance.read |
Balance endpoint auth example
Legacy auth style
GET /api/v1/{api_key}/balancev4 auth style
GET /api/v4/billing/balance
Authorization: Bearer YOUR_API_TOKENWhat this means for your current integration
If you are already using
However:
- You should start planning your migration to v4 now
- Any new development should target v4 only
- New customers will not be able to use legacy endpoints
We recommend migrating incrementally rather than rewriting everything at once.
Migration approach
It is safe to adopt v4 incrementally and run your migration in phases.
A practical migration plan is:
- Inventory the legacy endpoints your integration currently calls.
- Map each legacy endpoint to its v4 replacement.
- Update read paths first where possible (
GETendpoints). - Migrate write and action endpoints next (
POST,PATCH,PUT). - Test each migrated workflow in isolation.
- Remove legacy endpoint usage before the 12-month support period ends.
Recommended migration plan
Phase 1: Migrate read-only endpoints
Start with GET endpoints that do not change business behavior, for example:
- users
- teams
- queues
- numbers
- campaign read endpoints
- reporting read endpoints
- billing balance
This lets you validate resource mapping and response handling with lower operational risk.
Phase 2: Migrate write workflows
Next, migrate workflows that create or update state, for example:
- voice calls
- messaging sends
- scheduled callbacks
- campaign creation and updates
- lead creation and updates
Phase 3: Migrate operational actions
Finally, migrate action-driven workflows and edge-case flows, such as:
- call hangup
- campaign start/stop/pause
- webhook failure retrigger
Endpoint mapping
The following table shows the current mapping from legacy endpoints to v4.
Voice
| v4 endpoint | Legacy endpoint |
|---|---|
POST /api/v4/voice/calls | POST /api/v1/{api_key}/click2call |
POST /api/v4/voice/calls/:id/hangup | POST /api/v1/{api_key}/click2call_hangup |
Users
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/users | GET /api/v2/cdr/agents |
GET /api/v4/users/:id | GET /api/v1/{api_key}/agents_status |
GET /api/v4/users/deleted | GET /api/v2/cdr/deleted_agents |
GET /api/v4/users/deleted/:id | GET /api/v2/cdr/deleted_agents |
Teams
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/users/teams | GET /api/v2/cdr/teams |
GET /api/v4/users/teams/:id | GET /api/v2/cdr/teams |
GET /api/v4/users/teams/:id/users | GET /api/v2/cdr/teams |
GET /api/v4/users/teams/:id/supervisors | GET /api/v2/cdr/teams |
Routing queues
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/routing/queues | GET /api/v2/cdr/queues |
GET /api/v4/routing/queues/:id | GET /api/v2/cdr/queues |
GET /api/v4/routing/queues/:id/users | GET /api/v2/cdr/queues |
GET /api/v4/routing/queues/:id/supervisors | GET /api/v2/cdr/queues |
Routing skills
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/routing/skills | — |
GET /api/v4/routing/skills/:id | — |
GET /api/v4/users/skills | GET /api/user_management/v1/users |
GET /api/v4/users/skills/:id | — |
Numbers
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/numbers | GET /api/numbers/v1/numbers |
GET /api/v4/numbers/:id | GET /api/numbers/v1/numbers |
Scheduled callbacks
| v4 endpoint | Legacy endpoint |
|---|---|
POST /api/v4/tasks/schedule_callbacks | POST /api/task/v1/scheduled_callbacks |
GET /api/v4/tasks/schedule_callbacks | POST /api/task/v1/scheduled_callbacks |
GET /api/v4/tasks/schedule_callbacks/:id | POST /api/task/v1/scheduled_callbacks |
Messaging channel profiles
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/messaging/channel_profiles | — |
GET /api/v4/messaging/channel_profiles/:id | — |
WhatsApp & SMS conversations
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/messaging/conversations/:id | CDR API |
GET /api/v4/messaging/conversations/:id/messages | GET /api/conversation/v1/conversations/{uuid}/messages |
GET /api/v4/messaging/conversations/:id/messages/:id | GET /api/conversation/v1/conversations/{uuid}/messages |
POST /api/v4/messaging/conversations | POST /api/v3/messages/whatsapp |
POST /api/v4/messaging/conversations/:id/messages | POST /api/conversation/v1/conversations/{uuid}/messages |
POST /api/v4/messaging/sms | POST /api/v1/{api_key}/sendsms |
WhatsApp & SMS templates
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/messaging/canned_messages | GET /api/v3/messages/sms/templates |
GET /api/v4/messaging/canned_messages/:id | GET /api/v3/messages/sms/templates |
GET /api/v4/messaging/whatsapp_templates | GET /api/v3/messages/whatsapp/templates |
GET /api/v4/messaging/whatsapp_templates/:id | GET /api/v3/messages/whatsapp/templates |
Reporting
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/reporting/cdrs | GET /api/v2/cdr |
GET /api/v4/reporting/cdrs/events | GET /api/v2/cdr |
Campaigns
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/campaigns | GET /api/dialer/v1/campaigns |
GET /api/v4/campaigns/:id | GET /api/dialer/v1/campaigns/{campaign_id} |
POST /api/v4/campaigns | POST /api/dialer/v1/campaigns |
PATCH /api/v4/campaigns/:id | PUT /api/dialer/v1/campaigns/{campaign_id} |
PATCH /api/v4/campaigns/:id/users | PATCH /api/dialer/v1/campaigns/{campaign_id}/agents |
PATCH /api/v4/campaigns/:id/teams | PATCH /api/dialer/v1/campaigns/{campaign_id}/agents |
POST /api/v4/campaigns/:id/start | POST /api/dialer/v1/campaigns/{campaign_id}/operation |
POST /api/v4/campaigns/:id/stop | POST /api/dialer/v1/campaigns/{campaign_id}/operation |
POST /api/v4/campaigns/:id/pause | POST /api/dialer/v1/campaigns/{campaign_id}/operation |
POST /api/v4/campaigns/:id/leads | POST /api/v1/{api_key}/campaigns/{campaign_id}/contacts |
PATCH /api/v4/campaigns/:id/leads | PUT /api/v1/{api_key}/campaigns/{campaign_id}/contacts |
Billing
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/billing/balance | GET /api/v1/{api_key}/balance |
Contact center
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/contact_center/wrapup_codes | GET /api/v2/cdr/wrapup_codes |
GET /api/v4/contact_center/wrapup_codes/:id | GET /api/v2/cdr/wrapup_codes |
GET /api/v4/contact_center/wrapup_code_groups | GET /api/v2/cdr/wrapup_codes |
GET /api/v4/contact_center/wrapup_code_groups/:id | GET /api/v2/cdr/wrapup_codes |
Webhooks failures
| v4 endpoint | Legacy endpoint |
|---|---|
GET /api/v4/tasks/webhooks/failures | GET /api/webhooks/v1/failures |
GET /api/v4/tasks/webhooks/failures/:id/retrigger | POST /api/webhooks/v1/failures/{id}/retrigger |
Important migration patterns
1. Move from legacy path styles to resource-oriented v4 paths
Legacy APIs use several path styles, including:
- embedded API keys in the path, such as
/{api_key}/... - product-specific prefixes such as
/cdr,/dialer,/numbers,/conversation, and/webhooks - action-style endpoints such as
click2call_hangup
v4 standardizes these into consistent resource paths under /api/v4/....
2. Expect some one-to-many mapping changes
Some legacy endpoints returned broad datasets that are now represented by multiple v4 endpoints.
Examples:
- team information is split into team detail, team users, and team supervisors
- queue information is split into queue detail, queue users, and queue supervisors
- CDR reporting is split into CDRs and CDR events
- wrap-up metadata is split into wrap-up codes and wrap-up code groups
3. Action endpoints are more explicit in v4
Some operations that were previously multiplexed through a single endpoint are now expressed as separate actions.
Example:
-
legacy:
POST /api/dialer/v1/campaigns/{campaign_id}/operation -
v4:
POST /api/v4/campaigns/:id/startPOST /api/v4/campaigns/:id/stopPOST /api/v4/campaigns/:id/pause
This makes intent clearer and reduces ambiguity in client code.
4. Some HTTP methods change in v4
In a few places, v4 uses a different HTTP method for an equivalent operation.
Examples:
- campaign updates move from
PUTtoPATCH - webhook retrigger changes from
POSTtoGETin the current mapping
Review your HTTP method usage carefully when updating clients, SDK wrappers, and firewall allowlists.
Before and after examples
Click-to-call
Before
POST /api/v1/{api_key}/click2callPOST /api/v1/{api_key}/click2call_hangup
After
POST /api/v4/voice/callsPOST /api/v4/voice/calls/:id/hangup
Campaign operations
Before
POST /api/dialer/v1/campaigns/{campaign_id}/operation
After
POST /api/v4/campaigns/:id/startPOST /api/v4/campaigns/:id/stopPOST /api/v4/campaigns/:id/pause
Messaging
Before
POST /api/v1/{api_key}/sendsmsPOST /api/v3/messages/whatsappPOST /api/conversation/v1/conversations/{uuid}/messages
After
POST /api/v4/messaging/smsPOST /api/v4/messaging/conversationsPOST /api/v4/messaging/conversations/:id/messages
Testing checklist
Before switching fully to v4, verify that you have tested:
- endpoint path updates
- HTTP method changes
- path parameter changes, for example
:idand{uuid}differences - request body compatibility
- response parsing in your application
- pagination, filtering, and sorting behavior where applicable
- error handling and retry logic
- permission and authentication behavior
- monitoring, alerting, and audit logs
Frequently asked questions
How long will legacy endpoints be supported?
Legacy v1, v2, and v3 endpoints will continue to be supported for 12 months to March 31, 2027.
Do I need to migrate immediately?
You do not need to migrate immediately, but you should begin planning now. All customers are expected to complete migration to v4 within the support window.
Can new customers use legacy APIs?
No. New customers can use only v4 endpoints.
Can I migrate incrementally?
Yes. We recommend migrating endpoint groups and workflows in phases instead of replacing your entire integration at once.
Summary
API v4 is the long-term API foundation for future development. Existing customers have a 12-month window to migrate from legacy v1, v2, and v3 endpoints. Start by mapping your current usage, move read paths first, then migrate writes and operational actions, and complete all testing before disabling legacy usage.