If you only need to call the API from your own systems, an API key is simpler and is probably what you want.
Two ways to get a client
Self-registration is deliberately open — that is what lets Claude and ChatGPT connect without you creating credentials first — so its clients are treated as unverified. A trusted client is one VoiceInfra has created for a named app.
Requesting a trusted client
A trusted client is created for you by VoiceInfra, so that a server-side app gets a secret it can hold safely. Contact hello@voiceinfra.ai with:- Your app’s name
- The redirect URIs the app will use — at least one, up to five, and all
httpsapart fromlocalhostduring development - The permissions you need, and why
- Any logo, policy, and terms URLs you want shown on the consent screen, so customers can see who they are approving
client_id and client_secret.
The authorization flow
Your app sends the customer to VoiceInfra, they approve, and you get back an authorization code to exchange for a token.1. Start the authorization request
Send the user to the authorization endpoint with your client ID, redirect URI, requested scopes, astate, and a PKCE challenge:
string
required
Must be
S256. PKCE is required — the plain method was removed in OAuth 2.1.string
The resource you want a token for. Clients must name it (RFC 8707), which prevents a token issued for one resource being replayed against another.
2. The user decides
VoiceInfra shows your app’s name, links, and the permissions you asked for — grouped into readable areas, with anything that spends credit called out separately. The customer picks which workspace the app may act in, and can allow change access to some areas and not others. Your app’s ability to change anything is still bounded by the customer’s role in that workspace.3. Receive the decision
The customer returns to your redirect URI with either acode or an error (access_denied if they refused). The response carries an iss parameter (RFC 9207) — verify it matches the issuer to protect against mix-up attacks.
4. Exchange the code for a token
access_token, a refresh_token, expires_in, and the granted scope.
5. Refresh
Access tokens expire. Exchange the refresh token at the same endpoint withgrant_type=refresh_token. Refresh tokens rotate — store the new one each time.
Revoking
A customer disconnecting your app takes effect straight away, including on tokens that have not yet expired. Your app must handle a
401 by sending the user through the authorization flow again, not by retrying.