Dynatrace Classic authenticates API calls with Classic access tokens, managed through the Environment API v2/apiTokens endpoint. Latest Dynatrace introduces platform tokens as the recommended mechanism for programmatic access: They're user-bounded, managed centrally in Account Management, and governed at the account level.
This guide covers the full upgrade from Classic access tokens to platform tokens.
This upgrade affects every integration, script, CI/CD pipeline, and third-party tool that currently authenticates with a Classic access token.
Classic access tokens encouraged creating tokens with broad scopes, had no required association to a specific user or service account, and had no practical upper limit per environment, which often led to token sprawl and unclear ownership. Platform tokens close these gaps:
| Classic access token | Platform token |
|---|---|
Created via | Created in Account Management |
Scoped to a Dynatrace environment | Scoped to an account, optionally narrowed to specific environments |
Owned by the environment | Owned by a user or service user |
Unlimited per environment | 50 per user, 100 per service user, per account (see Platform tokens) |
Base URL: | Base URL: |
|
|
Managed via the Environment API | Managed via Account Management |
You'll upgrade every integration that authenticates with a Classic access token. First, you'll build an inventory of your existing Classic access tokens and classify them by usage. Then you replace each active integration with a platform token, validate it, and decommission the Classic access tokens you no longer need.
apiTokens.read scope (to export the inventory) and the apiTokens.write scope (to deactivate and delete tokens). See Access tokens classic.platform-token:tokens:manage scope.iam:service-users:use permission, optionally scoped to specific service users using iam:service-user-email. See Platform tokens.Authorization: Api-Token <your-classic-access-token> for Classic access tokens to Authorization: Bearer <your-platform-token> for platform tokens.Where you manage Classic access tokens depends on your environment state. Platform tokens are always managed through the Account Management API (https://api.dynatrace.com), which is available in all states.
Hybrid: Both Classic and Latest functionality are available.
Classic access token management remains. It additionally becomes available via the .apps domain, and platform tokens are available alongside Classic access tokens.
When an environment enters the Hybrid state, the v2/apiTokens endpoint moves from the .live to the .apps base URL. Update any scripts or configurations that hardcode .live URLs before the transition.
Latest: Only platform tokens are available. Classic access tokens don't exist, and v2/apiTokens isn't available.
Each Classic v2/apiTokens operation maps to a platform-token operation in the Account Management API. All platform token management operations require the platform-token:tokens:manage scope.
| Operation | Classic access tokens (v2/apiTokens) | Platform tokens (Account Management API) |
|---|---|---|
List all tokens |
|
|
Get a token by ID |
| No direct equivalent. Use the list endpoint with |
Find a token by secret |
| Not available. Platform tokens don't support lookup by secret value |
Create a token |
|
|
Activate or deactivate a token |
|
|
Update expiration date |
|
|
Delete a token |
|
|
Export a complete snapshot of your existing Classic access tokens before making any changes. This baseline lets you measure progress, preserves point-in-time metadata (such as last-used dates, scopes, and expiry), and provides an audit trail.
Call the v2/apiTokens endpoint with the metadata fields you need, using the base URL for your environment.
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"
This call requires the apiTokens.read scope. Responses are paged, so keep requesting with ?nextPageKey=<value> until the endpoint returns no nextPageKey. For the full endpoint reference, see Access tokens API - GET all tokens.
Store the export in an access-controlled location, such as a restricted repository, a private page, or an upgrade ticket attachment, and record that location. The export contains token metadata, including IP addresses (lastUsedIpAddress), which may be personal data. Keep access to it restricted and apply your organization's data-handling policy for personal data.
Classify every Classic access token before you act. Don't delete a token on the assumption that it's unused, because it might be used in a periodic or seasonal workflow.
The API doesn't enforce unique token names, so that an environment can contain multiple tokens with the same name. Always track, quarantine, and delete tokens by their unique ID, never by name. Names are for human readability only.
Use the following guide:
| Classification | Signal | Recommended action |
|---|---|---|
Actively used |
| Upgrade first. Highest impact if blocked. |
Rarely used |
| Find the owner, schedule upgrade. |
Batch or periodic |
| Apply a grace period (at least one full job cycle) before acting. |
Unused or orphaned | No recorded | Quarantine, then delete. |
Some tokens serve infrequent but legitimate tasks, such as quarterly reports, annual audit exports, or fortnightly batch jobs. Before treating a token as inactive, cross-reference its lastUsedDate with the known schedule of the integration it serves. Scopes related to reporting, data export, or archival are a signal of periodic use. Treat the 30/180-day thresholds as a starting point, not a rule.
For richer classification—which endpoints a token calls, how often, and from where—query the Dynatrace audit logs with DQL in
Notebooks:
fetch dt.system.events| filter event.kind == "AUDIT_EVENT"| filter event.provider == "CLASSIC_API"| summarize count(), by:{authentication.token, endpoint}
authentication.token is the public portion of the token, which you can match to your inventory.endpoint shows how often and how regularly each token calls a given endpoint, which helps you spot periodic or batch use.Querying dt.system.events requires access to Grail and the appropriate query permissions. How far back you can look depends on your Grail retention configuration.
For each Classic access token classified as actively used, or rarely used with a confirmed owner, replace it with a platform token:
Create a platform token in Account Management, assigned to a service user for automation, with the minimum scopes the integration needs. To see which scopes map to which endpoints, use the Dynatrace API explorer your environment offers under this URL: https://<your-environment>.apps.dynatrace.com/platform/swagger-ui/index.html.
Find every place the old token is stored: secrets managers, CI/CD variables, Kubernetes secrets, config files, and scheduled scripts.
Replace the stored value with the new platform token.
Update the authorization header from Authorization: Api-Token <your-classic-access-token> to Authorization: Bearer <your-platform-token>.
For example:
curl -s \-H "Authorization: Bearer <your-platform-token>" \"https://{your-environment-id}.apps.dynatrace.com/platform/storage/logs/v1/export"
Run the integration end-to-end against the platform token before removing the Classic access token.
Don't delete the old Classic access token until you can confirm the platform token works. If you get a 403, see Troubleshoot issues.
Confirm all of the following before removing the Classic access token:
Once the platform token works, retire the Classic access token:
Deactivate the Classic access token. You can reactivate a token that was deactivated due to a missing dependency, so deactivating it first is safer than deleting it outright.
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}"
This call requires the apiTokens.write scope. See Access tokens API - PUT a token.
Wait one full business or job cycle to confirm nothing still depends on the token.
Delete the Classic access token. Deletion is permanent.
Delete tokens by their unique ID, never by name. Token names aren't unique.
curl -s -X DELETE \-H "Authorization: Api-Token <your-classic-access-token>" \"https://{your-environment-id}.live.dynatrace.com/api/v2/apiTokens/{id}"
This call requires the apiTokens.write scope. See Access tokens API - DELETE a token.
Leave your last Classic access token in place for now. Removing it needs a different approach, covered in the next step.
The v2/apiTokens API requires a Classic access token to authenticate, which creates a circular dependency when you delete your final token. There's no Classic access token left to authorize the deletion. Handle it one of two ways.
Self-removal
apiTokens.write scope as your final cleanup token, and remove all the others.DELETE /api/v2/apiTokens/{id} endpoint accepts the token's own ID.Platform token on .apps
DELETE /api/v2/apiTokens/{id} on the .apps domain to delete each remaining Classic access token, including the last one.Plan this sequence before you start, so you don't delete every token with the apiTokens.write scope before cleanup is complete.
Your upgrade is complete when:
If an integration breaks after switching to a platform token:
If an upgraded integration fails after switching to a platform token, check these common issues.
A 403 means either the token lacks the required scope for the endpoint, or the user or service user the token belongs to lacks the required Dynatrace permission. Both must be in place, since a scope 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—use the built-in rotate function to replace expiring tokens before they lapse. See Platform tokens.
Deactivating a platform token takes effect immediately, but propagation across all platform services can take up to five minutes. During that window, some services may still accept the token.