Reflyma API
A read-first REST API over the same evidence the dashboard uses: crawls, technical audits, AI visibility reports, alerts and usage. Authenticate with an organization API key.
Overview
All endpoints live under https://reflyma.com/api/public/v1. Requests and responses are JSON, UTF-8. Every response is scoped to the organization that owns the API key — there is no way to read another organization's data with a valid key.
curl "https://reflyma.com/api/public/v1/projects?limit=10" \
-H "Authorization: Bearer rfk_live_xxxxxxxxxxxxxxxx"Authentication
Create keys in the dashboard under Settings → API keys. The full key is shown once at creation; only a SHA-256 hash is stored. Send it either way:
Authorization: Bearer rfk_live_xxxxxxxxxxxxxxxx
# or
X-Reflyma-Key: rfk_live_xxxxxxxxxxxxxxxxKeys can carry an expiry date and can be revoked at any time; revoked or expired keys fail with 401 immediately.
Scopes and restrictions
Every key holds a scope set. read permits all GET endpoints; write is required for POST endpoints and also grants read.
Keys may additionally be restricted to a single project, to an IP allow-list (exact addresses, a 203.0.113. prefix or a /24 block) and to a domain allow-list matched against the request Origin. Restricted callers get 403.
Response format
Successful responses wrap the payload in data with a meta envelope. Creates return 201, reads return 200.
{
"data": [ { "id": "…", "name": "Acme", "domain": "acme.com" } ],
"meta": {
"request_id": "8f2c1ab4",
"api_version": "v1",
"generated_at": "2026-08-02T18:00:00.000Z"
}
}Errors use the same envelope shape with an error object instead of data:
{
"error": { "code": "insufficient_scope", "message": "This API key lacks the \"write\" scope." },
"meta": { "request_id": "8f2c1ab4", "api_version": "v1" }
}Every response carries X-Reflyma-Request-Id and X-Reflyma-Api-Version. Quote the request id when reporting a problem — each call is logged with it.
Rate limits
Four windows are enforced per key, tightest first: a burst window of 10 seconds (one third of the per-minute allowance), then per minute, per day and per 30 days. The per-key limits are set when the key is created and depend on your plan.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Window: 60When a window is exhausted the API returns 429 with a Retry-After header in seconds. Retry after that delay with exponential backoff; do not retry 4xx responses other than 429.
Error codes
| Status | Code | Meaning |
|---|---|---|
| 400 | request_failed | A required query parameter is missing or invalid. |
| 401 | missing_api_key | No Authorization: Bearer header and no X-Reflyma-Key header. |
| 401 | invalid_api_key | The key is not recognised. |
| 401 | key_revoked | The key was revoked or deactivated. |
| 401 | key_expired | The key passed its expiry date. |
| 403 | insufficient_scope | The key lacks the read or write scope the endpoint requires. |
| 403 | ip_not_allowed | The caller IP is outside the key's allow-list. |
| 403 | domain_not_allowed | The request Origin is outside the key's domain allow-list. |
| 404 | project_not_found | The project does not exist in the key's organization. |
| 404 | not_found | No route matches the method and path. |
| 429 | rate_limited | A rate-limit window is exhausted. Honour the Retry-After header. |
| 500 | internal_error | Unexpected failure. Quote the request id from meta.request_id. |
Endpoints
Paths below are relative to https://reflyma.com. List endpoints accept limit (1–200, default 50) and return newest rows first.
/api/public/v1/projectsread scopeList projects visible to the key's organization.
Soft-deleted projects are excluded.
limitquery · optional — Max rows, 1–200 (default 50).
Returns: Array of project objects, newest first. Project-scoped keys return only their project.
/api/public/v1/projects/{projectId}read scopeGet a single project.
projectIdpath · required — Project UUID.
Returns: One project object, or 404 when the project is not in your organization.
/api/public/v1/projects/{projectId}/crawlsread scopeList crawl snapshots.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Crawl snapshot rows including status, page counts and timings.
/api/public/v1/projects/{projectId}/crawlswrite scopeQueue a new crawl snapshot.
The crawl starts on the next worker tick. No request body is required — the project's website URL is used as the start URL.
projectIdpath · required — Project UUID.
Returns: The queued snapshot ({ id, status, created_at }) with HTTP 201.
/api/public/v1/projects/{projectId}/seo-auditsread scopeList technical SEO audits.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Audit runs with scores and issue counts.
/api/public/v1/projects/{projectId}/performanceread scopeList performance audits and scores.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Performance audit runs including Core Web Vitals summaries.
/api/public/v1/projects/{projectId}/ai-seoread scopeList AI readiness analyses.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Site-level AI readiness analysis rows.
/api/public/v1/projects/{projectId}/contentread scopeList content intelligence runs.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Content intelligence run rows.
/api/public/v1/projects/{projectId}/competitorsread scopeList competitor scores.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Competitor score rows, newest first.
/api/public/v1/projects/{projectId}/reportsread scopeList report runs.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Report run rows with status and completion timestamps.
/api/public/v1/projects/{projectId}/ai-presenceread scopeLatest AI presence metrics.
projectIdpath · required — Project UUID.
Returns: The most recent visibility report run, or null when none has completed.
/api/public/v1/projects/{projectId}/alertsread scopeList alert events.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Alert events ordered by triggered_at.
/api/public/v1/projects/{projectId}/monitoringread scopeList detected change events.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Change events ordered by detected_at.
/api/public/v1/projects/{projectId}/recommendationsread scopeList SEO fix recommendations.
projectIdpath · required — Project UUID.limitquery · optional — Max rows, 1–200 (default 50).
Returns: Recommendation rows with priority and status.
/api/public/v1/searchread scopeSearch across projects, automations and API keys.
qquery · required — Search term.
Returns: { projects, automations, api_keys } — up to 20 matches each.
/api/public/v1/exportsread scopeList generated report exports.
limitquery · optional — Max rows, 1–200 (default 50).
Returns: Export rows across all projects in the organization.
/api/public/v1/usageread scopeCurrent billing-period usage for the organization.
Returns: { billing_month, usage, limits }.
/api/public/v1/openapi.jsonread scopeThis OpenAPI 3.1 document.
Public — no API key required.
Returns: OpenAPI 3.1 JSON.
OpenAPI and clients
The machine-readable OpenAPI 3.1 document is public and always reflects the live router — generate typed clients from it instead of hand-writing models.
curl https://reflyma.com/api/public/v1/openapi.json -o reflyma-openapi.json
npx openapi-typescript reflyma-openapi.json -o reflyma-api.d.tsPrefer push over polling for changes: configure Slack, webhook or email digest delivery in a project's notification settings rather than polling the alerts endpoint on a tight loop.