GET /v1/projects/:projectId/metrics
Unified organic metrics across post, account, project, and layer scopes. One query shape, one response shape.
GET
/v1/projects/{projectId}/metricsPhase 1stable
- Auth
- Bearer
- Scope
- metrics:read
Organic metrics for anything you can identify — a single platform post, a social account, a project layer, a whole project, or your organization. scope controls what kind of thing you are asking about; id is the specific one; metrics, since, until, and granularity control what you get back.
Metrics always come back as (series, totals). series is the bucketed time series at your requested granularity; totals is the aggregate over the full window. You get both so your UI can render the chart and the big number without a second call.
For ranked creatives rather than raw time series, use GET /v1/projects/:projectId/top-performers.
Query
scopestringrequiredWhat you are asking about.One of:platform_post,social_account,project,project_layer,organizationidstringrequiredId of the scoped entity. platform_post takes a platform_post_id; social_account takes a social_account_id; project takes a project_id; project_layer takes a project_layer_id; organization takes the org id from /v1/whoami.metricsstring[]optionalWhich metrics to return. Omit for the default bundle for the scope.One of:views,reach,impressions,likes,comments,shares,saves,watch_time_ms,engagement_rate,followers,follower_delta,posts_publishedsincestring (ISO-8601)optionaldefault: 30 days agoWindow start. Inclusive.untilstring (ISO-8601)optionaldefault: nowWindow end. Exclusive.granularitystringoptionaldefault: daySeries bucket size.One of:hour,day,week
Example request
curl "https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/metrics?scope=project&id=prj_01HX9Y7K8M2P4RSTUV56789AB&metrics=views&metrics=engagement_rate&since=2026-04-01T00:00:00Z&until=2026-04-18T00:00:00Z&granularity=day" \
-H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."const params = new URLSearchParams({
scope: "project",
id: "prj_01HX9Y7K8M2P4RSTUV56789AB",
since: "2026-04-01T00:00:00Z",
until: "2026-04-18T00:00:00Z",
granularity: "day",
});
params.append("metrics", "views");
params.append("metrics", "engagement_rate");
const res = await fetch(
`https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/metrics?${params}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
const { series, totals } = await res.json();import httpx
params = [
("scope", "project"),
("id", "prj_01HX9Y7K8M2P4RSTUV56789AB"),
("since", "2026-04-01T00:00:00Z"),
("until", "2026-04-18T00:00:00Z"),
("granularity", "day"),
("metrics", "views"),
("metrics", "engagement_rate"),
]
r = httpx.get(
"https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/metrics",
params=params,
headers={"Authorization": f"Bearer {api_key}"},
)
payload = r.json()Response
200OK
{
"scope": "project",
"id": "prj_01HX9Y7K8M2P4RSTUV56789AB",
"window": {
"since": "2026-04-01T00:00:00Z",
"until": "2026-04-18T00:00:00Z",
"granularity": "day"
},
"series": [
{ "bucket": "2026-04-01", "views": 12840, "engagement_rate": 0.041 },
{ "bucket": "2026-04-02", "views": 17220, "engagement_rate": 0.052 },
{ "bucket": "2026-04-03", "views": 9880, "engagement_rate": 0.037 }
],
"totals": {
"views": 240911,
"engagement_rate": 0.047,
"post_count": 23
}
}422scope/id mismatch or unknown metric.
{ "error": { "code": "VALIDATION", "message": "Unknown metric: conversions. Use /v1/projects/:projectId/ads-metrics for paid metrics." } }404Scoped entity not found or not in your organization.
Defaults by scope
| Scope | Default metrics | Notes |
|---|---|---|
platform_post | views, likes, comments, shares, saves, engagement_rate | Single post; granularity=day or hour. |
social_account | followers, follower_delta, posts_published, views | Account-level roll-up. |
project_layer | views, engagement_rate, posts_published | Per-layer so you can compare Social Content vs Managed UGC side by side. |
project | Same as project_layer, summed across layers. | |
organization | views, posts_published across all projects. | Coarse — use for an overview pane. |
Notes
- Engagement rate is
(likes + comments + shares + saves) / max(views, 1). Platforms report each differently; we normalize before computing. watch_time_msis only populated for platforms that expose it (TikTok, Instagram Reels). Zero on static formats.- Paid metrics (spend, CPA, ROAS) live on
GET /v1/projects/:projectId/ads-metrics. Asking forspendhere returnsVALIDATION. - Windows longer than 90 days with
granularity=hourget clamped. Either narrow the window or step up today.
See also
GET /v1/projects/:projectId/ads-metrics— paid metricsGET /v1/projects/:projectId/top-performers— ranked creatives- Publish to learn — the read-side feedback loop