Telephony Integration REST API Authorization for Agentforce Voice
Salesforce verifies a partner-signed JWT on each request. You hold the private key, and you upload the matching public key to the Agentforce Voice channel that you own. There's no client secret and no OAuth exchange. A signed JWT is the bearer token.
To authorize your requests, set up an Agentforce Voice channel and register your public key, and then mint and send a signed JWT on each request.
If you're integrating a call center or Service Cloud Voice contact center instead of Agentforce Voice, see Telephony Integration REST API Authorization.
Set Up an Agentforce Voice Channel and Register Your Public Key
Before you mint a JWT, set up an Agentforce Voice channel and register your public key.
- From Setup, in the Quick Find box, enter Partner Telephony Setup, and then select Partner Telephony Setup.
- Click New Channel to create a new channel, and select Agentforce Voice (AFV)—SIP / Dynamic Routing as the channel type.
-
Choose a Channel Name, the developer-facing API name, not the
display label.
The name must be alphanumeric with underscores only, must be unique within the org, and can't be renamed after creation. For example, acme_voice_prod.
Salesforce stores the channel name on the underlying record as channelDeveloperName. This is the exact value that you put in the sub claim of every JWT that you sign for this channel. Salesforce uses channelDeveloperName to look up the public key to verify the token. Note that customers see the Channel Name, not the Channel Developer Name. The two can differ.
-
Generate an RSA key pair and keep the private key secret. Export the public key in
SubjectPublicKeyInfo (PKCS#8) armor.
1-----BEGIN PUBLIC KEY----- 2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA... 3-----END PUBLIC KEY-----Only SubjectPublicKeyInfo (PKCS#8) format is supported. PKCS#1 RSA public keys and X.509 certificates aren't supported for this channel type. An X.509 certificate is the call center or Service Cloud Voice path, not Agentforce Voice. Never upload a private key.
-
Open the channel and go to Channel Setup and click
Authentication, paste the public key into the Public
Key field, and then click Save.

You can update the public key at any time to rotate it. The new key takes effect within a few minutes as caches expire. Rotate the public key at least annually.
- Mint and send a signed JWT.
Mint and Send a Signed JWT
After your channel and public key are in place, mint a JWT for each request and send it as a bearer token.
-
Construct a JSON claims set for the JWT.
Claim Required Value iss Yes Your Salesforce org ID (18-character). sub Yes The channel name you chose during setup (channelDeveloperName). iat Yes Issued-at time, in seconds since the Unix epoch. exp Yes Expiry, in seconds since the Unix epoch. Unlike the call center or Service Cloud Voice JWT, this expiration isn't capped at 24 hours. Choose a lifetime that matches your key-rotation policy. We recommend short-lived tokens (minutes to a few hours) minted per call or per session. roles Yes The literal string voiceagent. This private body claim is how Salesforce recognizes the token as an Agentforce Voice partner token and routes it to the Agentforce Voice public-key lookup. Any other value, or an absent claim, is treated as a call center or Service Cloud Voice token, fails key lookup, and returns a 401. Example claims set:
1{ 2 "iss": "00Dxx0000001gPAEAY", 3 "sub": "acme_voice_prod", 4 "iat": 1785312000, 5 "exp": 1785315600, 6 "roles": "voiceagent" 7} -
Sign the token with your private key using RS256.
RS256 is the only signing algorithm that Salesforce accepts for this channel type.
-
Send the signed JWT in the standard HTTP Authorization header on every request.
1Authorization: Bearer <your-signed-jwt>Don't embed the private key in shipped client code or store it in a repository. Treat it like a database password.
On every request, Salesforce checks that:
- The signing algorithm is RS256.
- The roles claim equals voiceagent, which routes the request to the Agentforce Voice key lookup instead of the call center key lookup.
- The channel is found by (iss, sub) and its uploaded public key is read.
- The signature verifies against that public key.
- The exp claim hasn't passed.
Salesforce stamps requests that pass all checks with the ROLE_AFV_PARTNER role. Only Agentforce Voice-eligible endpoints accept this role; calls to other endpoints get a 403.
Troubleshoot Authorization Errors
Use this table to diagnose common authorization failures.
| Symptom | Likely Cause |
|---|---|
| 401 Unauthorized immediately after onboarding | The roles claim is missing or isn't exactly voiceagent. Salesforce routed the request to the call center or Service Cloud Voice key store and found no key. |
| 401 after uploading a new public key | The cache still holds the old key. Wait a few minutes, or retry. |
| 401 on tokens that verify locally | The sub claim doesn't match the channel's name, or iss isn't your 18-character org ID. |
| 403 Forbidden on a specific endpoint | The endpoint isn't opted into the Agentforce Voice role. Confirm with your Salesforce contact that the endpoint accepts ROLE_AFV_PARTNER. |
| Invalid public key on upload | The public key isn't in SubjectPublicKeyInfo (PKCS#8) armor. |