For agencies and integrations

Put your SEO audits on autopilot.

Start an audit from your own platform, check its progress, and pull the finished report when it is ready. Requests run in the background, so your app never has to sit and wait for a crawl.

1

Quick start

Create a key, send one request, and use the returned status URL to follow the audit.

Terminal
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

Accepted

Save 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-…" }
}
What comes back? A 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.

1 · Create

POST the target URL and save audit.id.

2 · Queue

The API returns 202 while work is queued or running.

3 · Poll

Use links.status until status is complete or failed.

4 · Read

Fetch the result, evidence, coverage or export when complete.

Polling example
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
done

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

Keep it private. If a key is exposed, revoke it immediately and create a replacement.
Authorization: Bearer nb_liv_...YOUR_KEY
audits:create

Required only when starting an audit.

audits:read

Required for lists, status, results, evidence, coverage and exports.

Endpoints

Use the create permission to start work and the read permission to retrieve it.

POST/api/v1/audits

Start an asynchronous audit. Requires audits:create.

GET/api/v1/audits

List your agency’s audits. Requires audits:read.

GET/api/v1/audits/{id}/status

Check queue, crawl progress, completion, and failure details.

DELETE/api/v1/audits/{id}

Cancel a queued or running audit. Requires audits:create. Cancellation is terminal and does not produce a score.

Check progress
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 ***'
Python example
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")
Store the ID

Your system owns the customer/job mapping. The API owns the audit record.

Retry safely

Reuse the same Idempotency-Key when retrying a create request.

Read after completion

Do not treat queued or running summaries as final scores.

Permissions, responses and limits

audits:create

Start new audits.

audits:read

List and read audits, progress, evidence, and exports.

202

Audit accepted and queued.

401 / 403

Key is missing, invalid, revoked, or lacks permission.

402

The account needs more SEO credits.

429 / 503

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-Key for retriable create requests; repeating the key for the same account returns the original audit.
  • Pagination: GET /audits accepts page and per_page; the response includes meta.current_page, meta.last_page, meta.per_page and meta.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:create

Start new audits.

audits:read

List and read audits, progress, evidence, and exports.

202

Audit accepted and queued.

401 / 403

Key is missing, invalid, revoked, or lacks permission.

402

The account needs more SEO credits.

429 / 503

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.