Summary and recommendation
Vonage exposes two distinct API surfaces that are easy to conflate.
The legacy Nexmo REST API (api.nexmo.com / rest.nexmo.com) uses API key + secret and handles account-level operations.
User management for Vonage Business Communications lives in a separate VBC Provisioning API at api.vonage.com/t/vbc.prod/provisioning/v1, which requires JWT authentication obtained via a dedicated OAuth 2.0 client credentials flow at https://api.vonage.com/token
not the standard Vonage application private key flow.
The VBC Provisioning API supports full CRUD on user objects: List (GET), Get (GET /{user_id}), Create (POST), Update (PUT - full replacement semantics), and Delete (DELETE).
Key user object fields include id (UUID), email, status, role, extension, phone_number, and department, which are the primary fields needed to maintain an accurate identity graph across your directory and downstream systems.
SCIM 2.0 is available on the Advanced plan with SSO as a hard prerequisite.
Supported IdPs are Okta, Microsoft Entra ID, Google Workspace, and OneLogin.
The SCIM endpoint URL is tenant-generated in the admin portal - no static public base URL is published.
Webhooks for user-management events are not available;
change detection requires polling the List Users endpoint or relying on IdP-driven SCIM push.
API quick reference
| Has user API | Yes |
| Auth method | API Key + Secret (Basic Auth header or query params) for Account API; JWT (Bearer token) for Application and newer APIs |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Advanced (formerly Business tier) |
Authentication
Auth method: API Key + Secret (Basic Auth header or query params) for Account API; JWT (Bearer token) for Application and newer APIs
Setup steps
- Log in to the Vonage API Dashboard at https://dashboard.nexmo.com.
- Locate your API Key and API Secret on the dashboard home page.
- For Basic Auth: Base64-encode 'api_key:api_secret' and pass as Authorization: Basic
header. - For JWT auth: Create a Vonage Application in the dashboard, download the private key, and generate a signed JWT using your application ID and private key.
- Include the JWT as Authorization: Bearer
header on supported endpoints.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique user identifier (UUID) | system-generated | immutable | Used in SCIM as the externalId reference |
| name | string | Display name of the user | required | optional | Maps to SCIM displayName |
| string | User's email address; used as login identifier | required | optional | Must be unique within the account | |
| extension | string | Internal phone extension assigned to the user | optional | optional | Vonage Business Communications specific |
| phone_number | string | DID number assigned to the user | optional | optional | E.164 format |
| first_name | string | User's first name | required | optional | Maps to SCIM name.givenName |
| last_name | string | User's last name | required | optional | Maps to SCIM name.familyName |
| status | string | Account status: active or inactive | defaults to active | optional | Maps to SCIM active boolean |
| role | string | User role within the account (e.g., Admin, User) | optional | optional | Account-level permission role |
| department | string | Department the user belongs to | optional | optional | Maps to SCIM urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department |
| location | string | Office location associated with the user | optional | optional | Vonage Business Communications attribute |
| login_name | string | Username for portal login | optional | optional | Often same as email |
Core endpoints
List Users
- Method: GET
- URL:
https://api.vonage.com/t/vbc.prod/provisioning/v1/accounts/{account_id}/users - Watch out for: JWT must be scoped to the correct Vonage Business Communications application; standard Vonage API keys do not work for this endpoint.
Request example
GET /t/vbc.prod/provisioning/v1/accounts/12345/users?page_size=10&page_index=1
Authorization: Bearer <JWT>
Response example
{
"page_size": 10,
"page_index": 1,
"total_items": 42,
"_embedded": {
"users": [{"id":"uuid","email":"user@example.com","first_name":"Jane"}]
}
}
Get User
- Method: GET
- URL:
https://api.vonage.com/t/vbc.prod/provisioning/v1/accounts/{account_id}/users/{user_id} - Watch out for: User ID is a UUID, not the email address.
Request example
GET /t/vbc.prod/provisioning/v1/accounts/12345/users/uuid-abc
Authorization: Bearer <JWT>
Response example
{
"id": "uuid-abc",
"email": "user@example.com",
"first_name": "Jane",
"last_name": "Doe",
"status": "active"
}
Create User
- Method: POST
- URL:
https://api.vonage.com/t/vbc.prod/provisioning/v1/accounts/{account_id}/users - Watch out for: A license/seat must be available on the account before user creation succeeds.
Request example
POST /t/vbc.prod/provisioning/v1/accounts/12345/users
Authorization: Bearer <JWT>
Content-Type: application/json
{
"email": "newuser@example.com",
"first_name": "John",
"last_name": "Smith"
}
Response example
{
"id": "uuid-new",
"email": "newuser@example.com",
"status": "active"
}
Update User
- Method: PUT
- URL:
https://api.vonage.com/t/vbc.prod/provisioning/v1/accounts/{account_id}/users/{user_id} - Watch out for: Uses PUT (full replacement semantics); omitting optional fields may clear them.
Request example
PUT /t/vbc.prod/provisioning/v1/accounts/12345/users/uuid-abc
Authorization: Bearer <JWT>
Content-Type: application/json
{
"first_name": "Jane",
"last_name": "Updated"
}
Response example
{
"id": "uuid-abc",
"first_name": "Jane",
"last_name": "Updated",
"status": "active"
}
Delete User
- Method: DELETE
- URL:
https://api.vonage.com/t/vbc.prod/provisioning/v1/accounts/{account_id}/users/{user_id} - Watch out for: Deleting a user releases their license seat but does not automatically reassign their DID number.
Request example
DELETE /t/vbc.prod/provisioning/v1/accounts/12345/users/uuid-abc
Authorization: Bearer <JWT>
Response example
HTTP 204 No Content
List Extensions
- Method: GET
- URL:
https://api.vonage.com/t/vbc.prod/provisioning/v1/accounts/{account_id}/extensions - Watch out for: Extensions are managed separately from user objects and must be assigned after user creation.
Request example
GET /t/vbc.prod/provisioning/v1/accounts/12345/extensions
Authorization: Bearer <JWT>
Response example
{
"_embedded": {
"extensions": [{"extension":"101","user_id":"uuid-abc"}]
}
}
Get Account Details
- Method: GET
- URL:
https://rest.nexmo.com/account/get-balance - Watch out for: This is the legacy Nexmo Account API using api_key/api_secret query params, not JWT. Separate from VBC Provisioning API.
Request example
GET /account/get-balance?api_key=KEY&api_secret=SECRET
Response example
{
"value": 10.28,
"autoReload": false
}
Rate limits, pagination, and events
Rate limits: Vonage does not publicly document per-endpoint rate limits in a unified table. General guidance from developer docs indicates limits vary by endpoint and account tier. No explicit rate-limit headers or Retry-After behavior is documented publicly.
Rate-limit headers: No
Retry-After header: No
Rate-limit notes: Contact Vonage support for account-specific rate limit details. HTTP 429 responses are returned when limits are exceeded.
Pagination method: offset
Default page size: 10
Max page size: 100
Pagination pointer: page_size / page_index
Webhooks available: No
Webhook notes: Vonage Business Communications Provisioning API does not document user-management webhooks. The Vonage Communications APIs (SMS, Voice) support event webhooks but these are not user-management events.
Alternative event strategy: Poll the List Users endpoint periodically to detect changes, or use SCIM provisioning with an IdP that supports push-based sync.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Advanced (formerly Business tier)
Endpoint: Tenant-specific SCIM endpoint provided during SSO/SCIM setup in the Vonage admin portal; format is IdP-generated and not a static public URL.
Supported operations: Create User (POST /Users), Read User (GET /Users/{id}), Update User (PUT /Users/{id}), Deactivate User (PATCH /Users/{id} with active:false), List Users (GET /Users), Push Groups (GET/POST /Groups)
Limitations:
- SSO must be configured and active before SCIM provisioning can be enabled.
- SCIM is available only on the Advanced plan (equivalent to legacy Business tier).
- Supported IdPs: Okta, Microsoft Entra ID (Azure AD), Google Workspace, OneLogin.
- SCIM endpoint URL is generated per-tenant in the admin portal; no universal static base URL is published.
- Group push support varies by IdP configuration.
- Password sync is not supported via SCIM; authentication is handled by the IdP via SSO.
Common scenarios
Provisioning via SCIM (Okta example): Confirm the account is on the Advanced plan, configure SSO first under Company Settings > Single Sign-On, then enable SCIM and copy the tenant-specific base URL and Bearer token into the Okta app configuration.
Okta pushes SCIM POST /Users on assignment.
If no license seat is available, the request fails with a 400/409 in Okta's provisioning logs - pre-purchase seats before any bulk provisioning run.
Deactivating a departing employee via REST: Obtain a JWT via POST https://api.vonage.com/token, resolve the user's UUID with GET /users?email=user@example.com, then call DELETE /users/{user_id}.
DELETE is permanent and irreversible.
If preserving the user record is required, use SCIM PATCH with active:false instead - this deactivates without deleting and is the only soft-deactivation path available.
Bulk audit: Paginate GET /users with page_size=100 starting at page_index=1 (1-based, not 0-based - off-by-one errors are common).
Calculate total pages from total_items in the response.
Cross-reference email, status, extension, and department fields against your HR system or identity graph to surface stale or mismatched records.
Provision a new employee via SCIM with Okta
- Ensure the Vonage account is on the Advanced plan.
- Configure SSO in the Vonage admin portal under Company Settings > Single Sign-On.
- Enable SCIM provisioning in the Vonage admin portal; copy the SCIM base URL and Bearer token.
- In Okta, add the Vonage app from the Okta Integration Network and configure SCIM settings with the copied URL and token.
- Assign the Okta user to the Vonage application; Okta pushes a SCIM POST /Users request.
- Vonage creates the user and assigns a license seat; the user receives an activation email.
Watch out for: If no license seats are available, the SCIM provisioning request will fail with a 400/409 error in Okta's provisioning logs. Pre-purchase seats before bulk provisioning.
Deactivate a departing employee via REST API
- Obtain a JWT token via POST https://api.vonage.com/token with client_id and client_secret.
- Call GET /t/vbc.prod/provisioning/v1/accounts/{account_id}/users?email=user@example.com to retrieve the user's UUID.
- Call DELETE /t/vbc.prod/provisioning/v1/accounts/{account_id}/users/{user_id} to remove the user.
- Verify the DID number is unassigned and reassign as needed via the Extensions API.
Watch out for: DELETE is irreversible. If you need to preserve the user record, use SCIM PATCH with active:false instead, which deactivates without deleting.
Bulk list and audit all users on an account
- Obtain a JWT token via the VBC token endpoint.
- Call GET /t/vbc.prod/provisioning/v1/accounts/{account_id}/users?page_size=100&page_index=1.
- Check total_items in the response to determine total pages (ceil(total_items / page_size)).
- Iterate page_index from 1 to total pages, collecting all user records.
- Cross-reference email, status, and extension fields against your HR system.
Watch out for: page_index is 1-based. Using page_index=0 may return an error or duplicate the first page depending on API version.
Why building this yourself is a trap
The dual-API architecture is the primary integration trap. Developers who authenticate with a standard Vonage API key will hit the Nexmo Account API and get no access to VBC user objects.
The VBC Provisioning API requires a separate OAuth 2.0 client credentials grant - this is not documented prominently and causes silent auth failures if the wrong credential type is used.
PUT semantics on the Update User endpoint mean omitting any optional field will clear it. Partial updates require reading the full user object first, merging changes, and writing the complete payload back - there is no PATCH equivalent on the REST API for user objects outside of SCIM.
Rate limits are not publicly documented in a unified table and no Retry-After header is returned on 429 responses. Account-specific limits must be obtained from Vonage support, which makes capacity planning for high-volume provisioning pipelines difficult.
Pagination is 1-based (page_index), and the /t/vbc.prod/ gateway path in the base URL deviates from standard REST conventions, which can cause request construction errors in SDK-generated clients that assume a clean base path.
Automate Vonage workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.