Skip to content
How it works AI answers Website Apps Pricing
Sign in Start free
How it works AI answers Website Apps Pricing Questions Sign in

API

The Ternly API

Everything the app knows about your AI answers, rankings, audits and app listings, as JSON for your own code. Pull it into a dashboard or a client report, or add questions, keywords and competitors and start runs from a script.

Last updated 26 October 2026

Before you start

  • The API comes with every paid plan: Indie, Studio and Agency. Free workspaces can’t make API keys.
  • Make a key on the API tab of the Workspace page. It’s shown once: keep it like a password, on a server, never in a web page or an app you ship.
  • A key belongs to one workspace and to you. It sees that workspace only and can do what your role there allows: a viewer’s key only reads.
  • The same key works with Ternly’s MCP server, for Cursor and other AI apps that can’t sign in with OAuth.

Your first call

Every address starts with https://app.ternly.io/api/v1. Send the key as a bearer token:

curl https://app.ternly.io/api/v1/sites \
  -H "Authorization: Bearer tern_pat_…"

GET https://app.ternly.io/api/v1 answers with the workspace the key is for, your role, and every endpoint you may call. Here’s a script that adds two questions, asks every AI now, and reads the result when it’s done:

KEY="tern_pat_…"
API=https://app.ternly.io/api/v1

curl -X POST $API/sites/halcyon.app/ai-questions \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"questions": ["best hiking app for iPhone", "apps like AllTrails"]}'

curl -X POST $API/sites/halcyon.app/runs/ai -H "Authorization: Bearer $KEY"
# {"crawl_id": 4812, "name": "AI visibility", "status": "queued"}

curl $API/crawls/4812 -H "Authorization: Bearer $KEY"   # until "status": "finished"
curl "$API/sites/halcyon.app/ai-visibility?include_answers=true" -H "Authorization: Bearer $KEY"

How it works

  • Sites and apps. {site} is a site’s domain (halcyon.app) or its id from GET /sites. An app without a website has an id only. {app} is the app’s id from GET /sites/{site}/apps, its App Store ID, its Google Play package name or its name.
  • Parameters. A GET takes them in the query string; POST, PATCH and DELETE take a JSON object. A parameter the endpoint doesn’t know is an error, so a typo never passes quietly.
  • Runs. Starting a run answers at once with a crawl_id. Poll GET /crawls/{crawl_id} until its status is finished, then read the results. A run that’s already going is returned rather than started twice.
  • Paid runs (marked below) spend your plan’s monthly allowances, the same as starting them in the app: AI answers, rank checks, pages and briefs.
  • Missing values. null or a missing field means Ternly doesn’t know it yet, not zero.

Errors and limits

An error answers with a status and a detail that says what to change:

{"detail": "No site 'halcyon.io'. Sites: halcyon.app"}
  • 400 a parameter is missing or unknown, 422 one has the wrong type.
  • 401 no key, or a key that was revoked or whose person left the workspace.
  • 402 the plan’s allowance for the month is used up. 403 a viewer’s key tried to change something, or the workspace is back on Free.
  • 404 no such site, app, run or brief in this workspace.
  • 429 too many calls: up to 60 a minute per person, and 30 paid runs a day per workspace (these limits are shared with MCP). Wait for Retry-After seconds.

Endpoints

Paths are under https://app.ternly.io/api/v1.

Workspace and sites

  • GET /workspaceThe workspace: its plan, subscription, this month’s usage and its people.
  • GET /sitesEvery site and app in the workspace, with its competitors.
  • POST /sitesAdd a website (and its brand names and competitors).
  • GET /sites/{site}A site at a glance: latest audit, search, rankings and AI answers.
  • PATCH /sites/{site}Rename a site, change its website, brand names or settings.

AI answers

  • GET /sites/{site}/ai-visibilityHow each AI answers your questions: mentions, position, share of voice, cited pages. include_answers=true adds the answers.
  • GET /sites/{site}/ai-questionsThe questions asked of each AI, with each AI’s latest result.
  • POST /sites/{site}/ai-questionsAdd questions (questions, optional tags).
  • PATCH /sites/{site}/ai-questions/{question_id}Pause, resume or retag a question.
  • POST /sites/{site}/ai-questions/removeRemove questions by id (question_ids).
  • POST /sites/{site}/ai-questions/suggest PaidHave Claude suggest questions people ask about apps like yours.
  • GET /sites/{site}/ai-changesPer-question trends and which cited pages came and went.
  • GET /sites/{site}/ai-crawlersVisits from GPTBot, ClaudeBot and other AI crawlers (with Cloudflare connected).
  • GET /sites/{site}/brand-profileHow the AIs describe your brand.
  • POST /sites/{site}/brand-profile PaidBuild the brand profile again from the latest answers.
  • GET /sites/{site}/outdated-answersAnswers with wrong facts or stale cited pages.
  • POST /sites/{site}/outdated-answers/check PaidCheck the latest answers for out-of-date facts now.
  • POST /sites/{site}/runs/ai PaidAsk every active question of each AI now. Returns a crawl_id.

To-do

  • GET /sites/{site}/weekly-planThis week’s to-do plan: what to change, where, the text to paste and why.
  • GET /sites/{site}/todoEvery open to-do task.
  • PATCH /sites/{site}/todo/{key}Mark a task done, skipped or open again (status).

Apps and stores

  • GET /sites/{site}/appsThe site’s apps and competitors’ apps: listings, ratings, store rankings, analytics.
  • POST /sites/{site}/appsFollow an app by store link, App Store ID or package name (app, competitor).
  • DELETE /sites/{site}/apps/{app}Stop following an app.
  • GET /sites/{site}/apps/{app}/reviewsAn app’s reviews, filtered by stars or search.
  • POST /sites/{site}/apps/{app}/keywordsTrack store search keywords for an app (keywords).
  • POST /sites/{site}/apps/{app}/keywords/removeStop tracking store keywords.
  • POST /sites/{site}/runs/app-syncSync the stores and app analytics now.
  • GET /sites/{site}/web-app-insightsHow the website and the apps line up: installs from search, pages that lead to the store.

Google keywords and search

  • GET /sites/{site}/keywordsEvery tracked Google keyword with its position, AI Overview and AI answers.
  • POST /sites/{site}/keywordsTrack Google keywords, with country, language, engine and device.
  • POST /sites/{site}/keywords/removeStop tracking keywords.
  • POST /sites/{site}/keywords/pausePause or resume keywords (resume=true).
  • GET /sites/{site}/rankingsLatest Google positions and their history.
  • POST /sites/{site}/runs/rank-check PaidCheck every tracked keyword’s position now.
  • GET /sites/{site}/keyword-clustersKeywords grouped by topic.
  • GET /sites/{site}/search-performanceSearch Console and GA4: clicks, impressions, top pages and queries.
  • GET /sites/{site}/search-opportunitiesQueries close to page one, and pages losing clicks.
  • POST /sites/{site}/runs/search-consoleSync Search Console and GA4 now.

Competitors

  • POST /sites/{site}/competitorsAdd or remove competitors (add, remove).
  • GET /sites/{site}/competitor-watchWhat changed on competitors’ sites.
  • POST /sites/{site}/runs/competitor-watchLook at competitors’ sites now.
  • GET /sites/{site}/content-gapTopics competitors cover that you don’t.
  • GET /sites/{site}/backlinksReferring domains and links, yours and competitors’.

Briefs

  • GET /sites/{site}/briefsWritten briefs, or one with brief_id.
  • POST /sites/{site}/briefs PaidHave Claude write a brief for a keyword or the to-do list.
  • GET /sites/{site}/content-briefWhat to cover to rank for a keyword, from the latest results.

Website audits

  • GET /sites/{site}/audit/issuesIssues found by the latest audit, with counts.
  • GET /sites/{site}/audit/issues/{check}The pages with one issue (check is its code).
  • GET /sites/{site}/audit/pageEverything the audit found on one page (url).
  • GET /sites/{site}/alertsAlerts from the last days.
  • GET /sites/{site}/indexingGoogle indexing status of the site’s pages.
  • GET /sites/{site}/internal-linksInternal links worth adding.
  • POST /audits PaidCrawl a site (url, optional max_pages). Returns a crawl_id.
  • GET /check-urlLook at one page now: status, title, headings, schema, issues.

Runs (crawls)

  • GET /crawlsRecent runs of every kind (site, mode, limit).
  • GET /crawls/{crawl_id}A run’s status and progress: poll it after starting one.
  • POST /crawls/{crawl_id}/cancelStop a run.

Managing keys

The API tab of the Workspace page lists every key with when it was last used. Revoke stops one at once. Owners and admins see and can revoke everyone’s; others see their own. Removing someone from the workspace, or moving it to Free, stops their keys too. Each person can have up to 20 keys in a workspace.

Things the API leaves to the app: deleting sites or workspaces, inviting people, changing the plan, and connecting accounts such as Google.

Help

Write to aiden@ternly.io if something doesn’t work, or you need an endpoint that isn’t here.

AI visibility for SaaS and apps, and the sites behind them.

Product

How it works AI answers Website Apps

Ternly

Pricing Questions Ternly vs Otterly Claude and ChatGPT (MCP) API Guides Blog Newsletter Sign in llms.txt Privacy Terms

© 2026 ternly. Named for the Arctic tern.