1. Review your current OAuth usage
To start, search your codebase, configuration, or any other infrastructure for your app for references to the following endpoints:/oauth/v1/token/oauth/v1/access-tokens/oauth/v1/refresh-tokens
- Backend services and workers
- Serverless functions and webhooks
- CI/CD scripts, integration tests, and SDK wrappers
- Any third-party tools or libraries where you’ve configured authentication
2. Update token exchange
For any references in your app’s code that handle the authorization code flow via aPOST request to the /oauth/v1/token endpoint, swap the endpoint over to /oauth/2026-03/token instead.
Ensure all parameters are provided as form-encoded body fields, not as query parameters.
The tabs below provide an example cURL request using the v1 endpoint compared to the equivalent latest endpoint (2026-03):
- Before (v1)
- After (2026-03)
3. Update refresh token logic
Any refresh token logic that sends aPOST request to the /oauth/v1/token endpoint should be updated to use the /oauth/2026-03/token endpoint instead.
Ensure all parameters are provided as form-encoded body parameters. You should also confirm that your code uses the new access_token property returned by this endpoint, and use the expires_in field to determine the token lifetime.
Consult the tabs below to compare an example cURL request using the v1 endpoint against the equivalent latest endpoint (2026-03):
- Before (v1)
- After (2026-03)
4. Replace token metadata calls with introspection requests
You’ll need to find any existingGET requests for the v1 token metadata endpoints listed below:
/oauth/v1/access-tokens/{token}/oauth/v1/refresh-tokens/{token}
POST requests to the token introspect endpoint at /oauth/2026-03/token/introspect.
Rather than providing the token in the path in the v1 endpoints, send it in the request body instead, along with any required client credentials.
Additionally, unlike the /oauth/2026-03/token endpoints, which return an identical response to the /oauth/v1/token endpoint, the /oauth/2026-03/token/introspect endpoint returns a new model, detailed below:
Refresh token model
The table below shows the equivalent fields returned in the new response from the/oauth/2026-03/token/introspect endpoint for a refresh token compared to the v1 equivalent:
| Field | v1 model | 2026-03 model |
|---|---|---|
tokenType | "refresh" | "Bearer" |
token_use | (absent) | "refresh_token" |
appId | (absent) | Integer |
active | (absent) | Boolean |
Access token model
| Field | v1 model | 2026-03 model |
|---|---|---|
clientId | (absent) | String |
tokenType | "access" (default) | "Bearer" |
token_use | (absent) | "access_token" |
active | (absent) | Boolean |
Request fields
When making aPOST request to the /oauth/2026-03/token/introspect endpoint, the request body is form-urlencoded with the following fields:
| Field | Type | Description |
|---|---|---|
client_id | String | Your app’s client ID |
client_secret | String | Your app’s client secret |
token_type_hint | String | Either “access_token” or “refresh_token” |
token | String | The refresh token or access token value, depending on which token you’re introspecting. |
cURL request to the introspect endpoint:
5. Update token revocation logic
If your app had any explicit logic to revoke refresh tokens when users uninstall or disconnect your app, you must migrate from the v1DELETE endpoint to the new 2026-03 revoke endpoint.
Replace any previous DELETE requests to /oauth/v1/refresh-tokens/{token} with a POST request to /oauth/2026-03/token/revoke.
Ensure that you pass the refresh token in a URL-encoded request body.
6. Standardize your error handling
With the 2026-03 version of the OAuth API, error responses include both standard OAuth and HubSpot-specific fields:- Standard:
error,error_description - HubSpot-specific:
status,message
error and error_description for conditional logic and displaying user-facing messages.
From there, you can optionally continue logging or monitoring the status and message fields, since they’ll remain available for backward compatibility.
These changes to error handling will make your app more portable across OAuth providers and more resilient to future internal changes to HubSpot-specific error fields.
7. Test and deploy
Before rolling changes to production, it’s recommended that you do the following:- Test in a non-production environment: complete a full OAuth install flow by performing an authorization code exchange, token refresh, and testing out any paths that introspect or revoke tokens.
- Verify logs and telemetry: confirm that your app’s client ID, client secret, authorization code, and tokens no longer appear in URLs or logs.
- Monitor rollout: watch for increased
4xxresponses around OAuth endpoints. Pay particular attention to the new error payload and ensure your error handling correctly parses theerroranderror_description.
Other considerations
Keep the following points in mind as you plan your migration to the latest version of the OAuth API:- The OAuth install URL, consent page, and any scopes you request are unchanged. The migration updates only the backend token and token metadata endpoints your app calls after a user installs the app.
- If you’re using the v3 OAuth API:
- Confirm all sensitive fields are passed in the request body and not in the URL. Requests that include sensitive data in the URL will return an error, even if the same data is provided in the body.
- Update your error handling to rely on
erroranderror_descriptionif you haven’t already. - It’s recommended that you update your API paths to
/oauth/2026-03to align with HubSpot’s broader date-based API versioning release.
Further resources
For more information, check out the following resources:- OAuth 2026-03 API guide: provides details and reference information on the latest API.
- OAuth v1 guide: provides information on the legacy behavior to help you understand what you’re migrating away from.
- v1 OAuth API deprecation changelog announcement: review the official deprecation announcement, including the rationale and official sunset timeline.