List Outcomes
Get outcome events with milestone tracking data. This is the learning-loop read endpoint.
GET
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
brand_idstringrequiredThe brand UUID.
Response
{
"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
curl -H "X-API-Key: $BM_API_KEY" \
https://api.boringmarketing.com/brands/$BRAND_ID/outcomes
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).