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

GET/api/v1/domains

Active monitored domains the key owner can access.

{
  "domains": [
    { "id": "…", "domain": "example.com", "url": "https://example.com",
      "isCompetitor": false, "isActive": true, "label": null }
  ]
}
GET/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": "…" }
}
GET/api/v1/domains/{domainId}/history

Completed readiness snapshots, newest first. Readable for inactive domains too.

{
  "history": [
    { "period": "2026-09", "compositeScore": 74.5, "compositeGrade": "B",
      "toolScores": { … }, "completedAt": "…" }
  ]
}
GET/api/v1/domains/{domainId}/performance

AI 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": "…" }
  ]
}
GET/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 latest
  • model — 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.

GET/api/v1/content

List content pieces.

  • status
  • type
  • campaignId
  • q — search
  • page (default 1)
  • pageSize (max 100, default 20)
{ "items": [ … ], "total": 42, "page": 1, "pageSize": 20, "totalPages": 3 }
POST/api/v1/content

Create a content piece. Always lands as a DRAFT for human review — the API cannot publish.

  • workingTitle (required)
  • type
  • brief
  • body
  • excerpt
  • seoTitle
  • seoDescription
  • campaignId
  • contentIdeaId
201 Created — the created piece
GET/api/v1/content/{id}

One content piece with author, reviewer and related records.

The content piece, or 404.
GET/api/v1/ideas

List content ideas.

  • status
  • priority
  • campaignId
  • q — search
An array of ideas.
POST/api/v1/ideas

Create a content idea. Lands in NEW for human review.

  • title (required)
  • description
  • audience
  • searchIntent
  • priority (LOW|MEDIUM|HIGH|URGENT)
  • campaignId
  • priorityAreaId
201 Created — the created idea
GET/api/v1/campaigns

List campaigns.

  • status
  • q — search
An array of campaigns.
GET/api/v1/stats

Content 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.