REST API v1
API documentation
Integrate SEO scans into your product using service account API keys. All endpoints require HTTPS URLs and return JSON.
Overview
The API runs at https://seo.fluidify.io/api/v1. You receive a service account API key (prefix sa_) from your account manager or dashboard administrator.
Keys are shown only once when created — store them securely.
Scan batch vs. single audit
- Scan batch — runs five tools in parallel (Lighthouse, crawler, DataForSEO, Moz, Wappalyzer). Returns immediately with
202 Accepted; poll for results. - Lighthouse audit — synchronous single-page Lighthouse run. Returns when the audit completes or fails.
Authentication
Send your API key on every request using one of:
- Header
X-API-Key: sa_your_key_here - Header
Authorization: Bearer sa_your_key_here
Only active service accounts can authenticate. Invalid or missing keys receive 401 Unauthorized.
curl -H "X-API-Key: sa_your_key_here" https://seo.fluidify.io/api/v1/seo/scans/1
Start scan batch
POST
https://seo.fluidify.io/api/v1/seo/scans
Queues a multi-tool SEO scan for the given URL. The response includes a batch id used for polling.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | HTTPS URL to scan (max 2048 characters) |
max_crawl_count |
integer | No | Pages to crawl (1–20, default 20) |
Example
curl -X POST "https://seo.fluidify.io/api/v1/seo/scans" \
-H "Content-Type: application/json" \
-H "X-API-Key: sa_your_key_here" \
-d '{"url": "https://example.com", "max_crawl_count": 5}'
Response 202 Accepted
{
"status": "accepted",
"batch": {
"id": 42,
"batch_uuid": "550e8400-e29b-41d4-a716-446655440000",
"requested_url": "https://example.com",
"domain": "example.com",
"status": "queued"
}
}
Batch status
GET
https://seo.fluidify.io/api/v1/seo/scans/{id}
Returns batch progress and per-tool results for batches owned by your service account. Poll until batch.status reaches a terminal state.
Batch statuses
queued— batch created, jobs not started yetrunning— one or more tools in progresscompleted— all jobs succeeded (terminal)completed_with_errors— finished with some failed jobs (terminal)failed— batch failed (terminal)
Example
curl -H "X-API-Key: sa_your_key_here" \
"https://seo.fluidify.io/api/v1/seo/scans/42"
Response 200 OK
{
"batch": {
"id": 42,
"batch_uuid": "550e8400-e29b-41d4-a716-446655440000",
"requested_url": "https://example.com",
"domain": "example.com",
"status": "completed",
"requested_at": "2026-05-28T10:00:00.000000Z",
"completed_at": "2026-05-28T10:02:30.000000Z",
"robots_blocked": false,
"robots_message": null,
"jobs": {
"total": 5,
"succeeded": 5,
"failed": 0
}
},
"tools": [
{
"tool_name": "lighthouse",
"status": "succeeded",
"error_message": null,
"normalized_result": { }
}
]
}
Lighthouse audit (single page)
POST
https://seo.fluidify.io/api/v1/seo/audit
Runs a synchronous Lighthouse audit. Use when you only need performance/SEO scores for one URL.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | HTTPS URL to audit |
strategy |
string | No | mobile (default) or desktop |
curl -X POST "https://seo.fluidify.io/api/v1/seo/audit" \
-H "Content-Type: application/json" \
-H "X-API-Key: sa_your_key_here" \
-d '{"url": "https://example.com", "strategy": "mobile"}'
Success returns 200 with scores and metrics. Audit failure returns 422 with an error message.
Recommended workflow
- Obtain an API key for your service account.
POST /api/v1/seo/scanswith the target URL.- Save the returned
batch.id. - Poll
GET /api/v1/seo/scans/{id}every few seconds until the batch reaches a terminal status. - Read per-tool results from the
toolsarray.
Scan batches are processed asynchronously. Your integration must poll for completion; the initial 202 response does not include tool output.
Errors
| Status | Meaning |
|---|---|
401 |
Missing or invalid API key |
404 |
Batch not found, or batch belongs to another service account |
422 |
Validation failed (e.g. non-HTTPS URL) or audit failed |
429 |
Rate limit exceeded for your API key (see Retry-After header) |
Validation error example
{
"message": "The url field must start with https://.",
"errors": {
"url": ["The url field must start with https://."]
}
}