create-service-account-token
dci create-service-account-token [body] [flags]
Mints an API token for the service account and returns its accessToken once. The token
inherits the service account's permissions as they stand at creation; there is no per-token
scoping. Returns 409 when the service account already has a token of the same name, and
422 at the cap of 10 tokens.
dryRun=true checks the name bounds only, then returns a preview without creating anything.
It does not verify that the service account exists, that the name is unused, or that the
account is under the token cap, so a dry run can succeed where the real create then returns
404, 409 or 422. Requires the serviceAccountCreator permission.
Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.
Request
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Name, unique among the service account's tokens. Leading or trailing whitespace returns 400. |
expiresTime | string (date-time) | When the token should stop authenticating. Omit to let the server set the default expiry. |
Example body (JSON)
{
"name": "ci-pipeline-prod",
"expiresTime": "2027-09-01T08:00:00Z"
}
Raw JSON schema
{
"type": "object",
"description": "Fields of a new API token.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "Name, unique among the service account's tokens. Leading or trailing whitespace returns `400`.",
"example": "ci-pipeline-prod"
},
"expiresTime": {
"type": "string",
"format": "date-time",
"description": "When the token should stop authenticating. Omit to let the server set the default expiry.",
"example": "2027-09-01T08:00:00Z"
}
}
}
Flags
| Flag | Type | Default | Example | Description |
|---|---|---|---|---|
--dry-run | boolean | false | If true, validates the request and returns the would-be result without applying it. The response then carries the X-Dry-Run header. |
Every command also accepts the CLI-wide flags for output shaping — see Output formats and Table output options.
Output
OK - Dry run only (dryRun=true). The name passed its bounds check and nothing was created; id and createTime are null and accessToken is an empty string. Not a guarantee that a real create would succeed — see the operation description.
By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.
| Field | Type | Description |
|---|---|---|
accessToken | string (password) | The token credential, and the secret that authenticates as this service account. Returned only by this operation and never retrievable again, so store it somewhere safe on receipt; an empty string on a dry-run create. Treat it like a password. |
id | string | API token ID. null only on a dry-run create. |
serviceAccountId | string | ID of the service account that owns the token. |
customerId | string | ID of the customer whose service account the token belongs to. |
name | string | Name, unique among the service account's tokens. |
state | string | The token's stored state: active while it is enabled, disabled once it has been turned off. This is not a liveness signal — a token whose expiresTime has passed stops authenticating but keeps the state it was stored with, so active here does not by itself mean the token still works; compare expiresTime. Only these two values can be set. One of: "active", "disabled". |
createTime | string (date-time) | When the token was created. null only on a dry-run create. |
expiresTime | string (date-time) | When the token stops authenticating. null when it does not expire. |
lastUsedTime | string (date-time) | When the token last authenticated a request. null until it is first used. |
Example response (--output json)
{
"id": null,
"serviceAccountId": "Lq3nO9rM5wS2tU0xY4zA",
"customerId": "Kp2mN8qL4vR0sT1wX3yZ",
"name": "ci-pipeline-prod",
"state": "active",
"createTime": null,
"expiresTime": "2027-09-01T08:00:00Z",
"lastUsedTime": null,
"accessToken": ""
}
Raw JSON schema
{
"description": "A newly created API token, together with the credential that authenticates as it.",
"allOf": [
{
"type": "object",
"description": "An API token of a service account. It authenticates with the service account's permissions, and carries no secret material after the create response.",
"required": [
"id",
"serviceAccountId",
"customerId",
"name",
"state",
"createTime",
"expiresTime",
"lastUsedTime"
],
"properties": {
"id": {
"type": "string",
"nullable": true,
"readOnly": true,
"description": "API token ID. `null` only on a dry-run create.",
"example": "Mr0sN7pQ4tU2vW5xY8zC"
},
"serviceAccountId": {
"type": "string",
"readOnly": true,
"description": "ID of the service account that owns the token.",
"example": "Lq3nO9rM5wS2tU0xY4zA"
},
"customerId": {
"type": "string",
"readOnly": true,
"description": "ID of the customer whose service account the token belongs to.",
"example": "Kp2mN8qL4vR0sT1wX3yZ"
},
"name": {
"type": "string",
"description": "Name, unique among the service account's tokens.",
"example": "ci-pipeline-prod"
},
"state": {
"type": "string",
"enum": [
"active",
"disabled"
],
"description": "The token's stored state: `active` while it is enabled, `disabled` once it has been turned off. This is not a liveness signal — a token whose `expiresTime` has passed stops authenticating but keeps the state it was stored with, so `active` here does not by itself mean the token still works; compare `expiresTime`. Only these two values can be set.",
"example": "active"
},
"createTime": {
"type": "string",
"format": "date-time",
"nullable": true,
"readOnly": true,
"description": "When the token was created. `null` only on a dry-run create.",
"example": "2026-09-01T08:00:00Z"
},
"expiresTime": {
"type": "string",
"format": "date-time",
"nullable": true,
"description": "When the token stops authenticating. `null` when it does not expire.",
"example": "2027-09-01T08:00:00Z"
},
"lastUsedTime": {
"type": "string",
"format": "date-time",
"nullable": true,
"readOnly": true,
"description": "When the token last authenticated a request. `null` until it is first used.",
"example": "2026-09-20T14:31:00Z"
}
}
},
{
"type": "object",
"required": [
"accessToken"
],
"properties": {
"accessToken": {
"type": "string",
"format": "password",
"readOnly": true,
"description": "The token credential, and the secret that authenticates as this service account. Returned only by this operation and never retrievable again, so store it somewhere safe on receipt; an empty string on a dry-run create. Treat it like a password.",
"example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example.signature"
}
}
}
]
}
Errors
On failure, dci prints a single error message — with a hint when one is available — and exits with a typed code your scripts can branch on. See Errors and exit codes for the full contract.
HTTP status to exit code mapping
| HTTP status | Exit code | Error code | Meaning |
|---|---|---|---|
| 400, 422 | 30 | VALIDATION_ERROR | The arguments or request body were rejected. Review the command's flags and payload. |
| 401 | 10 | AUTHENTICATION_FAILED | Not signed in, or the API token is invalid. Run dci login or check DCI_API_KEY. |
| 403 | 11 | PERMISSION_DENIED | The DoiT user or the active customer context does not have access. |
| 404 | 20 | RESOURCE_NOT_FOUND | The requested resource does not exist. Check the identifier argument. |
| 409 | 21 | RESOURCE_CONFLICT | The operation conflicts with the resource's current state. |
| 500 | 40 | API_SERVER_ERROR | The API failed to process the request. Retryable; contact DoiT support if it persists. |
Related
- create-service-account — Create a service account
- delete-service-account — Delete a service account
- delete-service-account-token — Delete an API token
- get-service-account — Get a service account
- get-service-account-token — Get an API token
- list-service-account-tokens — List API tokens for a service account
- list-service-accounts — List service accounts
- update-service-account — Update a service account
- update-service-account-token — Enable or disable an API token
- API reference: POST /iam/v1/service-accounts/{serviceAccountId}/api-tokens
Aliases: createserviceaccounttoken