---
title: List Outcomes
api: GET /brands/{brand_id}/outcomes
description: "Get outcome events with milestone tracking data. This is the learning-loop read endpoint."
---

> **For AI agents:** the complete documentation index is at [llms.txt](https://docs.boringmarketing.com/llms.txt). Append `.md` to any page URL for its markdown version.

Returns all recorded outcome events for a brand, joined with their 7/30/90-day milestone observation data. This is the read side of the learning loop — the write side is `POST /track/outcomes/report`.

## Path parameters

<ParamField path="brand_id" type="string" required>
  The brand UUID.
</ParamField>

## Response

```json
{
  "brand_id": "brand-uuid",
  "total": 12,
  "outcomes": [
    {
      "id": "outcome-uuid",
      "brand_id": "brand-uuid",
      "content_url": "https://yourdomain.com/article",
      "keyword": "ai marketing tools",
      "published_at": "2026-03-07T10:00:00Z",
      "opportunity_id": "opp-uuid",
      "brief_id": "brief-uuid",
      "execution_id": "exec-uuid",
      "run_id": "run-uuid",
      "rank_at_publish": null,
      "days_since_publish": 32,
      "status": "tracking",
      "observed_7d": {
        "milestone_days": 7,
        "rank": 14,
        "rank_delta": null,
        "citations_total": 2,
        "citations_by_platform": { "chat_gpt": 2 },
        "citation_delta": null,
        "aio_present": null,
        "checked_at": "2026-03-14T10:00:00Z"
      },
      "observed_30d": {
        "milestone_days": 30,
        "rank": 6,
        "rank_delta": null,
        "citations_total": 5,
        "citations_by_platform": { "chat_gpt": 5 },
        "citation_delta": null,
        "aio_present": null,
        "checked_at": "2026-04-06T10:00:00Z"
      },
      "observed_90d": null
    }
  ]
}
```

Milestone slots (`observed_7d`, `observed_30d`, `observed_90d`) are top-level fields on the outcome — not nested under a `milestones` object. A slot is `null` until the milestone has been observed; populated slots have the shape shown above.

| Field | Notes |
|---|---|
| `rank_at_publish` | The brand's organic rank for `keyword` at publish time. **Currently always `null`** — there is no write site that captures this baseline yet. Wired into the response so the contract is stable for when the baseline-capture follow-up lands. |
| `rank_delta` | Computed as `rank - rank_at_publish` when both are present. **Always `null` today** because `rank_at_publish` is never populated. |
| `citation_delta` | **Always `null`.** There is no `citations_at_publish` baseline column yet — `citation_delta` is reserved for the same baseline-capture follow-up. Do not infer "no change" from `null`. |
| `citations_by_platform` | Dict keyed by platform name. **Automated milestone checks via `POST /outcomes/check` only query `chat_gpt` today** (the `MENTION_PLATFORMS` constant in the milestone checker is hardcoded to `("chat_gpt",)`), so the dict will normally only contain that key on auto-checked milestones. The schema still tolerates additional keys for future expansion. |
| `aio_present` | `null` unless explicitly observed. AI Overview detection is opt-in, not default. |
| `status` | Always `"tracking"` on auto-generated rows. The status field exists for future state transitions; the API does not transition it today. |

## Example

```bash
curl -H "X-API-Key: $BM_API_KEY" \
  https://api.boringmarketing.com/brands/$BRAND_ID/outcomes
```

<Tip>
Pair this with `POST /brands/{id}/outcomes/check` to trigger milestone checks for any overdue outcomes (those past 7/30/90 days since the `completed` event).
</Tip>
