API documentation
Two REST surfaces, both under /api/v1: AI visibility data for your monitored domains, and the editorial content pipeline. All responses are JSON.
Authentication
Send a personal API key as a bearer token. Create one in Settings → API; the key is shown once and stored only as a hash.
curl https://your-host/api/v1/domains \ -H "Authorization: Bearer mtr_live_…"
A key can read the organisations its owner belongs to; a key scoped to one organisation is limited to it. Invalid or revoked keys return 401, unknown or inaccessible domains 404. The content endpoints also accept a server-configured agent token.
Rate limit: 100 requests per minute per key, returning 429 once exceeded.
AI visibility
/api/v1/domainsActive monitored domains the key owner can access.
{
"domains": [
{ "id": "…", "domain": "example.com", "url": "https://example.com",
"isCompetitor": false, "isActive": true, "label": null }
]
}/api/v1/domains/{domainId}One domain plus its latest completed readiness snapshot.
{
"domain": { "id": "…", "domain": "example.com", "url": "…", "label": null,
"isCompetitor": false, "isActive": true, "companyName": "…",
"category": "…", "createdAt": "2026-01-01T00:00:00.000Z" },
"snapshot": { "compositeScore": 74.5, "compositeGrade": "B",
"toolScores": { … }, "period": "2026-09", "completedAt": "…" }
}/api/v1/domains/{domainId}/historyCompleted readiness snapshots, newest first. Readable for inactive domains too.
{
"history": [
{ "period": "2026-09", "compositeScore": 74.5, "compositeGrade": "B",
"toolScores": { … }, "completedAt": "…" }
]
}/api/v1/domains/{domainId}/performanceAI answer performance per period and model.
model — optional, filter to one model id (e.g. gpt-4o)
{
"performance": [
{ "period": "2026-09", "model": "gpt-4o", "brandMentionRate": 0.42,
"avgPosition": 2.4, "queriesRun": 24, "queriesMentioned": 10,
"completedAt": "…" }
]
}/api/v1/domains/{domainId}/performance/{period}Full detail for one period: per-model coverage, competitor presence, citations, brand alignment and per-query results. Use latest for the most recent completed period.
period — YYYY-MM, YYYY-MM-DD or latestmodel — optional, filter to one model id
{
"period": "2026-09",
"domain": { "id": "…", "domain": "…", "url": "…", "label": null,
"companyName": "…", "category": "…",
"customQueries": [...], "targetMessaging": [...], "regions": ["global"] },
"competitors": [{ "id": "…", "domain": "…", "name": "…" }],
"models": [
{ "model": "gpt-4o", "modelLabel": "GPT-4o mini", "period": "2026-09",
"completedAt": "…", "methodologyVersion": "…",
"brandMentionRate": 0.42, "avgPosition": 2.4, "bestPosition": 1,
"queriesRun": 24, "queriesMentioned": 10,
"coverageByType": { … }, "competitorPresence": { … },
"brandAlignment": { … } | null,
"citations": [{ "url": "…", "domain": "…", "query": "…" }],
"queryResults": [
{ "query": "…", "queryType": "top_n", "mentioned": true,
"position": 2, "competitors": ["…"], "sentiment": "neutral",
"excerpt": "…", "productName": null, "parentQuery": null }
] }
]
}Content pipeline
Responses include both organisationId and organizationId so existing integrations keep working.
/api/v1/contentList content pieces.
statustypecampaignIdq — searchpage (default 1)pageSize (max 100, default 20)
{ "items": [ … ], "total": 42, "page": 1, "pageSize": 20, "totalPages": 3 }/api/v1/contentCreate a content piece. Always lands as a DRAFT for human review — the API cannot publish.
workingTitle (required)typebriefbodyexcerptseoTitleseoDescriptioncampaignIdcontentIdeaId
201 Created — the created piece
/api/v1/content/{id}One content piece with author, reviewer and related records.
The content piece, or 404.
/api/v1/ideasList content ideas.
statusprioritycampaignIdq — search
An array of ideas.
/api/v1/ideasCreate a content idea. Lands in NEW for human review.
title (required)descriptionaudiencesearchIntentpriority (LOW|MEDIUM|HIGH|URGENT)campaignIdpriorityAreaId
201 Created — the created idea
/api/v1/campaignsList campaigns.
statusq — search
An array of campaigns.
/api/v1/statsContent pipeline snapshot.
{ "contentByStatus": { "DRAFT": 5, "PUBLISHED": 12 },
"newIdeas": 8, "activeCampaigns": 2,
"upcomingScheduled": [{ "id": "…", "runAt": "…", "contentPieceId": "…" }] }A note on AI answer data
Figures describe answers observed at the time of the scan. AI answers vary between runs, users and regions, and models change without notice, so treat these as measurements rather than guarantees.