API keys
Create, use, scope, rotate and revoke the API keys that authenticate requests to Windpaint.
An API key authenticates requests to the Windpaint API, the CLI and the MCP server. It acts in your organization with your role, unless you bind it to a narrower one. Send it as a bearer token:
curl https://api.windpaint.ai/v1/generation/models \
-H "Authorization: Bearer aak_3f9c1a7e5b2d4c8f0a6e9b1d3c5f7a9e2b4d6f8a0c1e3b5d"
Creating a key
Only owner and admin can create keys. Members and read-only users can list their own keys but not create them.
Open Settings → API Keys
In the dashboard, go to Settings → API Keys and choose Create key.
Name it and pick an expiry
Give it a name that says where it runs (render-pipeline-prod, ci, laptop). Pick an expiry of 30, 90, 180 or 365 days.
Copy the key
The full key is shown once. Copy it into your secret store now. Windpaint only stores a hash, so it can’t show the key again.
Key format
A key is aak_ followed by 48 hexadecimal characters. After creation, only key_prefix (the first 12 characters, such as aak_3f9c1a7e) is ever shown, so you can tell keys apart in a list.
Using a key
The CLI and the agent plugins read WINDPAINT_API_KEY.
A key acts in its creator’s organization. Requests made with it count as API traffic (source: "api") in the runs list, separate from jobs started in Studio.
Logging in to the CLI with a key
To save the key instead of exporting it in every shell:
windpaint auth login --api-key aak_...
# or keep it out of your shell history
echo "$WINDPAINT_API_KEY" | windpaint auth login --api-key -
The CLI checks the key against the API, then writes it to ~/.windpaint/credentials.json with 0600 permissions. windpaint auth whoami shows who it authenticates as; windpaint auth logout removes it. See CLI authentication.
Scoping a key to a role
By default a key has its creator’s permissions, and follows them: if your role changes, so does the key. For automation, bind the key to a narrower role with role_id. The key’s role then replaces your permissions entirely for requests made with it.
Look up the role’s id with GET /v1/roles. Any key can call it. It returns the roles you can assign in your organization (owner, admin, member and read_only), with no_users counting the members of your organization who hold each one:
curl https://api.windpaint.ai/v1/roles \
-H "Authorization: Bearer $WINDPAINT_API_KEY"
{
"data": [
{
"id": "7c1e9a24-3b5d-4f6e-8a0c-2d4f6b8e0a1c",
"name": "member",
"description": "Tenant member: day-to-day use of the organisation.",
"is_active": true,
"context": "tenant",
"no_users": 3,
"created_at": "2026-09-26T10:00:00Z",
"updated_at": null
}
]
}
Pick the role by name, then:
curl -X POST https://api.windpaint.ai/v1/api-keys \
-H "Authorization: Bearer $WINDPAINT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "render-worker", "role_id": "<member-role-id>"}'
A member-scoped key can generate and read, but can’t touch keys, webhooks, projects or billing settings. A read_only key can’t generate at all. You can’t bind a key to a role with more permissions than your own; that returns 403 with "You cannot grant a role with more permissions than your own."
Binding a role is API-only today; the dashboard creates keys with the creator’s permissions. You can change a key’s role later with PATCH /v1/api-keys/{id}, or send "role_id": null to go back to the creator’s permissions. See the API keys reference.
Rotating a key
There’s no in-place rotation. Rotate in three steps:
Create the replacement
Create a new key with the same role and a new expiry.
Swap it in
Update the secret everywhere the old key is used, and confirm requests succeed with the new one. last_used_at on the old key stops moving once nothing uses it (it updates at most once a minute).
Revoke the old key
Revoke it in the dashboard or with DELETE /v1/api-keys/{id}.
The dashboard’s API Keys page lists keys expiring in the next 45 days so you can rotate them before they lapse. An expired key returns 401; there’s no grace period.
Revoking a key
In the dashboard, open Settings → API Keys and revoke the key. Through the API:
curl -X DELETE https://api.windpaint.ai/v1/api-keys/9a7c2e41-5b3d-4f6a-8c0e-1d2f3a4b5c6d \
-H "Authorization: Bearer $WINDPAINT_API_KEY"
Revocation takes effect on the next request: the key returns 401. It can’t be undone. Jobs the key already submitted keep running.
If you only want to pause a key, PATCH it with {"is_active": false} and set it back to true later. A key also stops working when its creator is removed from the organization.
Storing keys safely
- Keep keys in a secret manager or your CI’s secret store, and load them into
WINDPAINT_API_KEYat runtime. Don’t commit them. - Use one key per environment and per service, so revoking one doesn’t take down the others and
last_used_attells you which is in use. - Bind keys used by services to the smallest role that works.
- Set an expiry. The dashboard requires one; through the API, prefer one over a non-expiring key.
- Never put a key in client-side code or a mobile app. Anyone who can read it can spend your credits. Call Windpaint from your backend.
GET /v1/api-keys lists only the keys you created. There’s no listing of every key in the organization through the API.