Kenso

CLI logins

The Kenso CLI's browser login: start a login, then poll it until it hands the CLI an API key.

Workspace and credits2 endpointsKen-Version: 2026-11-02AuthenticationWorkspacesErrors

Start a CLI login

POST/v1/cli/loginscli-logins.create

Try it on developer.ken.so

No credential. deviceName (1 to 100 characters) is shown on the approval page. Returns the loginId to poll POST /v1/cli/logins/token with (keep it private), the userCode to show, the verificationUrl to open, expiresIn seconds and the poll interval in seconds.

Parameters

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.

Request body

application/json, optional.

Field
Type
Required
Description
deviceName
string
optional
The machine the CLI runs on, shown on the approval page. 1 to 100 characters.

Response 201

data is a CliLoginCreatedModel.

Field
Type
Description
loginId
string
The CLI's pickup credential for POST /v1/cli/logins/token. Keep it private.
userCode
string
XXXX-XXXX: the code the person confirms in the browser.
verificationUrl
string
The approval page with the code filled in.
expiresIn
integer (int32)
Seconds until the login expires.
interval
integer (int32)
Seconds to wait between polls.
Request
curl -X POST "https://api.ken.so/v1/cli/logins" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 2026-11-02" \
  -H "Content-Type: application/json" \
  -d '{
  "deviceName": "string"
}'
Response 201
{
  "success": true,
  "data": {
    "loginId": "string",
    "userCode": "string",
    "verificationUrl": "https://example.com",
    "expiresIn": 1,
    "interval": 1
  }
}

Poll a CLI login for its API key

POST/v1/cli/logins/tokencli-logins.token

Try it on developer.ken.so

No credential: loginId is the credential. Once the login is approved, returns the new apiKey with its apiKeyId, the chosen workspaceId, the approver's email and the key's expiresAt, one time, and deletes the login. Otherwise 400 with error.code set to authorization_pending (keep polling), slow_down (polled sooner than interval; wait longer), access_denied or expired_token (stop; start a new login).

Parameters

Name
In
Type
Required
Description
Ken-Version
In: header
string, one of: 2026-11-02, 1.1
required
The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.

Request body

application/json, optional.

Field
Type
Required
Description
loginId
string
optional
The loginId the create returned.

Response 200

data is a CliLoginTokenModel.

Field
Type
Description
apiKey
string
The new Kenso API key (ken_...). Returned once.
apiKeyId
string
Its id, as GET /v1/api-keys lists it.
workspaceId
integer (int64)
The workspace the person picked: the CLI profile's default.
email
string
The approver's email, when their session carried one.
expiresAt
string (date-time)
When the key expires.
Request
curl -X POST "https://api.ken.so/v1/cli/logins/token" \
  -H "Authorization: Bearer $KEN_API_KEY" \
  -H "Ken-Version: 2026-11-02" \
  -H "Content-Type: application/json" \
  -d '{
  "loginId": "string"
}'
Response 200
{
  "success": true,
  "data": {
    "apiKey": "string",
    "apiKeyId": "string",
    "workspaceId": 812,
    "email": "[email protected]",
    "expiresAt": "2026-09-23T15:02:11Z"
  }
}