Authentication
The REST API accepts one kind of credential: a personal API token that you create in SimpleVox. Use it for your own scripts, reports and integrations. Every token can read. On Boost, a token can also carry write permissions to send texts, save contacts and start calls.
Tokens from AI app connections, web sign-in cookies and SimpleVox mobile app tokens don’t work with the REST API. AI apps connect to the MCP server with delegated OAuth instead.
Create a personal API token
Section titled “Create a personal API token”
-
Sign in at my.simplevox.app and open Settings → API tokens. The Public REST API section shows the base URL and a link to the API reference.
-
Under Create token, enter a Name, up to 80 characters, so you can recognize it later.
-
On Boost, tick any Write permissions the token needs: Edit shared contacts, Send SMS, Start assisted calls or End assisted calls. Leave them unticked for a token that only reads. See Write permissions on Boost.
-
Choose the numbers it can use: tick numbers under Phone lines, or tick All lines I can access, including future lines.
-
Choose Create token.
-
Copy the token. SimpleVox shows it once: “Copy your token. It won’t be shown again.” Choose Copy token, store it somewhere safe, then choose Done.
Every token can “Read contacts, call and message history, transcripts and recordings.” A token with write permissions can also do what you ticked, and nothing more. Every token expires 90 days after you create it.
A token belongs to you and your current workspace. It can never read more than you can in SimpleVox. With All lines I can access, including future lines, it follows your access as it changes, including numbers you’re given later. With selected numbers, it stays limited to those, even if you’re an admin. Your membership, role and number access are checked on every request.
If creating a token fails with “The response was lost”, check Your tokens and revoke the new token before trying again.
Write permissions on Boost
Section titled “Write permissions on Boost”On Boost, a personal token can send texts, save contacts and set up calls for your integration:
| Write permission | Permission ID | What it allows |
|---|---|---|
| Edit shared contacts | contacts.manage |
Create and update shared contacts. See Contacts. Admins only. |
| Send SMS | messages.send |
Send texts from the token’s numbers. See Send texts. |
| Start assisted calls | calls.start |
Set up calls between you and a customer from the token’s numbers, and see which numbers and devices you can call with. See Start calls. |
| End assisted calls | calls.control |
Cancel or hang up a call the token started. See Start calls. |
- You only see what you can do. Write permissions shows on Boost, and only lists the permissions your role allows. Members can send texts and start and end calls on their numbers; only admins can edit contacts.
- Permissions are set when you create the token. To add or remove one, create a new token with the permissions you need, switch your integration to it, then revoke the old one.
- Contacts are workspace-wide. Contacts are shared, so Edit shared contacts covers every contact, even on a token limited to selected numbers. Sending texts and starting calls stay limited to the token’s numbers.
- Writes follow your plan. If the workspace moves off Boost, new writes stop with
403andapi_writes_unavailable. Reads keep working, including reading texts the token already sent, and a token can still check and end calls it started. - Your access is checked every time. Your role and number access are checked on each write, as they are for reads.
Use the token
Section titled “Use the token”Send the token in the Authorization header, never in a URL:
curl --get 'https://api.simplevox.app/v1/contacts' \ -H 'Accept: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN" \ --data-urlencode 'q=Mary'Use the API reference to inspect parameters and try requests. Paste a token you created into Authorize. The console keeps it in memory for that page only, clears it on reload or when you choose to clear authorization, and sends requests directly to https://api.simplevox.app/v1 without cookies. Don’t paste a token into support chat, a form or an analytics field.
Store tokens in your integration’s secret store. Keep them out of logs, source control and URLs.
Expiry and revocation
Section titled “Expiry and revocation”Your tokens lists each token with its permissions (such as Read · Send SMS), its numbers (All permitted lines or Selected lines), its expiry date, and when it was last used, or Never used. Personal tokens have no refresh token. Before one expires, create a replacement, switch your integration to it, then choose Revoke on the old one. Revocation takes effect on the next request. Losing your workspace membership or access to a number also removes the matching access.
A missing, expired or revoked token, or one whose owner has left the workspace, gets 401:
HTTP/1.1 401 UnauthorizedWWW-Authenticate: Bearer realm="public-api", scope="api:read"Content-Type: application/json
{"error": {"code": "not_authorized", "message": "Send a valid personal API token in the Authorization header."}}Retrying won’t help. Create a new token in Settings and switch your integration to it; personal tokens can’t be refreshed. A record you can’t access returns 404, just like a missing one. See Handle errors.
Delegated OAuth for MCP
Section titled “Delegated OAuth for MCP”AI apps connect to the MCP server at https://my.simplevox.app/mcp with OAuth 2.1 authorization code and PKCE (S256), resource https://my.simplevox.app/mcp and scope mcp:use. The tokens this issues work only with the MCP server; the REST API refuses them with 401. Personal API tokens don’t work with MCP.
| Setting | Value |
|---|---|
| MCP endpoint and resource | https://my.simplevox.app/mcp |
| Protected resource metadata | https://my.simplevox.app/.well-known/oauth-protected-resource/mcp |
| Authorization server metadata | https://my.simplevox.app/.well-known/oauth-authorization-server |
| Client registration | https://my.simplevox.app/oauth/register |
| Authorization | https://my.simplevox.app/oauth/authorize |
| Token exchange | https://my.simplevox.app/oauth/token |
| Client type | Public, token_endpoint_auth_method=none; no client secret |
| Grant types | authorization_code and refresh_token |
| Scope | mcp:use, exactly |
Register a client
Section titled “Register a client”Read the resource metadata and the authorization server metadata it points to before connecting. Then register with dynamic client registration:
curl https://my.simplevox.app/oauth/register \ -H 'Content-Type: application/json' \ -d '{"client_name":"Dispatch Board","redirect_uris":["https://dispatch.example.com/oauth/callback"]}'- Send 1 to 5
redirect_uris. Each must be an absolute HTTPS URL, or a loopback URL for an app on the person’s computer (http://127.0.0.1,http://[::1]orhttp://localhost), with no user information or fragment, up to 2,048 bytes. A loopback callback matches on any port, because the app picks its port when it starts; the path must match, and the token request must repeat the exact callback. Custom-scheme callbacks aren’t accepted. - Optional
client_uri,logo_uri,policy_uriandtos_urimust be HTTPS. The consent screen shows them as links supplied by the client; SimpleVox doesn’t verify them. - Registration is limited to 10 requests a minute and 16 KB of metadata. It creates a public client and returns its
client_id; it doesn’t give the client any access. - SimpleVox doesn’t support client ID metadata documents. Use dynamic registration.
Authorize and exchange the code
Section titled “Authorize and exchange the code”Send the person to /oauth/authorize with response_type=code, your client_id, your exact redirect_uri, a random state, scope=mcp:use, resource=https://my.simplevox.app/mcp, and your PKCE code_challenge with code_challenge_method=S256.
The person signs in, finishes email verification or workspace setup if needed, and sees the consent screen for their current workspace. Verify state on the callback, then exchange the code with the same resource and redirect URI plus your code_verifier:
curl https://my.simplevox.app/oauth/token \ -d grant_type=authorization_code \ -d client_id=CLIENT_ID \ -d redirect_uri=https://dispatch.example.com/oauth/callback \ -d code=AUTHORIZATION_CODE \ -d code_verifier=CODE_VERIFIER \ -d resource=https://my.simplevox.app/mcpWhat the person allows
Section titled “What the person allows”Every connection can read. The person ticks optional permissions and chooses all numbers they can access or only selected numbers. The consent screen lists only the optional permissions their own role allows.
| Permission | Consent screen label | Access |
|---|---|---|
history.view |
Always included: “Your business’s contacts” and “Calls, voicemails and texts on the numbers below, with their recordings, transcripts and summaries” | Read contacts, calls, texts, recordings, transcripts and summaries, count activity and check setup. |
messages.send |
Send text messages | Send texts from permitted numbers. |
contacts.manage |
Create and edit contacts | Create and update shared contacts. Admins only. |
calls.start |
Start assisted phone calls | Place calls for the person: ring their phone, then dial the customer when they answer. |
calls.control |
Cancel setup and end assisted calls | Cancel setup or end an assisted call the connection started. |
A connection is tied to the person, their workspace, the client and the resource. Its permissions never grow on their own: when you need more, the person disconnects in Settings → Integrations and authorizes again. Refreshing a token never adds permissions. See MCP tools for which tool needs which permission.
Refresh and revocation
Section titled “Refresh and revocation”Access tokens expire after 15 minutes. Refresh with grant_type=refresh_token, your client_id, the refresh token and the same resource. Refresh tokens last 30 days and rotate: each works once, so serialize refreshes and store the replacement securely. If refresh fails, send the person through authorization again.
People see their connections in Settings → Integrations and can Disconnect any of them. That ends the connection and revokes its access and refresh tokens. Current membership, role and number access still apply on every request.