# Get cross-platform analytics > Markdown version of https://docs.postlake.dev/api/get-analytics . The canonical page for humans. > PostLake is the social media API for AI agents: https://postlake.dev/llms.txt `GET /v1/analytics` Read private saved reports for all collected destinations, without a 50-post sample or live provider calls. Cold or invalidated reports use a globally limited read-only builder; busy admission returns 429 with Retry-After: 60 and database failures return 503. Same-filter saved results can be retained with snapshot.stale=true. measuredAt is collection time and snapshot.generatedAt is preparation time. Production reads check the durable generation directly, without an additional edge-cache delay after collection completes. Period mode reports observed counter growth, including older content; Content mode reports lifetime performance of content published in the range. Totals, current, chart and breakdown share mode and filters. Rankings contain up to twenty destinations. POST /v1/analytics/refresh queues collection; GET that route reports progress. GET /v1/analytics/methodology defines reconciliation and freshness. ## Request Authenticate with a bearer API key. Agents calling over MCP authorise with OAuth instead and never handle the key. ```bash curl -X GET https://api.postlake.dev/v1/analytics \ -H "Authorization: Bearer $POSTLAKE_API_KEY" ``` ### Parameters | Field | Type | Required | What it is | | --- | --- | --- | --- | | `period` | string | No | Query string. | | `profile` | string | No | Query string. Profile username. Omit for the whole workspace. | | `mode` | string | No | Query string. Observed period activity, or lifetime performance of content published in the range. | | `sort` | string | No | Query string. Rank the complete matching destination population before limiting to 20. Unavailable readings sort last. Rates require a positive reported audience count. | | `channel` | string | No | Query string. Connected social account ID. Shared posts contribute only matching destinations. | | `network` | string | No | Query string. Optional platform name. | | `from` | string | No | Query string. Inclusive first UTC date, YYYY-MM-DD. | | `to` | string | No | Query string. Inclusive last UTC date, YYYY-MM-DD. Maximum range 365 days. | | `agent` | string | No | Query string. Stable creator client ID, not display name. Unknown historical attribution is not inferred. | | `origin` | string | No | Query string. Recorded interface, separate from creator identity. Account-wide supplements are omitted for actor/interface filters. | ## Response Success (`200`). | Field | Type | Required | What it is | | --- | --- | --- | --- | | `period` | string | Yes | | | `since` | string | Yes | | | `mode` | string (period, content) | No | | | `until` | string | No | | | `measuredAt` | string | No | | | `snapshot` | object | No | Private saved report metadata. generatedAt is report preparation, not metric collection. stale means rebuilding failed or a newer collection invalidated this report. | | `snapshot.generatedAt` | string | Yes | | | `snapshot.stale` | boolean | Yes | | | `rankingScope` | string | No | | | `rankingMetric` | string (views, likes, comments, engagement, engagementRate, impressions, clicks) | No | | | `averageViews` | object | No | Content mode only: lifetime views divided by destinations explicitly reporting views. Includes measured zeros, excludes unknown readings. A shared post counts once per destination. | | `averageViews.value` | number | Yes | | | `averageViews.destinations` | integer | Yes | | | `nativeExtrasBasis` | string | No | Supplemental native extras are lifetime counters, never period activity. | | `posts` | integer | Yes | Distinct posts with collected readings published in the range, not every published post. | | `totals` | object | Yes | | | `methodologyUrl` | string | No | Machine-readable metric and reconciliation definitions. | | `current` | object | No | Selected-mode totals for the requested window. Period: observed activity. Content: lifetime results of published content. | | `previous` | object | No | Same mode and filters in the preceding equal-length window. Null means no usable observations. | | `timeseries` | array of object | No | UTC daily observed growth in Period mode, or lifetime results by publication date in Content mode. Includes likes, comments and engagementRate. A daily rate is null without usable audience counts, not zero. | | `byChannel` | array of object | No | One row per actual connected social account. Account-wide insights are separate from post totals. fieldCoverage includes readings, unknown legacy readings and per-counter returned counts from latest observations scoped by observation date (Period) or publication date (Content), not historical daily coverage. | | `topPosts` | array of object | No | Up to 20 ranked destinations across the complete matching population, with optional thumbnailUrl. A shared post can appear more than once. | | `derived` | object | No | Engagement, blended engagement rate and CTR. See methodology for denominators. | | `byPlatform` | array of object | Yes | | ### Example ```json { "period": "…", "since": "2026-08-16T07:00:00Z", "mode": "period", "until": "…", "measuredAt": "2026-08-16T07:00:00Z", "snapshot": { "generatedAt": "2026-08-16T07:00:00Z", "stale": false }, "rankingScope": "…", "rankingMetric": "views" } ``` ## Calling this from an agent Agents do not call REST. They call tools. Over the hosted MCP server this operation is `get_analytics`, and the agent authorises with OAuth so your API key is never pasted into a chat or seen by the model. You control what any one agent may do: which brands it may act for, which networks it may reach, how much a day, and whether it may spend credits bought up front. ## Errors Every failure uses one shape: a stable `type`, a granular `code`, the field at fault in `param`, and a plain-language `fix`. See https://docs.postlake.dev/errors.md . Check the result before retrying a write. Only operations that explicitly support idempotency can safely replay an `Idempotency-Key`. ## Common questions **Can an AI agent do this without the REST API?** Yes. Over MCP the same job is the get_analytics tool. The agent authorises with OAuth, so no API key is pasted into a chat or seen by the model, and the answer comes back in the same normalised shape. **How often can I call this?** Reads are rate limited per account and every response carries X-RateLimit-Remaining and X-RateLimit-Reset. On a 429 the Retry-After header tells you how long to wait. **What happens when it fails?** You get one error shape: a stable type, a granular code you can branch on, the offending field in param, and a fix written so an agent can correct itself rather than stop. Full list on Errors and retries. ## Related - [Read analytics methodology](https://docs.postlake.dev/api/get-analytics-methodology.md) `GET /v1/analytics/methodology` - [Get analytics refresh progress](https://docs.postlake.dev/api/get-analytics-refresh.md) `GET /v1/analytics/refresh` - [Get post analytics](https://docs.postlake.dev/api/get-posts-by-id-analytics.md) `GET /v1/posts/{id}/analytics` - [Request background analytics refresh](https://docs.postlake.dev/api/post-analytics-refresh.md) `POST /v1/analytics/refresh`