Authorization Code Flow (PKCE)
Use this flow when your application makes ZoomInfo API requests on behalf of an authenticated user.
After the user signs in and grants permission, your application receives an access token that represents that user. Every API request made with this token returns data specific to the authenticated user.
For example, Contact Recommendations are personalized based on the authenticated user's activity in ZoomInfo, such as profile views, CRM exports, and other engagement signals. Using this flow ensures your application returns the same personalized recommendations and user-specific experience available in ZoomInfo.
ZoomInfo requires PKCE (Proof Key for Code Exchange) on top of the standard authorization code grant. This prevents authorization code interception attacks.
Before You Begin
Before implementing the authorization flow, ensure that you have:
- Created an application and obtained its Client ID.
- Configured a valid redirect URI.
- Implemented secure storage for access tokens and refresh tokens.
Integration Steps
The authorization process consists of four steps:
Generate a PKCE code verifier and code challenge.
Redirect the user to ZoomInfo for authentication and consent.
Receive an authorization code through your redirect URI.
Exchange the authorization code for an access token and refresh token.
Looking to implement this flow in Python, Java, or JavaScript? We've provided complete implementation recipes for each language.
1. Generate a PKCE Challenge
Generate a random code_verifier and derive a code_challenge using SHA-256 encoding. The code_challengeis sent during authorization, while the original code_verifier is used later when exchanging the authorization code for tokens.
Store the code_verifier securely, as it is required in Step 4 when exchanging the authorization code for an access token.
2. Request User Authorization
Redirect the user to the authorization endpoint.
GET https://api.zoominfo.com/auth/authorizehttps://api.zoominfo.com/auth/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://your-app.com/callback&
code_challenge=CODE_CHALLENGE&
code_challenge_method=S256&
state=RANDOM_STATEThe following query parameters are required for every authorization code request.
| Parameter | Required | Description |
|---|---|---|
| response_type | Yes | The OAuth 2.0 grant type requested by the external web service. The value must always be code to indicate that the web service is requesting an authorization code. |
| client_id | Yes | The identifier of the application that is requesting authorization. This identifier can be found in the ZoomInfo DevPortal by clicking on the application name in the API Apps table or clicking the Edit button on the context menu for the application. In the details page scroll down to the Client ID section to find the value for your application. |
| redirect_uri | Yes | The URL where that the user will be redirected to upon successful authentication. The redirect_uri MUST match one of the values in the application's Sign-in Redirect URIs list managed in the app creation portal. |
| code_challenge | Yes | The SHA256 hash of the code_verifier used in the token request; created as per the PKCE standard. This parameter helps to prevent authorization code interception attacks. The value must be base64url encoded as per RFC 4846. |
| code_challenge_method | Yes | Must be S256. |
| state | Recommended | An identifier provided by the application requesting authorization to maintain state between the request and callback. If provided, this value will be passed back to the client via the callback URL when ZoomInfo grants the authorization code. This value is also intended to be used by the clients to prevent cross-site request forgery. This value must be URL encoded |
Additionally, these optional parameters may be provided in the authorization code request
| Parameter | Required | Description |
|---|---|---|
| scope | Yes | A space-delimited list of scopes that application requests be applied to the generated access token. If provided, this list must be a subset of the scopes selected when the app was created in the ZoomInfo DevPortal. An authorization requests with invalid scopes will return an error response. |
If you don't specify any scopes, the authorization request will use all the scopes selected for your application in the ZoomInfo app creation portal. See the full list of available scopes.
After the user successfully authenticates and grants access, ZoomInfo redirects them to the configured redirect URI.
3. Receive the Authorization Code
The redirect URI receives a temporary authorization code.
https://your-app.com/callback?code=AUTHORIZATION_CODE| Parameter | Parameter Description |
|---|---|
| code | The authorization code that the external client can use to request an access token |
| state | If provided during the initial request for authorization code, the same value will be returned in this parameter |
Extract and store the authorization code. Authorization codes are short-lived and can only be exchanged once.
4. Exchange the Code for Token
Exchange the authorization code for an access token by sending a request to the token endpoint.
The request must include your application's client_id and client_secret so ZoomInfo can authenticate your application. You can provide these credentials in one of two ways:
- HTTP Basic Authentication (recommended)
- Request body parameters
HTTP Basic Authentication is the preferred method because it keeps client credentials separate from the request payload.
If both methods are used, the Authorization header takes precedence, and any credentials included in the request body are ignored.
Request Parameters
| Parameter | Required | Description |
|---|---|---|
| grant_type | Yes | The type of validation that the client can provide to prove it can be issued access tokens. For this flow the value is always authorization_code |
| code | Yes | The temporary authorization code provided by the authorization server. |
| redirect_uri | Yes | The URL used as the callback for this authorization. The redirect_uri MUST match one of the values in the application's Sign-in Redirect URIs list managed in the ZoomInfo app creation portal. |
| code_verifier | Yes | A high-entropy cryptographic random string of up to 128 bytes. For more information on PKCE code verifiers see RFC 7636. The value must be base64url encoded as defined in RFC 4846 |
Upon successful verification of the external client's credentials and authorization details, ZoomInfo's authorization server will respond with the access token. The response will always be encoded in the application/json content type.
{
"access_token": "eyJraWQiOiJKdThxUW1tTUx1SG9QSEFVQlJnUmh...jnIn951t3kLf6VZ6SOsYKSVY9kGeNbCGkufCNLQ",
"expires_in": 1000,
"id_token": "eyJraWQiOiJKdThxUW1tTUx1SG9QSEFVQlJnUmh...CUxqHWQpbUXU0TTuzrQilNWEoggi5haJkQ",
"refresh_token": "7PV7YVxG0UswgzFFaX-mDMoVRIgN5WEfLS0hfx9qSDo",
"scope": "api:data:company api:data:contact api:audience:read...",
"token_type": "Bearer"
}| Parameter | Description |
|---|---|
| access_token | OAuth token that can be used by applications calling the ZoomInfo API |
| expires_in | The length of time, in seconds, that the access token is valid |
| id_token | A signed JWT that contains claims about the authentication event and the authenticated user. Unlike an access token (which authorizes access to resources), the ID token is intended for the client application to verify the user's identity. |
| refresh_token | This token can be used to refresh the access_token when it has expired. This value is a secret, please protect it accordingly. For more information on how to utilize this token see Refresh Token Flow. |
| scope | The list of scopes that are applied to this access token |
| token_type | Denotes the type of token provided. This value will always be `"Bearer"` but is included for completeness. This indicates that this token is meant to be included in the `Authorization` header using the bearer format. See RFC-6750 for more information on Bearer token usage in OAuth. |
Use the Access Token
Include the access token in the Authorization header when calling ZoomInfo APIs.
Authorization: Bearer ACCESS_TOKENRefresh Expired Access Token
When the access token expires, use the refresh token to obtain a new access token without requiring the user to re-authorize the application.
See the Refresh Token documentation for implementation details.
Error Handling
| Error | Description |
|---|---|
| invalid_request | Required request parameter is missing or invalid. |
| invalid_grant | Authorization code is invalid, expired, or already used. |
| invalid_client | Client ID is invalid. |
| invalid_code_verifier | Provided code verifier does not match the original code challenge. |
Security Best Practices
- Always use
S256for PKCE. - Validate the
stateparameter after redirect. - Use HTTPS for all authorization and token requests.
- Store access and refresh tokens securely.
- Never expose tokens in client-side logs or URLs.
Updated 5 days ago