Skip to content

API Quickstart

This guide gets you from zero to a working API call in under five minutes. It uses the live /v1 surface — the same contract published at /api/v1/openapi.json and documented in the full API reference.

  • A VisibilityIQ account with at least one project.
  • A completed audit on that project (run one first if you have none — the audits endpoint returns null until a crawl finishes).
  1. Sign in and open Developer API at /dashboard/developer.
  2. Click Create key, name it (e.g. quickstart-test), and grant the scopes you need. For this walkthrough, select audits:read and rankings:read.
  3. Copy the key the moment it appears. The secret is shown once — only its SHA-256 hash is stored, so a lost key is regenerated, never recovered.

Keys are prefixed viq_live_. Never embed one in client-side code; treat it like a password.

Every /v1 endpoint takes a Bearer key in the Authorization header. Export it once so the examples below stay copy-pasteable:

Terminal window
export VIQ_KEY="viq_live_xxxxxxxxxxxxxxxxxxxxxxxx"

A missing, malformed, unknown, or revoked key returns 401 — the auth chain never reveals which, so you cannot probe for valid keys. A key that authenticates but lacks the endpoint’s scope returns 403 {"error":"missing_scope:<scope>"}.

The cheapest first call is the latest-audit summary. It reads your own data from D1, so it costs 0 credits and is safe to poll. Replace uscoinshows with your own project ID (visible in the dashboard URL):

Terminal window
curl https://visibilityiq365.com/api/v1/audits/uscoinshows \
-H "Authorization: Bearer $VIQ_KEY"

Success responses use the envelope { "success": true, "data": { … } }; failures use { "success": false, "error": "<code>" }. A real 200 body:

{
"success": true,
"data": {
"projectId": "uscoinshows",
"domain": "uscoinshows.com",
"audit": {
"id": "audit-1781524209869-wjp57j",
"status": "completed",
"score": 93,
"totalIssues": 16897,
"criticalIssues": 0,
"warnings": 727,
"notices": 16170,
"pagesCrawled": 5000,
"completedAt": "2026-06-15T13:32:06.473Z",
"createdAt": "2026-06-15T11:50:09.869Z"
}
}
}

audit is null when the project has no completed audit yet — check for it before reading audit.score. In code:

const res = await fetch(
`https://visibilityiq365.com/api/v1/audits/${projectId}`,
{ headers: { Authorization: `Bearer ${process.env.VIQ_KEY}` } },
);
if (res.status === 401) throw new Error('Bad or revoked API key');
if (res.status === 403) throw new Error('Key is missing the audits:read scope');
if (res.status === 429) {
const wait = Number(res.headers.get('Retry-After') ?? '60');
throw new Error(`Rate limited — retry after ${wait}s`);
}
const body = await res.json();
if (!body.success) throw new Error(`API error: ${body.error}`);
const audit = body.data.audit;
if (audit === null) {
console.log('No completed audit yet — run a crawl first.');
} else {
console.log(`Score ${audit.score}, ${audit.criticalIssues} critical issues.`);
}

Every response carries credit and rate-limit state in headers — read them rather than guessing your remaining budget:

HeaderMeaning
X-Credits-CostCredits charged for this request (0 for own-data reads)
X-Credits-RemainingCredits left in the current monthly period
X-RateLimit-RemainingCalls left in the current per-minute window
Retry-AfterSeconds to wait before retrying (on 429 only)

A failed request (4xx/5xx) is refunded — you are charged only on 200. A spent budget returns 402 {"error":"credit_exhausted"}.