List a brand's recommendations
The brand's full active recommendation set (every proposed recommendation, not just the acted-on subset). Each recommendation includes its rationale (`why`), the suggested action, expected impact, measurement plan, score and score breakdown, and lifecycle timestamps (`implementedAt` is the shipped date). Each also nests `artifacts` — the generated content produced for it, including the full `body` — and `outcomes` — the measured before/after metric values with their baselines. Requires a Pro or higher plan.
/api/brands/{brand_id}/recommendations/Personal Access Token (create one from Settings -> API Keys in the dashboard). Send as Authorization: Bearer gr_live_.... An X-API-Key: gr_live_... header (see the apiKeyAuth scheme) is accepted as an equivalent alternative — send ONE of the two, not both.
In: header
Path Parameters
Query Parameters
1-based page number.
Rows per page. Server-side default/cap vary per endpoint.
Response Body
application/json
curl -X GET "https://example.com/api/brands/0/recommendations/"{ "count": 1, "next": null, "previous": null, "results": [ { "id": "3f9a1c2e-7b4d-4e2a-9c11-0a1b2c3d4e5f", "recType": "schema_gap_organization", "title": "Add Organization schema to your homepage", "status": "implemented", "priority": "high", "score": 4.4, "why": "No crawled page declares Organization structured data.", "suggestedAction": "Add a JSON-LD Organization block to the homepage head.", "expectedImpact": "Helps AI engines identify and cite the brand entity.", "measurementPlan": "Track brand mention rate over the next 30 days.", "scoreBreakdown": { "impact": 5, "effort": 2, "confidence": 4 }, "startedAt": "2026-07-01T14:03:00+00:00", "implementedAt": "2026-07-08T09:11:00+00:00", "dismissedAt": null, "dismissedReason": "", "supersededAt": null, "createdAt": "2026-06-27T09:11:00+00:00", "updatedAt": "2026-07-08T09:11:00+00:00", "artifacts": [ { "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "artifactType": "schema_jsonld", "title": "Organization JSON-LD block", "body": "<script type=\"application/ld+json\">{...}</script>", "targetUrl": "https://acme.example/", "status": "published", "generatedByModel": "claude-opus-4", "generationPromptVersion": "v3", "publishedAt": "2026-07-08T09:11:00+00:00", "createdAt": "2026-07-02T10:00:00+00:00", "updatedAt": "2026-07-08T09:11:00+00:00" } ], "outcomes": [ { "id": "b2c3d4e5-6f7a-4b8c-9d0e-1f2a3b4c5d6e", "metricName": "brand_mention_rate_overall", "metricSubject": "", "baselineValue": 42, "currentValue": 55, "baselineAt": "2026-07-08T09:11:00+00:00", "measuredAt": "2026-08-07T09:11:00+00:00", "measurementWindowDays": 30, "attributionConfidence": "medium", "isMeasured": true, "notes": "" } ] } ]}Get run status GET
The four poll-loop fields from run detail — `id`, `status`, `pollUrl`, `finishedAt` — and nothing else. Reads a single run row: no answers, no competitor or source aggregation. This is the endpoint a "is the scan finished?" loop should call.
List a brand's report artifacts GET
List artifacts for a brand. Filters: ?reportType=, ?categoryId=. Response shape (paginator-augmented): { "count": int, "next": url|null, "previous": url|null, "results": ReportArtifact[], "permissions": { "canViewReports": bool, "canGenerate": bool, "canGenerateFreeReport": bool, "hasFreeReport": bool, "reportsReady": bool, "isDemo": bool } } `permissions` is appended to the paginator response so the frontend can render the upsell card (when canViewReports=False) and decide whether to show the Generate cards (canGenerate=False on demo brands or read-only tiers) without a second round-trip.