# API keys

An API key lets scripts and tools call the API as you, with your role in each workspace. Send it as `Authorization: Bearer ctk_…` or `X-API-Key: ctk_…`. Its secret is shown once, when the key is created.

## The ApiKey object

An API key that acts as you. The API shows only its first and last characters, never the full secret.

### Attributes

- `id` (string, required): Unique ID of the API key.
- `name` (string, required): The name you gave the key, such as CI deploys.
- `tokenPrefix` (string, required): The secret's first 8 characters, such as ctk_9fQx, to recognize the key.
- `lastFour` (string, required): The secret's last 4 characters.
- `createdAt` (string, required): When the key was created, as an ISO 8601 timestamp.
- `lastUsedAt` (nullable string, required): When the key last authenticated a request, as an ISO 8601 timestamp; null if never.

### Example

```json
{
  "id": "Ak8TqW3nVr5L",
  "name": "CI deploys",
  "tokenPrefix": "ctk_9fQx",
  "lastFour": "rVwA",
  "createdAt": "2026-10-01T16:20:00.000Z",
  "lastUsedAt": "2026-10-14T09:05:12.000Z"
}
```

## List API keys

`GET /v1/api-keys`

Returns your API keys that are not revoked, newest first. Account API keys cannot list keys.

### Returns

Returns an array of [ApiKey](https://docs.qa.clankership.net/api/api-keys/object.md) objects. The status is 200.

### Request

```bash
curl https://api.qa.clankership.net/v1/api-keys \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
[
  {
    "id": "Ak8TqW3nVr5L",
    "name": "CI deploys",
    "tokenPrefix": "ctk_9fQx",
    "lastFour": "rVwA",
    "createdAt": "2026-10-01T16:20:00.000Z",
    "lastUsedAt": "2026-10-14T09:05:12.000Z"
  }
]
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Create an API key

`POST /v1/api-keys`

Creates an API key that acts as you and returns its secret, which is shown only this once. You can have up to 20 active keys. Account API keys cannot create keys.

### Parameters

- `name` (string, required): A name that says where the key is used, 1 to 80 characters.

### Returns

Returns an object with these fields. The status is 200. An API key you just created, with its secret.

- `id` (string, required): Unique ID of the API key.
- `name` (string, required): The name you gave the key, such as CI deploys.
- `tokenPrefix` (string, required): The secret's first 8 characters, such as ctk_9fQx, to recognize the key.
- `lastFour` (string, required): The secret's last 4 characters.
- `secret` (string, required): The full key, starting with ctk_. Store it now: the API never returns it again.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/api-keys \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI deploys"
  }'
```

### Response

```json
{
  "id": "Ak8TqW3nVr5L",
  "name": "CI deploys",
  "tokenPrefix": "ctk_9fQx",
  "lastFour": "rVwA",
  "secret": "ctk_9fQxR2mT7vLp4WnK8sDj3HcB6yZa1EuG5oNi0qXrVwA"
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Revoke an API key

`POST /v1/api-keys/{apiKeyId}/revoke`

Revokes one of your API keys, so requests with it fail with Unauthorized from then on. Fails with NotFound when the key is not yours or is already revoked.

### Parameters

- `apiKeyId` (string, in path, required): The API key's ID, such as Ak8TqW3nVr5L.

### Returns

Returns an object with these fields. The status is 200.

- `ok` (boolean, required): Always true: the change was made. Always `true`.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/api-keys/{apiKeyId}/revoke \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "ok": true
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.
