## The protocol contract

Every request to `/api/v1` carries one header:

```http
Authorization: Bearer <your API key>
```

That's the whole handshake. No token endpoint to call, no refresh flow to
implement, nothing that expires mid-integration. The key you paste in is the
credential — full stop.

## Getting a key

Sign in at [/signin](/signin) with your email and the code that arrives, then
open [API keys](/app/keys). Name the key after the thing that will use it,
create it, and **copy the secret — it is shown exactly once**.

After that, **no part of the key appears anywhere** — not a prefix, not a
preview. The console lists each key by the alias you gave it, which is why
naming it for the thing that will use it matters. We store a
SHA-256 hash of the key and nothing else, so nobody at Stylumia can retrieve it
later, including support. Lost one? Revoke it and create another.

## One key per integration

Create as many as you need. Give every service, script, agent or notebook its
own key, named for what it does:

```text
warehouse-sync     created 15 Sep · last used 2 min ago
trend-reports      created 15 Sep · last used yesterday
notebook-adhoc     created 12 Sep · never used
```

Sharing one key between two systems means a leak or a revocation takes both
down together, and your logs can no longer tell you which system made a given
call. Naming each key is what lets you attribute traffic to one without ever
exposing it.

Names are labels, not identifiers — rename a key whenever its job changes, and
reuse a name across two keys if you like. Renaming never changes the secret.

## Keys do not expire

A key works until you revoke it. There is no TTL, no renewal, and nothing to
schedule.

**Revocation is immediate and permanent.** The next request made with a revoked
key fails — there is no cache to wait out. That makes rotation safe and boring:

1. Create the replacement key.
2. Deploy it.
3. Revoke the old one, once the new one is confirmed live.

Both keys work during the overlap, so nothing goes dark.

## Keys are bound to your team

A key carries the team you belong to, and the catalog data it reads is your
team's. A key cannot read another team's slice and cannot widen its own access
— there is no parameter, header or scope you can add to a request that grants
more than the team already has.

Every [endpoint](/reference) on this surface is a read. A key cannot mutate
anything, delete anything, or spend anything.

## The three easy 401s

Most [`invalid_credentials`](/errors#invalid_credentials) and
[`missing_credentials`](/errors#missing_credentials) responses trace back to
one of three habits:

1. **The key was revoked.** Check its status in the [console](/app/keys). A
   revoked key stays listed, so you can tell "revoked" from "never existed".
2. **Double `Bearer`.** Some client libraries add the `Bearer ` prefix
   automatically. If you also type `Bearer ` into the key field, the header
   becomes `Authorization: Bearer Bearer <key>` and authentication fails.
3. **Never copying it.** The secret is shown once, at creation. If you missed
   it, it is gone — nothing can recover it. Revoke that key and create
   another.

`invalid_credentials` is deliberately the same response whether the key is
unknown or revoked — that ambiguity is intentional; see
[Error handling](/docs/error-handling).

## Handle it like a password

A key is a bearer credential: whoever holds it can read what you can read,
until you revoke it. Keep it out of source control, out of client-side code,
and out of logs — see [Credential security](/docs/key-security).

**We will never ask you for your API key.** Not in an email, not in a support
ticket, not over a call. If anything claiming to be Stylumia asks for it, it
isn't us.
