API reference

Read-only REST API for Peak Answer. JSON over HTTPS, bearer key, 4 endpoints.

The API returns what Peak Answer measures for one brand: your visibility in AI answers, how each tracked question is doing, and what Google shows for them. It only reads. To change what is tracked, use the app or the MCP server.

It is described as OpenAPI 3.1, so you can load it into Postman, Insomnia or any client generator.

Base URL

https://peakanswer.com/api/v1

Authentication

Create a key in Settings, Account, API key and MCP. Send it as a bearer token on every request.

Authorization: Bearer asq_your_key_here

A key belongs to one brand and reads only that brand. The key is shown once, when you create it. Replacing it ends the old one straight away. Requests fail with 401 if the key is wrong or the plan is no longer active.

Keep the key on your server. The API does not allow browser requests from other sites, so a key placed in front-end code would be readable by anyone who loads the page.

Rate limits

Each endpoint allows 60 requests an hour per brand. All your keys and servers share that allowance. Past it, the API answers 429 with a Retry-After header giving the seconds to wait. Measurements are updated on a schedule rather than live, so there is little to gain from polling more often than every few minutes.

Errors

Errors use the status code that fits and a JSON body with one field, error, holding a sentence you can show to a person.

{ "error": "Missing or invalid API key. Create one in Settings and send it as a bearer token." }
StatusMeaning
400The question id is empty or too long.
401The key is missing, wrong, or its plan is no longer active.
404No tracked question with that id belongs to the brand.
429Too many requests. Wait the number of seconds in Retry-After.
500The data could not be loaded. Try again.

Every response carries Cache-Control: no-store, so nothing is kept by proxies on the way.

Endpoints

RequestReturns
GET /api/v1/visibilityGet everything measured for the brand
GET /api/v1/questions/suggestionsGet questions worth tracking
GET /api/v1/questions/{id}/googleGet what Google shows for a question
GET /api/v1/questions/{id}/google-pageGet the brand's page that ranks for a question

GET /api/v1/visibility

The visibility index and its history, how each engine does, every tracked question, strategy, framing, answers lost and the pages engines quote, in one document. Poll it on a schedule rather than calling it per question.

Example

curl https://peakanswer.com/api/v1/visibility \
  -H "Authorization: Bearer $PEAK_ANSWER_KEY"

Response fields

FieldTypeDescription
brandobjectThe brand the key belongs to.
brand.namestringThe brand name.
brand.domainstringThe brand's website domain.
visibilityobject or nullThe latest visibility index. Null until the first measurement has finished.
visibility.indexnumberThe visibility index from 0 to 100, smoothed over recent days.
visibility.daystring (date)The day the index is for.
visibility.confidenceBandnumberHow far the index could be off in either direction, in points.
visibility.byEngineobjectHow often each engine names the brand, as a percentage of its answers. The keys are engine ids. An engine that is missing was not measured, which is different from measured at zero.
visibility.brandedPresencenumber or nullHow often the brand is named on questions that already contain its name. Reported on its own and never part of the index.
visibility.categoryRankinteger or nullThe brand's rank among the competitors tracked for it.
visibility.categorySizeinteger or nullHow many brands that rank is out of.
footprintobject or nullHow established the brand is on the wider web. Null until measured.
footprint.scoreintegerThe overall score from 0 to 100.
footprint.publicScoreintegerThe part of the score that can be compared with another company's, from 0 to 100.
footprint.coveragenumberThe share of the score's factors that had data, from 0 to 1. A low number means the score rests on little.
footprint.factorsobjectThe individual factors behind the score.
footprint.daystring (date)The day the score is for.
historyarray of objectsUp to 90 days of the index, newest first.
history[].daystring (date)The day.
history[].indexnumberThe smoothed index for that day.
history[].observednumberThe unsmoothed reading for that day.
strategyobjectHow the tracked questions split by what it takes to win them.
strategy.winnableWithContentintegerQuestions that new content can win.
strategy.needsAuthorityintegerQuestions that need mentions on other sites first.
strategy.inconsistentintegerQuestions where the answer changes too much to say.
strategy.losingWithContentintegerQuestions that content can win and the brand is not yet named on.
strategy.losingWithAuthorityintegerQuestions that need authority and the brand is not yet named on.
questionsarray of objectsEvery tracked question with how it is doing.
questions[].idstringThe question's id. Use it with the per-question endpoints.
questions[].textstringThe question as it is asked of the engines.
questions[].presencenumberHow often the brand is named across all engines, from 0 to 100.
questions[].volatilitynumberHow much the answer changes from run to run, from 0 to 100. High means the position is open.
questions[].winnabilitystringWhat it takes to win this question. One of content, authority, mixed.
questions[].namesYoubooleanTrue when the question itself contains the brand's name. Those questions are measured but left out of the index.
questions[].byEnginearray of objects
questions[].byEngine[].enginestringThe engine id. One of chatgpt, claude, perplexity, gemini, google_serp, google_ai_mode, copilot.
questions[].byEngine[].labelstringThe engine's display name.
questions[].byEngine[].presencenumberHow often this engine names the brand on this question, from 0 to 100.
questions[].byEngine[].runsintegerHow many answers that is out of.
questions[].winnersarray of stringBrands named when this brand is not.
questions[].runsintegerTotal answers recorded for the question.
framingarray of objectsPhrases the engines use about the brand.
framing[].phrasestringThe phrase.
framing[].sentimentstringHow the phrase reads. One of positive, neutral, negative.
framing[].countintegerHow many answers used it.
framing[].examplestringOne sentence it appeared in.
regressionsarray of objectsAnswers the brand used to be named in and no longer is. Up to 20.
regressions[].questionstringThe question.
regressions[].enginestringThe engine id. One of chatgpt, claude, perplexity, gemini, google_serp, google_ai_mode, copilot.
regressions[].scoreBeforeintegerThe score when the brand was named.
regressions[].scoreAfterintegerThe score now.
regressions[].takenBystring or nullThe brand named in its place.
regressions[].detectedAtstring (date-time)When the drop was found.
quotedPagesarray of objectsThe brand's own pages the engines quote. Up to 20.
quotedPages[].urlstringThe page's address.
quotedPages[].titlestring or nullThe page's title.
quotedPages[].answersSeenintegerHow many recorded answers quoted it.
generatedAtstring (date-time)When this document was built.

GET /api/v1/questions/suggestions

Questions people ask on Google that fit the brand and are not tracked yet.

Example

curl https://peakanswer.com/api/v1/questions/suggestions \
  -H "Authorization: Bearer $PEAK_ANSWER_KEY"

Response fields

FieldTypeDescription
suggestionsarray of objects
suggestions[].idstringThe suggestion's id.
suggestions[].questionstringThe question.
suggestions[].searchDemandstringHow often people ask it, compared with the brand's other questions. One of High, Medium, Low, Not enough data.
refreshedAtstring (date-time) or nullWhen the list was last built.
statusstringpending means the first list is still being built. stale means it is older than a month. One of pending, ready, stale.

GET /api/v1/questions/{id}/google

The first 10 Google results, whether an AI Overview was shown and which pages it cites, where the brand ranks, and how many tracked competitors are on page one. Read from the last stored check; the request does not run a new search.

Path parameters

NameDescription
idA tracked question's id, as returned in `questions[].id` by /visibility.

Example

curl https://peakanswer.com/api/v1/questions/QUESTION_ID/google \
  -H "Authorization: Bearer $PEAK_ANSWER_KEY"

Response fields

FieldTypeDescription
questionIdstringThe question's id.
googleobject or nullNull when the question has not been checked on Google yet, or the last check is out of date. It is a reading, not an error.
google.searchPhrasestringThe search that was checked.
google.checkedAtstring (date-time)When it was checked.
google.searchDepthintegerHow many results were read. Always 100. One of 100.
google.topSitesarray of objectsThe first 10 results.
google.topSites[].positionintegerPlace in the results, 1 to 10.
google.topSites[].urlstringThe result's address.
google.topSites[].domainstringIts domain.
google.aiAnswerShownbooleanWhether Google showed an AI Overview for the search.
google.brandPositioninteger or nullThe brand's best place in the first 100 results. Null when it is not there.
google.competitorsOnPageOneintegerHow many tracked competitors are in the first 10 results.
google.aiAnswerobject or nullWhat the AI Overview said, when one was shown. Absent on checks made before this was recorded.
google.aiAnswer.citedPagesarray of objectsThe pages the AI Overview cites. Up to 30.
google.aiAnswer.citedPages[].urlstringThe page's address.
google.aiAnswer.citedPages[].domainstringIts domain.
google.aiAnswer.citedPages[].titlestringIts title.
google.aiAnswer.brandsNamedarray of objectsThe brand and tracked competitors named in the AI Overview's text.
google.aiAnswer.brandsNamed[].namestringThe brand's name.
google.aiAnswer.brandsNamed[].isSelfbooleanTrue for the brand the key belongs to.

GET /api/v1/questions/{id}/google-page

Which page of the brand's site Google ranks for the question's search, and where.

Path parameters

NameDescription
idA tracked question's id, as returned in `questions[].id` by /visibility.

Example

curl https://peakanswer.com/api/v1/questions/QUESTION_ID/google-page \
  -H "Authorization: Bearer $PEAK_ANSWER_KEY"

Response fields

FieldTypeDescription
questionIdstringThe question's id.
pageobject or nullNull when no page of the brand's site was found for the search, or the check is out of date.
page.urlstringThe page's address.
page.positionintegerIts place in Google's results.
page.searchPhrasestringThe search it ranks for.
page.checkedAtstring (date-time)When it was checked.

Using it with an assistant

To ask Claude or ChatGPT about the same data without writing any code, connect the MCP server. It also lets an assistant change what is tracked.