Developers

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_xxxxxxxxxxxxxxxx

Keys 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: 60

When 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

StatusCodeMeaning
400request_failedA required query parameter is missing or invalid.
401missing_api_keyNo Authorization: Bearer header and no X-Reflyma-Key header.
401invalid_api_keyThe key is not recognised.
401key_revokedThe key was revoked or deactivated.
401key_expiredThe key passed its expiry date.
403insufficient_scopeThe key lacks the read or write scope the endpoint requires.
403ip_not_allowedThe caller IP is outside the key's allow-list.
403domain_not_allowedThe request Origin is outside the key's domain allow-list.
404project_not_foundThe project does not exist in the key's organization.
404not_foundNo route matches the method and path.
429rate_limitedA rate-limit window is exhausted. Honour the Retry-After header.
500internal_errorUnexpected 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.

Projects
GET/api/public/v1/projectsread scope

List projects visible to the key's organization.

Soft-deleted projects are excluded.

  • limit query · optional Max rows, 1–200 (default 50).

Returns: Array of project objects, newest first. Project-scoped keys return only their project.

GET/api/public/v1/projects/{projectId}read scope

Get a single project.

  • projectId path · required Project UUID.

Returns: One project object, or 404 when the project is not in your organization.

Crawling
GET/api/public/v1/projects/{projectId}/crawlsread scope

List crawl snapshots.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Crawl snapshot rows including status, page counts and timings.

POST/api/public/v1/projects/{projectId}/crawlswrite scope

Queue 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.

  • projectId path · required Project UUID.

Returns: The queued snapshot ({ id, status, created_at }) with HTTP 201.

Analysis
GET/api/public/v1/projects/{projectId}/seo-auditsread scope

List technical SEO audits.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Audit runs with scores and issue counts.

GET/api/public/v1/projects/{projectId}/performanceread scope

List performance audits and scores.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Performance audit runs including Core Web Vitals summaries.

GET/api/public/v1/projects/{projectId}/ai-seoread scope

List AI readiness analyses.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Site-level AI readiness analysis rows.

GET/api/public/v1/projects/{projectId}/contentread scope

List content intelligence runs.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Content intelligence run rows.

GET/api/public/v1/projects/{projectId}/competitorsread scope

List competitor scores.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Competitor score rows, newest first.

Visibility
GET/api/public/v1/projects/{projectId}/reportsread scope

List report runs.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Report run rows with status and completion timestamps.

GET/api/public/v1/projects/{projectId}/ai-presenceread scope

Latest AI presence metrics.

  • projectId path · required Project UUID.

Returns: The most recent visibility report run, or null when none has completed.

Monitoring
GET/api/public/v1/projects/{projectId}/alertsread scope

List alert events.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Alert events ordered by triggered_at.

GET/api/public/v1/projects/{projectId}/monitoringread scope

List detected change events.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Change events ordered by detected_at.

GET/api/public/v1/projects/{projectId}/recommendationsread scope

List SEO fix recommendations.

  • projectId path · required Project UUID.
  • limit query · optional Max rows, 1–200 (default 50).

Returns: Recommendation rows with priority and status.

Account
GET/api/public/v1/searchread scope

Search across projects, automations and API keys.

  • q query · required Search term.

Returns: { projects, automations, api_keys } — up to 20 matches each.

GET/api/public/v1/exportsread scope

List generated report exports.

  • limit query · optional Max rows, 1–200 (default 50).

Returns: Export rows across all projects in the organization.

GET/api/public/v1/usageread scope

Current billing-period usage for the organization.

Returns: { billing_month, usage, limits }.

GET/api/public/v1/openapi.jsonread scope

This 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.ts

Prefer 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.