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
| State | Effect |
|---|---|
| Active | Authenticates normally. lastUsedAt is updated on each call. |
Expired (expiresAt past) | All requests return 401. |
| Revoked | All 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:
- Mint key B alongside key A.
- Deploy your servers using key B.
- 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’sname/createdBy.