Run a free AI-search visibility scan on any website (how visible a brand is in ChatGPT, Perplexity, Google AI, etc.) and read back a score, confidence interval, the biggest gap, and a branded report URL.
curl -X POST https://app.collimer.com/api/v1/scan \
-H 'Authorization: Bearer <key>' \
-H 'content-type: application/json' \
-d '{"url":"example.com","source":"agent"}'
→ 201 { scan_token, status, poll_url, report_url }
curl -H 'Authorization: Bearer <key>' https://app.collimer.com/api/v1/scan/<scan_token>
→ 202 while running, then 200 with the teaser
(score, confidence_interval, top_gap,
report_url, cta_url).
Base URL: https://app.collimer.com/api/v0. This version is unstable and can change.
It exposes the writing workflow, brands, work, recommendations, audits, and scans.
Send an API key or OAuth access token as Authorization: Bearer <token>.
The /api/v0/openapi.json spec lists every operation,
its required scope, parameters, and response shape. Some writing operations require
writing access for the acting organization.
Successful JSON responses use {"data": {...}, "resolved": {...},
"hint": "next step", "url": "..."}. resolved echoes what the
request matched; url is a UI link or null.
Some long-running operations return 202 with a receipt rather than a
finished result. For example, POST /api/v0/articles/{id}/stat-candidates/find
returns data.status: "pending" and data.receipt_id. Poll
GET /api/v0/articles/{id}/writing-jobs/stat_candidates/{receipt_id}
until data.status is done or failed. Other
asynchronous operations have their own poll paths in the spec and response hint.
/api/v1 and /api/v0 errors use the same shape:
{"error": {"code": "rate_limited", "message": "Too many requests — try again later.", "retry_after": 60}}
code is a stable machine token, message is human text and may
change, retry_after (seconds) is present only on 429/503
and mirrors the Retry-After response header. (/oauth/* and
/mcp use their own spec-mandated error shapes instead.)
For /api/v0, common statuses include 400 for an invalid
cursor or limit, 401 for an invalid credential, 403 for a
missing scope, 404 for an unavailable resource, 409 for a
state conflict, 422 for invalid input, and 429 for a
rate limit or another active job. Branch on error.code; consult
the v0 spec for operation-specific errors.
Both scan routes require a bearer credential with scans:write.
Read-only API keys and viewer grants receive 403. Create an API key at
/connect; an OAuth access token also works. The public docs
remain available before sign-in so you can inspect the API before requesting access.
/api/v1 routes (e.g.
GET /api/v1/ping) — an API key created at
/connect, sent as Authorization: Bearer <key>./mcp — an OAuth 2.1 access token, minted via
/oauth/register → /oauth/authorize → /oauth/token
and sent the same way. A client discovers those endpoints, rather than hardcoding them,
from:
/mcp trusts.Complete OAuth consent once interactively, requesting offline_access
with the scopes your runner needs. Store the returned refresh token securely. Before
the access token expires, refresh it through /oauth/token and persist the
new refresh token after every refresh; the old token cannot be used again.
A refresh token expires after 90 days without use. Give each parallel runner its own
OAuth connection: sharing one refresh token can trigger reuse detection and revoke
the grant. An API key from /connect is another option for
unattended /api/v0 calls, but API keys cannot authenticate
/mcp.
List endpoints take ?limit= (max 50) and
?after=<cursor>. Pass the previous page's next_cursor as
after to fetch the next page; it's null on the last page. The
cursor is opaque — treat it as an unparseable token, not an offset.
GET /api/v0/work defaults to 25; other list endpoints may have their own
defaults, so check their spec entries.
Connect an MCP-capable client to the live Streamable HTTP endpoint
/mcp with OAuth. Its
server card describes the available tools.
Scans initiated through the API can use source: "mcp" or
source: "agent".