---
title: "Portfolio rollup across all your apps (Agency plan)"
method: GET
path: "/api/v1/portfolio"
tags: ["Workspace"]
---

# Portfolio rollup across all your apps (Agency plan)

`GET /api/v1/portfolio`

## Request

- Base URL: `https://api.trysonar.app`
- URL: `https://api.trysonar.app/api/v1/portfolio`
- Auth: HTTP bearer

The whole portfolio's health in one call: per-app KPIs (visibility + matched-cohort 7-day delta, ranked/top-10 counts, net rank movement, rating), org-wide totals, biggest keyword movers both directions, a needs-attention triage list (visibility_drop / rating_drop / not_ranked signals), and the best discovered-keyword opportunities across apps. Same numbers as the /portfolio page. Requires an Agency plan — 403 on other plans. Keyword rows carry `popularity`, `popularity_source`, `popularity_apple` and `popularity_proxy` — the same values the dashboard shows (see the PopularityFields schema).

## Response `200`

{ kpis, apps[], movers_up[], movers_down[], attention[], opportunities[] }

- object
  - `data` object, required: Result payload — full field reference at https://trysonar.app/docs/api

## Other responses

- `400`: Missing or invalid request parameters
- `401`: Missing or invalid API key
- `403`: forbidden — the portfolio rollup requires an Agency plan
- `429`: Rate limited — see `error.reason`: daily_limit (Indie 1,000, Agency 5,000, trial 150 requests/day, resets 00:00 UTC; see `reset_at`), anonymous_daily_limit / batch_too_large (keyless free tier), store_rate_limited or concurrency_limit (transient, honor `retry_after_seconds`)
- `500`: Unexpected server error

---

[API](https://skmtc.dev/trysonar/apis/sonar-api.md) · [All operations](https://skmtc.dev/trysonar/apis/sonar-api/llms.txt) · [OpenAPI document](https://skmtc.dev/trysonar/apis/sonar-api/revisions/bf1d31dadd5f?raw)
