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:
- Zapier: use Webhooks by Zapier → Custom Request → GET, with the URL above and the
X-API-Keyheader. Schedule it, then feed the result into any of the 6,000 apps Zapier already talks to. - Make: an HTTP → Make a request module, same URL and header.
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 →