Tonecast API
The Tonecast API gives read access to your campaigns: what ChatGPT, Claude, Gemini and Perplexity answered, the metrics Tonecast computes from those answers, the source graph behind them, the claims checked against your fact sheet and your alerts. It is part of the Agency plan. Everything is read-only and JSON.
Authentication
Create a key in Settings → your company → API keys (company owners only). The key is shown once. Send it in
the Authorization header of every request:
curl https://tonecast.io/api/public/v1/campaigns/ \
-H "Authorization: Bearer tc_..."
A key reads every campaign of its company and nothing else. Revoke it in the same place; it stops working at once.
Limits and errors
- 1,200 requests per hour per key. Beyond that the API answers
429with aRetry-Afterheader. 401: missing, unknown or revoked key.403: the company's plan does not include the API.404: the campaign is not one of your company's.- Lists are paginated:
page(from 1) andpage_size(up to 100, default 50). Every list answers{"count", "page", "pages", "results"}. - Dates are ISO 8601; filters
fromandtotakeYYYY-MM-DD.
Endpoints
Base URL: https://tonecast.io/api/public/v1
GET /campaigns/
Your company's campaigns: id, name, type (brand, product, person, topic), subject, status, workspace, languages, countries, engines, start and launch dates.
GET /campaigns/{id}/
One campaign, same fields.
GET /campaigns/{id}/metrics/
The numbers of the campaign overview: AI visibility rate, Tone in AI, recommendation rate and claim counts with
their confidence intervals (summary); share of voice, Formative Sentiment Index and week-on-week deltas
(kpis); the same per engine (engines); weekly series of visibility, tone and FSI per
engine (series); and the state of the early signal. Filters: from, to,
engine, language, country.
GET /campaigns/{id}/answers/
The AI answers, newest first: time, engine and model, language and country, the prompt, the full text, whether it
names your subject, its tone, whether it recommends it, the competitors it names, its citations and the claims it
makes. Filters: engine, language, from, to,
mentioned (true/false).
{
"id": 4812,
"requested_at": "2026-09-21T06:05:00Z",
"engine": "perplexity",
"model": "sonar",
"language": "en",
"prompt": {"id": 31, "text": "best compostable coffee capsules", "category": "discovery"},
"text": "…",
"mentioned": true,
"tone": "positive",
"recommended": true,
"competitors_mentioned": ["BrewNest"],
"citations": [{"url": "https://…", "domain": "…", "title": "…", "position": 1}],
"claims": [{"attribute": "price per capsule", "value": "€0.35", "status": "outdated"}]
}
GET /campaigns/{id}/sources/
The source graph, heaviest first: URL, domain, title, source type, tier (cited,
formative, owned), whether it is selected, its influence weight per engine, and why it
is in the graph. Filters: tier, engine, source_type, domain.
GET /campaigns/{id}/claims/
Claims the answers make about your subject, with their check against your fact sheet (consistent, incorrect, outdated, unverifiable), the sentence, the engine and the answer. Filter: status.
GET /campaigns/{id}/alerts/
Alerts raised for the campaign: kind, severity, engine, title, week and time.
Example: weekly visibility into a spreadsheet
import requests
API = "https://tonecast.io/api/public/v1"
HEADERS = {"Authorization": "Bearer tc_..."}
metrics = requests.get(f"{API}/campaigns/42/metrics/", headers=HEADERS, timeout=30).json()
for engine, series in metrics["series"]["engines"].items():
print(engine, list(zip(metrics["series"]["grid"], series["visibility_rate"])))
Versioning
Fields may be added to version 1 at any time; none is removed or renamed without a new version and at least 90 days of notice to the owners of the keys in use.