---
title: "Account and API keys API"
description: "Check API health, read the account behind an API key, and create, list, or revoke scoped API keys."
canonical_url: https://lyricwinter.com/docs/api/account
markdown_url: https://lyricwinter.com/docs/api/account.md
last_updated: 2026-09-30
status: beta
---
# LyricWinter API reference: Account and API keys

> Check API health, read the account behind an API key, and create, list, or revoke scoped API keys.

The LyricWinter API is in beta. Base URL: `https://lyricwinter.com/api/v1`. Authenticate every request with `Authorization: Bearer lw_...`. Successful responses are wrapped as `{ "data": ..., "request_id": "req_..." }`. Machine-readable contract: https://lyricwinter.com/api/v1/openapi.json.

## Endpoints

- [Check API health](https://lyricwinter.com/docs/api/account#get-health): `GET /health`
- [Get the current account](https://lyricwinter.com/docs/api/account#get-current-account-profile): `GET /me`
- [List API keys](https://lyricwinter.com/docs/api/account#list-api-keys): `GET /api-keys`
- [Create an API key](https://lyricwinter.com/docs/api/account#create-api-key): `POST /api-keys`
- [Revoke an API key](https://lyricwinter.com/docs/api/account#revoke-api-key): `DELETE /api-keys/{apiKeyId}`

### Check API health

`GET /health`

Authentication: none · Operation ID: `getHealth`

Returns a static payload when the LyricWinter API is reachable. It needs no authentication and performs no account checks.

#### Response 200

Stable API health response.

Fields inside `data`:

- `ok` (true; required)
- `service` ("lyricwinter"; required)
- `version` ("v1"; required)

#### Example request

```bash
curl "https://lyricwinter.com/api/v1/health" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
```

### Get the current account

`GET /me`

Scope: `account:read` · Operation ID: `getCurrentAccountProfile`

Returns the profile of the account that owns the API key: its ID, username, display name, avatar URL, and email.

#### Response 200

Current account profile.

Fields inside `data`:

- `profile` (object; required)
  - `id` (string; required)
  - `username` (string | null, 3–30 chars; required)
  - `name` (string | null, max 100 chars; required)
  - `image` (string | null, uri; required)
  - `email` (string | null, email; required)

Errors: `401`, `403`, `500` return the standard error envelope.

#### Example request

```bash
curl "https://lyricwinter.com/api/v1/me" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
```

### List API keys

`GET /api-keys`

Scope: `api_keys:read` · Operation ID: `listApiKeys`

Lists metadata for the account's API keys, including name, scopes, expiry, last use, and revocation time. Raw keys are never returned.

#### Response 200

Caller-owned API key metadata without raw key material or token hashes.

Fields inside `data`:

- `api_keys` (array of object; required)
  - `id` (string, uuid; required)
  - `name` (string, 1–80 chars; required)
  - `token_prefix` (string, pattern ^lw_[A-Za-z0-9_-]{8,32}$; required): Safe display prefix for identifying a key.
  - `scopes` (array of string, one of `account:read`, `account:write`, `api_keys:read`, `api_keys:write`, `audio_runs:read`, `audio_runs:write`, `billing:read`, `billing:write`, `demo_videos:read`, `demo_videos:write`, `feedback:write`, `projects:read`, `projects:write`, `reactions:read`, `reactions:write`, `stories:read`, `stories:write`, `studio:read`, `studio:write`, `voice_pins:read`, `voice_pins:write`, `voice_actors:read`, `voice_shares:read`, `voice_shares:write`, `voices:read`, `voices:write`; required)
  - `expires_at` (string | null, date-time; required)
  - `last_used_at` (string | null, date-time; required)
  - `revoked_at` (string | null, date-time; required)
  - `created_at` (string, date-time; required)
  - `updated_at` (string, date-time; required)

Errors: `401`, `403`, `500` return the standard error envelope.

#### Example request

```bash
curl "https://lyricwinter.com/api/v1/api-keys" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
```

### Create an API key

`POST /api-keys`

Scope: `api_keys:write` · Operation ID: `createApiKey`

Creates a scoped API key. The response contains `raw_key` exactly once; LyricWinter stores only a hash. When you call this endpoint with an API key, the new key can only have scopes that the calling key already holds.

#### Request body (application/json, required)

- `name` (string, 1–80 chars; required)
- `scopes` (array of string, min 1 items, one of `account:read`, `account:write`, `api_keys:read`, `api_keys:write`, `audio_runs:read`, `audio_runs:write`, `billing:read`, `billing:write`, `demo_videos:read`, `demo_videos:write`, `feedback:write`, `projects:read`, `projects:write`, `reactions:read`, `reactions:write`, `stories:read`, `stories:write`, `studio:read`, `studio:write`, `voice_pins:read`, `voice_pins:write`, `voice_actors:read`, `voice_shares:read`, `voice_shares:write`, `voices:read`, `voices:write`; required): Duplicate scopes are accepted and deduplicated.
- `expires_at` (string | null, date-time; optional): Optional expiration timestamp. Null or omitted creates a non-expiring key.

#### Response 201

API key created. The raw key is returned only in this response.

Fields inside `data`:

- `api_key` (object; required)
  - `id` (string, uuid; required)
  - `name` (string, 1–80 chars; required)
  - `token_prefix` (string, pattern ^lw_[A-Za-z0-9_-]{8,32}$; required): Safe display prefix for identifying a key.
  - `scopes` (array of string, one of `account:read`, `account:write`, `api_keys:read`, `api_keys:write`, `audio_runs:read`, `audio_runs:write`, `billing:read`, `billing:write`, `demo_videos:read`, `demo_videos:write`, `feedback:write`, `projects:read`, `projects:write`, `reactions:read`, `reactions:write`, `stories:read`, `stories:write`, `studio:read`, `studio:write`, `voice_pins:read`, `voice_pins:write`, `voice_actors:read`, `voice_shares:read`, `voice_shares:write`, `voices:read`, `voices:write`; required)
  - `expires_at` (string | null, date-time; required)
  - `last_used_at` (string | null, date-time; required)
  - `revoked_at` (string | null, date-time; required)
  - `created_at` (string, date-time; required)
  - `updated_at` (string, date-time; required)
- `raw_key` (string, pattern ^lw_[A-Za-z0-9_-]{8,32}_[A-Za-z0-9_-]+$; required): Display-once raw API key. The server stores only a SHA-256 hash.

Errors: `400`, `401`, `403`, `409`, `500` return the standard error envelope.

#### Example request

```bash
curl -X POST "https://lyricwinter.com/api/v1/api-keys" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My integration",
  "scopes": [
    "account:read"
  ]
}'
```

### Revoke an API key

`DELETE /api-keys/{apiKeyId}`

Scope: `api_keys:write` · Operation ID: `revokeApiKey`

Revokes one of the account's API keys immediately. Revoking a key that is already revoked succeeds without changes.

#### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `apiKeyId` | string, uuid | Yes |  |

#### Response 200

Caller-owned API key was revoked, or was already revoked.

Fields inside `data`:

- `ok` (true; required)
- `api_key` (object; required)
  - `id` (string, uuid; required)
  - `name` (string, 1–80 chars; required)
  - `token_prefix` (string, pattern ^lw_[A-Za-z0-9_-]{8,32}$; required): Safe display prefix for identifying a key.
  - `scopes` (array of string, one of `account:read`, `account:write`, `api_keys:read`, `api_keys:write`, `audio_runs:read`, `audio_runs:write`, `billing:read`, `billing:write`, `demo_videos:read`, `demo_videos:write`, `feedback:write`, `projects:read`, `projects:write`, `reactions:read`, `reactions:write`, `stories:read`, `stories:write`, `studio:read`, `studio:write`, `voice_pins:read`, `voice_pins:write`, `voice_actors:read`, `voice_shares:read`, `voice_shares:write`, `voices:read`, `voices:write`; required)
  - `expires_at` (string | null, date-time; required)
  - `last_used_at` (string | null, date-time; required)
  - `revoked_at` (string | null, date-time; required)
  - `created_at` (string, date-time; required)
  - `updated_at` (string, date-time; required)

Errors: `400`, `401`, `403`, `404`, `500` return the standard error envelope.

#### Example request

```bash
curl -X DELETE "https://lyricwinter.com/api/v1/api-keys/$API_KEY_ID" \
  -H "Authorization: Bearer $LYRICWINTER_API_KEY"
```

