Skip to content

Authentication

Every request to the Kreuzberg Cloud API carries an API key as a bearer token. There are two flavours:

Tier Prefix How you get one Limits
Live kz_ Dashboard → API keys Project quota + plan limits
Sandbox sk_sandbox_ POST /v1/sandbox/key (no auth, IP-rate-limited) 50 pages, 24 h, IP-bound

Live keys are 32 characters (kz_ + 29 Base62) and scoped to a single project. The plaintext is shown once at creation — store it somewhere safe.

Use the key

All SDKs read the key from a constructor argument. Keep it out of source via an env var:

export KREUZBERG_API_KEY="kz_..."
Python
import os
from kreuzberg_cloud import KreuzbergCloud
with KreuzbergCloud(api_key=os.environ["KREUZBERG_API_KEY"]) as client:
    ...
TypeScript
const client = new KreuzbergCloud({ apiKey: process.env.KREUZBERG_API_KEY! });
Go
client, _ := kreuzbergcloud.New(kreuzbergcloud.WithAPIKey(os.Getenv("KREUZBERG_API_KEY")))
Dart
final client = KreuzbergCloudClient(apiKey: Platform.environment['KREUZBERG_API_KEY']!);
curl
curl -H "Authorization: Bearer $KREUZBERG_API_KEY" \
  https://api.kreuzberg.dev/v1/extract \
  -F file=@invoice.pdf \
  -F 'webhook={"url":""}'

How it works

  • The bearer token is SHA-256 hashed in transit and compared against the api_keys table.
  • A two-tier cache (NATS KV config bucket → PostgreSQL) keeps validation sub-millisecond on the hot path.
  • Each authenticated request resolves to a project_id. PostgreSQL Row-Level Security restricts every query to that project — there is no cross-tenant data leak surface.

Failure modes

  • 401 Unauthorized — the bearer token is missing, malformed, or doesn't match any active key.
  • 403 Forbidden — the key is valid but the project doesn't own the requested resource (e.g. someone else's job_id).
  • 429 Too Many Requests — the project (or sandbox IP) is over its rate or page quota.

Sandbox keys

The anonymous sandbox issues short-lived sk_sandbox_ keys via POST /v1/sandbox/key. They're meant for unauthenticated trial use from the docs and the landing page — don't ship them in production code.

Edit this page on GitHub