Dynatrace Classic authenticates API calls with Classic access tokens, managed through the Environment API v2/apiTokens endpoint. Latest Dynatrace replaces them with platform tokens: credentials bound to a specific user or service user, managed centrally in Account Management, and governed at the account level.
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 broad scopes, had no required association to a specific user or service account, and had no practical upper limit per environment. The result was often token sprawl and unclear ownership. Platform tokens close these gaps:
| Classic access token | Platform token |
|---|---|
Created via POST /api/v2/apiTokens or in Access tokens | 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: .live.dynatrace.com | Base URL: api.dynatrace.com (Account Management API) |
Authorization: Api-Token <your-classic-access-token> | Authorization: Bearer <your-platform-token> |
| Managed via the Environment API | Managed via Account Management |
In this upgrade guide, you'll:
To complete this upgrade guide, you need:
platform-token:tokens:manage scope. See Platform tokens API - GET all a platform token.iam:service-users:use permission (optionally scoped with iam:service-user-email) granted to the relevant group by an account administrator, to assign tokens to service users. See Platform tokens.apiTokens.read scope to export the inventory, and the apiTokens.write scope to disable and delete tokens.| Change | Required action |
|---|---|
v2/apiTokens moves to the .apps base URL in hybrid environments | Update any scripts, SDK configurations, or documentation that hardcode the .live URL before your environment enters the hybrid state. |
| Authentication header format changes | Replace Authorization: Api-Token <your-classic-access-token> with Authorization: Bearer <your-platform-token> in every upgraded integration. |
v2/apiTokens isn't available in latest environments | Complete the upgrade before your environment reaches the latest state. There's no Classic access token management after that point. |
Where you manage tokens depends on the token type.
Classic access tokens only, managed through v2/apiTokens on the .live domain.
Both Classic and latest functionality are available. Classic access token management remains, but moves to the .apps domain, and platform tokens are available alongside Classic access tokens. Most environments moving to Latest Dynatrace functionality run in the hybrid state.
Platform tokens only. Classic access tokens don't exist, and v2/apiTokens isn't available.
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.
Each Classic v2/apiTokens operation maps to a platform token operation in the Account Management API.
| Operation | Classic access tokens (v2/apiTokens) | Platform tokens (Account Management API) |
|---|---|---|
| List all tokens | GET https://{env-id}.live.dynatrace.com/api/v2/apiTokens | GET https://api.dynatrace.com/iam/v1/accounts/{accountUuid}/platform-tokens |
| Get a token by ID | GET https://{env-id}.live.dynatrace.com/api/v2/apiTokens/{id} | No direct equivalent. Use the list endpoint with searchTerm={tokenId} to filter |
| Find a token by secret | POST https://{env-id}.live.dynatrace.com/api/v2/apiTokens/lookup | Not available. Platform tokens don't support lookup by secret value |
| Create a token | POST https://{env-id}.live.dynatrace.com/api/v2/apiTokens | POST https://api.dynatrace.com/iam/v1/accounts/{accountUuid}/platform-tokens |
| Enable or disable a token | PUT https://{env-id}.live.dynatrace.com/api/v2/apiTokens/{id} (set revoked) | PUT https://api.dynatrace.com/iam/v1/accounts/{accountUuid}/platform-tokens/{platformTokenId}/status |
| Update expiration date | PUT https://{env-id}.live.dynatrace.com/api/v2/apiTokens/{id} | PUT https://api.dynatrace.com/iam/v1/accounts/{accountUuid}/platform-tokens/{platformTokenId}/expiration-date |
| Delete a token | DELETE https://{env-id}.live.dynatrace.com/api/v2/apiTokens/{id} | DELETE https://api.dynatrace.com/iam/v1/accounts/{accountUuid}/platform-tokens/{platformTokenId} |
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 (last-used dates, scopes, and expiry), and gives you an audit trail for compliance review.
The Dynatrace API doesn't enforce unique names for Classic access tokens, so 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, upgrade tracking, and deletion.
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 attachment on your upgrade ticket, 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.
You now have a complete, timestamped baseline of every Classic access token in the environment.
Classify every Classic access token before you act. A token that looks idle may still serve a periodic or seasonal workflow, so don't delete it until you've confirmed what it does.
Use the lastUsedDate from your inventory:
| Classification | Signal | Recommended action |
|---|---|---|
| Actively used | lastUsedDate within the last 30 days | Upgrade first. Highest impact if blocked. |
| Rarely used | lastUsedDate between 30 and 180 days ago | Find the owner, then schedule the upgrade. |
| Batch or periodic | lastUsedDate beyond the threshold, but known as a scheduled job | Apply a grace period of at least one full job cycle before acting. |
| Unused or orphaned | No recorded lastUsedDate, or an old token with no identified owner | 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, biweekly batch jobs), so cross-reference lastUsedDate against the known schedule of the integration before treating a token as inactive. Scopes related to reporting, data export, or archival are a signal of periodic use.
For a richer view—which endpoints a token calls, how often, and from where—query the 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 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, create a platform token replacement.
Create the platform token in Account Management, not in the environment's settings or API configuration.
For the full procedure, see Platform tokens. To see which scopes map to which endpoints, use the Dynatrace API explorer in your environment: https://{your-environment-id}.apps.dynatrace.com/platform/swagger-ui/index.html.
For automated integrations, assign the token to a service user rather than your personal account. A service-user token keeps automation credentials separate from your personal limit of 50 tokens.
Replace the token in each integration.
Authorization: Api-Token <your-classic-access-token> to Authorization: Bearer <your-platform-token>. See Platform tokens.Don't delete the old Classic access token until you confirm the platform token works. If you get a 403, see Why does my platform token return HTTP 403?.
Each upgraded integration now authenticates with a platform token scoped to a user or service user, instead of an environment-wide Classic access token.
For each upgraded integration, confirm the following before removing the Classic access token.
Once the platform token works, retire the Classic access token.
Disable the Classic access token. A disabled token can be re-enabled if you missed a dependency, so disabling 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 at least one full business or job cycle to confirm that nothing still depends on the token.
Delete the Classic access token by its unique ID, never by name. Deletion is permanent.
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.
When you delete your last Classic access token, you can either use the token itself (if it has the apiTokens.write scope) or a new platform token.
Use the Classic access token to delete itself:
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.Use a new platform token to delete the Classic access token:
DELETE /api/v2/apiTokens/{id} on the .apps domain to delete each remaining Classic access token, including the last one.Your upgrade is complete 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 must be in place, because a 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 lapse. See Platform tokens.
Disabling a platform token is recorded immediately, but propagation across all platform services can take up to five minutes. During that window, some services may still accept the token.
If an integration breaks after you switch to a platform token: