Overview

A campaign sends a topic's prompts to one or more LLM models and extracts brand mentions from the responses. Credits are consumed at launch based on the number of prompts, models, and runs per model.

Endpoints

MethodPathDescription
GET/brands/{brandId}/campaignsList campaigns
POST/brands/{brandId}/campaignsLaunch a campaign
GET/brands/{brandId}/campaigns/{campaignId}Get campaign status

GET /brands//campaigns

List all campaigns for a brand, ordered by most recent first.

Query parameters

ParameterTypeDefaultDescription
limitinteger50Max results (capped at 200)
offsetinteger0Pagination offset
curl "https://mentova.ai/api/v1/brands/clxabc123/campaigns?limit=10" \
  -H "X-API-Key: mtv_live_your_key"

Response 200

{
  "data": [
    {
      "id": "clxcampaign1",
      "status": "COMPLETED",
      "createdAt": "2026-06-01T09:00:00.000Z",
      "completedAt": "2026-06-01T09:08:00.000Z",
      "models": ["GPT4O_MINI", "CLAUDE_HAIKU"],
      "runsPerModel": 3,
      "topic": {
        "id": "clxtopic1",
        "seed": "What is the best project management tool for remote teams?"
      },
      "_count": { "runs": 6 }
    }
  ],
  "total": 12,
  "limit": 10,
  "offset": 0
}

POST /brands//campaigns

Launch a new campaign on a topic. The campaign is processed asynchronously.

Request body

FieldTypeRequiredDescription
topicIdstringYesID of the topic to run the campaign on
modelsstring[]NoLLM model enum values to use. Defaults to the brand's selected models
runsPerModelintegerNoNumber of runs per model (1-20). Defaults to plan setting
maxPromptsintegerNoCap on prompts to include. Defaults to all topic prompts
curl -X POST https://mentova.ai/api/v1/brands/clxabc123/campaigns \
  -H "X-API-Key: mtv_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "topicId": "clxtopic1",
    "models": ["GPT4O_MINI", "CLAUDE_HAIKU"],
    "runsPerModel": 3
  }'

Response 201

{
  "data": {
    "id": "clxcampaign2",
    "status": "PENDING",
    "createdAt": "2026-06-01T10:00:00.000Z",
    "completedAt": null,
    "models": ["GPT4O_MINI", "CLAUDE_HAIKU"],
    "runsPerModel": 3,
    "topic": {
      "id": "clxtopic1",
      "seed": "What is the best project management tool for remote teams?"
    },
    "_count": { "runs": 0 }
  }
}

Error responses

HTTPcodeCause
404NOT_FOUNDTopic not found or does not belong to this brand
422QUOTA_EXCEEDEDInsufficient credits to launch the campaign
422VALIDATION_ERRORInvalid request body

GET /brands//campaigns/

Get the current status and details of a campaign. Poll this endpoint to track progress.

curl https://mentova.ai/api/v1/brands/clxabc123/campaigns/clxcampaign2 \
  -H "X-API-Key: mtv_live_your_key"

Response 200

{
  "data": {
    "id": "clxcampaign2",
    "status": "RUNNING",
    "createdAt": "2026-06-01T10:00:00.000Z",
    "completedAt": null,
    "models": ["GPT4O_MINI", "CLAUDE_HAIKU"],
    "runsPerModel": 3,
    "topic": {
      "id": "clxtopic1",
      "seed": "What is the best project management tool for remote teams?"
    },
    "_count": { "runs": 4 }
  }
}

Campaign status values

StatusDescription
PENDINGAccepted, waiting to enter the processing queue
QUEUEDPicked up by the worker, waiting for an execution slot
RUNNINGLLM calls in progress
COMPLETEDAll runs finished, mentions extracted
FAILEDProcessing error - credits are refunded
TIMEOUTWorker timed out - credits are refunded

Polling pattern

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

// Launch
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 }),
}).then(r => r.json());

// Poll until done
let status = campaign.status;
while (status === "PENDING" || status === "QUEUED" || status === "RUNNING") {
  await new Promise(r => setTimeout(r, 5000));
  const { data } = await fetch(
    `${BASE}/brands/${brandId}/campaigns/${campaign.id}`,
    { headers: { "X-API-Key": API_KEY } }
  ).then(r => r.json());
  status = data.status;
}