Getting your AI visibility data into your own tools

Two ways in: a key that lets anything pull your data on its own schedule, and webhooks that push the moment something changes. Both are on Scale and Enterprise, and neither needs a developer.

Everything the Tracker measures is yours to take. This page covers both routes and gives working recipes for the tools people actually ask about.

Which one do you want?

Pull, with an API key, when something else owns the schedule: a BI dashboard that refreshes every morning, a warehouse job, a spreadsheet somebody opens on a Monday.

Push, with a webhook, when the point is to react: a Slack channel, an alert, a ticket. Nothing to poll and no delay.

Both are available on Scale and Enterprise. Create either in Settings → Integrations.

Pulling your data

One request returns every observation behind every number on your dashboard, one row per question, engine and scan.

GET https://api.searchscore.io/api/tracker/export?format=csv
X-API-Key: <your key>

The key already knows which account it belongs to, so there is no domain to pass. It cannot return anybody else’s data, and there is no parameter you can get wrong.

Useful parameters:

Parameter Does
format=csv or format=json CSV for spreadsheets and BI, JSON for code
table=competitors One row per rival per scan instead, with each engine’s rate
scans=20 How many scans back to include
offset=20 Skip that many, to page through history
answers=1 Include the full answer text each engine gave

Every row carries the measurement epoch and, where it was recorded, the retrieval mode, so you can recompute any figure we publish rather than taking it on trust.

Looker Studio, Google Sheets and Excel

These fetch a URL and cannot set a custom header, so pass the key as a parameter instead:

https://api.searchscore.io/api/tracker/export?format=csv&api_key=<your key>

In Google Sheets: =IMPORTDATA("..."). In Excel: Data → From Web. In Looker Studio: add a CSV-by-URL source pointing at the same address.

One caveat we would rather state than have you discover. A key in a URL is visible to anything that logs URLs: browser history, proxy logs, the sharing settings of the document holding it. That is the price of tools that cannot send headers. Use a separate key for each of these so you can revoke one without breaking the others, and keep the document private. Revoking is instant.

Zapier and Make

There is no SearchScore app in either directory yet. There does not need to be:

If you want the other direction, with SearchScore starting the Zap rather than Zapier polling us, use a webhook instead, below. It is faster and costs no tasks.

Pushing events

Add an endpoint in Settings → Integrations and we POST to it when something happens:

Event Fires when
scan.completed A scan finishes, with the headline numbers
citation.lost An engine that used to cite you stops
citation.gained An engine starts citing you
rival.appeared A brand we had not seen before shows up in your answers

Slack and Microsoft Teams

Paste your incoming-webhook URL into the same box. We detect it and send a readable message instead of raw JSON, with nothing else to configure:

SearchScore: 3 citations lost for acme.com

Verifying it was us

Every request carries X-SearchScore-Signature, an HMAC-SHA256 of the exact body under the secret shown once when you created the endpoint, and X-SearchScore-Event-Timestamp. To verify:

expected = HMAC_SHA256(secret, timestamp + "." + rawBody)

Compare it with the header value after sha256=. The timestamp is inside the signed material, so a captured request cannot be replayed later with a fresh one. Reject anything more than a few minutes old.

Verify before you act on a webhook. An endpoint that accepts unsigned POSTs is a URL anyone who learns it can write into.

When an endpoint stops working

We try once per event, with a short timeout, and record the outcome. There is no retry queue on purpose: a webhook that retries into an outage makes a bad afternoon worse, and one that blocks a scan would cost you a datapoint.

Settings shows the last status and the current failure run for every endpoint. After 10 consecutive failures we switch it off and say so, rather than posting into a void indefinitely. Fix it and re-enable.

Asking an AI assistant about your visibility

There is an MCP server in the repository at tools/mcp-server.js. Point Claude Desktop, or any MCP client, at it and you can ask questions in plain language instead of reading a CSV: which engine ignores us, who is ChatGPT recommending instead of us, did anything change this week.

{
  "mcpServers": {
    "searchscore": {
      "command": "node",
      "args": ["/path/to/mcp-server.js"],
      "env": { "SEARCHSCORE_API_KEY": "ss_..." }
    }
  }
}

It runs on your machine, not ours. It needs no packages installed, only Node 18 or newer, and it uses the same key and the same read-only API described above. Nothing it can do changes anything: an assistant given this server can answer questions about your visibility and that is all.

What this is not

There is no write API. Nothing here changes your configuration, adds questions or triggers a scan. Everything is a read of data we have already collected, which is why a leaked key is a disclosure problem rather than a billing one, and still worth revoking immediately.

Part of Pillar Article - see all guides in this series →