Sail

Mint Ephemeral User Token

POST/users/{user_id}/tokens

Mints a short-lived token for PII access. Mint, use, discard. Never store it. Requires the token_admin key scope, which on live keys is exclusive: the minting key carries no data scopes and cannot itself use the tokens it mints. Concurrent tokens are allowed. Expiry is the cleanup. Every mint is audit-logged and mint velocity is rate-limited per user. Narrow scopes below the key’s grants per workload, e.g. ["numbers"] for a service that renders masked numbers but must never reveal.

Path Parameters

user_idstringrequired

The Sail user id.

Body application/json

ttl_secondsinteger

How long the minted token remains valid, in seconds.

scopes"identity" | "numbers" | "numbers:reveal"[]

Defaults to all token scopes the minting key’s grants allow. Narrow per workload — omit numbers:reveal for services that only display masked numbers.

Response

Token minted.

user_tokenstring

The minted ephemeral token. Pass it in the x-sail-user-token header.

expires_atstring<date-time>

When the token expires.

scopesstring[]

The token scopes actually granted.

insufficient_key_scope: key lacks token_admin.

rate_limited: mint velocity exceeded for this user.

Standard error envelope covering 400, 401, 403, 404, 429, and 500.

errorobject

The error detail.

Show error properties
codestring

Machine-readable code, e.g. not_found, token_scope_mismatch, product_not_enabled, insufficient_key_scope, insufficient_token_scope, user_token_required, user_token_expired, invalid_user_token, invalid_key_configuration, connection_not_reconnectable, rate_limited.

messagestring

Human-readable error message. May change, so match on error.code instead.

paramstring

The request field that caused the error, when applicable. Null otherwise.

Request
curl -X POST "https://live.savewithsail.com/api/v1/users/<user_id>/tokens" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
  "ttl_seconds": 900,
  "scopes": [
    "identity"
  ]
}'
Response
{
  "user_token": "ut_test_p2m88xnq1",
  "expires_at": "1970-01-01T00:00:00.000Z",
  "scopes": [
    "string"
  ]
}