Authentication

Project API keys, key formats, and how to pass them on each request.

Every call to /api/v1/* is authenticated with a project API key. Keys are scoped to one project — there’s no fine-grained per-resource scoping today.

Mint a key

In the FlowKoi dashboard: Project Settings → API → New API key.

You’re shown the full key once (flo_<random>). Copy it immediately into your password manager or env var; the dashboard only ever shows a prefix afterwards. If you lose it, revoke and mint a new one — there’s no recovery flow on purpose.

Pass it on every request

Bearer header (preferred)

GET /api/v1/flows HTTP/1.1
Host: api.flowkoi.com
Authorization: Bearer flo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
curl https://api.flowkoi.com/api/v1/flows \
  -H "Authorization: Bearer $FLOWKOI_API_KEY"

Query parameter (for EventSource / WebSocket)

Browser SSE (new EventSource(url)) and WebSocket clients can’t set custom headers. Use the query fallback for those:

const stream = new EventSource(
  `https://api.flowkoi.com/api/v1/runs/${runId}/stream?api_key=${encodeURIComponent(apiKey)}`,
);

warning

Query-string keys may appear in proxy logs, browser history, and Referer headers. Use them only when headers aren’t available; for server-to-server calls, always prefer the Bearer header.

Key lifecycle

StateEffect
ActiveAuthenticates normally. lastUsedAt is updated on each call.
Expired (expiresAt past)All requests return 401.
RevokedAll requests return 401. Action is immediate; existing runs are not killed.

Revoking is reversible at most in the sense that you can mint a new key with the same name — the raw bytes are gone forever.

Rotating keys

We recommend a two-key rotation:

  1. Mint key B alongside key A.
  2. Deploy your servers using key B.
  3. After your last A-using deploy drains, revoke A.

There’s no rate limit on key creation; mint as many as you want.

Per-key rate limits

Each key has its own rateLimitRpm (default 60 req/min). Bump it in Project Settings → API when you have a hot-path integration. Quotas at the project level (concurrent runs, monthly volume) still apply regardless of per-key settings — see Rate limits.

What an API key can’t do

  • Trigger runs in a different project — keys are project-scoped.
  • Access the dashboard’s Firebase-authenticated endpoints (/api/projects/..., user management, etc).
  • Read another user’s runs in the same project — every run is filtered by projectId, but auditing who-triggered-what is by the key’s name / createdBy.