XenonFlare

Developers

Developer API

Programmatic access to your XenonFlare workspace for integrations, CI pipelines, and internal tools.

Checking API…
status.xenonflare.com →
Base URL: https://api.xenonflare.com/api/v1
Plan: Starter or Growth required. Manage keys in the web app under Developer API in the sidebar.
Keys: Up to 5 active keys per organization.

Quickstart

Three lines to your first API call

Authenticate with a Bearer key from Developer API in the app sidebar (Starter or Growth). 1000 reads/hr and 60 writes/hr per key · 500 org writes/day · up to 5 active keys.

curl -H "Authorization: Bearer xf_live_xxxxxxxx" \
  https://api.xenonflare.com/api/v1/properties

Base URL: https://api.xenonflare.com/api/v1 · Rate limits · All endpoints · SEO automation API

Overview

The Developer API is organization-scoped. Each API key belongs to one workspace and carries explicit permission scopes. All authenticated routes return JSON with a consistent envelope and include a requestId in meta for support.

  • Read endpoints list properties, jobs, organization details, and usage.
  • Write endpoints create properties and queue SEO scans or crawls.
  • Keys use the format xf_live_... (live) or xf_test_... (sandbox) and can be revoked instantly from the app.

Authentication

Send your API key as a Bearer token in the Authorization header. Create keys in the web app — they are shown once at creation; store them securely.

curl -H "Authorization: Bearer xf_live_xxxxxxxx" \
  https://api.xenonflare.com/api/v1/properties

Revoked or invalid keys receive 401 with error.code: "api_key_invalid".

Test keys (sandbox)

Choose Test when creating a key to get an xf_test_… sandbox credential. Test keys read real workspace data but write endpoints return mock responses with no side effects — ideal for CI pipelines and integrator onboarding. Writes include the X-Developer-Api-Mode: test response header.

Agencies and portfolio monitoring

Agencies on Growth run one workspace with many client properties, then automate nightly POST /scans/batch, webhook alerts, and CSV activity exports for client reporting. Scoped keys let you separate read-only dashboards from automation that queues crawls. See the agency portfolio guide and SEO automation API landing for positioning and integration patterns.

Request ID

Send an optional X-Request-Id header on any authenticated request. When provided, the same value is echoed in meta.requestId on success and error responses — useful when contacting support or correlating logs on your side.

curl -H "Authorization: Bearer xf_live_xxxxxxxx" \
  -H "X-Request-Id: deploy-2026-06-07-001" \
  https://api.xenonflare.com/api/v1/organization

Scopes

When creating a key, select only the scopes your integration needs.

ScopeAccess
org:readOrganization overview
properties:readList and read website properties
properties:writeCreate new properties
jobs:readList and read scan/crawl jobs
jobs:writeQueue scans and crawls
usage:readUsage totals and plan limits
reports:readList and read shared audit reports
gsc:readRead cached Google Search Console snapshots (GET /properties/:id/gsc, GET /organization/gsc). Connect GSC in the web app first. Field reference.
gsc:writeTrigger GSC snapshot refresh (POST /properties/:id/gsc/sync)
webhooks:readList outbound webhook endpoints
webhooks:writeCreate, update, and delete webhook endpoints

See also the nightly crawl guide, CI pipeline guide, and agency portfolio guide for automation patterns.

Endpoints

System

MethodPathAuthDescription
GET/healthNoneAPI reachability — returns status, version, timestamp, and a statusPage URL (status.xenonflare.com)

Organization

MethodPathScopeDescription
GET/organizationorg:readWorkspace summary and usage totals

Properties

MethodPathScopeDescription
GET/propertiesproperties:readPaginated list of website properties
POST/propertiesproperties:writeCreate property — body: { "url", "name?" }
GET/properties/:idproperties:readSingle property detail — optional ?include=gsc,lastScan
GET/properties/:id/issuesproperties:readPaginated SEO issues with lifecycle summary
POST/properties/:id/scansjobs:writeQueue an SEO scan job (seo-scan)
POST/properties/:id/crawlsjobs:writeQueue a crawl (same job type as scans)

Optional scan/crawl body: { "maxPages": number, "maxDepth": number }. Successful queue responses return 202 Accepted. Use ?include=gsc,lastScan on property list/detail to embed GSC summary or last scan metadata without extra round trips.

Jobs

MethodPathScopeDescription
GET/jobsjobs:readPaginated list of jobs
GET/jobs/:idjobs:readJob status, stable result payload, and recent logs
POST/jobs/:id/canceljobs:writeCancel a pending or processing job
POST/scans/batchjobs:writeQueue up to 25 scans — per-property success/error in results

Optional filters on GET /jobs: status (pending, processing, completed, failed, cancelled), propertyId, and type (for example seo-scan).

Completed scan jobs expose a stable result object on GET /jobs/:id:

{
  "scanId": "507f1f77bcf86cd799439016",
  "score": 82,
  "issuesCount": 14,
  "pagesScanned": 48,
  "pagesFailed": 0,
  "pagesSkipped": 2,
  "stopReason": "max_pages",
  "maxPages": 50,
  "urlsAttempted": 52,
  "categoryScores": { "technical": 90, "content": 78 },
  "shareUrl": null
}
GET https://api.xenonflare.com/api/v1/jobs?status=completed&propertyId=PROPERTY_ID&type=seo-scan

Usage

MethodPathScopeDescription
GET/usageusage:readCurrent usage against plan limits
GET/limitsusage:readPlan limits for the workspace
GET/rate-limitsusage:readLive remaining read/write and org daily write counters for this API key

Webhooks

MethodPathScopeDescription
GET/webhookswebhooks:readList outbound webhook endpoints
POST/webhookswebhooks:writeCreate endpoint — signingSecret returned once
PATCH/webhooks/:idwebhooks:writeUpdate name, URL, events, or enabled flag
DELETE/webhooks/:idwebhooks:writeRemove webhook endpoint
POST/webhooks/:id/testwebhooks:writeSend a signed sample payload (test: true in body) — also available as Test in the Developer API webhooks tab

Events: job.completed, job.failed, job.cancelled. Verify deliveries with the X-XenonFlare-Signature header (HMAC SHA-256 over {timestamp}.{body}). Test deliveries use the same headers with a synthetic job and test: true in the JSON body.

Reports

MethodPathScopeDescription
GET/reportsreports:readList active shared audit reports (non-expired links)
GET/reports/:tokenreports:readReport metadata and public URL for a share token

Reports are created in the web app when you share an audit. Each item includes a publicUrl pointing to the read-only report page on xenonflare.com. Use reports:read on keys that should list share links but not queue scans — common for client-facing dashboards and monthly reporting pipelines.

Example: list shared reports

curl -H "Authorization: Bearer xf_live_..." \
  https://api.xenonflare.com/api/v1/reports?limit=20
{
  "data": {
    "reports": [
      {
        "token": "abc123sharetoken",
        "propertyId": "507f1f77bcf86cd799439012",
        "propertyName": "example.com",
        "propertyUrl": "https://example.com",
        "scanId": "507f1f77bcf86cd799439013",
        "expiresAt": "2026-07-07T12:00:00.000Z",
        "viewCount": 4,
        "createdAt": "2026-06-07T12:00:00.000Z",
        "publicUrl": "https://xenonflare.com/reports/abc123sharetoken"
      }
    ]
  },
  "meta": {
    "requestId": "req_reports_001",
    "hasMore": false,
    "nextCursor": null
  }
}

Fetch a single report with GET /reports/:token. Related: Site audit API, agency portfolio guide.

Search Console

MethodPathScopeDescription
GET/organization/gscgsc:readPortfolio summary — linked properties, 28-day clicks and impressions totals
GET/properties/:id/gscgsc:readCached snapshot: queries, pages, daily series, crawl correlation (null when not linked)
GET/properties/:id/gsc/overviewgsc:readConnection status and 28-day totals only
GET/properties/:id/gsc/queriesgsc:readPaginated top queries from cached snapshot
GET/properties/:id/gsc/pagesgsc:readPaginated top pages from cached snapshot
POST/properties/:id/gsc/syncgsc:writeTrigger a live GSC refresh (uses org OAuth from the web app)

GSC OAuth connect runs in the web app. Most read endpoints use stored MongoDB snapshots; POST …/gsc/sync calls Google with the linked org token.

Response format

Successful responses wrap data in a consistent envelope:

{
  "data": { },
  "meta": {
    "requestId": "...",
    "hasMore": false,
    "nextCursor": null
  }
}

Errors use the same meta.requestId with an error object:

{
  "error": {
    "code": "plan_required",
    "message": "..."
  },
  "meta": { "requestId": "..." }
}

Examples

GET /organization

{
  "data": {
    "organization": {
      "id": "507f1f77bcf86cd799439011",
      "name": "Acme Marketing",
      "plan": "starter"
    },
    "usage": { "plan": "starter", "periodLabel": "Jun 2026" },
    "totals": { "properties": 3, "activeJobs": 1 }
  },
  "meta": { "requestId": "req_abc123" }
}

GET /properties

{
  "data": {
    "properties": [
      {
        "id": "507f1f77bcf86cd799439012",
        "name": "example.com",
        "url": "https://example.com",
        "verified": true,
        "createdAt": "2026-06-01T10:00:00.000Z"
      }
    ]
  },
  "meta": {
    "requestId": "req_abc123",
    "hasMore": false,
    "nextCursor": null
  }
}

POST /properties/:id/scans (202)

{
  "data": {
    "job": {
      "id": "507f1f77bcf86cd799439014",
      "status": "pending",
      "type": "seo-scan",
      "propertyId": "507f1f77bcf86cd799439012",
      "createdAt": "2026-06-07T12:00:00.000Z"
    },
    "crawlTier": "verified",
    "effectiveLimits": { "maxPages": 500, "maxDepth": 8 },
    "message": "Website SEO scan queued."
  },
  "meta": { "requestId": "req_scan_001" }
}

GET /jobs/:id

{
  "data": {
    "job": {
      "id": "507f1f77bcf86cd799439014",
      "type": "seo-scan",
      "status": "completed",
      "progress": 100,
      "propertyId": "507f1f77bcf86cd799439012",
      "propertyName": "example.com",
      "createdAt": "2026-06-07T12:00:00.000Z",
      "completedAt": "2026-06-07T12:05:12.000Z",
      "error": null
    }
  },
  "meta": { "requestId": "req_job_poll" }
}

Error (403 plan_required)

{
  "error": {
    "code": "plan_required",
    "message": "Website limit reached for this workspace."
  },
  "meta": { "requestId": "req_limit_001" }
}

Pagination

List endpoints accept limit (max 100, default 40) and cursor. When more results exist, meta.hasMore is true and meta.nextCursor contains an opaque token for the next page.

GET https://api.xenonflare.com/api/v1/properties?limit=40&cursor=opaque_token

Idempotency

Write endpoints (POST) accept an optional Idempotency-Key header (max 128 characters). Repeating the same key within 24 hours returns the original successful response without duplicating side effects — useful for retries in CI or webhook handlers.

curl -X POST \
  -H "Authorization: Bearer xf_live_..." \
  -H "Idempotency-Key: scan-2026-06-07-example-com" \
  https://api.xenonflare.com/api/v1/properties/PROPERTY_ID/scans

Full guide: Idempotency for write requests (TTL, replay rules, CI key patterns, retry matrix).

Rate limits

Two layers apply: API rate limits (per key / per org) and plan quotas (scans, websites, crawl pages). Plan quotas are enforced on write endpoints and return 403 plan_required; API rate limits return 429 rate_limit.

LimitDefaultScope
Read requests per API key1,000 / hourAPI rate limit
Write requests per API key60 / hourAPI rate limit
Write requests per organization500 / dayAPI rate limit (safety net)
Active API keys per organization5Key cap
Scans / websites / crawl pagesPlan-dependentPlan quota — see GET /limits

Headers and live counters

Successful responses include X-Developer-Api-RateLimit-read-* or X-Developer-Api-RateLimit-write-* headers (Limit, Remaining, Reset). For programmatic backoff, call GET /rate-limits (usage:read):

curl -H "Authorization: Bearer xf_live_..." \
  https://api.xenonflare.com/api/v1/rate-limits
{
  "data": {
    "rateLimits": {
      "read": { "limit": 1000, "remaining": 987, "used": 13, "resetAt": "2026-06-07T13:00:00.000Z" },
      "write": { "limit": 60, "remaining": 58, "used": 2, "resetAt": "2026-06-07T13:00:00.000Z" },
      "orgWriteDaily": { "limit": 500, "remaining": 495, "used": 5, "resetAt": "2026-06-08T00:00:00.000Z" }
    }
  }
}

Static plan caps (including documented API limits) are on GET /limits under data.developerApi. When exceeded, the API returns 429 with a Retry-After header (seconds until the window resets):

HTTP/1.1 429 Too Many Requests
Retry-After: 1847

{
  "error": { "code": "rate_limit", "message": "Rate limit exceeded — try again later" },
  "meta": { "requestId": "req_rl_001" }
}

For incident and uptime information, see status.xenonflare.com. AI assistants can use the llms.txt index for a concise map of endpoints and guides.

Step-by-step

  1. Sign in at app.xenonflare.com on a Starter or Growth plan.
  2. Open Developer API in the sidebar and create a key with properties:read and jobs:write as needed.
  3. List properties, queue a scan, and poll job status:
# List properties
curl -H "Authorization: Bearer xf_live_..." \
  https://api.xenonflare.com/api/v1/properties

# Queue a scan
curl -X POST \
  -H "Authorization: Bearer xf_live_..." \
  https://api.xenonflare.com/api/v1/properties/PROPERTY_ID/scans

# Poll job status
curl -H "Authorization: Bearer xf_live_..." \
  https://api.xenonflare.com/api/v1/jobs/JOB_ID

Error catalog

All errors use { error: { code, message }, meta: { requestId } }.

CodeHTTPWhenWhat to do
api_key_invalid401Missing, malformed, or revoked Bearer tokenCheck header format; create or rotate key in Developer settings
unauthorized401Developer API disabled or auth rejectedVerify plan and that Developer API is enabled for the workspace
insufficient_scope403Key lacks required scope for the routeCreate a key with the scope listed on the endpoint, or rotate with broader scopes
forbidden403Generic access denied (non-scope)Confirm org membership and endpoint access rules
plan_required403Free plan, or monthly scan/website quota exhaustedUpgrade plan or wait for billing period reset; check GET /usage
rate_limit429API read/write or org daily write cap exceededBackoff until reset; use GET /rate-limits or rate-limit headers
not_found404Property, job, webhook, or report not in this orgVerify ID belongs to the keyed organization
validation_error400Invalid body, query param, or business rule (e.g. cancel completed job)Fix request per message; use new idempotency key if body changed
internal_error500Unexpected server failureRetry with backoff; contact support with meta.requestId

SDK & code generation

Generate a typed client from the OpenAPI spec with OpenAPI Generator. Replace the output directory with your project path.

TypeScript (fetch)

npx @openapitools/openapi-generator-cli generate \
  -i https://xenonflare.com/openapi/developer-v1.yaml \
  -g typescript-fetch \
  -o ./src/generated/xenonflare-api

Python

npx @openapitools/openapi-generator-cli generate \
  -i https://xenonflare.com/openapi/developer-v1.yaml \
  -g python \
  -o ./xenonflare_api_client

Pass your key on every request: Authorization: Bearer xf_live_…. For local development, point -i at http://localhost:4000/openapi/developer-v1.yaml or the copy in this repo.

OpenAPI

Machine-readable specification for code generation and API clients: developer-v1.yaml (OpenAPI 3.1). Download from the quickstart panel above or import into your preferred API client.

Developer API

Create your first API key

Available on Starter and Growth plans. Keys are managed per organization with granular scopes.