Create API token

Creates a new API token for the authenticated user. The raw token value is returned only once in the creation response and cannot be retrieved again. Store it securely immediately after creation.

Requested scopes must be a subset of the permissions the authenticated user already holds. Attempting to grant scopes the user does not have will result in a validation error.

POST /api/v1/api-tokens

Request

Headers

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token for authentication
Content-TypestringYesMust be application/json

Body Parameters

ParameterTypeRequiredDescription
namestringYesA human-readable label for the token (e.g. "CI/CD Pipeline")
scopesstring[]YesOne or more permission scope values. Must be valid Permission values and a subset of the user's own permissions. See List available scopes
expiresAtstringNoISO 8601 datetime at which the token expires. Omit for a non-expiring token

Response

Returns the created token object with a 201 Created status. The response includes a token field containing the raw token value. This field is not included in any subsequent response.

Response Fields

FieldTypeDescription
idstringUnique identifier (UUID)
namestringHuman-readable name
tokenstringThe full raw token value — store this securely, it will not be shown again
tokenPrefixstringFirst 12 characters of the token, used for future identification
scopesstring[]Permission scopes granted to this token
lastUsedAtstring | nullAlways null on creation
expireAtstring | nullISO 8601 expiry timestamp, or null if the token never expires
revokedAtstring | nullAlways null on creation
createdAtstringISO 8601 creation timestamp

Example Request

curl -X POST 'https://api.storno.ro/api/v1/api-tokens' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "CI/CD Pipeline",
    "scopes": ["invoice.view", "invoice.create", "client.view"],
    "expiresAt": "2027-01-01T00:00:00Z"
  }'

Example Response

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "CI/CD Pipeline",
  "token": "af_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3",
  "tokenPrefix": "af_a1b2c3d4e",
  "scopes": ["invoice.view", "invoice.create", "client.view"],
  "lastUsedAt": null,
  "expireAt": "2027-01-01T00:00:00Z",
  "revokedAt": null,
  "createdAt": "2026-02-18T10:00:00Z"
}

Errors

Status CodeError CodeDescription
401unauthorizedInvalid or missing authentication token
422validation_errorInvalid input data (see error details)

Validation Errors

Common validation errors include:

  • Missing name field
  • Missing or empty scopes array
  • One or more scope values are not valid Permission values
  • One or more scopes exceed the authenticated user's own permissions
  • expiresAt is in the past or has an invalid date format

Important Notes

  • The token field in the response is the only time the raw token value is ever transmitted — it is stored as a one-way hash server-side
  • Tokens use the af_ prefix to make them easily identifiable in source code and logs
  • There is no upper limit on the number of tokens a user can create, but each token is subject to the same rate limits as interactive sessions
  • Tokens inherit the organization context from the user who created them