Migrating from Legacy Tokens to API Keysets

Overview

Legacy Demandbase API tokens are created under an individual user's profile. Because they are user-specific, integrations can be disrupted if that user is deactivated or their access changes.

API Key Sets provide platform-level credentials with permissions scoped to a specific integration. They are not tied to an individual user and support safer credential rotation. For more information, see Generate and Manage API Key Sets.

This guide covers authentication migration only. API endpoint, payload, and version changes should be handled separately.

What Changes

Legacy authenticationAPI Key Set authentication
One user-specific API tokenPlatform-level credentials
The legacy token is sent directly as a bearer tokenA Client ID and Client Secret are exchanged for a temporary access token
Access follows the user contextPermissions are explicitly assigned to the API Key Set
User changes can disrupt integrationsIntegrations remain independent of individual users

Resource API requests continue to use the bearer authentication header:

Authorization: Bearer <access-token>

The primary application change is obtaining and refreshing the access token.

Terminology

TermMeaning
API Key SetNamed permission container for an integration
API TokenClient ID and Client Secret created within the API Key Set
Access TokenTemporary JWT returned by the authentication endpoint and used as the bearer token

Do not send the Client Secret directly in the Authorization header.

Before You Begin

You need:

  • Demandbase administrator access or permission to manage API Key Sets.
  • An inventory of the applications and jobs using the legacy token.
  • A secure secrets manager for the Client ID and Client Secret.
  • Access to a sandbox or controlled test environment, when available.

Migration Procedure

1. Inventory Existing Integrations

Identify every place where the legacy token is used, including:

  • Applications and scheduled jobs
  • CI/CD variables
  • Cloud secret managers
  • Postman environments
  • Middleware and third-party integrations
  • Production and sandbox environments

Record which Demandbase APIs and operations each integration uses. This determines the permissions its new API Key Set requires.

2. Design the API Key Sets

Create a separate API Key Set for each independent workload or trust boundary. For example:

  • Production Data Export
  • Production Data Import
  • Salesforce Integration
  • Development Testing

Avoid creating one broadly privileged API Key Set for every integration. Demandbase currently allows up to five API Key Sets and up to five active tokens within each set.

3. Create an API Key Set

A Demandbase administrator should:

  1. Go to Settings > APIs > API Key Sets.
  2. Click Create New.
  3. Enter a descriptive name.
  4. Assign only the API permissions required by the integration.
  5. Create an API token.
  6. Copy the generated Client ID and Client Secret.

The Client Secret is shown only once. Store it immediately in an approved secrets manager.

Do not place the Client ID, Client Secret, or access tokens in:

  • Source control
  • Support tickets
  • Email or chat
  • Application logs
  • Unencrypted configuration files

The public configuration flow currently lists permissions for Admin, B2B, Data Export, and Data Import APIs. B2B and Data Export permissions may require enablement by your Demandbase account team.

4. Exchange the Credentials for an Access Token

Send the Client ID and Client Secret to the Generate a JWT Token endpoint:

TOKEN_RESPONSE="$(
  curl --silent --show-error --fail-with-body \
    --request POST \
    --url 'https://uapi.demandbase.com/auth/v1/token' \
    --header 'Accept: application/json' \
    --header 'Content-Type: application/json' \
    --data "$(
      jq --null-input \
        --arg clientId "$DEMANDBASE_CLIENT_ID" \
        --arg clientSecret "$DEMANDBASE_CLIENT_SECRET" \
        '{
          grantType: "client_credentials",
          clientId: $clientId,
          clientSecret: $clientSecret
        }'
    )"
)"

ACCESS_TOKEN="$(jq --raw-output '.accessToken' <<<"$TOKEN_RESPONSE")"
EXPIRES_IN="$(jq --raw-output '.expiresIn' <<<"$TOKEN_RESPONSE")"

The response has this structure:

{
  "accessToken": "...",
  "tokenType": "bearer",
  "expiresIn": 3600
}

Treat the returned expiresIn value as authoritative. Do not hardcode a fixed token lifetime.

5. Call the Resource API

Replace the legacy bearer token with the returned access token:

curl --silent --show-error --fail-with-body \
  --url 'https://uapi.demandbase.com/<api-path>' \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  --header 'Accept: application/json'

All Demandbase APIs expect the JWT in the bearer header. See Authenticating with the APIs.

6. Implement Token Lifecycle Management

Production integrations should:

  • Cache the access token instead of requesting one for every API call.
  • Calculate expiration using the returned expiresIn value.
  • Refresh shortly before expiration, allowing a small clock-skew buffer.
  • On a 401, discard the cached token, obtain a new one, and retry once.
  • Do not automatically retry a 403; verify the API Key Set permissions.
  • Prevent multiple application instances from refreshing simultaneously where practical.
  • Never log the Client Secret or complete access token.

The token-management flow should follow this pattern:

1. Return the cached access token when it is still valid.
2. Otherwise, exchange the Client ID and Client Secret for a new token.
3. Cache the new token until shortly before its reported expiration.
4. If an API request returns 401, clear the cache and retry once with a new token.

The Demandbase Python SDK can manage authentication and token refresh using the DEMANDBASE_CLIENT_ID and DEMANDBASE_CLIENT_SECRET environment variables. See Python SDK Error Handling.

7. Validate Before Cutover

Validate more than the token-generation request:

  • Confirm the authentication endpoint returns 200.
  • Exercise a representative read operation.
  • Test controlled write operations where applicable.
  • For the Data Import or Data Export API, complete a full job lifecycle.
  • Confirm the integration refreshes an expired access token.
  • Confirm insufficient permissions return 403.
  • Monitor 401, 403, 429, and 5xx responses.

Avoid submitting the same write operation through both authentication paths during testing.

8. Cut Over the Integration

  1. Deploy the new credentials alongside the legacy configuration.
  2. Enable API Key Set authentication for a small workload or canary.
  3. Monitor the complete integration lifecycle.
  4. Move the remaining traffic to the new authentication path.
  5. Maintain the legacy path only for the agreed rollback window.

9. Retire the Legacy Token

After the new authentication path is stable:

  1. Remove the legacy token from applications and scheduled jobs.
  2. Remove it from secret stores, CI/CD variables, and Postman environments.
  3. Confirm that no successful requests still depend on it.
  4. Revoke the legacy token using the supported tenant or Demandbase Support process.
  5. Document the API Key Set owner and rotation procedure.

Rollback Procedure

If the new authentication path causes unexpected failures during the rollout window:

  1. Switch the affected integration back to the legacy authentication configuration.
  2. Preserve the new API Key Set for investigation; do not expose its credentials.
  3. Capture the affected endpoint, request time, HTTP status, and diagnostic ID.
  4. Correct credential, entitlement, or permission issues.
  5. Repeat validation before attempting the cutover again.

Troubleshooting

Response or symptomLikely causeAction
400 from the token endpointIncorrect JSON field names or request formatUse grantType, clientId, and clientSecret with Content-Type: application/json
401 from the token endpointInvalid, deleted, or deactivated credentialsVerify the Client ID, Client Secret, token status, and environment
401 from a resource APIMissing or expired access tokenObtain a new access token and retry once
403 from a resource APIMissing API Key Set permission or API entitlementReview the API Key Set permissions and API enablement
Legacy token succeeds but the new token failsPermission or endpoint-support differenceCapture the endpoint, timestamp, status, and diagnostic ID for Support
429 from a resource APIRate limit exceededHonor the response headers and use exponential backoff

Never provide Client IDs, Client Secrets, or complete access tokens when opening a support request.

Migration Checklist

  • Inventory all legacy-token consumers.
  • Map each integration to the required API permissions.
  • Create workload-specific API Key Sets.
  • Store the Client ID and Client Secret securely.
  • Implement access-token acquisition and caching.
  • Implement expiration handling and one-time 401 retry.
  • Test representative reads, writes, and job lifecycles.
  • Complete a monitored canary rollout.
  • Move all production traffic to API Key Set authentication.
  • Remove and revoke the legacy token.
  • Document credential ownership and rotation procedures.

Additional Resources