Quick start
Create a key, send a free audit request, and use the returned status URL to follow the audit. Your daily free allowance covers eligible requests.
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 for any verified account within its daily free allowance or with explicitly approved NT use. 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.
A 10.00 NT balance is required only after the free quota is used and paid use was explicitly authorised.
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: free requests use the daily account allowance; an extra audit requires allow_paid_usage: true and only charges 10.00 NT after verified completion; 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.
A 10.00 NT balance is required only after the free quota is used and paid use was explicitly authorised.
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: free requests use the daily account allowance; an extra audit requires allow_paid_usage: true and only charges 10.00 NT after verified completion; 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.
Free quota and optional NT usage
Every verified NOTABIS Account receives a daily free allowance for the SEO API. Website and API requests share 2 successful free audits per UTC day, with a limit of 50 pages per audit. Anonymous website use remains 1 audit of up to 20 pages per day.
If the free account quota is used, the API returns 429 free_quota_exhausted. To approve an extra audit, send the boolean allow_paid_usage: true in the JSON request. The audit is limited to 50 pages and costs 10.00 NT only after a verified successful report. The same audit is not charged twice when a callback or request is retried.
{"url":"https://example.com/","allow_paid_usage":true}402 insufficient_nt means the wallet does not have the required balance. 503 wallet_unavailable means the central wallet could not be checked. Invalid paid authorisation returns 422. Scheduled audits use only the free quota, never charge NT automatically, and pause when the daily quota is exhausted.