Skip to content

Authentication

Most fetch.li endpoints are public GET requests on the demo tier and do not need a key. The POST /v1/vibe/classify endpoint always requires a valid API key. Humans can sign in with email and later connect Google, GitHub, or X. That session is not an API key. See Login.

Plain English summary

An API key proves you are allowed to use paid features (vibe classification) and, on production plans, may unlock higher rate limits. You send the key in a standard HTTP header called Authorization. fetch.li checks the key with Unkey on every protected request before running your job.

Who needs a key

Endpoint type Key required?
All GET endpoints (/v1/moon, /v1/vat, and so on) No (demo tier: 60 calls/hour per IP)
POST /v1/vibe/classify Yes, always

How to send your key

Use the Bearer scheme. The header must look exactly like this (one space after Bearer):

Authorization: Bearer ukdev_live_abc123xyz789

curl

curl -sS https://fetch.li/v1/vibe/classify \
  -H "Authorization: Bearer ukdev_live_abc123xyz789" \
  -H "Content-Type: application/json" \
  -d '{"texts":["Your sample copy here."]}'

JavaScript (Node.js or server-side only)

const response = await fetch("https://fetch.li/v1/vibe/classify", {
  method: "POST",
  headers: {
    Authorization: "Bearer ukdev_live_abc123xyz789",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ texts: ["Your sample copy here."] }),
});

const data = await response.json();
console.log(data);

Python

import requests

response = requests.post(
    "https://fetch.li/v1/vibe/classify",
    headers={
        "Authorization": "Bearer ukdev_live_abc123xyz789",
        "Content-Type": "application/json",
    },
    json={"texts": ["Your sample copy here."]},
)

print(response.json())

Unkey and what gets verified

fetch.li uses Unkey to issue and verify customer keys. When you send Authorization: Bearer <token>, the API calls Unkey’s verify endpoint. If the key is valid, active, and permitted for this product, the request proceeds.

You receive a customer API key after purchase. That is the token you send in Authorization.

You do not send:

  • Your Unkey root key
  • Your Anthropic or other upstream provider keys
  • Keys embedded in public web pages

Optional deployment settings (UNKEY_API_ID, permissions) can restrict keys to fetch.li only. That is configured on the server, not in your client code.

Security rules (read this)

  1. Never commit keys to Git. Use environment variables (.env locally, secrets manager in production).
  2. Never put keys in frontend repos. Browser JavaScript, React apps, mobile apps shipped to users, and public GitHub repos are not safe places for secrets. Anyone can extract them.
  3. Call protected endpoints from your server. Your backend holds the key and forwards results to the client if needed.
  4. Revoke if leaked. Kill the key on the account page, then request a replacement from pricing. Update your environment variables.

Good pattern

User browser  →  Your server (has UKDEV_API_KEY)  →  fetch.li

Bad pattern

User browser (key visible in DevTools)  →  fetch.li

Error responses for auth problems

All errors use the same JSON shape:

{
  "error": {
    "code": "unauthorized",
    "message": "Send Authorization: Bearer <token> with a valid fetch.li API key."
  }
}
HTTP status error.code Typical cause
401 unauthorized Missing header, malformed Bearer token, or invalid/expired key
403 forbidden Key valid but lacks permission for this product
429 rate_limited Key hit Unkey usage or rate limits (reason may be RATE_LIMITED or USAGE_EXCEEDED)
503 unkey_unavailable Key verification service temporarily down; retry with backoff

Example with reason:

{
  "error": {
    "code": "rate_limited",
    "message": "API key was rejected.",
    "reason": "USAGE_EXCEEDED"
  }
}

Request IDs

Every response includes X-Request-Id (a unique ID for that request). When contacting support about auth failures, include that header value and the approximate time of the call.

Related pages