Nothing matches your search.
Promptrack API

Build on your AI search visibility data

A simple, token-based REST API over everything Promptrack tracks — prompts, rankings, competitors, cited sources, recommended actions, reports, site audits and AI crawler traffic. Same data as your dashboard, JSON-first.

Base URL
https://promptrack.io/api/v1
Prefer to work from an AI assistant? Every endpoint below is also exposed as an MCP server — connect Claude, Cursor or ChatGPT to your workspace with the same token.

Authentication

Bearer tokens, created from your dashboard.

Create a token under API (/api-tokens). The secret is shown once — store it safely. Send it as a Bearer token on every request:

cURL
curl https://promptrack.io/api/v1/me
  -H "Authorization: Bearer prm_live_xxxxxxxxxxxxxxxx"

Token abilities

Each token carries a scope. Read tokens can call every GET endpoint; write tokens can also add prompts and update prompts & actions.

AbilityGrants
readAll read endpoints — projects, prompts, results, competitors, reports, audits, traffic.
writeEverything read can, plus POST /prompts, PATCH /prompts, PATCH /actions.
!
Tokens are hashed in our database and expire after 90 days. A read token that hits a write endpoint gets 403 — never a silent no-op.

Rate limits

60 requests per minute, per token. Every response carries the standard headers so you can back off gracefully:

HeaderMeaning
X-RateLimit-LimitRequests allowed per window (60).
X-RateLimit-RemainingRequests left in the current window.
Retry-AfterSeconds to wait — sent on a 429.

Errors

Errors are JSON with a human message, and an application code for the ones you can act on. Validation errors also include a field-keyed errors object.

StatusCodeWhen
401Missing, invalid or expired token.
403demo_readonlyThe demo workspace is read-only.
403subscription_requiredThe workspace has no active plan.
403A read token called a write endpoint.
404Resource not found — or not yours. We never confirm existence.
422Validation failed. Includes a field-keyed "errors" object.
422batch_rejectedA prompt batch failed a quota or business rule.
422quota_exceededReactivating a prompt would exceed your plan.
429Rate limit hit — back off using Retry-After.

Pagination

Only GET /projects/{id}/prompts is paginated. It returns a data array with links and meta. Pass ?per_page= (max 100) and ?page=. All other list endpoints return a plain { "data": [...] }.

Account

GET /me read

Your account, plan and remaining prompt slots.

Response
{
  "data": {
    "name": "North Star Agency",
    "email": "team@northstar.co",
    "plan": "pro",
    "prompt_slots_remaining": 142,
    "projects_count": 4
  }
}

Projects

GET /projects read

Every brand you track, with its engines and active prompt count.

Response
{
  "data": [
    {
      "id": 23,
      "brand_name": "CatchDoms",
      "brand_domain": "catchdoms.com",
      "competitors": ["DropCatch", "Namecheap"],
      "engines": ["chatgpt", "perplexity", "ai_overview", "ai_mode", "claude", "copilot"],
      "active_prompts_count": 18,
      "created_at": "2026-08-12T10:00:00+00:00"
    }
  ]
}
GET /projects/{id} read

A single project plus its live overview — KPIs, share of voice and cited sources.

Response
{
  "data": {
    "id": 23,
    "brand_name": "CatchDoms",
    "brand_domain": "catchdoms.com",
    "competitors": ["DropCatch", "Namecheap"],
    "engines": ["chatgpt", "perplexity", "ai_overview", "ai_mode", "claude", "copilot"],
    "active_prompts_count": 18,
    "created_at": "2026-08-12T10:00:00+00:00",
    "overview": {
      "kpis": {
        "answers_count": 40,
        "mentioned_count": 22,
        "visibility": 55,
        "visibility_delta": 3.0,
        "avg_position": 2.4,
        "avg_position_delta": -0.3,
        "sov": 18.5,
        "sov_delta": 1.2,
        "sov_brands": 9,
        "positive_pct": 70,
        "positive_delta": 5.0
      },
      "share_of_voice": [
        {
          "name": "DropCatch",
          "is_you": false,
          "domain": "dropcatch.com",
          "ckey": "domain:dropcatch.com",
          "pct": 24,
          "delta": 2,
          "visibility": 45,
          "avg_position": 2.1,
          "positive_pct": 60,
          "rank": 1
        }
      ],
      "sources": {
        "total": 128,
        "rows": [
          {
            "domain": "g2.com",
            "count": 12,
            "pct": 80,
            "community": false,
            "type": "reviews",
            "is_you": false,
            "delta": 3,
            "pages": 4,
            "prompts_count": 6,
            "share": 15,
            "topics": [
              {
                "name": "Best backorder services",
                "count": 5,
                "urls": [
                  { "url": "https://g2.com/categories/backorder", "count": 2, "engines": ["chatgpt"], "types": ["reviews", "listicle"], "prompts": ["best domain backorder service"] }
                ]
              }
            ]
          }
        ]
      }
    }
  }
}

Prompts

GET /projects/{id}/prompts read

Tracked prompts for a project. This is the only paginated endpoint.

ParameterInTypeDescription
per_page query integer Items per page. Default 50, max 100.
page query integer Page number.
Response
{
  "data": [
    {
      "id": 5,
      "project_id": 23,
      "text": "best domain backorder service",
      "tag": "Backorder",
      "country": "US",
      "is_active": true,
      "engines": ["chatgpt", "perplexity"],
      "source": "manual",
      "created_at": "2026-08-12T10:00:00+00:00"
    }
  ],
  "links": { "first": "…?page=1", "last": "…?page=3", "prev": null, "next": "…?page=2" },
  "meta": { "current_page": 1, "from": 1, "last_page": 3, "per_page": 50, "to": 50, "total": 142 }
}
POST /projects/{id}/prompts write

Add up to 50 prompts and fire an immediate run.

ParameterInTypeDescription
promptsrequired body string[] 1–50 prompt texts, 10–300 characters each.
llmsrequired body string[] At least one of chatgpt, perplexity, ai_overview.
countryrequired body string ISO-2 country: US, GB, FR, DE, ES, IT, NL, CA, AU.
tag body string Topic label (max 30 chars).
!
A batch that breaks a business rule returns 422 { "message": "…", "code": "batch_rejected" } — distinct from field validation.
Response (201)
{
  "data": {
    "run_id": 123,
    "created": [
      { "id": 5, "project_id": 23, "text": "best domain backorder service", "tag": "Backorder", "country": "US", "is_active": true, "engines": ["chatgpt", "perplexity"], "source": "manual", "created_at": "2026-08-12T10:00:00+00:00" }
    ],
    "skipped_duplicates": ["best expired domains"],
    "engines": ["chatgpt", "perplexity"]
  }
}
PATCH /prompts/{id} write

Pause or resume a prompt, or change its tag/country. Reactivating consumes a slot.

ParameterInTypeDescription
is_active body boolean Pause (false) or resume (true).
tag body string Topic label (max 30 chars).
country body string ISO-2 country (same list as above).
!
Reactivating past your plan limit returns 422 { "message": "…", "code": "quota_exceeded" }.
Response (200)
{
  "data": {
    "id": 5,
    "project_id": 23,
    "text": "best domain backorder service",
    "tag": "Backorder",
    "country": "US",
    "is_active": false,
    "engines": ["chatgpt", "perplexity"],
    "source": "manual",
    "created_at": "2026-08-12T10:00:00+00:00"
  }
}

Results

GET /prompts/{id}/results read

Latest analyzed result per engine for a prompt.

ParameterInTypeDescription
include query string Pass include=raw to add the full captured answer (raw_response).
Response
{
  "data": [
    {
      "engine": "chatgpt",
      "run_id": 123,
      "analyzed_at": "2026-08-12T10:05:00+00:00",
      "brand_mentioned": true,
      "brand_position": 2,
      "brand_sentiment": "positive",
      "brands_mentioned": [
        { "name": "DropCatch", "position": 1, "sentiment": "neutral" }
      ],
      "urls_cited": ["https://g2.com/categories/backorder"],
      "raw_response": null
    }
  ]
}

Competitors

GET /projects/{id}/competitors read

Every brand AI names on your prompts, ranked, with your brand marked as "you".

!
Before any run: { "data": null, "message": "No analyzed answers yet." }.
Response
{
  "data": {
    "kpis": {
      "total": 9,
      "you_sov": 18.5,
      "leader": { "name": "DropCatch", "sov": 24.0 },
      "gap": 5.5,
      "answers": 40
    },
    "you": {
      "key": "domain:catchdoms.com",
      "rank": 3,
      "name": "You",
      "domain": "catchdoms.com",
      "tracked": true,
      "you": true,
      "mentions": 15,
      "engines": { "chatgpt": 8, "perplexity": 7 },
      "visibility": 40,
      "avg_rank": 2.4,
      "positive_pct": 70,
      "sov": 18.5,
      "sov_delta": 1.2,
      "top_pro": "Fast catch on expiring domains",
      "top_con": "Pricing is higher than rivals"
    },
    "competitors": [
      {
        "key": "domain:dropcatch.com",
        "name": "DropCatch",
        "domain": "dropcatch.com",
        "tracked": true,
        "mentions": 18,
        "engines": { "chatgpt": 10, "perplexity": 8 },
        "visibility": 45,
        "avg_rank": 2.1,
        "positive_pct": 60,
        "sov": 24.0,
        "sov_delta": 2.0,
        "rank": 1,
        "top_pro": null,
        "top_con": null
      }
    ]
  }
}
GET /projects/{id}/competitors/detail read

Citations for a single brand — occurrences and cited URLs.

ParameterInTypeDescription
keyrequired query string Brand key from the leaderboard, e.g. domain:dropcatch.com. Unknown key → 404.
Response
{
  "data": {
    "name": "DropCatch",
    "domain": "dropcatch.com",
    "tracked": true,
    "you": false,
    "stats": {
      "mentions": 18,
      "prompts": 6,
      "avg_rank": 2.1,
      "sentiment": { "positive": 10, "neutral": 5, "negative": 3 },
      "engines": { "chatgpt": 10, "perplexity": 8 },
      "truncated": 0
    },
    "occurrences": [
      {
        "prompt": "best domain backorder service",
        "tag": "Backorder",
        "engine": "ChatGPT",
        "engine_key": "chatgpt",
        "date": "Aug 12",
        "position": 2,
        "sentiment": "positive",
        "prompt_id": 5,
        "urls": ["https://dropcatch.com/"],
        "excerpt_html": "…<mark>DropCatch</mark> is a strong option…"
      }
    ],
    "urls": [
      { "url": "https://dropcatch.com/", "count": 3, "prompts": ["best domain backorder service"] }
    ]
  }
}

Actions

GET /projects/{id}/actions read

Recommended actions ranked by estimated impact. Read-only (no sync).

Response
{
  "data": [
    {
      "id": 3,
      "project_id": 23,
      "title": "Create content targeting \"best domain backorder service\"",
      "why": "You are absent from this prompt on every engine.",
      "category": "content",
      "status": "todo",
      "estimated_gain_pts": 5,
      "target_url": "https://catchdoms.com/backorder",
      "completed_at": null,
      "created_at": "2026-08-12T10:00:00+00:00"
    }
  ]
}
PATCH /actions/{id} write

Move an action to in_progress or done.

ParameterInTypeDescription
statusrequired body string One of todo, in_progress, done. Setting done stamps completed_at.
Response (200)
{
  "data": {
    "id": 3,
    "project_id": 23,
    "title": "Create content targeting \"best domain backorder service\"",
    "why": "You are absent from this prompt on every engine.",
    "category": "content",
    "status": "done",
    "estimated_gain_pts": 5,
    "target_url": "https://catchdoms.com/backorder",
    "completed_at": "2026-08-19T09:00:00+00:00",
    "created_at": "2026-08-12T10:00:00+00:00"
  }
}

Reports

GET /projects/{id}/reports read

The last 24 weekly reports, each with short-lived signed download URLs.

!
Download URLs are signed and valid for 15 minutes — the signature is the auth, no token needed on the download itself.
Response
{
  "data": [
    {
      "id": 10,
      "status": "sent",
      "period_start": "2026-08-01",
      "period_end": "2026-08-07",
      "created_at": "2026-08-08T06:00:00+00:00",
      "downloads": {
        "pdf": "https://promptrack.io/api/v1/reports/10/download/pdf?expires=…&signature=…",
        "csv": "https://promptrack.io/api/v1/reports/10/download/csv?expires=…&signature=…"
      }
    }
  ]
}

Site audit

GET /projects/{id}/site-audit read

Latest AI-readiness audit — GEO score, agent-readiness score, sub-scores and per-check findings.

!
Returns { "data": null } when no audit has run yet.
Response
{
  "data": {
    "id": 7,
    "score": 82,
    "subscores": { "bot_access": 90, "ai_indexability": 78, "content_readiness": 80, "observed_evidence": 84 },
    "checks": [
      { "id": "robots-txt", "category": "bot_access", "result": "pass", "evidence": "declared", "summary": "robots.txt allows AI crawlers" }
    ],
    "agent_score": 74,
    "agent_level": "Discoverable",
    "agent_subscores": { "discoverability": 80, "content": 70 },
    "agent_checks": [
      { "id": "llms-txt", "result": "warn", "summary": "llms.txt could not be verified" }
    ],
    "pages_crawled": 25,
    "partial": false,
    "finished_at": "2026-08-18T08:00:00+00:00"
  }
}

AI traffic & logs

GET /projects/{id}/traffic/summary read

AI-referred visits over a period (visits sent by ChatGPT, Perplexity, etc.).

ParameterInTypeDescription
from query date Y-m-d. Defaults to 13 days ago. Window capped at 365 days.
to query date Y-m-d. Defaults to today. Must be ≥ from.
!
by_engine, by_country, by_device and top_pages are objects (key → count), not arrays.
Response
{
  "data": {
    "period": { "from": "2026-07-30", "to": "2026-08-12" },
    "views": 1200,
    "visitors": 800,
    "by_engine": { "chatgpt": 500, "perplexity": 300 },
    "by_country": { "US": 400, "FR": 200 },
    "by_device": { "desktop": 600, "mobile": 200 },
    "top_pages": { "https://catchdoms.com/backorder": 120 }
  }
}
GET /projects/{id}/logs/summary read

AI crawler activity over a period (GPTBot, ClaudeBot, PerplexityBot…).

ParameterInTypeDescription
from query date Y-m-d. Defaults to 13 days ago. Window capped at 365 days.
to query date Y-m-d. Defaults to today. Must be ≥ from.
Response
{
  "data": {
    "period": { "from": "2026-07-30", "to": "2026-08-12" },
    "hits": 3400,
    "by_bot": { "GPTBot": 2000, "PerplexityBot": 900 },
    "by_status": { "200": 3000, "404": 400 },
    "top_paths": { "/robots.txt": 500 }
  }
}

MCP server

Make Claude your agency's GEO analyst.

Promptrack ships a Model Context Protocol server at https://promptrack.io/mcp, authenticated with the same Bearer tokens. Connect any MCP client and ask questions in plain language — it calls the tools below against your workspace.

Tools

list_projects read
workspace_overview read
list_prompts read
prompt_results read
list_competitors read
competitor_detail read
list_actions read
list_reports read
site_audit read
traffic_summary read
logs_summary read
add_promptswrite
set_prompt_activewrite
set_action_statuswrite

Connect a client

In Claude Code, one command wires it up. Desktop & Cursor use the same URL and Bearer token — see the in-app setup for copy-paste configs.

Claude Code
claude mcp add promptrack \
  --transport http https://promptrack.io/mcp \
  --header "Authorization: Bearer prm_live_…"