Public API reference (v1)
The machine-readable OpenAPI 3.1 contract is served live at /api/v1/openapi.json — load it into Postman, Insomnia, or Swagger UI. This page is the human-facing companion: auth, credit billing, every endpoint, and real request/response examples.
- Base URL:
https://visibilityiq365.com/api/v1 - Format: JSON in, JSON out. Success →
{ "success": true, "data": { … } }· Failure →{ "success": false, "error": "<code>" }
Authentication
Section titled “Authentication”Every /v1 endpoint requires a Bearer API key:
Authorization: Bearer viq_live_xxxxxxxxxxxxxxxxxxxxxxxxKeys are minted in the dashboard at Developer API (/dashboard/developer). The secret is shown once at creation — only its SHA-256 hash is stored, so a lost key is regenerated, never recovered. Never embed a key in client-side code.
A request is rejected with 401 when the key is missing, malformed, unknown, or revoked; the auth chain never reveals which.
Scopes
Section titled “Scopes”A key grants access only to the endpoint groups whose scope it holds. Scopes use resource:verb order (audits:read, not read:audits).
| Scope | Unlocks |
|---|---|
audits:read | GET /v1/audits/{projectId} |
rankings:read | GET /v1/rankings/{projectId}, GET /v1/serp/overlay |
keywords:read | GET /v1/keywords, POST /v1/keywords/bulk |
backlinks:read | GET /v1/backlinks/{target}, POST /v1/backlinks/batch |
A call whose key lacks the scope returns 403 {"error":"missing_scope:<scope>"}.
Billing — credits and rate limits
Section titled “Billing — credits and rate limits”Each call costs max(base, perRow × rows) credits where rows is the requested page size (limit) or item count (seeds/targets). Own-data reads served from D1 cost 0. A failed request (4xx/5xx) is refunded — you are charged only on 200.
| Endpoint | Base | Per-row | Effective cost |
|---|---|---|---|
GET /v1/audits/{projectId} | 0 | 0 | 0 (own data) |
GET /v1/rankings/{projectId} | 0 | 0 | 0 (own data) |
GET /v1/serp/overlay | 1 | 0 | 0 on cache hit, else 1 |
GET /v1/keywords | 5 | 1 | max(5, limit) |
POST /v1/keywords/bulk | 0 | 1 | 1 × number of seeds |
GET /v1/backlinks/{target} | 10 | 1 | max(10, limit) |
POST /v1/backlinks/batch | 0 | 10 | 10 × number of targets |
| Tier | Monthly credits | Rate limit | Overage |
|---|---|---|---|
| Starter | 5,000 | 60 / min | $1.00 / 1,000 |
| Pro | 50,000 | 120 / min | $1.00 / 1,000 |
| Agency | 250,000 | 300 / min | $0.75 / 1,000 |
Credits reset at the start of each calendar month.
Response headers
Section titled “Response headers”| Header | Meaning |
|---|---|
X-Credits-Cost | Credits charged for this request |
X-Credits-Remaining | Credits left in the current monthly period |
X-RateLimit-Limit / X-RateLimit-Remaining | Per-minute window state |
Retry-After | Seconds to wait before retrying (on 429 only) |
Error model
Section titled “Error model”| Status | Meaning |
|---|---|
400 | Invalid query or body (Zod validation) |
401 | Missing / malformed / unknown / revoked key |
402 | Credit budget exhausted (credit_exhausted) |
403 | Key lacks the required scope (missing_scope:<scope>) |
404 | Project or target not found, or not in the key’s organisation |
429 | Rate limit exceeded (rate_limited; see Retry-After) |
502 | Upstream data-provider error |
503 | Data source not configured |
Cross-tenant access returns 404, never 403, so a key cannot probe another organisation’s project IDs.
Endpoints
Section titled “Endpoints”GET /v1/audits/{projectId} — latest audit summary
Section titled “GET /v1/audits/{projectId} — latest audit summary”Scope audits:read · 0 credits. Returns the latest completed audit for a project in the key’s organisation.
curl https://visibilityiq365.com/api/v1/audits/uscoinshows \ -H "Authorization: Bearer $VIQ_KEY"{ "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.
GET /v1/rankings/{projectId} — organic ranking keywords
Section titled “GET /v1/rankings/{projectId} — organic ranking keywords”Scope rankings:read · 0 credits. Offset-paginated.
| Query param | Default | Notes |
|---|---|---|
limit | 100 | 1–1000 page size |
offset | 0 | Row offset |
positionMax | — | Only keywords ranking at or above this position (1–100) |
curl "https://visibilityiq365.com/api/v1/rankings/uscoinshows?limit=5&positionMax=20" \ -H "Authorization: Bearer $VIQ_KEY"{ "success": true, "data": { "projectId": "uscoinshows", "domain": "uscoinshows.com", "total": 244, "limit": 5, "offset": 0, "keywords": [ { "keyword": "coin shows in texas", "keywordHash": "e98288bc…", "position": 1, "previousPosition": null, "positionChange": 0, "searchVolume": 720, "trafficEstimate": 216, "intent": 0, "serpFeaturesCount": 3, "url": "https://www.uscoinshows.com/shows/tx", "isBranded": false } ] }}intent: 0 informational · 1 navigational · 2 commercial · 3 transactional.
positionChange: current − previous (positive = dropped).
Paginate: loop offset += limit until offset ≥ total.
GET /v1/keywords — keyword ideas
Section titled “GET /v1/keywords — keyword ideas”Scope keywords:read · max(5, limit) credits. Powered by VisibilityIQ’s keyword intelligence.
| Query param | Default | Notes |
|---|---|---|
seed | — (required) | 2–120 characters |
database | us | Locale code |
limit | 100 | 1–1000 ideas |
curl "https://visibilityiq365.com/api/v1/keywords?seed=coin%20show&limit=5" \ -H "Authorization: Bearer $VIQ_KEY"{ "success": true, "data": { "seed": "coin show", "database": "us", "count": 5, "keywords": [ { "keyword": "pcgs coin grading", "searchVolume": 22200, "cpc": 2.27, "keywordDifficulty": 61, "competition": "LOW", "intent": "informational" } ] }}Response headers on this call: X-Credits-Cost: 5, X-Credits-Remaining: 4995.
POST /v1/keywords/bulk — keyword ideas for many seeds
Section titled “POST /v1/keywords/bulk — keyword ideas for many seeds”Scope keywords:read · 1 credit per seed.
curl -X POST https://visibilityiq365.com/api/v1/keywords/bulk \ -H "Authorization: Bearer $VIQ_KEY" \ -H "Content-Type: application/json" \ -d '{"seeds":["coin show","rare coins"],"database":"us","limitPerSeed":3}'Body: seeds (1–100 strings), database (default us), limitPerSeed (1–200, default 50).
{ "success": true, "data": { "database": "us", "seedCount": 2, "results": [ { "seed": "coin show", "count": 3, "keywords": [ "…same shape as /keywords…" ] }, { "seed": "rare coins", "count": 3, "keywords": [] } ] }}GET /v1/backlinks/{target} — backlink profile
Section titled “GET /v1/backlinks/{target} — backlink profile”Scope backlinks:read · max(10, limit) credits. target is a URL-encoded domain or URL.
curl "https://visibilityiq365.com/api/v1/backlinks/uscoinshows.com?limit=50" \ -H "Authorization: Bearer $VIQ_KEY"Returns { target, summary:{referringDomains,backlinks,dfsRank}, authority:{calibrated,components}, referringDomains:[{domain,domainAuthority,dofollow,backlinks}] }.
POST /v1/backlinks/batch — backlink summaries for many targets
Section titled “POST /v1/backlinks/batch — backlink summaries for many targets”Scope backlinks:read · 10 credits per target.
Body: targets (1–25 strings), limitPerTarget (1–1000, default 100).
GET /v1/serp/overlay — per-URL SERP metrics
Section titled “GET /v1/serp/overlay — per-URL SERP metrics”Scope rankings:read · 0 credits on cache hit (else 1). Powers the browser-extension overlay.
| Query param | Notes |
|---|---|
url | Required — the page to look up |
projectId | Required — the project that owns the rankings |
Returns { url, domain, keywords:[{keyword,position,volume,ctr,impressions,estimatedTraffic}], topKeyword, estimatedTraffic, crawlStatus } for the URL’s top 5 ranking keywords. Returns 200 with an empty keywords array when the domain has no ranking data yet.
GET /v1/openapi.json — the spec
Section titled “GET /v1/openapi.json — the spec”Public, no auth. The full OpenAPI 3.1 document — load into Swagger UI, Postman, or Insomnia.
Quick start
Section titled “Quick start”export VIQ_KEY="viq_live_…" # from /dashboard/developer (shown once at creation)BASE="https://visibilityiq365.com/api/v1"
# Free own-data reads:curl "$BASE/audits/<projectId>" -H "Authorization: Bearer $VIQ_KEY"curl "$BASE/rankings/<projectId>?limit=100&positionMax=10" -H "Authorization: Bearer $VIQ_KEY"
# Metered keyword research (watch X-Credits-Remaining):curl "$BASE/keywords?seed=your%20topic&limit=20" -H "Authorization: Bearer $VIQ_KEY"Pagination: loop offset += limit until offset ≥ data.total.
Rate limits: on 429, sleep Retry-After seconds and retry.
Budget: watch X-Credits-Remaining; 402 means the monthly budget is spent — upgrade or wait for the reset.