Developers

Answer Audit in your AI assistant, or your own code.

Answer Audit measures whether AI assistants such as ChatGPT, Gemini, Perplexity, Claude and Google Search's AI answer name a company when a buyer asks them who to use. AEO, answer engine optimisation, is the work of getting named in those answers; Answer Audit is the measurement.

Connect Claude, ChatGPT, Claude Code or Cursor to our MCP server (MCP is the Model Context Protocol, the way AI apps connect to outside tools) and ask about your reports in plain words, or read them with the REST API. Both only read: nothing can be bought or changed through them.

MCP serverhttps://answeraudit.co.uk/api/mcp
Public MCP, no sign-inhttps://answeraudit.co.uk/api/mcp/public
REST APIhttps://answeraudit.co.uk/api/v1

The quickest way

Paste this line into the assistant you want to connect. It reads our setup guide and walks you through the steps for that app.

Paste into your assistant
Read https://answeraudit.co.uk/developers/setup.md and help me connect Answer Audit to the app I am using now.

Connect an assistant

Every app takes the same address, https://answeraudit.co.uk/api/mcp, and signs you in on Answer Audit's own site.

Claude (claude.ai and the desktop app)

The same steps work on claude.ai and in the Claude desktop app.

  1. Open Settings, then Connectors.
  2. Choose Add custom connector. Name it Answer Audit and paste the URL: https://answeraudit.co.uk/api/mcp
  3. Choose Connect. Answer Audit opens in your browser: sign in with the link we email you, then choose Allow.

If you do not see the option to add a custom connector, your Claude plan or your organisation's settings may not allow it yet.

ChatGPT

ChatGPT adds your own MCP servers through its developer mode, on the plans that offer it. OpenAI renames these menus from time to time, so look for developer mode in Settings.

  1. In Settings, turn on developer mode.
  2. Create a connector (the wording may differ in your version), name it Answer Audit, paste the URL https://answeraudit.co.uk/api/mcp, and pick OAuth if it asks how to sign in.
  3. Answer Audit opens in your browser: sign in with the link we email you, then choose Allow.

Claude Code

  1. Run the first command below in your terminal. Add --scope user to have it in every project, not only this one.
  2. Then, in Claude Code, type /mcp, choose answer-audit and sign in. Answer Audit opens in your browser: sign in with the link we email you, then choose Allow.
  3. Or use the second command, with a personal API key from your account page, and skip the browser.
Sign in through your browser
claude mcp add --transport http answer-audit https://answeraudit.co.uk/api/mcp
Or with a personal API key
claude mcp add --transport http answer-audit https://answeraudit.co.uk/api/mcp --header "Authorization: Bearer aa_key_..."

Cursor

  1. Add the first snippet below to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json in one project.
  2. In Cursor's MCP settings, choose the sign-in button beside answer-audit. Answer Audit opens in your browser: sign in with the link we email you, then choose Allow.
  3. Or use the second snippet, with a personal API key in a headers entry, instead of signing in.
mcp.json
{
  "mcpServers": {
    "answer-audit": {
      "url": "https://answeraudit.co.uk/api/mcp"
    }
  }
}
mcp.json with a personal API key
{
  "mcpServers": {
    "answer-audit": {
      "url": "https://answeraudit.co.uk/api/mcp",
      "headers": {
        "Authorization": "Bearer aa_key_..."
      }
    }
  }
}

Any other MCP client

  1. Server URL: https://answeraudit.co.uk/api/mcp (Streamable HTTP).
  2. Sign-in: OAuth 2.1 with PKCE. Clients find everything they need at https://answeraudit.co.uk/.well-known/oauth-protected-resource and https://answeraudit.co.uk/.well-known/oauth-authorization-server; both dynamic client registration and Client ID Metadata Documents work.
  3. Or send a personal API key as Authorization: Bearer aa_key_....
  4. For the public tools only, with no sign-in, use https://answeraudit.co.uk/api/mcp/public.

Signing in, and what it can read

  1. The app opens Answer Audit in your browser. If you are not signed in, enter your email and click the link we send you. There is no password.
  2. We show which app is asking and what it can do: read the reports under your email address, nothing else. Choose Allow, or Deny.
  3. You are back in the app, connected. It stays connected while the app keeps using it, until you choose Disconnect under Apps and API keys on your account page.

Every account reads exactly what its report pages and CSVs show it, for what it bought: a free check reads as the free report, a paid report as what was bought, and an agency reads its clients' reports as well as its own. Nothing is read that the report page would not show.

The answers are collected through each AI assistant's API with web search switched on. They are a close proxy for what a person sees in the apps, not a copy of it.

Tools

Every tool reads only. The public tools read the published category league tables and their questions, on both servers. The signed-in tools read your own reports, on https://answeraudit.co.uk/api/mcp only.

Public, no sign-in

list_categories

No sign-in

List published categories

Lists the buyer categories Answer Audit publishes league tables for, in every market or in one. Each entry has the category's slug and market (for get_category and get_questions), how many questions it holds, whether it has been measured, and its public page. Filter with query to find a category by name or sector.

  • market string, optional: Only this market: us, uk, global, ca, au, ie or de.
  • query string, optional: Words to look for in the category name or sector, such as "payroll".
  • limit whole number, optional: How many to return (default 50, at most 200).
  • offset whole number, optional: How many to skip, to read the next page.

get_category

No sign-in

Get a category's league table

One published category in one market: which companies AI assistants name most often for its buyer questions (the top of the table, with counts and the date asked), how many more were named, and the category's public page. Use list_categories to find the slug and market.

  • slug string, required: The category's slug, from list_categories.
  • market string, required: A market code such as us, uk or global.

get_questions

No sign-in

Get a category's buyer questions

Every buyer question in one published category and market, numbered as its public page numbers them, with its topic and buying stage, and a link to the question's own page where it has one (questions answered by at least two assistants).

  • slug string, required: The category's slug, from list_categories.
  • market string, required: A market code such as us, uk or global.

get_question

No sign-in

Get one question's results

One buyer question's public page: the companies the assistants named most often in answer to it (with counts and the date asked), how many more were named, and the websites the answers cited. Use get_questions for the question slugs; only questions with hasPage true have one.

  • slug string, required: The category's slug, from list_categories.
  • market string, required: A market code such as us, uk or global.
  • question string, required: The question's slug, from get_questions.

brand_lookup

No sign-in

Find a company in the league tables

Finds where a company is named near the top of Answer Audit's published league tables: the category, market, its place, how many answers named it and when they were asked. A company named only further down a table, or only in private reports, is not found.

  • name string, required: The company or brand name, such as "HubSpot".

Your reports, signed in

list_reports

Signed in

List my reports

Lists every report on the signed-in account: free checks, full reports, monitored reports, market reports and, for an agency, its clients' reports. Each has its id (for the other report tools), domain, brand, category, market, status, kind, score and when it last ran.

No inputs.

get_report

Signed in

Get a report

One report's results as its page shows them for what was bought: the score, how often each AI assistant named the brand, the question sets, gaps, suggested fixes, who was named instead, the websites cited, competitor grids and the page plan where the report includes them, and this month against last on a monitored report.

  • id string, required: A report id, from list_reports.

get_answers

Signed in

Get a report's answers

The answers behind a report, question by question and assistant by assistant: whether the brand was named, who else was, the websites cited and the answer text, as much of it as the report's tier shows. Narrow with set (0 is the buyer questions, then each supplied list) and question (its number in that set).

  • id string, required: A report id, from list_reports.
  • set whole number, optional: The question set: 0 for the buyer questions, 1 and up for supplied lists.
  • question whole number, optional: The question's number in its set, as the report numbers it.

get_history

Signed in

Get a report's history

Every run of a report, newest first, with its date, why it ran, the score and how many answers named the brand, so a monitored report's movement month by month can be read.

  • id string, required: A report id, from list_reports.

get_report_csv

Signed in

Get a report as CSV

The report as CSV, one row per question and assistant, exactly as the report's own Download CSV gives it for its tier.

  • id string, required: A report id, from list_reports.

REST API

Base URL https://answeraudit.co.uk/api/v1. Routes for your reports need a personal API key, sent as Authorization: Bearer aa_key_.... A sign-in from an AI assistant works only with the MCP server, not here. Public routes need no key. The full description is at openapi.json (OpenAPI 3.1).

Every route reads only, with GET. A reply is { data, meta } when it works, where meta holds the version and when the reply was made, and { error: { code, message } } when it does not. The codes are unauthorized, rate_limited, not_found, bad_request, not_ready, method_not_allowed and server_error. A report that is still being built answers ready: false with its status, and its CSV route answers 409.

Your reports

GET /reports

API key

Every report under your account.

Example
curl -H "Authorization: Bearer aa_key_..." "https://answeraudit.co.uk/api/v1/reports"
What comes back in data
[
  {
    "id": "string",
    "domain": "string",
    "brand": "string",
    "category": "string",
    "market": "string",
    "status": "string",
    "kind": "string",
    "tier": "string",
    "monitored": "boolean",
    "score": "number | null",
    "createdAt": "date-time",
    "updatedAt": "date-time",
    "parentId": "string | null",
    "agencyClient": {
      "active": "boolean"
    },
    "monitor": {
      "refreshed": "string | null",
      "next": "string"
    },
    "links": {
      "report": "url",
      "csv": "url"
    }
  }
]

GET /reports/{id}

API key

One report's summary.

  • id in the path, required: The report's id.
Example
curl -H "Authorization: Bearer aa_key_..." "https://answeraudit.co.uk/api/v1/reports/REPORT_ID"
What comes back in data
{
  "ready": true,
  "id": "string",
  "domain": "string",
  "brand": "string",
  "category": "string",
  "market": "string",
  "createdAt": "date-time",
  "kind": "string",
  "tier": "string",
  "preparedBy": {
    "name": "string",
    "contact": "string",
    "contactHref": "string",
    "logo": "string",
    "whiteLabel": "boolean"
  },
  "score": "number",
  "namedIn": "integer",
  "answered": "integer",
  "cited": "integer",
  "questions": {
    "asked": "integer",
    "total": "integer"
  },
  "engines": [
    {
      "engine": "string",
      "assistant": "string",
      "namedIn": "integer",
      "answered": "integer"
    }
  ],
  "weakestAssistant": "string | null",
  "insight": "string",
  "sets": [
    {
      "label": "string",
      "kind": "category | supplied",
      "givenAt": "string | null",
      "score": "number",
      "namedIn": "integer",
      "answered": "integer",
      "questions": "integer",
      "movement": "{...} | null"
    }
  ],
  "gaps": [
    {
      "question": "string",
      "namedOthers": "integer",
      "answered": "integer",
      "names": [
        {
          "name": "string",
          "count": "integer"
        }
      ],
      "fit": "string"
    }
  ],
  "fixes": [
    {
      "text": "string",
      "effort": "string | null",
      "impact": "string | null"
    }
  ],
  "shareOfVoice": {
    "share": "string",
    "namedIn": "integer",
    "mentions": "integer",
    "position": {
      "average": "number",
      "always": "boolean",
      "answers": "integer",
      "text": "string"
    }
  },
  "competitorShare": [
    {
      "name": "string",
      "count": "integer",
      "share": "string"
    }
  ],
  "otherNamed": [
    {
      "name": "string",
      "count": "integer",
      "share": "string"
    }
  ],
  "competitorDomains": [
    {
      "domain": "string",
      "count": "integer"
    }
  ],
  "topCitedDomains": [
    {
      "domain": "string",
      "count": "integer"
    }
  ],
  "citationChecks": "{...} | null",
  "competitors": [
    {
      "name": "string",
      "domain": "string",
      "score": "number",
      "namedIn": "integer",
      "answered": "integer",
      "cells": [
        {
          "question": "string",
          "engine": "string",
          "assistant": "string",
          "named": "boolean",
          "cited": "boolean",
          "status": "answered | no_answer | no_ai_answer"
        }
      ],
      "shareOfVoice": {
        "share": "string",
        "namedIn": "integer",
        "mentions": "integer",
        "position": "{...} | null"
      }
    }
  ],
  "pagePlan": "{...} | null",
  "monitor": {
    "refreshed": "string | null",
    "next": "string"
  },
  "trial": {
    "active": "boolean",
    "lastDay": "string"
  },
  "lockedAssistants": [
    "string"
  ],
  "lockedQuestions": [
    "string"
  ],
  "markets": {
    "parent": {
      "id": "string",
      "market": "string"
    },
    "children": [
      {
        "id": "string",
        "market": "string",
        "status": "string",
        "score": "number | null"
      }
    ]
  },
  "links": {
    "report": "url",
    "csv": "url"
  }
}

GET /reports/{id}/answers

API key

A report's answers, cut for its tier.

  • id in the path, required: The report's id.
  • set query, optional: Only this question set: 0 for the buyer questions, then 1, 2... for each list of your own questions.
  • question query, optional: Only this question, by its number in its set (from 1).
Example
curl -H "Authorization: Bearer aa_key_..." "https://answeraudit.co.uk/api/v1/reports/REPORT_ID/answers"
What comes back in data
{
  "ready": true,
  "id": "string",
  "brand": "string",
  "answers": [
    {
      "label": "string",
      "kind": "category | supplied",
      "answers": [
        {
          "n": "integer",
          "question": "string",
          "engine": "string",
          "assistant": "string",
          "status": "answered | no_answer | no_ai_answer | locked",
          "brandNamed": "boolean",
          "competitorsNamed": [
            "string"
          ],
          "alsoNamed": [
            "string"
          ],
          "position": "integer",
          "companiesNamed": "integer",
          "cited": "boolean",
          "citedDomains": [
            "string"
          ],
          "text": "string",
          "textCut": "full | excerpt | tease",
          "error": "string"
        }
      ],
      "lockedQuestions": [
        "string"
      ]
    }
  ]
}

GET /reports/{id}/history

API key

A report's runs, as scores only.

  • id in the path, required: The report's id.
Example
curl -H "Authorization: Bearer aa_key_..." "https://answeraudit.co.uk/api/v1/reports/REPORT_ID/history"
What comes back in data
{
  "ready": true,
  "id": "string",
  "versions": [
    {
      "version": "integer",
      "date": "date-time",
      "reason": "string",
      "questionSet": "buyer questions | an earlier run, question set not recorded",
      "score": "number | null",
      "namedIn": "integer | null",
      "answered": "integer | null",
      "movement": {
        "since": "string",
        "previousScore": "number",
        "gained": "integer",
        "lost": "integer"
      }
    }
  ]
}

GET /reports/{id}/csv

API key

A report as CSV.

  • id in the path, required: The report's id.
Example
curl -H "Authorization: Bearer aa_key_..." "https://answeraudit.co.uk/api/v1/reports/REPORT_ID/csv"

Returns: CSV text, with a Content-Disposition file name.

Public data

GET /categories

No key

Every published category.

  • market query, optional: Only this market, such as us, uk or global.
Example
curl "https://answeraudit.co.uk/api/v1/categories"
What comes back in data
[
  {
    "slug": "string",
    "market": "string",
    "region": "string",
    "name": "string",
    "head": "string",
    "sector": "string",
    "measured": "boolean",
    "questions": "integer",
    "answers": "integer",
    "asked": "string | null",
    "written": "string",
    "assistants": [
      "string"
    ],
    "url": "url"
  }
]

GET /categories/{slug}/{market}

No key

One category in one market.

  • slug in the path, required: The category's slug, as in its page URL.
  • market in the path, required: The market's short name, such as us, uk or global.
Example
curl "https://answeraudit.co.uk/api/v1/categories/crm-software/global"
What comes back in data
{
  "slug": "string",
  "market": "string",
  "region": "string",
  "name": "string",
  "head": "string",
  "sector": "string",
  "measured": "boolean",
  "questions": "integer",
  "answers": "integer",
  "asked": "string | null",
  "written": "string",
  "assistants": [
    "string"
  ],
  "url": "url",
  "top": [
    {
      "name": "string",
      "answers": "integer",
      "share": "string",
      "position": {
        "average": "number",
        "always": "boolean",
        "answers": "integer",
        "text": "string"
      }
    }
  ],
  "moreNamed": "integer"
}

GET /categories/{slug}/{market}/questions

No key

A category's questions.

  • slug in the path, required: The category's slug, as in its page URL.
  • market in the path, required: The market's short name, such as us, uk or global.
Example
curl "https://answeraudit.co.uk/api/v1/categories/crm-software/global/questions"
What comes back in data
[
  {
    "n": "integer",
    "text": "string",
    "topic": "string | null",
    "stage": "string | null",
    "slug": "string",
    "hasPage": "boolean",
    "url": "url | null"
  }
]

GET /categories/{slug}/{market}/questions/{question}

No key

One question's page.

  • slug in the path, required: The category's slug, as in its page URL.
  • market in the path, required: The market's short name, such as us, uk or global.
  • question in the path, required: The question's slug, from the questions list.
Example
curl "https://answeraudit.co.uk/api/v1/categories/crm-software/global/questions/QUESTION_SLUG"
What comes back in data
{
  "category": {
    "slug": "string",
    "market": "string",
    "region": "string",
    "name": "string",
    "head": "string",
    "sector": "string",
    "measured": "boolean",
    "questions": "integer",
    "answers": "integer",
    "asked": "string | null",
    "written": "string",
    "assistants": [
      "string"
    ],
    "url": "url"
  },
  "text": "string",
  "stage": "string | null",
  "slug": "string",
  "answers": "integer",
  "assistants": [
    "string"
  ],
  "asked": "string",
  "top": [
    {
      "name": "string",
      "answers": "integer"
    }
  ],
  "moreNamed": "integer",
  "citedDomains": [
    {
      "domain": "string",
      "count": "integer"
    }
  ],
  "url": "url"
}

GET /brands

No key

Where a company is named in the published league tables.

  • name query, required: The company name, 2 to 100 characters.
Example
curl "https://answeraudit.co.uk/api/v1/brands?name=HubSpot"
What comes back in data
[
  {
    "category": "string",
    "head": "string",
    "slug": "string",
    "market": "string",
    "region": "string",
    "rank": "integer",
    "answers": "integer",
    "of": "integer",
    "asked": "string",
    "url": "url"
  }
]

GET /openapi.json

No key

The OpenAPI 3.1 description of this API.

Example
curl "https://answeraudit.co.uk/api/v1/openapi.json"

Returns: The OpenAPI 3.1 document itself (not wrapped in data and meta).

Make an API key

  1. Sign in on your account page with the email address your reports are under.
  2. Under Apps and API keys, give the key a name, such as the script that will use it, and choose Make a key.
  3. Copy the key straight away. It starts aa_key_ and is shown once: we keep only a fingerprint of it, so we cannot show it again.

An account can hold up to 10 keys. Revoke one on the same page and it stops working at once. A key reads what your account page shows you and nothing more; keep it out of web pages and shared code.

Limits

  • 120 requests a minute for each sign-in or API key.
  • REST API: 300 requests a minute across all of one account's keys.
  • Public MCP server: 120 requests a minute from one address.
  • Public data routes of the REST API (categories, questions, brands): 60 requests a minute from one address. openapi.json has no limit.
  • REST API: an address that sends 20 unrecognised keys in a minute is refused for the rest of that minute.

Past a limit the reply is 429 with a Retry-After header; wait that many seconds and try again.