API keys
An owner or admin makes a key in the app under Settings, API keys: a name, a scope (read, write, or events:write for a script or plugin that only reports changes of one site you choose, so make one key per site) and an optional expiry. The full key is shown once; only a keyed hash is stored, so a lost key cannot be recovered, only revoked and replaced. A key belongs to one organisation and acts as the member who made it: if that member leaves, the key stops working. Revoking, expiry and the plan check take effect on the next request.
read: every GET below.write: reads, plus creating, moving and deleting sites.- No key can reach billing, members, invitations, exports, branding, status page changes or the organisation settings.
curl https://YOUR-APP-HOST/api/v1/sites \
-H "Authorization: Bearer bfk_..."
Only the Authorization: Bearer header is accepted, never a cookie or a query parameter.
Endpoints
| Request | Scope | What it does |
|---|---|---|
GET /api/v1/me | read | The key in use and its organisation. |
GET /api/v1/sites | read | List sites (client_id, limit, cursor). |
POST /api/v1/sites | write | Create a site: {"hostname": "www.example.com"}. Plan limits apply. Supports Idempotency-Key. |
GET /api/v1/sites/{id} | read | One site with its monitors. |
PATCH /api/v1/sites/{id} | write | Move to a client: {"client_id": "..."} or null. |
DELETE /api/v1/sites/{id} | write | Delete the site and stop its monitors; history is kept. |
GET /api/v1/sites/{id}/status | read | Monitor status, uptime, coverage and open incidents (hours). |
GET /api/v1/status | read | Status of every live site. |
GET /api/v1/incidents | read | Incidents with evidence packs, newest first (site_id, state). |
GET /api/v1/incidents/{id} | read | One incident with its evidence pack. |
GET /api/v1/incidents/{id}/explanation | read | Why it happened: the likely cause with its confidence and reasons, who acts, fix steps, evidence, what was ruled out and what could not be checked. unknown is a normal answer. |
GET /api/v1/sites/{id}/timeline | read | What changed (hours). |
GET /api/v1/first-day | read | First-day findings across the portfolio. |
GET /api/v1/security | read | Security and SEO integrity of every live site: the latest counts (client_id, limit, cursor). A site that was not scanned has no counts: that is unavailable, not clean. |
GET /api/v1/sites/{id}/security | read | The latest security scan of one site: what was and was not checked, and each finding with its evidence. Text that a site hides for AI assistants is withheld; a key made by an owner or admin may send include_hidden_text=true to receive it, and that answer must never be passed to an assistant. |
GET /api/v1/reports, /reports/{id}, /reports/{id}/download | read | Monthly reports: list, one report, and a JSON file download. |
GET /api/v1/status-pages, /status-pages/{id} | read | Status pages (read only). |
GET /api/v1/channels | read | Alert channels (read only). |
POST /api/v1/change-markers | events:write | Report a deploy or plugin update: {"site": "www.example.com", "kind": "deploy", "title": "Deployed 2.4"} (optional state, ref, at, url, external_id). A key of scope events:write belongs to one site: it may leave site out, and naming another site is a 404. It becomes one clue in an incident’s explanation. Supports Idempotency-Key. |
Data the monitors have not produced is null or marked unavailable. It is never filled in with a guess.
Software advisories in security findings come from the CISA Known Exploited Vulnerabilities catalogue, the NVD and OSV. This product uses the NVD API but is not endorsed or certified by the NVD. A finding that used NVD or OSV data carries the notice or credit those sources ask for in detail.notice.
Pagination
Lists return {"data": [...], "next_cursor": "...", "has_more": true}. Pass next_cursor as cursor to get the next page; limit is 1 to 100 (default 50). Cursors are opaque and tied to your organisation and the route; a changed one is a 400 invalid_cursor.
Idempotency
Send an Idempotency-Key header (1 to 128 characters of letters, digits and . _ : -) with POST /api/v1/sites. The same key with the same body returns the first answer again, marked Idempotent-Replayed: true, and creates nothing twice. The same key with a different body is a 422 idempotency_key_reuse. Successful answers are kept for 24 hours.
Rate limits
Each key and each organisation has a per-minute budget. A refused request is a 429 rate_limited with a Retry-After header in seconds; answers to accepted requests carry X-RateLimit-Limit and X-RateLimit-Remaining for the key. The values are test-build proposals and may change.
Errors
Every error has the same shape:
{"error": {"code": "not_found", "message": "Not found.", "request_id": "req_..."}}
Common codes: invalid_api_key, api_key_revoked, api_key_expired (401); insufficient_scope, not_in_plan, terms_acceptance_required (403: the owner who made a write key has not accepted new terms 30 days after they took effect, so the key reads only until they do); not_found (404, also for another organisation’s ids); site_exists, entitlement_exceeded, no_active_plan (409); validation_error (422); rate_limited (429).
MCP server
MCP is a standard way for an AI assistant to read from a service. Beamfar offers a hosted, read-only MCP server: the assistant asks about your sites, incidents and reports and answers from your stored checks. It cannot add, change or delete anything. In the app, Connect an AI assistant (under Settings, next to API keys) makes a key, gives you the set-up text for Claude Desktop, Claude Code, Cursor and VS Code, and tests the connection.
- Address:
POST https://api.YOUR-DOMAIN/mcp(MCP Streamable HTTP transport; JSON answers; no session). The address your app shows on that page is the one to use. - Authentication: the same API key,
Authorization: Bearer bfk_.... A read key is enough and is what to use. Rate limits, revocation, expiry and the plan check are the API’s. - Tools (all read only):
list_sites,site_status,list_incidents,incident_evidence,explain_incident,what_changed,first_day_findings,monthly_report_summary,security_overview,site_security,list_maintenance,dns_changes. A tool answers “data unavailable” instead of guessing. - Browsers: a request that names an
Originis refused unless the operator allow-listed it, so a web page cannot use your key by tricking your browser. Assistants send no Origin. - Text from monitored pages is passed on as untrusted data and never as instructions.
claude mcp add --transport http NAME https://api.YOUR-DOMAIN/mcp \
--header "Authorization: Bearer bfk_..."
There is also a local stdio server for people who prefer to run it themselves; it needs the same key.