Dynatrace Classic authenticates API calls with access tokens managed through the Environment API's v2/apiTokens endpoint. In Latest Dynatrace, this model is replaced with platform tokens: credentials scoped to a specific user or service user and managed centrally in Account Management. This guide walks you through inventorying your existing classic access tokens, classifying them by usage, replacing active integrations with platform tokens, and safely decommissioning the tokens you no longer need.
Platform tokens are limited to 50 per user and 100 per service user, per account. Assign tokens used by automated integrations to service users rather than personal accounts, to keep automation credentials separate from your personal limit.
In this upgrade guide, you'll:
To complete this upgrade guide, you need:
platform-token:tokens:manage OAuth scope, to create and manage platform tokens.iam:service-users:use permission (optionally scoped with iam:service-user-email) granted to the relevant group, to assign tokens to service users.apiTokens.read scope, to export the token inventory.The following table summarizes breaking changes when upgrading to Latest Dynatrace platform tokens.
| Change | Required action |
|---|---|
| Update any scripts, SDK configurations, or documentation that hardcode the |
Authentication header format changes | Replace |
| Complete the migration before your environment reaches the latest state. There's no classic access token management after that point. |
Classic access tokens only, managed through v2/apiTokens on the .live domain.
Both classic and latest functionality are available. Classic token management remains available but moves to the .apps domain. Platform tokens are also available alongside classic access tokens. This is the most common state for environments that are migrating to Latest Dynatrace functionality.
Platform tokens only. Classic access tokens don't exist in latest environments, and v2/apiTokens isn't available.
In Latest Dynatrace, platform tokens can be assigned to a service user. This user is an account-level identity used to run automated integrations, separate from any individual's personal account. Platform tokens assigned to a service user don't count against a person's token limit.
Before taking any migration action, export and store a complete snapshot of all existing classic access tokens. This is your baseline: it preserves point-in-time metadata (last-used dates, scopes, expiry) and gives you an audit trail for compliance review.
The Dynatrace API doesn't enforce unique names for classic access tokens; an environment can contain multiple tokens with the same name. Always use the token's unique ID, not its name, as the stable reference for classification, migration tracking, and deletion.
Call the export endpoint for your environment type.
The calling token needs the apiTokens.read scope. If the response includes a nextPageKey, request additional pages with ?nextPageKey=<value> until it's no longer present.
Classic environment:
GET https://{your-environment-id}.live.dynatrace.com/api/v2/apiTokens?fields=+lastUsedDate,+lastUsedIpAddress,+expirationDate,+scopes
Hybrid environment:
GET https://{your-environment-id}.apps.dynatrace.com/api/v2/apiTokens?fields=+lastUsedDate,+lastUsedIpAddress,+expirationDate,+scopes
Here's an example curl call for classic environments:
curl -s \-H "Authorization: Api-Token <your-classic-access-token>" \"https://{your-environment-id}.live.dynatrace.com/api/v2/apiTokens?fields=%2BlastUsedDate,%2BlastUsedIpAddress,%2BexpirationDate,%2Bscopes"
Store the export in an access-controlled location (for example, a private Confluence page, a restricted repository, or an attachment on your migration ticket), and record where you stored it in your migration ticket. The export contains token metadata that shouldn't be broadly accessible.
Once you export the data, you will have a complete, timestamped baseline of every classic access token in the environment.
Alternatively, for a richer view than lastUsedDate alone, you can use DQL to query which endpoints a token calls and how often.
fetch dt.system.events| filter event.kind == "AUDIT_EVENT"| filter event.provider == "CLASSIC_API"
authentication.token gives you the public portion of the token to match against your inventory. Summarizing by: endpoint helps identify periodic or batch use cases. This requires Grail access and query permissions in your environment.
With the inventory in hand, classify each token before acting. An apparently unused token may be serving a periodic or seasonal workflow, so don't delete anything without classifying it first.
The following table provides a guideline for how to classify tokens based on the lastUsedDate from the export in step 1.
| Classification | Signal | Recommended action |
|---|---|---|
Actively used |
| Migrate these tokens first, because they have the highest impact if blocked. |
Rarely used |
| Find the owner, then schedule migration. |
Batch or periodic |
| Apply a grace period of at least one full job cycle before acting. |
Unused or orphaned | No recorded | Quarantine, then delete. |
The 30-day/180-day thresholds are a starting point, not a rule: adapt them to your environment. Some tokens serve infrequent but legitimate tasks (quarterly reports, annual audit exports, fortnightly batch jobs), so cross-reference lastUsedDate against the known schedule of the integration before treating a token as inactive.
For each token classified as actively used, or rarely used with a confirmed owner, create a platform token replacement.
Create the platform token in Account Management, not in the environment's settings or API configuration.
For automated integrations, assign the token to a service user rather than your personal account. An account administrator must grant the iam:service-users:use permission to the relevant group first (optionally scoped to specific service users with iam:service-user-email).
Replace the token in each integration.
Identify every location where the old token is stored: secrets managers, CI/CD pipeline variables, Kubernetes secrets, application configuration files, and scheduled scripts.
Update each location with the new platform token value.
Update the authorization header format.
Authorization: Api-Token <your-classic-access-token>.Authorization: Bearer <your-platform-token>.Run the integration end-to-end to confirm it works before decommissioning the old token.
curl -s \-H "Authorization: Bearer <your-platform-token>" \"https://{your-environment-id}.apps.dynatrace.com/platform/storage/logs/v1/export"
Each migrated integration authenticates with a platform token scoped to a user or service user, instead of an environment-wide classic access token.
For each migrated integration, confirm all of the following before removing the classic access token.
Check that the platform token works end-to-end, with no HTTP 401 or 403 responses.
Confirm the platform token has the minimum required scopes, and that the underlying user or service user has the required permissions. If it doesn't, see Why does a platform token return HTTP 403?.
Remove the old classic access token from every known location: secrets managers, CI/CD variables, Kubernetes secrets, configuration files, scripts, and source code.
Don't delete the old classic access token until you confirm the replacement works.
Once you've confirmed that the replacement platform token works, you can disable the classic access token. Before you permanently delete the token, wait at least one full business or job cycle before permanent deletion. This is because a disabled token can be re-enabled if you missed a dependency; deletion is permanent.
Disable the token.
Here's an example curl call for classic environments:
curl -s -X PUT \-H "Authorization: Api-Token <your-classic-access-token>" \-H "Content-Type: application/json" \-d '{"revoked": true}' \"https://{your-environment-id}.live.dynatrace.com/api/v2/apiTokens/{id}"
Delete the token using its unique ID, not its name.
Classic environment:
DELETE https://{your-environment-id}.live.dynatrace.com/api/v2/apiTokens/{id}
Hybrid environment:
DELETE https://{your-environment-id}.apps.dynatrace.com/api/v2/apiTokens/{id}
Here's an example curl call for hybrid environments:
curl -s -X DELETE \-H "Authorization: Api-Token <your-classic-access-token>" \"https://{your-environment-id}.apps.dynatrace.com/api/v2/apiTokens/{id}"
For your last remaining classic access token, plan ahead: v2/apiTokens can only be managed with a classic access token, so deleting the final one creates a circular dependency. Either keep one token with apiTokens.write scope as a self-removal cleanup token (a token can delete itself by ID), or use a platform token with the appropriate scope to call DELETE against the .apps domain endpoint.
You've completed the migration when:
Account administrators can now manage every token from Account Management, with rotation and per-token governance available across the account.
A 403 means one of two things: the token doesn't have the required scope for the endpoint being called, or the user or service user it's assigned to doesn't have the required Dynatrace permissions. Both the token scope and the user's platform permissions must be in place. Scope selection can't grant access beyond what the assigned user is allowed to do.
Expired tokens also return 403. Check the token's expiration date: expired tokens remain in the token list until explicitly deleted, so use the rotate function in Account Management to replace expiring tokens before they expire.
Disabling a platform token takes effect immediately, but propagation across all platform services can take up to five minutes. During that window, the token may still authenticate successfully against some services.
If you haven't yet deleted the token, just re-enable the old classic access token to restore service immediately. Revert the integration to the classic access token while you diagnose the issue, then re-attempt the migration. Classic and platform token access can run side by side; see Validate before decommissioning.
If you have already deleted the token, this cannot be undone. You need to create a valid platform token.