API · v1.0
Flatline SEO REST API
Run audits, fetch your sites, keywords, backlinks, and visibility-score history. Stripe-shape conventions, OpenAPI 3.1 spec, available on the Agency plan.
Get API access9
Endpoints
100/min
Per-token rate limit
24h
Idempotency window
OpenAPI 3.1
Spec format
Quickstart
Generate a token at app.flatlineseo.com/client/api-keys. The plaintext is shown once. Authenticate with the standard Authorization header.
# Run an audit
curl -X POST https://app.flatlineseo.com/api/v1/audits \
-H "Authorization: Bearer fl_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-site.com"}'Full machine-readable spec: /api/openapi.json. Drop it into Stoplight, Postman, or any OpenAPI generator.
Conventions
Five Stripe-style conventions you only need to learn once. They apply to every endpoint.
Authentication
Authorization: Bearer fl_live_… on every request. The plaintext is shown once at creation; only the SHA-256 hash is stored on our side.
A ?token= query-string fallback exists for clients without custom-header support — flagged in our audit log so you can detect tokens accidentally landing in URLs.
Errors
Failures return JSON in the shape:
{"error":{"code":"invalid_request",
"message":"...",
"type":"invalid_request_error",
"param":"url"}}Dispatch on code (stable, machine-readable). Don't parse message — copy may change.
Rate limits
Three windows per token: 100/min · 600/hr · 5000/day. The tightest trips first. Every response carries X-RateLimit-Limit-*, -Remaining-*, -Reset-* headers (minute / hour / day).
429 responses include Retry-After in seconds. Back off, don't hammer.
Idempotency
Required on every POST. Send Idempotency-Key: <uuid>. Replaying the same key + body within 24h returns the cached response (and an Idempotent-Replayed: true header).
Replaying with a different body returns 409 idempotency_key_mismatch.
Pagination
Cursor-based on list endpoints. Append ?starting_after=<last_id>&limit=20 (limit max 100, default 20).
Response includes has_more and next_cursor. When has_more is false, you've hit the end.
Sandbox
Tokens prefixed fl_test_ hit the same validation but run against a fixture set — no real audits, no third-party API spend. Use them in CI.
Sandbox fixtures are returned for shape-stability testing. Don't treat the data as real customer data.
Endpoints
All endpoints are rooted at https://app.flatlineseo.com/api/v1. Method + path + a working curl + response excerpt for each.
Account
/meToken + plan introspection
Useful for SDK boot. Tells you the token's owner type, the plan it inherits, and the number of sites it can see.
Request
curl https://app.flatlineseo.com/api/v1/me \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"object": "token",
"token": { "id": "...", "prefix": "fl_live_qK4n", "mode": "live" },
"plan": {
"id": "agency",
"label": "Agency",
"limits": { "audits_per_month": null, "max_sites": 25, ... }
},
"sites_count": 3,
"rate_limits": { "per_minute": 100, "per_hour": 600, "per_day": 5000 }
}Audits
/auditsRun a fresh audit
Triggers PageSpeed + on-page meta scrape and returns a visibility score 0–100 plus enumerated findings. Idempotency-Key required.
Request
curl -X POST https://app.flatlineseo.com/api/v1/audits \
-H "Authorization: Bearer fl_live_..." \
-H "Idempotency-Key: 1234abcd-..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"scope": "country",
"country": "GB"
}'Response (excerpt)
{
"id": "01HX...",
"object": "audit",
"business_id": "01HX...",
"url": "https://example.com",
"scope": "country",
"country": "GB",
"visibility_score": 78,
"pagespeed": {
"performance": 84,
"seo": 91,
"accessibility": 88,
"best_practices": 92,
"load_time_ms": 2140
},
"pagespeed_status": "ok",
"findings": [
{
"severity": "warning",
"category": "performance",
"title": "Slow page load on mobile",
"explanation": "Mobile load time is over 3 seconds..."
}
],
"created_at": "2026-05-19T14:23:11.000Z"
}/audits/{id}Fetch one audit
Request
curl https://app.flatlineseo.com/api/v1/audits/01HX... \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"id": "01HX...",
"object": "audit",
"url": "https://example.com",
"visibility_score": 78,
"pagespeed": { ... },
"created_at": "2026-05-19T14:23:11.000Z"
}/audits?domain=&starting_after=&limit=List audits
Cursor-paginated. Filter by domain (apex match, case-insensitive).
Request
curl "https://app.flatlineseo.com/api/v1/audits?domain=example.com&limit=20" \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"object": "list",
"data": [
{ "id": "01HX...", "object": "audit", ... },
...
],
"has_more": true,
"next_cursor": "01HX..."
}Sites
/sitesList your sites
Request
curl https://app.flatlineseo.com/api/v1/sites \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"object": "list",
"data": [
{
"id": "01HX...",
"object": "site",
"name": "Example Co",
"url": "https://example.com",
"country": "United Kingdom",
"city": "Belfast",
"visibility_score": 78,
"last_scored_at": "2026-05-19T14:23:11.000Z"
}
],
"has_more": false,
"next_cursor": null
}/sites/{id}Fetch one site
Request
curl https://app.flatlineseo.com/api/v1/sites/01HX... \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"id": "01HX...",
"object": "site",
"name": "Example Co",
"url": "https://example.com",
"visibility_score": 78,
"pagespeed": { "performance": 84, ... },
"google_business_profile": {
"rating": 4.7,
"review_count": 142
},
"last_scored_at": "2026-05-19T14:23:11.000Z"
}/sites/{id}/keywordsRanked keywords
Up to 100 keywords from the cached DataForSEO enrichment. Includes position, search volume, and CPC where available.
Request
curl https://app.flatlineseo.com/api/v1/sites/01HX.../keywords \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"object": "list",
"data": [
{
"object": "keyword",
"keyword": "belfast plumber emergency",
"position": 7,
"search_volume": 480,
"url": "https://example.com/emergency",
"cpc": 1.84
}
],
"enriched_at": "2026-05-18T09:11:00.000Z"
}/sites/{id}/backlinksBacklink summary
Total backlinks, referring domains, dofollow share, top 20 anchors.
Request
curl https://app.flatlineseo.com/api/v1/sites/01HX.../backlinks \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"object": "backlinks",
"total_backlinks": 1247,
"referring_domains": 89,
"rank": 412,
"dofollow_share": 0.78,
"top_anchors": [
{ "anchor": "example co belfast", "count": 84, "dofollow_share": 0.91 }
],
"enriched_at": "2026-05-18T09:11:00.000Z"
}/sites/{id}/score-historyVisibility-score time-series
Up to 365 score points, newest first. Drives trend charts on customer dashboards.
Request
curl https://app.flatlineseo.com/api/v1/sites/01HX.../score-history \ -H "Authorization: Bearer fl_live_..."
Response (excerpt)
{
"object": "list",
"data": [
{
"id": "01HX...",
"object": "score_point",
"visibility_score": 78,
"scope": "country",
"country": "GB",
"scored_at": "2026-05-19T14:23:11.000Z"
}
]
}Important
Why is there no opportunity_score?
We compute two scores internally: a public-facing 0–100 visibility_score (returned everywhere) and a 0–10 opportunity_score used only by our sales team to prioritise prospect outreach. The Public API will never return the opportunity score, by design — it would leak commercial intelligence about our prospecting.
Ready to wire it up?
Generate a key from your dashboard. Plaintext shown once. Sandbox fl_test_ keys are free.