> ## Documentation Index
> Fetch the complete documentation index at: https://docs.verseodin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Brands — mentions, citations, ranking

> Per-brand cross-cut of the data — your brand and every competitor on one row each.

The `/universes/{id}/brands` and `/universes/{id}/brands/{brand}`
endpoints expose a **brand-centric view** of your dashboard data.
Instead of querying `ai_visibility_ranking`, then
`ai_competitive_analysis`, then `geo_competitor_analysis` and joining
them by `brand_name` yourself, the API does it for you.

## What's on a brand row

Every entry in the response carries seven numbers — three from AI
mentions, two from GEO citations, plus rank and share-of-voice. Your
own brand sits in the same array as every competitor.

<ResponseField name="brand_name" type="string">
  Display name as it appears in the underlying history arrays.
  Preserves casing.

  **Example:** `"verseodin.com"`, `"Semrush"`, `"tryprofound.com"`
</ResponseField>

<ResponseField name="trust_mentions" type="integer">
  Count of prompts where the AI mentioned this brand by name in its
  answer. Drawn from `ai_visibility_ranking`.

  **Range:** `0` to `total_prompts` for the universe.
</ResponseField>

<ResponseField name="share_of_voice" type="number">
  This brand's mentions as a percentage of total brand mentions in
  the universe. The `share_of_voice` values across all brands sum to
  \~100% (rounding aside).

  **Example:** `18.7` means this brand accounts for \~19% of brand
  mentions across the universe.
</ResponseField>

<ResponseField name="visibility_rank" type="integer">
  1-indexed rank among all tracked brands by `trust_mentions`. `1` is
  the most-mentioned brand. Ties are broken by alphabetical order of
  `brand_name`.

  **Tip:** if your brand's rank goes from 3 → 1 over a week, that's
  the win you want to track.
</ResponseField>

<ResponseField name="ai_coverage_pct" type="number">
  Percentage of prompts where the AI mentioned this brand. Drawn from
  `ai_competitive_analysis.coverage_pct`.

  **Difference vs trust\_mentions:** `ai_coverage_pct` is the *rate*
  (`mentions / total_prompts × 100`); `trust_mentions` is the *count*.
</ResponseField>

<ResponseField name="geo_coverage_pct" type="number">
  Percentage of prompts where the AI **cited a URL** belonging to
  this brand's domain. Independent of whether the brand was named in
  the prose. Drawn from `geo_competitor_analysis.coverage_pct`.
</ResponseField>

<ResponseField name="geo_prompt_count" type="integer">
  Count of prompts where this brand's domain was cited at least once.
  Drawn from `geo_competitor_analysis.prompt_count`.
</ResponseField>

## Three things this view answers in one call

### "How is my own brand doing?"

```bash theme={null}
KEY=vso_xxx
UNI=7f45877a-0e8e-498f-bd7f-5e70ef65a2de

curl -H "Authorization: Bearer $KEY" \
  "https://verseodin.com/api/v1/universes/$UNI/brands/verseodin.com"
```

```json theme={null}
{
  "data": {
    "brand_name": "verseodin.com",
    "trust_mentions": 42,
    "share_of_voice": 18.7,
    "visibility_rank": 1,
    "ai_coverage_pct": 32.5,
    "geo_coverage_pct": 12.0,
    "geo_prompt_count": 60,
    "day": "2026-04-27",
    "engine": "chatgpt"
  }
}
```

### "How is competitor X doing?"

Same call, just swap the brand name:

```bash theme={null}
curl -H "Authorization: Bearer $KEY" \
  "https://verseodin.com/api/v1/universes/$UNI/brands/semrush.com"
```

### "Show me the leaderboard"

The list endpoint sorts by visibility\_rank ASC — top of the array is
the most-mentioned brand:

```bash theme={null}
curl -H "Authorization: Bearer $KEY" \
  "https://verseodin.com/api/v1/universes/$UNI/brands"
```

```json theme={null}
{
  "data": [
    { "brand_name": "verseodin.com",   "trust_mentions": 42, "visibility_rank": 1, ... },
    { "brand_name": "semrush.com",     "trust_mentions": 25, "visibility_rank": 2, ... },
    { "brand_name": "tryprofound.com", "trust_mentions": 14, "visibility_rank": 3, ... }
  ],
  "day": "2026-04-27",
  "engine": "chatgpt"
}
```

## Filtering

Both endpoints accept the standard `?day=` and `?engine=` query
params:

```bash theme={null}
# Brand snapshot for a specific past day
curl ".../brands?day=2026-04-26"

# Filter to a specific engine (when you have multi-engine data)
curl ".../brands?engine=chatgpt"
```

If multiple history rows match the filter (e.g. you don't pass
`engine=` and the universe has multiple engines), the **most recent
one is used**. The response's `day` + `engine` fields tell you which
row was actually consulted, so you can detect this.

## When a brand isn't found

The single-brand endpoint returns `404 not_found` when:

* The brand name doesn't appear in any of the three source arrays for the matched history row, OR
* No history row matches the day/engine filters

The list endpoint returns `200` with `data: []` and `day: null`,
`engine: null` if the filters match no history row at all.

## How this maps onto the raw history columns

If you want to do this synthesis yourself instead of using these
endpoints, here are the three source columns:

| Field on `BrandSummary`                               | Source column on `history`                                   |
| ----------------------------------------------------- | ------------------------------------------------------------ |
| `trust_mentions`, `share_of_voice`, `visibility_rank` | `ai_visibility_ranking[]`                                    |
| `ai_coverage_pct`                                     | `ai_competitive_analysis[].coverage_pct`                     |
| `geo_coverage_pct`, `geo_prompt_count`                | `geo_competitor_analysis[].coverage_pct` and `.prompt_count` |

Match `brand_name` case-insensitively across the three arrays.
