How-to guide

Authentication and API keys

Create the right API key, send it with every request, and keep it safe.

What you'll learn

How a request proves it comes from your workspace, which key to create for which job, the difference between test and live keys, and how to limit and rotate a key.

Prerequisites

  • A VoiceLayer account with access to Developers → API keys in the dashboard.

Step 1: Create a secret key

Your servers use a secret key. It can do everything the API offers for your workspace.

  1. In the dashboard, open Developers → API keys and choose Create key.
  2. For "What is this key for?", pick Your servers or the SDK.
  3. Choose an Environment: Testing for development, Live for real customers.
  4. Optionally set Limit to channels (for example sms, telegram) so the key can only act on those channels.
  5. Copy the key now. The dashboard shows it once.

Other kinds of key exist for other jobs: an MCP key for Claude Code, Cursor or another MCP client, a publishable key for the chat widget on your website, and worker keys for voice agents you host. The API routes on this site need a secret key; a publishable key is refused.

Step 2: Send the key with every request

Put the key in the Authorization header as a bearer token:

curl https://api.vlayers.ai/v1/channels \
  -H "Authorization: Bearer $VOICELAYER_API_KEY"

The SDKs take the key once:

curl https://api.vlayers.ai/v1/channels \
  -H "Authorization: Bearer $VOICELAYER_API_KEY"

A request without a valid key is refused with 401 unauthorized.

Step 3: Choose test or live

Test keyLive key
Prefixvl_test_vl_live_
Reaches a real carrierNo: a simulated carrierYes
CostsNothing (daily caps apply)Normal prices
Who it can messageOnly reserved test addressesReal addresses only

Your code is the same for both. Only the key, and the addresses you message, change. See Test mode.

Scopes

Each API operation needs one scope. A secret key from the dashboard holds all of them; the scope tells you what a request needs and what a missing scope means in an error.

ScopeLets the key
messages:sendSend messages and reply in conversations; simulate inbound messages in test mode
messages:readList messages and conversations, and read a conversation
conversations:controlHand a conversation to the agent, your code or a person
events:readRead events from the stream and the pull endpoint
channels:readList your channels and WhatsApp templates
webhooks:manageCreate, change and delete webhook subscriptions, and read and retry deliveries
logs:readRead your API request logs

A key without the scope an operation needs is refused with 403 insufficient_scope; details.required names the missing scope. A key limited to some channels gets the same error, or 404 not_found, for anything outside them.

Keep keys secret

  • Keep secret keys on your servers. Never put one in a browser, a mobile app or a public repository.
  • Read the key from an environment variable or a secrets manager, as the examples do with VOICELAYER_API_KEY.
  • Use a separate key per service and environment, so you can revoke one without touching the others.

Rotate a key

  1. Create a new key in Developers → API keys.
  2. Deploy it to your service.
  3. Delete the old key. Requests that still use it start failing with 401 unauthorized.

Test it

Call GET /v1/channels with your test key (Step 2). A 200 with your channels means the key works.

Common errors

ErrorStatusHow to fix
unauthorized401Send Authorization: Bearer <key> with a secret key from the dashboard (Developers → API keys). Test keys start with vl_test_.
insufficient_scope403Use a key with the scope named in details.required, or one whose restriction covers this channel or Binding.
no_project403Use an API key created inside the workspace you mean to act on.
test_address_required422Use a reserved test address, or a live key to reach a real person.
test_address_not_allowed422Use a test key (vl_test_…) for test addresses.

Next steps

On this page