Skip to content
Try the API

Automate personal access tokens

Manage the full lifecycle of personal access tokens (PATs) through the API: issue a narrowly scoped token with an expiry, rename or rescope it in place, rotate it without downtime, and revoke it when it is no longer needed. For how tokens, scope categories and access levels work, read Authentication first.

  • Token management is tenant admin only. The token you call these endpoints with must belong to a tenant admin.
  • Every operation acts on the tokens of the requesting user: you can list, update and revoke only tokens you issued yourself.
  • These operations are admin-only. The gateway works out your role from the token; if you get a 403, check that the token’s user is a tenant admin.

Scopes are expressed as grants, an array of {category, access} objects. category is one of inventory, security, protection, reporting, integrations or admin; access is read or write (write implies read). Set all_scopes: true instead for universal access.

Create a token that can only read reporting data and expires at the end of the quarter. name is required; grants must be non-empty unless all_scopes is true. Omit expires_at for a token that never expires.

POST
/gateway/shared-services/v1/personal-access-tokensIssue a personal access token
Try it
Terminal window
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "bi-export-reporting-ro",
"all_scopes": false,
"grants": [{ "category": "reporting", "access": "read" }],
"expires_at": "2026-12-31T23:59:59Z"
}'

The response is 201 with the raw token in token and the stored metadata in details:

{
"token": "<raw token value>",
"details": {
"id": "3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44",
"name": "bi-export-reporting-ro",
"tenant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"user_id": "5e8f9a10-1111-4222-8333-444455556666",
"all_scopes": false,
"grants": [{ "category": "reporting", "access": "read" }],
"expires_at": "2026-12-31T23:59:59Z",
"created_at": "2026-10-12T09:00:00Z"
}
}

List the tokens you have issued, for example to find tokens nearing expiry or tokens that have never been used (last_used_at absent). The list supports offset pagination with limit and offset, and returns a total.

GET
/gateway/shared-services/v1/personal-access-tokensList personal access tokens
Try it
Terminal window
curl "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens?limit=50&offset=0" \
-H "Authorization: Bearer $ELASTIO_TOKEN"
{
"tokens_details": [
{
"id": "3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44",
"name": "bi-export-reporting-ro",
"tenant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"user_id": "5e8f9a10-1111-4222-8333-444455556666",
"all_scopes": false,
"grants": [{ "category": "reporting", "access": "read" }],
"expires_at": "2026-12-31T23:59:59Z",
"last_used_at": "2026-10-12T10:15:02Z",
"created_at": "2026-10-12T09:00:00Z",
"updated_at": "2026-10-12T09:00:00Z"
}
],
"total": 1
}

PATCH updates a token in place, so the secret value doesn’t change. Each field is optional:

  • Send only name for a rename; omitting both all_scopes and grants leaves permissions unchanged.
  • Send grants (or all_scopes) to replace the token’s permissions.
  • Omitting expires_at leaves the expiry unchanged.
PATCH
/gateway/shared-services/v1/personal-access-tokens/{token_id}Update a personal access token
Try it
Terminal window
curl -X PATCH "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens/3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "bi-export",
"grants": [
{ "category": "reporting", "access": "read" },
{ "category": "inventory", "access": "read" }
]
}'

The response is the updated token (no secret):

{
"id": "3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44",
"name": "bi-export",
"tenant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"user_id": "5e8f9a10-1111-4222-8333-444455556666",
"all_scopes": false,
"grants": [
{ "category": "reporting", "access": "read" },
{ "category": "inventory", "access": "read" }
],
"expires_at": "2026-12-31T23:59:59Z",
"updated_at": "2026-10-12T11:02:40Z"
}

The API has no single “rotate” call; rotation is issue, deploy, then revoke:

  1. Issue a new token with the same grants (and a fresh expires_at) using POST /gateway/shared-services/v1/personal-access-tokens. Copy the old token’s grants from the list response.
  2. Deploy the new token value to your secret store and restart or reload the consumers.
  3. Verify the switch: list tokens again and confirm the new token’s last_used_at is set and the old token’s last_used_at has stopped advancing.
  4. Revoke the old token by ID (next section).
Terminal window
# 1. Issue the replacement (grants copied from the old token)
NEW=$(curl -s -X POST "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens" \
-H "Authorization: Bearer $ELASTIO_TOKEN" -H "Content-Type: application/json" \
-d '{"name":"bi-export-2026q4","grants":[{"category":"reporting","access":"read"}],"expires_at":"2027-03-31T23:59:59Z"}')
echo "$NEW" | jq -r '.token' # 2. deploy this value, then...
# 4. ...revoke the old token
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens/revoke" \
-H "Authorization: Bearer $ELASTIO_TOKEN" -H "Content-Type: application/json" \
-d '{"token_ids":["3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44"]}'

Revoke one or more of your tokens by ID. The call returns 204 with no body. Revoked tokens appear in the revoked list, which has the same shape and limit/offset pagination as the active list.

POST
/gateway/shared-services/v1/personal-access-tokens/revokeRevoke personal access tokens
Try it
Terminal window
curl -X POST "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens/revoke" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "token_ids": ["3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44"] }'

To confirm, list revoked tokens:

GET
/gateway/shared-services/v1/personal-access-tokens/revokedList revoked personal access tokens
Try it
Terminal window
curl "https://acme.app.elastio.com/gateway/shared-services/v1/personal-access-tokens/revoked?limit=20" \
-H "Authorization: Bearer $ELASTIO_TOKEN"
{
"tokens_details": [
{
"id": "3f6c2a1e-8d4b-4c1a-9e2f-7b5d0a9c1e44",
"name": "bi-export",
"tenant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"user_id": "5e8f9a10-1111-4222-8333-444455556666",
"all_scopes": false,
"grants": [{ "category": "reporting", "access": "read" }],
…
}
],
"total": 1
}