API documentation
BioFlow REST API docs: API-key auth, 22 operations across pages, contacts, files, analytics and webhooks — RFC 9457 errors, rate limits, and idempotency.
A REST API for the page your users keep in their bio: read and edit pages, add
blocks, publish, capture contacts, pull analytics, and manage webhooks — all at
https://app.getbioflow.com/v1, described by an OpenAPI 3.1 spec, available on Creator and Pro.
Quickstart
1. Get your API key
Create a key in the developer console — pick its scopes
when you create it. bf_live_ keys are production keys; bf_test_ keys are
read-only.
2. List your pages
Paste-runnable — swap in your key:
curl "https://app.getbioflow.com/v1/pages" \
-H "Authorization: Bearer bf_live_YOUR_KEY"const res = await fetch("https://app.getbioflow.com/v1/pages", {
headers: {
Authorization: "Bearer bf_live_YOUR_KEY",
},
});
if (!res.ok) {
// RFC 9457 problem+json — switch on the stable `code` field.
const problem = await res.json();
throw new Error(`BioFlow API ${problem.code}: ${problem.title}`);
}
const data = await res.json();3. Read the response
A cursor page of your bio pages — every list endpoint uses the same
{ data, has_more, next_cursor } envelope:
{
"data": [
{
"id": "pg_abc123",
"title": "My links",
"slug": "maya",
"status": "PUBLISHED",
"block_count": 6,
"public_url": "https://getbioflow.com/maya",
"updated_at": "2026-07-20T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}Authentication
Two equivalent header forms — send exactly one per request:
Authorization: Bearer bf_live_YOUR_KEY
x-api-key: bf_live_YOUR_KEYbf_live_ keys can do everything their scopes allow. bf_test_ keys are
restricted to read operations — a write with a test key returns
403 test_key_read_only, so test
integrations can never touch live data.
Rate limits and quotas
| Plan | Monthly quota | Per-key burst |
|---|---|---|
| Free | — (no API access) | — |
| Creator | 10,000 requests/mo | 60 requests/min |
| Pro | 100,000 requests/mo | 120 requests/min |
The quota counts successful /v1 requests per calendar month (UTC);
GET /v1/usage is free and shows where you stand. Every response carries IETF
draft-11 RateLimit / RateLimit-Policy headers. Bursting past the per-minute
limit returns 429 rate_limited; an exhausted
month returns 429 quota_exhausted;
Free-plan keys get
403 feature_not_enabled. Full plan
pricing on getbioflow.com/pricing.
Conventions
Cursor pagination. List endpoints return
{ data, has_more, next_cursor }. Pass limit for page size and feed
next_cursor back as after until has_more is false. Cursors are opaque —
never parse them.
Idempotency keys. Consequential POSTs (create page, add block, publish,
webhook management) accept an Idempotency-Key header — any unique string per
logical attempt. Retrying with the same key returns the original result instead
of repeating the action; reusing a key with a different body returns
422 idempotency_key_reused.
Errors
Every error is application/problem+json with a stable code your
integration can branch on (never parse title or detail), a type URI that
resolves to the pages below, and a request_id to quote at support.
| Code | Status | Meaning |
|---|---|---|
invalid_request | 400 | The request body or parameters failed validation |
invalid_api_key | 401 | Missing, malformed, unknown, disabled, or expired API key |
insufficient_scope | 403 | The API key was not granted the required scope |
feature_not_enabled | 403 | The workspace plan does not include public API access |
test_key_read_only | 403 | Test-mode keys are restricted to read operations |
resource_not_found | 404 | No resource with that ID exists in this workspace |
stale_snapshot | 409 | The draft changed since it was last read |
idempotency_in_progress | 409 | A request with this Idempotency-Key is still executing |
idempotency_key_reused | 422 | This Idempotency-Key was already used with a different request |
endpoint_verification_failed | 422 | The webhook endpoint did not accept the signed test event |
endpoint_limit_reached | 422 | The workspace webhook endpoint limit was reached |
rate_limited | 429 | Per-key rate limit exceeded |
quota_exhausted | 429 | Monthly API quota exhausted |
internal_error | 500 | Something went wrong on our side |
Reference
All 22 operations. Each links to its full reference page — parameters, schemas, and a live request builder.
| Operation | Endpoint | Scope |
|---|---|---|
| Get analytics summary | GET /v1/analytics/summary | analytics:read |
| List contacts | GET /v1/contacts | contacts:read |
| List files | GET /v1/files | files:read |
| List pages | GET /v1/pages | pages:read |
| Create a page | POST /v1/pages | pages:write |
| Delete a page | DELETE /v1/pages/{page_id} | pages:write |
| Get a page | GET /v1/pages/{page_id} | pages:read |
| Update a page draft | PATCH /v1/pages/{page_id} | pages:write |
| Add a block | POST /v1/pages/{page_id}/blocks | pages:write |
| Remove a block | DELETE /v1/pages/{page_id}/blocks/{block_id} | pages:write |
| Publish a page | POST /v1/pages/{page_id}/publish | publish |
| Get API usage | GET /v1/usage | pages:read, pages:write, analytics:read, contacts:read, files:read, publish |
| List webhook endpoints | GET /v1/webhook-endpoints | webhooks:read |
| Create a webhook endpoint | POST /v1/webhook-endpoints | webhooks:write |
| Delete a webhook endpoint | DELETE /v1/webhook-endpoints/{endpoint_id} | webhooks:write |
| Get a webhook endpoint | GET /v1/webhook-endpoints/{endpoint_id} | webhooks:read |
| Update a webhook endpoint | PATCH /v1/webhook-endpoints/{endpoint_id} | webhooks:write |
| List deliveries | GET /v1/webhook-endpoints/{endpoint_id}/deliveries | webhooks:read |
| Resend a delivery | POST /v1/webhook-endpoints/{endpoint_id}/deliveries/{delivery_id}/resend | webhooks:write |
| Replay failed deliveries | POST /v1/webhook-endpoints/{endpoint_id}/replay | webhooks:write |
| Rotate the signing secret | POST /v1/webhook-endpoints/{endpoint_id}/rotate-secret | webhooks:write |
| Send a test event | POST /v1/webhook-endpoints/{endpoint_id}/test | webhooks:write |
Go deeper
- Interactive reference — every operation, schema, and example, rendered straight from the OpenAPI 3.1 spec.
- Webhooks — Standard Webhooks v1 signing, four event types, retries with replay, and verification snippets.
- Changelog — dated, factual platform updates, one URL per entry, RSS included.
- TypeScript SDK — open source on GitHub: spec-generated types, typed errors, safe retries, pagination, webhook verification. npm package landing shortly.
- MCP server — let Claude, ChatGPT, or any MCP client operate your workspace: 12 tools behind OAuth 2.1 with safety rails.
- AI tooling — llms.txt, llms-full.txt, markdown twins of every docs page, and the spec download.
Machine-readable spec: /docs/api/openapi.json · this page as markdown: /docs/api.md
Connecting AI assistants (MCP)
Connect Claude, ChatGPT, Copilot or any MCP client to your BioFlow workspace over OAuth 2.1 — setup per client, the 12 tools, the 6 scopes, and the safety rails.
Webhooks
BioFlow outbound webhooks: Standard Webhooks v1 signing, an event catalog, verification snippets, retry schedule, auto-disable ladder, and replay.