Quick start
Create a key, send one request, and use the returned status URL to follow the audit.
curl -X POST https://seo.notabis.com/api/v1/audits \
-H 'Authorization: Bearer nb_live_YOUR_KEY' \
-H 'Idempotency-Key: agency-job-123' \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com/"}'The 202 response
AcceptedSave the audit ID and poll links.status until the audit is complete.
{
"audit": { "id": "7f3b2f1a-…", "url": "https://example.com/", "status": "queued", "pages_crawled": 0, "progress_message": "Queued" },
"links": { "status": "https://seo.notabis.com/api/v1/audits/7f3b2f1a-…/status", "data": "https://seo.notabis.com/api/v1/audits/7f3b2f1a-…" }
}202 Accepted response with an audit ID and links for checking progress and reading the result.The audit lifecycle
An audit is asynchronous. Treat the create response as a job receipt, not the finished report.
POST the target URL and save audit.id.
The API returns 202 while work is queued or running.
Use links.status until status is complete or failed.
Fetch the result, evidence, coverage or export when complete.
while true; do
status=$(curl -s https://seo.notabis.com/api/v1/audits/$AUDIT_ID/status \
-H 'Authorization: Bearer ***')
echo "$status"
case "$status" in
*'"status":"complete"'*) break ;;
*'"status":"failed"'*) exit 1 ;;
esac
sleep 5
doneUse a backoff in production. Do not poll more often than necessary; the API returns rate-limit headers when a limit applies.
Authentication
API keys are managed on your SEO account. We show the full key once, then keep only a secure hash. Store it in your server-side secret manager — never in browser code, URLs, screenshots, or source control.
Authorization: Bearer nb_liv_...YOUR_KEYaudits:createRequired only when starting an audit.
audits:readRequired for lists, status, results, evidence, coverage and exports.
Endpoints
Use the create permission to start work and the read permission to retrieve it.
/api/v1/auditsStart an asynchronous audit. Requires audits:create.
/api/v1/auditsList your agency’s audits. Requires audits:read.
/api/v1/audits/{id}/statusCheck queue, crawl progress, completion, and failure details.
/api/v1/audits/{id}Cancel a queued or running audit. Requires audits:create. Cancellation is terminal and does not produce a score.
curl https://seo.notabis.com/api/v1/audits/AUDIT_ID/status \
-H 'Authorization: Bearer nb_live_YOUR_KEY'A practical integration
A typical agency workflow stores the audit ID in its own job record, polls in a worker, and only fetches the larger report after completion.
List recent audits
The list is account-scoped and paginated. Use per_page from 1 to 100.
curl 'https://seo.notabis.com/api/v1/audits?per_page=25&page=1' \
-H 'Authorization: Bearer ***'Read a completed report
Use the links returned by the API rather than constructing URLs in your client.
curl https://seo.notabis.com/api/v1/audits/$AUDIT_ID \
-H 'Authorization: Bearer ***'import os
import time
import requests
BASE = "https://seo.notabis.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SEO_API_KEY']}"}
created = requests.post(
f"{BASE}/audits",
headers={**HEADERS, "Idempotency-Key": "customer-42-job-981"},
json={"url": "https://example.com/"},
)
created.raise_for_status()
audit_id = created.json()["audit"]["id"]
status = created.json()["audit"]["status"]
while status not in ("complete", "failed"):
time.sleep(5)
status = requests.get(
f"{BASE}/audits/{audit_id}/status", headers=HEADERS
).json()["status"]
if status == "complete":
report = requests.get(
f"{BASE}/audits/{audit_id}", headers=HEADERS
)
report.raise_for_status()
print(report.json())
else:
raise RuntimeError("SEO audit failed")Your system owns the customer/job mapping. The API owns the audit record.
Reuse the same Idempotency-Key when retrying a create request.
Do not treat queued or running summaries as final scores.
Permissions, responses and limits
audits:createStart new audits.
audits:readList and read audits, progress, evidence, and exports.
Audit accepted and queued.
Key is missing, invalid, revoked, or lacks permission.
The account needs more SEO credits.
Slow down and retry later, or a required service is temporarily unavailable.
Important request rules
- Create: one JSON field is required:
url. - Idempotency: send
Idempotency-Keyfor retriable create requests; repeating the key for the same account returns the original audit. - Pagination:
GET /auditsacceptspageandper_page; the response includesmeta.current_page,meta.last_page,meta.per_pageandmeta.total. - Billing: starting an audit reserves SEO credit; reads, polling, evidence and exports do not start another crawl.
- Security: requests must be made server-side. Never expose API keys in browser JavaScript.
A completed result
Complete{
"id": "7f3b2f1a-…", "status": "complete", "score": 88,
"pages_crawled": 42, "issues": 17,
"links": { "export": "https://seo.notabis.com/api/v1/audits/7f3b2f1a-…/export" }
}Audit creation is limited to 10 requests per minute. Reads are limited to 120 requests per minute. Honour the Retry-After header when present.
audits:createStart new audits.
audits:readList and read audits, progress, evidence, and exports.
Audit accepted and queued.
Key is missing, invalid, revoked, or lacks permission.
The account needs more SEO credits.
Slow down and retry later, or a required service is temporarily unavailable.
A completed result
Complete{
"id": "7f3b2f1a-…", "status": "complete", "score": 88,
"pages_crawled": 42, "issues": 17,
"links": { "export": "https://seo.notabis.com/api/v1/audits/7f3b2f1a-…/export" }
}Audit creation is limited to 10 requests per minute. Reads are limited to 120 requests per minute. Honour the Retry-After header when present.