citeviz1

API v1

Pull AI visibility data into your own tools

Available on Growth and Agency. Your key is in Settings. All requests: Authorization: Bearer cv_..., JSON in and out. Base URL https://citeviz.com/api/v1.

GET /me

Plan, monthly usage and limits.

curl -H "Authorization: Bearer $KEY" https://citeviz.com/api/v1/me

GET /brands

All active brands with last score and last run time.

POST /brands

Create a brand. If prompts is omitted we generate up to 10 from the homepage.

curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"domain":"acme.com","name":"Acme","competitors":["rival.com"],"market":"United States","language":"en",
       "prompts":["best CRM for real estate teams","Acme alternatives"]}' \
  https://citeviz.com/api/v1/brands

GET /brands/{id}

Brand, its prompts and run history.

POST /brands/{id}/run

Queue a run on the brand's engines. Consumes prompts x engines checks. Returns {"run_id": 123, "status": "queued"}. Returns 409 if a run is already in progress or quota is out.

GET /runs/{id}?results=1

Status, progress, summary and recommendations. With results=1, every (prompt, engine) row with citations.

{
  "id": 123, "status": "done", "score": 42.0,
  "summary": {
    "score": 42.0, "mention_rate": 63.3, "share_of_voice": 38.5,
    "engines": [{"engine":"chatgpt","label":"ChatGPT","score":50.0,"cited":5,"total":10,"avg_position":2.4}, ...],
    "competitors": [{"domain":"rival.com","cited":9,"sov":45.0}, ...],
    "others": [{"domain":"g2.com","cited":14,"engines":["chatgpt","perplexity"]}, ...],
    "gaps": [{"prompt":"...","winners":["g2.com","capterra.com"],"mentioned":false}, ...],
    "wins": [{"prompt":"...","cited":3,"of":5,"engines":["chatgpt","claude","grok"]}, ...],
    "delta": {"score": 4.0, "mention_rate": -1.7, "engines": {"chatgpt": 10.0}}
  },
  "recommendations": ["...", "..."],
  "results": [{"prompt_text":"...","engine":"gemini","cited":1,"position":2,"mentioned":1,
               "citations":[{"url":"https://...","domain":"acme.com","target":true}, ...],
               "competitors_cited":["rival.com"],"snippet":"..."}]
}

POST /check

One-off synchronous check of any domain without creating a brand. Handy for prospecting and for agencies' own tools. Up to 25 prompts; without prompts we generate 5. Takes 30 to 120 s.

curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"domain":"prospect.com","engines":["chatgpt","perplexity"],"competitors":["rival.com"]}' \
  https://citeviz.com/api/v1/check

Search module

The same key reads the Search side: sites, imported Search Console data, the task queue and the uplift report.

GET /sites · POST /sites

curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"domain":"acme.com","name":"Acme","market":"United States","language":"en"}' \
  https://citeviz.com/api/v1/sites

Creating a site queues the crawl immediately.

POST /sites/{id}/import?filename=export.zip

The request body is the export itself (CSV, TSV, ZIP or JSON from the Search Analytics API), not JSON metadata. Returns the import id, the queued run id and what we parsed.

curl -X POST -H "Authorization: Bearer $KEY" --data-binary @export.zip \
  "https://citeviz.com/api/v1/sites/12/import?filename=export.zip"

{"import_id": 8, "run_id": 15, "status": "queued",
 "totals": {"clicks": 4911, "impressions": 232841, "queries": 4820, "pages": 990, "pairs": 19004,
            "ctr": 0.021, "position": 7.1},
 "warnings": []}

GET /sruns/{id}

Progress of one analysis pass: step is a human label (crawling the site, writing the deliverables), summary arrives when it is done.

GET /sites/{id}/tasks?status=open&full=1

The queue. full=1 adds the evidence and the deliverable.

{"tasks": [{"id": 91, "type": "cannibal", "status": "open", "priority": 1,
  "title": "\"imax odyssey\" is split between 2 pages",
  "url": "https://acme.com/a/", "impact_clicks_28d": 74.0, "locked": false,
  "measured": {"state": "improved", "delta_clicks": 31.0, "position_before": 8.1, "position_after": 5.2}}]}

POST /tasks/{id}/status

{"status": "done"} (or open, dismissed). Marking a task done is what makes it count in the uplift report instead of counting as a control.

GET /sites/{id}/uplift

Measured change for every task that has a snapshot and a newer import to compare against, plus the totals for done and untouched tasks.

Errors

401 bad key or plan without API. 402 monthly quota exhausted. 409 run already in progress. Bodies are {"error": "..."}.

Limits

Quota is shared with the dashboard. Be gentle: one run per brand at a time, and poll /runs/{id} no more than every 10 s.