# Authentication (/docs/auth)



LinkFetch uses bearer-token authentication. Every request carries your
key in the `Authorization` header. Keys are scoped to a single
workspace and rotate without downtime.

## Where to get a key [#where-to-get-a-key]

Sign in at [linkfetch.io/signin](/signin) → the dashboard shows your
default key. Create additional keys for CI, production, and local dev
on the [keys page](/keys).

## Send it on every request [#send-it-on-every-request]

```bash
curl https://api.linkfetch.io/v1/jobs?q=staff+engineer \
  -H "Authorization: Bearer sk_live_..."
```

```ts
const res = await fetch(
  "https://api.linkfetch.io/v1/jobs?q=staff+engineer",
  { headers: { Authorization: `Bearer ${process.env.LINKFETCH_KEY}` } },
);
```

```py
import os, requests
res = requests.get(
    "https://api.linkfetch.io/v1/jobs",
    params={"q": "staff engineer"},
    headers={"Authorization": f"Bearer {os.environ['LINKFETCH_KEY']}"},
)
```

## Key shape [#key-shape]

Keys are prefixed `sk_live_` for production and `sk_test_` for sandbox.
The prefix is returned in the `X-Api-Key-Prefix` header on every
response, so you can double-check routing in logs.

| Prefix      | Purpose                          | Rotation                       |
| ----------- | -------------------------------- | ------------------------------ |
| `sk_live_…` | Production traffic, real credits | 24-hour grace window on revoke |
| `sk_test_…` | Sandbox router, no credit debit  | Same                           |

## Rotating keys [#rotating-keys]

1. Create a new key in the dashboard.
2. Deploy it to your service.
3. Revoke the old key. &#x2A;*For 24 hours, both keys keep working.**
4. After 24 hours, the revoked key returns `401 invalid_key`.

Plaintext is shown **once**, on creation. We hash on ingest and can't
recover the original — only the prefix is shown after that. If you lose
a key, rotate it.

## Secret handling [#secret-handling]

* **Never commit a key.** If one leaks, revoke it immediately from the
  dashboard.
* Store keys in a secrets manager (Doppler, AWS Secrets Manager, Vercel
  env vars, GitHub Actions secrets).
* For CI and server-to-server, use a dedicated key labelled `ci` or
  `server` so you can revoke without disrupting dev.
* Per-environment keys also help with provenance — the `request_id` log
  tells you which key served a request.

## Common errors [#common-errors]

| Code           | Status | When                                                      |
| -------------- | ------ | --------------------------------------------------------- |
| `missing_key`  | 401    | No `Authorization` header.                                |
| `invalid_key`  | 401    | Key is wrong, revoked, or past the grace window.          |
| `scope_denied` | 403    | Key is scoped and the endpoint is out of scope.           |
| `rate_limit`   | 429    | Too many requests — see [Rate limits](/docs/rate-limits). |

See [Errors](/docs/errors) for the full envelope.

## Scopes (coming soon) [#scopes-coming-soon]

Enterprise customers can scope keys to specific endpoints (read-only,
no outreach queue, etc.). Ask your account owner or email
[info@linkfetch.io](mailto:info@linkfetch.io).
