1. What it is
Whoever owns a set of data in Manager.Social ticks the numbers they are willing to share. A receiving system logs in, asks for those numbers for any date range, and gets them as JSON, XML or CSV. It never has to know the numbers in advance: a catalogue tells it every number's name, unit and meaning, and a dry run returns the exact shape of a real answer with zeros in it, so you can build and test your mapping before any real data flows.
A data client is one receiver's credentials, with a scope (the platform, an organisation or a workspace — fixed when the client is created, never taken from your request), a selection (which metrics and breakdowns were ticked) and settings (token lifetime, freshness, timezone, currency mode, formats). The data owner creates and manages clients in their console; you receive a client id and a secret, shown once.
Common rules
- Base URL
https://manager.social/metrics-exchange/v1. HTTPS only. - Every response carries
X-Request-Id. Every data document carriesquery_id. - Every endpoint except
/tokenand/token/revokerequiresAuthorization: Bearer <token>; those two authenticate with the client id and secret. - Every timestamp is ISO 8601 with offset. Dates in requests are interpreted in the client's timezone. Week grouping starts on Monday (ISO 8601).
- Choose the format with the
format=json|xml|csvquery parameter, orAccept: application/json | application/xml | text/csv. Default JSON. Errors are always Problem Details JSON regardless of the requested format. - Version 1 only ever changes by adding. A breaking change would be a new
/v2/path.
2. The five doors
In the order a receiver uses them:
| Door | Question it answers |
|---|---|
POST /token | Who are you? |
GET /health | Are we connected, and is my setup what I think it is? |
GET /time | What is "today" on your side, exactly? |
GET /catalogue | What can I ask for, and what does each thing mean? |
GET /data / POST /data | Give me the numbers. |
Your only write is POST /token/revoke, to kill a token you believe has leaked; everything else about a client (selection, secrets, deletion) belongs to the data owner's console.
GET /health
Besides uptime, /health reports your client's setup, so you can verify your configuration on every heartbeat.
{
"status": "ok",
"contract": "metrics-exchange/1",
"provider": "example.provider",
"server_time": "2026-10-16T05:07:05Z",
"data_as_of": "2026-10-16T05:05:00Z",
"client": {
"name": "BI production",
"scope": { "level": "platform", "id": null, "name": "Example" },
"metrics_enabled": 9,
"formats": ["json", "xml", "csv"],
"freshness_seconds": 300,
"token_lifetime_seconds": 3600,
"timezone": "Asia/Kolkata"
}
}status: ok, degraded (data delayed beyond freshness), down. When metrics_enabled changes, refetch /catalogue.
3. Tokens
POST /token
OAuth 2 client credentials (RFC 6749 §4.4). Form or JSON: grant_type=client_credentials, client_id, client_secret.
curl -s -X POST 'https://manager.social/metrics-exchange/v1/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>'{ "access_token": "mx_at_…", "token_type": "Bearer", "expires_in": 3600, "scope": "metrics:read" }- Tokens are opaque; do not parse them. Renew before
expires_in. - Token lifetime is set per client, 5 minutes to 24 hours, default 1 hour.
- A revoked client's tokens die immediately.
- Requests are limited per caller (20 per minute, IP + client id) and, on top, per address (60 per minute across
/tokenand/token/revoke, whatever the client id) →RATE_LIMITEDwithRetry-After. - While the administrator switch for every level is off, every client gets
INVALID_CLIENTwithout its credentials being checked.
POST /token/revoke
RFC 7009. Form or JSON: token, plus client_id and client_secret. The answer is always 200 {}, even for an unknown token — except past the per-caller limit (20 per minute) or the per-address limit (60 per minute across /token and /token/revoke), which answer 429 RATE_LIMITED with Retry-After.
curl -s -X POST 'https://manager.social/metrics-exchange/v1/token/revoke' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'token=<token>&client_id=<client_id>&client_secret=<client_secret>'4. Time windows
GET /time returns the provider clock, your client's timezone, data_as_of and the exact resolved window for every shortcut. /data echoes the same period, so "today" means the same thing on both sides.
{
"server_time": "2026-10-16T10:37:05+05:30",
"server_time_utc": "2026-10-16T05:07:05Z",
"timezone": "Asia/Kolkata",
"utc_offset": "+05:30",
"data_as_of": "2026-10-16T10:35:00+05:30",
"week_starts_on": "monday",
"shortcuts": {
"today": { "from": "2026-10-16T00:00:00+05:30", "to": "2026-10-17T00:00:00+05:30" },
"yesterday": { "from": "2026-10-15T00:00:00+05:30", "to": "2026-10-16T00:00:00+05:30" },
"this_week": { "from": "2026-10-12T00:00:00+05:30", "to": "2026-10-19T00:00:00+05:30" },
"last_7_days": { "from": "2026-10-09T00:00:00+05:30", "to": "2026-10-16T00:00:00+05:30" },
"this_month": { "from": "2026-10-01T00:00:00+05:30", "to": "2026-11-01T00:00:00+05:30" },
"last_month": { "from": "2026-09-01T00:00:00+05:30", "to": "2026-10-01T00:00:00+05:30" }
}
}- Optional
?timezone=<IANA>if the client allows overrides; the shortcuts are then resolved in that zone. tois always exclusive.last_7_daysexcludes today;this_weekandthis_monthinclude it.date=2026-10-15is exactly that day in the client’s timezone — the simplest way to ask for one day’s numbers.- Call
/timeonce a day, and after any clock or daylight-saving doubt.
5. Catalogue & metrics
GET /catalogue lists only the metrics and breakdowns ticked for your client. Every metric carries a sample_point — a point of the right kind with zero values — so you can map fields from the catalogue alone.
{
"contract": "metrics-exchange/1",
"provider": "example.provider",
"scope": { "level": "organisation", "id": "org_…", "name": "Acme Ltd" },
"timezone": { "default": "Asia/Kolkata", "override_allowed": true },
"currency_mode": "single",
"currency": "USD",
"groupings": ["hour", "day", "week", "month"],
"shortcuts": ["today", "yesterday", "this_week", "last_7_days", "this_month", "last_month"],
"formats": ["json", "xml", "csv"],
"limits": { "max_points": 10000, "requests_per_day": 1000 },
"template": "revenue",
"metrics": [
{
"id": "revenue", "version": 1,
"label": "Revenue",
"description": "Successful payments in the period, in USD at time of purchase. Includes test payments.",
"unit": "currency", "kind": "sum",
"breakdowns": ["region"],
"status": "active", "available_from": "2026-01-01", "withdrawn_on": null,
"sample_point": { "start": "…", "end": "…", "value": "0.00", "currency": "USD", "final": false, "breakdown": null }
}
]
}unit∈count,currency,percent,seconds,bytes.kind∈count,sum,distinct,ratio,gauge. Onlycountandsummay be summed across periods;ratiosendsnumeratoranddenominator;gaugeis a value at period end.currency_modeissingle(withcurrency) orper_currency. Money is a decimal string and always carries its currency.templatenames the template the client started from, ornull; it is informational only.- Ids are permanent and carry a definition
version: a changed meaning is a new id. Withdrawn metrics get 30 days' notice throughwithdrawn_onandnotices. - Ranges before a metric's
available_fromreturnRANGE_BEFORE_AVAILABLE, never a silent zero.
Metrics Manager.Social offers
Every metric below is version 1 and includes all data, including test and internal accounts. Your catalogue shows only the ones ticked for your client and allowed at its scope.
| Id | Label | Kind / unit | Description | Scopes | Breakdowns | Available from |
|---|---|---|---|---|---|---|
signups | Signups | count / count | User accounts created in the period, in any status, including soft-deleted ones; accounts permanently erased later (GDPR or purge) are no longer counted. Breakdowns (MS-577): country, source and channel come from sign-up tracking, recorded from 2026-10-13 (older accounts: unknown); method is form or the sign-in provider (google). | Platform | country, source, channel, method | 2026-03-06 |
companies_created | Companies created | count / count | Companies created in the period, in any status, including soft-deleted ones; companies permanently erased later (purge) are no longer counted. | Organisation | — | 2026-03-06 |
members_joined | Members joined | count / count | People added to a company in the period, by invitation or added directly, who are still recorded as members; removed members are no longer counted. | Organisation, Workspace | company | 2026-03-06 |
invites_sent | Invitations sent | count / count | Company invitations sent in the period, whatever happened to them later. | Organisation, Workspace | company | 2026-03-06 |
credit_purchases | Credit purchases | count / count | Completed credit-pack payments in the period. Counted when the payment completed; purchases made before 2026-10-16 use the order time. | Platform, Organisation | — | 2026-06-15 |
credits_purchased | Credits bought | sum / count | Credits bought through completed credit-pack payments in the period. Counted when the payment completed; purchases made before 2026-10-16 use the order time. | Platform, Organisation | — | 2026-06-15 |
payments | Payments | sum / currency | Amount paid for completed credit packs in the period, in the currency recorded at payment time. Counted when the payment completed; purchases made before 2026-10-16 use the order time. | Platform, Organisation | — | 2026-06-15 |
credits_spent | Credits spent | sum / count | Credits charged for features in the period, before refunds. | Platform, Organisation, Workspace | company | 2026-06-09 |
credits_refunded | Credits refunded | sum / count | Credits given back after a failed or cancelled feature run in the period. | Platform, Organisation, Workspace | company | 2026-06-10 |
accounts_approved | Accounts approved | count / count | Sign-up approvals recorded in the period, by a Super Admin or automatically (auto-approve on). Breakdown method: manual or auto. Approval history is recorded from 2026-09-04. | Platform | method | 2026-09-04 |
accounts_rejected | Accounts rejected | count / count | Sign-ups rejected by a Super Admin in the period. Approval history is recorded from 2026-09-04. | Platform | — | 2026-09-04 |
approval_rate | Approval rate | ratio / percent | Approved sign-ups (manual and automatic) as a share of all approval decisions made in the period; numerator = approved, denominator = approved + rejected. 0/0 when no decision was made. Never add percentages across periods; add numerators and denominators. | Platform | — | 2026-09-04 |
approvals_pending | Pending approvals | gauge / count | Self-signup accounts waiting for approval at the end of each period (for a period still running: now). An account counts from its sign-up until its approve or reject decision; accounts deleted while waiting stop counting when deleted. A value at a point in time: never add it across periods. | Platform | — | 2026-09-04 |
administrators_total | Administrators | gauge / count | Self-signup administrator accounts that existed at the end of each period (for a period still running: now), in any status; deleted accounts stop counting when deleted, permanently erased ones are no longer counted at all. A value at a point in time: never add it across periods. | Platform | — | 2026-03-06 |
active_administrators | Active administrators | distinct / count | Self-signup administrators who signed in or used the app (a session refresh) at least once in the period; each one counts once per period. Recorded from 2026-11-05. Never add it across periods: the same person is counted in each. | Platform | — | 2026-11-05 |
administrators_suspended | Suspended administrators | gauge / count | Self-signup administrators who were suspended at the end of each period (for a period still running: now): their last suspend or reactivate before that moment was a suspend. An account suspended before suspensions were recorded (2026-10-23) counts from its suspension time while it is still suspended. A value at a point in time: never add it across periods. | Platform | — | 2026-10-23 |
credits_held | Credits held | gauge / count | Credits sitting in all wallets at the end of each period (for a period still running: now), from each wallet's last ledger balance. A value at a point in time: never add it across periods. | Platform | — | 2026-06-09 |
credits_allocated | Credits allocated | sum / count | Credits added to wallets in the period, other than refunds and adjustments. Breakdown source: signup (free credits on sign-up), bought (credit-pack purchase), reseller (from a reseller), grantedBySuperAdmin (every other allocation). The same rule as the Super Admin credits page. | Platform | source | 2026-06-09 |
credit_adjustments | Credit adjustments | sum / count | Net credits changed by manual adjustments in the period: added minus removed, so the value can be negative. Breakdown direction: adjustedIn, adjustedOut (negative), returnedToReseller (negative). | Platform | direction | 2026-06-09 |
refund_rate | Refund rate | ratio / percent | Credits refunded as a share of credits spent in the same period; numerator = credits refunded, denominator = credits spent. A refund counts in the period it was made, even when the charge was earlier. 0/0 when nothing was spent. | Platform | — | 2026-06-10 |
payments_failed | Failed payments | count / count | Credit-pack orders that ended as failed, counted by order time. An order can still be recovered later by the payment check. | Platform | — | 2026-06-15 |
agencies_created | Agencies created | count / count | Agencies created in the period, in any status, including soft-deleted ones. | Platform | — | 2026-10-01 |
reseller_applications | Reseller applications | count / count | Reseller applications received in the period. Breakdown status: the application's status now (PENDING, APPROVED, REJECTED…). | Platform | status | 2026-10-20 |
wrapped_purchases | Reseller stock purchases | count / count | Completed purchases of wrapped (reseller) credit stock in the period, counted when the payment completed. | Platform | — | 2026-10-20 |
wrapped_credits_sold | Reseller credits sold | sum / count | Wrapped credits (including bonus credits) in completed reseller stock purchases in the period. | Platform | — | 2026-10-20 |
wrapped_payments | Reseller payments | sum / currency | Amount paid for completed reseller stock purchases in the period, in the currency recorded at payment time. | Platform | — | 2026-10-20 |
contact_inquiries | Contact inquiries | count / count | Messages received through the public contact form in the period, including ones deleted later. Breakdown inquiry_type: the type picked on the form. | Platform | inquiry_type | 2026-03-06 |
provider_calls | Data provider calls | count / count | Calls made to outside data providers (DataForSEO, Google Search Console, GA4, PageSpeed …) in the period, whatever their result. Breakdown provider. Recorded from 2026-10-27. | Platform | provider | 2026-10-27 |
emails_sent | Emails sent | count / count | Emails the platform handed to the email provider in the period, whatever happened to them later. Breakdown purpose: what the email was for (password reset, sign-up code …). | Platform | purpose | 2026-09-01 |
emails_delivered | Emails delivered | count / count | Emails sent in the period that the provider reported as delivered (or opened). Needs the WiredMessage delivery webhook to be set up: an email with no delivery report yet is not counted, so the number can rise after the period ends. | Platform | purpose | 2026-11-05 |
emails_failed | Emails failed | count / count | Emails sent in the period that the provider reported as failed, bounced or rejected. Needs the WiredMessage delivery webhook to be set up: an email with no delivery report yet is not counted, so the number can rise after the period ends. | Platform | purpose | 2026-11-05 |
maintenance_downtime | Planned maintenance time | sum / seconds | Seconds of planned maintenance inside the period: the part of each maintenance window (start to its real end, or its planned end while running) that falls in the period, up to now. | Platform | — | 2026-10-19 |
6. Data
GET /data and POST /data take the same parameters; POST takes them as a JSON body, for long metric lists.
| Parameter | Meaning |
|---|---|
metrics | Required. Comma-separated ids (JSON array on POST), or * for every ticked metric. |
date | One calendar date (YYYY-MM-DD) in the client’s timezone: that whole day. Give it alone, not with range or from/to. |
from, to | Date or date-time in the client’s timezone; to is exclusive. Or range=<shortcut>, or date=<day>. |
range | A shortcut instead of from/to: today, yesterday, this_week, last_7_days, this_month, last_month. |
group | hour, day, week, month, or omitted for one total per metric. |
breakdown | One breakdown name. Optional. |
timezone | IANA zone, if overrides are allowed. |
format | json, xml, csv. |
dry_run | true returns the document shape with zero values and no database work. |
page | Opaque cursor from next_page. |
curl -s 'https://manager.social/metrics-exchange/v1/data?metrics=signups,credits_spent&range=last_7_days&group=day' \
-H 'Authorization: Bearer <token>'curl -s -X POST 'https://manager.social/metrics-exchange/v1/data' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{ "metrics": ["signups", "credits_spent"], "from": "2026-10-01", "to": "2026-10-08", "group": "day" }'Shortcuts, grouping and breakdowns
- Shortcuts:
today,yesterday,this_week,last_7_days,this_month,last_month. Giverangeorfrom/to, never both (INVALID_RANGE). group:hour,day,week(Monday start),month; omitted gives one total per metric.breakdownsplits a metric by one dimension it offers (see the catalogue). Breakdown points carry"breakdown": { "name": "company", "value": "…" }; groups smaller than 5 merge into"Other".- A point may carry a note such as
unconverted_countwhen part of a sum could not be expressed in the reporting currency; notes never replace the value.
Dry run
dry_run=true returns the full document for the requested metrics and range with zero values and "dry_run": true, without touching the database. A dry run counts as 0.1 of a request against the daily limit. Test your pipeline with it before go-live.
JSON (master shape)
{
"contract": "metrics-exchange/1",
"query_id": "mxq_01J…",
"dry_run": false,
"provider": "example.provider",
"scope": { "level": "workspace", "id": "ws_…", "name": "Northern region" },
"generated_at": "2026-10-16T10:37:05+05:30",
"data_as_of": "2026-10-16T10:35:00+05:30",
"timezone": "Asia/Kolkata",
"period": { "from": "2026-10-16T00:00:00+05:30", "to": "2026-10-17T00:00:00+05:30", "group": "day", "range": "today" },
"metrics": [
{ "id": "orders", "version": 1, "label": "Orders", "unit": "count", "kind": "count",
"points": [ { "start": "2026-10-16T00:00:00+05:30", "end": "2026-10-17T00:00:00+05:30", "value": "412", "final": false, "breakdown": null } ] },
{ "id": "fulfilment_rate", "version": 1, "label": "Fulfilment rate", "unit": "percent", "kind": "ratio",
"points": [ { "start": "…", "end": "…", "value": "93.10", "numerator": "384", "denominator": "412", "final": false, "breakdown": null } ] }
],
"notices": [ { "metric": "old_metric", "type": "withdrawn", "on": "2026-11-15" } ],
"next_page": null
}XML
The same tree with fixed element names, validated by /schema.xsd. <next_page> appears only when a next page exists; a point's optional fields are child elements <currency>, <numerator>, <denominator>, <unconverted_count> and <breakdown name="…" value="…"/> after <value>; notices are <notice metric="…" type="…" on="…"/>. Content type application/xml; charset=utf-8.
<?xml version="1.0" encoding="UTF-8"?>
<metrics-exchange contract="1">
<query_id>mxq_01J…</query_id> <dry_run>false</dry_run> <provider>example.provider</provider>
<scope level="workspace" id="ws_…" name="Northern region"/>
<generated_at>…</generated_at> <data_as_of>…</data_as_of> <timezone>Asia/Kolkata</timezone>
<period from="…" to="…" group="day" range="today"/>
<metrics>
<metric id="orders" version="1" label="Orders" unit="count" kind="count">
<point start="…" end="…" final="false"><value>412</value></point>
</metric>
</metrics>
<notices/>
</metrics-exchange>CSV
Long format, one row per point, UTF-8 without BOM, LF line endings, booleans true/false, content type text/csv; charset=utf-8. An empty cell means not applicable. CSV has no notices; poll JSON or watch /health for them. The header row:
query_id,dry_run,metric_id,metric_version,label,unit,kind,start,end,value,currency,numerator,denominator,final,breakdown_name,breakdown_value,timezone,data_as_ofFormats
format= wins over Accept. An unknown format= value, or a format not enabled for your client, is 406 FORMAT_NOT_ALLOWED; an Accept header naming none of the three media types falls back to JSON.
Paging
A response holds at most 10,000 points, and larger answers are paged. A request whose grouping alone would need more points fails with TOO_MANY_POINTS, carrying a suggested_group (a coarser grouping that fits). When there is more, the JSON next_page (XML <next_page>) holds an opaque cursor, and every format also sends it in headers:
X-Next-Page: <cursor>
Link: <…/data?<the same query>&page=<cursor>>; rel="next"A cursor is valid only with the same query: repeat the query with page=<cursor> (the Link header already does). A paged answer is a snapshot valid for 15 minutes; an expired or mismatched next_page cursor returns INVALID_RANGE — restart from the first page.
Receiver rules
- Upsert on (metric id,
start, breakdown); never append. - Treat
final: falseas provisional, andfinal: trueas closed but not frozen — it can still decrease when source rows are permanently erased. - Never sum
distinct,ratio,gaugeacross periods. - Render unknown metrics from the catalogue (
label,unit,kind,sample_point). - Pull no faster than the client's freshness interval (1–60 minutes, default 5).
Receiver checklist
- Store id and secret; get a token; renew before expiry.
- Call
/timeonce a day (and after any clock or DST doubt) to learn the exact windows. - Call
/catalogueonce a day, onMETRIC_NOT_ALLOWED, and when/health.client.metrics_enabledchanges. Build KPI cards fromlabel,unit,kind,sample_point. - Test your pipeline with
dry_run=truebefore go-live. - Pull
/datano faster than the freshness interval. Upsert. Show provisional points as such. - Watch
noticesfor withdrawals.
7. Errors
Problem Details (RFC 9457), always JSON, whatever format you asked for:
{ "type": "https://<provider>/metrics-exchange/errors/METRIC_NOT_ALLOWED", "title": "Metric not available to this client",
"status": 403, "code": "METRIC_NOT_ALLOWED", "detail": "…", "query_id": "mxq_…", "request_id": "…" }| Code | Status | When |
|---|---|---|
INVALID_CLIENT | 401 | Bad id/secret |
TOKEN_EXPIRED | 401 | Expired or revoked |
CLIENT_DISABLED | 403 | Revoked or switched off by its scope |
ACCOUNT_SUSPENDED | 403 | Grace period over (30 days after the tenant was suspended) |
SCOPE_DISABLED | 403 | Administrator switch for this level is off |
METRIC_NOT_ALLOWED | 403 | Not ticked |
BREAKDOWN_NOT_ALLOWED | 403 | Not ticked |
INVALID_RANGE | 400 | from ≥ to, unknown shortcut, both given |
RANGE_BEFORE_AVAILABLE | 400 | Before available_from |
TOO_MANY_POINTS | 400 | Carries suggested_group |
INVALID_TIMEZONE | 400 | Unknown zone or override not allowed |
FORMAT_NOT_ALLOWED | 406 | Format not enabled for this client |
RATE_LIMITED | 429 | With Retry-After |
UNAVAILABLE | 503 | Engine or store down |
An unknown path or method under /metrics-exchange/v1 answers 404 Problem Details with code NOT_FOUND (and X-Request-Id); it is not part of the contract table above.
8. Limits
Free, with fair-use limits. These are the defaults; the console shows the values in force. Over a limit → RATE_LIMITED with Retry-After, never partial data.
| Limit | Default |
|---|---|
| Data clients per organisation (workspace clients count toward their organisation) | 3 |
| Data clients for the platform | unlimited |
| Requests per client per day (dry-run counts 0.1) | 1,000 |
| /token and /token/revoke calls per caller (IP + client id) per minute | 20 |
| /token and /token/revoke calls per IP address per minute, any client id | 60 |
| Points per response | 10,000 |
9. OpenAPI, XSD & conformance
GET /openapi.json— the OpenAPI 3.1 description of every endpoint and response. It is the arbiter of the contract.GET /schema.xsd— the XML schema every XML document validates against.
Both are served at https://manager.social/metrics-exchange/v1/openapi.json and https://manager.social/metrics-exchange/v1/schema.xsd and need a bearer token, like every data endpoint:
curl -s 'https://manager.social/metrics-exchange/v1/openapi.json' -H 'Authorization: Bearer <token>' -o openapi.json
curl -s 'https://manager.social/metrics-exchange/v1/schema.xsd' -H 'Authorization: Bearer <token>' -o schema.xsdConformance script
A small script (Python 3 plus requests), run against a base URL and credentials. It checks, in order: token issue and expiry; the /health shape; /time windows contiguous and in the stated zone; a valid sample_point for every catalogue metric; the dry run matching the catalogue; real /data in all three formats validating against openapi.json and schema.xsd; every error code reproducible; the point cap triggering TOO_MANY_POINTS; suppression yielding Other. It exits non-zero on any failure. The script is not published on a public URL yet — ask us for the conformance script.
10. Quickstart
With the client id and secret from the data owner, these four calls take you from a token to a dry-run document. Replace the <…> placeholders; the token comes from step 1's access_token.
# 1. Get a token (client credentials)
curl -s -X POST 'https://manager.social/metrics-exchange/v1/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>'
# 2. Check the clock and the time windows
curl -s 'https://manager.social/metrics-exchange/v1/time' -H 'Authorization: Bearer <token>'
# 3. See the metrics this client may read
curl -s 'https://manager.social/metrics-exchange/v1/catalogue' -H 'Authorization: Bearer <token>'
# 4. Dry run: the document shape with zero values
curl -s 'https://manager.social/metrics-exchange/v1/data?metrics=*&range=last_7_days&dry_run=true' -H 'Authorization: Bearer <token>'Then drop dry_run=true to get real numbers, add group=day for a daily series, or format=csv for a spreadsheet-friendly answer. Questions: [email protected].