Agency plan

API Reference

Access all your brand data programmatically. Available on the Agency plan.

Authentication

Generate API keys in your dashboard under Settings → API. Keys follow the format mtv_live_<32hex>. Pass the key in every request:

X-API-Key: mtv_live_your_key_here
# or
Authorization: Bearer mtv_live_your_key_here

Rate Limiting

60 requests per minute per API key. Exceeding this returns 429 Too Many Requests with a Retry-After: 60 header. Redis failure is handled gracefully — rate limiting fails open.

Response format

Success

{ "data": <T> }

Paginated list

{ "data": [...],
  "total": 42,
  "limit": 50,
  "offset": 0 }

Error

{ "error": "Human-readable message",
  "code": "MACHINE_CODE" }

Endpoints

Base URL: https://mentova.ai/api/v1

Brands

MethodEndpointDescription
GET/brandsList all brands
POST/brandsCreate a brand
GET/brands/:idGet brand details
PATCH/brands/:idUpdate brand
DELETE/brands/:idDelete brand

Topics

MethodEndpointDescription
GET/brands/:id/topicsList topics
POST/brands/:id/topicsCreate topic
DELETE/brands/:id/topics/:topicIdDelete topic

Campaigns & Prompts

MethodEndpointDescription
GET/brands/:id/campaignsList campaigns
POST/brands/:id/campaignsLaunch campaign
GET/brands/:id/campaigns/:campaignIdCampaign status + results
GET/brands/:id/promptsList prompts (?model= ?status= ?page= ?limit=)

Visibility & Analytics

MethodEndpointDescription
GET/brands/:id/visibilitySOV, mention rate + timeline (?days=30)
GET/brands/:id/competitorsCompetitor leaderboard
GET/brands/:id/sourcesInfluential sources list

Opportunities

MethodEndpointDescription
GET/brands/:id/opportunitiesList opportunities (?status=open|in_progress|done)
PATCH/brands/:id/opportunities/:oppIdUpdate opportunity status

Avatars

MethodEndpointDescription
GET/brands/:id/avatarsList audience avatars (max 5)
POST/brands/:id/avatarsCreate avatar (PRO_PLUS+ — name, sector, role, objectives)
PATCH/brands/:id/avatars/:avatarIdUpdate avatar fields
DELETE/brands/:id/avatars/:avatarIdDelete avatar

POST /brands/:id/avatars

Create an audience avatar for a brand. Requires PRO_PLUS or Agency plan. Max 5 avatars per brand.

Request body

FieldTypeRequiredDescription
namestringYesAvatar display name (max 100 chars)
sectorstringYesIndustry or sector (max 100 chars)
rolestringYesJob role or persona type (max 100 chars)
objectivesstringYesGoals and context for this persona (max 500 chars)
descriptionstringNoOptional longer description (max 1000 chars)
isDefaultbooleanNoSet as default avatar for new campaigns (default: false)

curl

curl -X POST https://mentova.ai/api/v1/brands/BRAND_ID/avatars \
  -H "X-API-Key: mtv_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sarah, CMO",
    "sector": "SaaS B2B",
    "role": "Chief Marketing Officer",
    "objectives": "Grow brand share of voice in AI search results",
    "isDefault": true
  }'

JavaScript

const { data: avatar } = await fetch(
  `https://mentova.ai/api/v1/brands/${brandId}/avatars`,
  {
    method: "POST",
    headers: {
      "X-API-Key": "mtv_live_your_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Sarah, CMO",
      sector: "SaaS B2B",
      role: "Chief Marketing Officer",
      objectives: "Grow brand share of voice in AI search results",
      isDefault: true,
    }),
  }
).then(r => r.json());

console.log(avatar.id); // "clx..."

Response 201 Created

{
  "data": {
    "id":          "clxabc123",
    "brandId":     "clxbrand456",
    "name":        "Sarah, CMO",
    "sector":      "SaaS B2B",
    "role":        "Chief Marketing Officer",
    "objectives":  "Grow brand share of voice in AI search results",
    "description": null,
    "isDefault":   true,
    "createdAt":   "2026-04-17T10:00:00.000Z",
    "updatedAt":   "2026-04-17T10:00:00.000Z"
  }
}

Examples

Fetch visibility data

const API_KEY = "mtv_live_your_key";
const BASE = "https://mentova.ai/api/v1";

const get = (path) =>
  fetch(`${BASE}${path}`, { headers: { "X-API-Key": API_KEY } }).then(r => r.json());

// List brands
const { data: brands } = await get("/brands");
const brandId = brands[0].id;

// Visibility — last 30 days
const { data: visibility } = await get(`/brands/${brandId}/visibility?days=30`);
console.log(visibility.mentionRate, visibility.shareOfVoice);

// Competitors leaderboard
const { data: competitors } = await get(`/brands/${brandId}/competitors`);

// Open opportunities
const { data: opps } = await get(`/brands/${brandId}/opportunities?status=open`);

Manage audience avatars

// Create an audience avatar
const { data: avatar } = await fetch(`${BASE}/brands/${brandId}/avatars`, {
  method: "POST",
  headers: { "X-API-Key": API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Sarah, CMO",
    sector: "SaaS B2B",
    role: "Chief Marketing Officer",
    objectives: "Grow brand share of voice in AI search results",
    isDefault: true,
  }),
}).then(r => r.json());

// List avatars
const { data: avatars } = await fetch(`${BASE}/brands/${brandId}/avatars`, {
  headers: { "X-API-Key": API_KEY },
}).then(r => r.json());

Launch a campaign

// Get topics first
const { data: topics } = await get(`/brands/${brandId}/topics`);

// Launch campaign on first topic
const { data: campaign } = await fetch(`${BASE}/brands/${brandId}/campaigns`, {
  method: "POST",
  headers: { "X-API-Key": API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({ topicId: topics[0].id }),
}).then(r => r.json());

// Poll status
let status = campaign.status;
while (status === "running") {
  await new Promise(r => setTimeout(r, 5000));
  const { data } = await get(`/brands/${brandId}/campaigns/${campaign.id}`);
  status = data.status;
}

// Fetch prompts when done
const { data: prompts } = await get(`/brands/${brandId}/prompts?status=mentioned`);

Error codes

HTTPcodeMeaning
401MISSING_API_KEYNo key provided
401INVALID_API_KEYKey not found or revoked
403PLAN_REQUIREDAgency plan required
403FORBIDDENResource belongs to another account
404NOT_FOUNDResource not found
422VALIDATION_ERRORInvalid request body
422LIMIT_REACHEDPlan limit reached (brands, keys…)
429RATE_LIMITED60 req/min exceeded

Ready to integrate?

API access is available on the Agency plan.