MetricsGo API & MCP

Read access to the Meta ads and organic social data MetricsGo has synced for your organisation — from your own dashboards and backends (REST) or from Claude, Cursor and agents (MCP).

  • REST base URL: https://metricsgo.srv1821420.hstgr.cloud/api/v1
  • MCP endpoint: https://metricsgo.srv1821420.hstgr.cloud/api/mcp
  • API reference: /docs/api/reference · OpenAPI document: GET /api/v1/openapi.json (no auth)
  • Field definitions: data-contract.md, also served by the describe_metrics MCP tool

Keys

An organisation admin creates keys under Settings → API & MCP. A key:

  • is shown once — MetricsGo stores a hash, not the key; lose it and you revoke it and create another
  • belongs to the organisation, not the person who made it; it keeps working after they leave — revoke it there
  • carries scopes (ads:read, social:read) that gate endpoints, and an optional client list that gates rows; neither can widen the other
  • looks like mg_live_ followed by 43 characters

Send it as a bearer token on every request:

Authorization: Bearer mg_live_…

Never in a query string, cookie or body — those are rejected, and a key in a URL is a key in someone's logs.

Keys stay on the server

The API sends no CORS headers, deliberately. A key in browser JavaScript is a key handed to every visitor of that page. Your dashboard calls your backend; your backend calls MetricsGo.

Endpoints

All GET. Dates are YYYY-MM-DD calendar days in Asia/Kolkata; a range may not exceed 366 days.

Endpoint Scope Query
/v1/me any
/v1/clients any
/v1/ads/overview ads:read from to client? campaignId? adSetId? adId?
/v1/ads/entities ads:read level=campaign|adset|ad from to client? search?
/v1/ads/breakdowns ads:read level entityId from to
/v1/social/overview social:read from to client?
/v1/social/posts social:read from to client? limit? (1–500, default 100)
/v1/social/thumbnail social:read post

client is a client id from /v1/clients. entityId is the entity's Meta platform id (as shown in Ads Manager) or its id from /v1/ads/entities.

Which client does a row belong to?

Every row from /v1/ads/entities — and every campaign in /v1/ads/overview — carries its lineage, the same join keys Meta puts on its own objects (account_id, campaign_id, adset_id) plus the names:

{
  "id": "…", "platformId": "120251864157900220", "name": "Paid Webinar Sales Campaign_Aug12",
  "account":  { "id": "…", "platformAccountId": "act_714689862204894", "name": "Sheizen Wellness" },
  "client":   { "id": "…", "name": "Sheizen Wellness" },
  "campaign": null,
  "adSet":    null
}
  • client is how a row is attributed to a client. An account that is not assigned to a client still gets a name — the account's own — with client.id null, so grouping by client.name always works.
  • campaign is set on ad-set and ad rows; adSet is set on ad rows. platformId inside them is the Meta id, so you can join to anything you already pull from Meta.
  • To pipe data per client, either call with client=<id> (one client per call) or call once without it and group by client.id.

Response envelope

{
  "data": { … },
  "meta": {
    "timezone": "Asia/Kolkata",
    "from": "2026-08-25",
    "to": "2026-08-31",
    "syncedAt": "2026-09-06T07:30:58.194Z",
    "currency": "INR",
    "truncated": false
  }
}

meta.syncedAt is always present: every number is stored data synced by MetricsGo. The API never calls Meta on your behalf, so a request never spends your Meta quota — and never returns anything fresher than the last sync.

Lists are capped at 500 rows. truncated: true means the cap applied; narrow the range or filter by client.

Errors

RFC 9457 application/problem+json:

{
  "type": "https://app.digygo.com/docs/api/errors#rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "TooManyRequests: 60 requests per minute per key",
  "code": "rate_limited"
}
Status code When
400 validation_failed bad query (errors[] lists each problem)
401 unauthorized missing, malformed, unknown, revoked or expired key
403 forbidden key lacks the endpoint's scope
404 not_found client or entity outside the key's reach (existence is never confirmed)
429 rate_limited over 60 requests/minute for this key — honour Retry-After
503 unavailable transient; retry after Retry-After

Rate limits

60 requests per minute per key, exact. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (unix seconds); a 429 adds Retry-After.

Freshness

Ads data syncs hourly (last 3 days re-pulled nightly, 28 days weekly, because Meta restates). Social syncs on the same schedule. Breakdowns are fetched on demand by the dashboard; the API serves the cache and sets stale: true when the dashboard would have refetched.

MCP

The MCP server exposes seven read-only tools: list_clients, get_ads_overview, list_ad_entities, get_ad_breakdowns, get_social_overview, list_social_posts, describe_metrics. They return the same { data, meta } envelope as REST, validated by the same schemas.

Claude Code — one command:

claude mcp add --transport http metricsgo "https://metricsgo.srv1821420.hstgr.cloud/api/mcp" --header "Authorization: Bearer <key>"

Cursor and other MCP clientsmcp.json:

{ "mcpServers": { "metricsgo": { "url": "https://metricsgo.srv1821420.hstgr.cloud/api/mcp", "headers": { "Authorization": "Bearer <key>" } } } }

Claude.ai, Claude Desktop and ChatGPT — no key needed. Add the connector with the MCP URL and click Connect: the client discovers MetricsGo's OAuth server (/.well-known/oauth-protected-resource/api/mcp/.well-known/oauth-authorization-server), sends you to sign in, and you approve it on a consent screen naming the app, the permissions and the organisation. The approval appears in Settings → API & MCP as a connected app and can be revoked there. Grants see exactly the clients the approving user can see. Organisations with Claude's "Request headers" beta can still use a key (Authorization: Bearer <key>).

OAuth 2.1 details (for client authors)

  • Authorization code + PKCE (S256 required), resource = https://metricsgo.srv1821420.hstgr.cloud/api/mcp (RFC 8707), tokens are audience-bound to the MCP endpoint and rejected on /api/v1.
  • Client identification: Client ID Metadata Documents (client_id = your https metadata URL) or dynamic registration at POST /oauth/register. Redirect URIs must be https or loopback (http://localhost/127.0.0.1, any port).
  • Endpoints: /oauth/authorize, /oauth/token (form-urlencoded; authorization_code, refresh_token), /oauth/revoke (RFC 7009).
  • Access tokens last 1 hour; refresh tokens 30 days and rotate on every use. Reusing a rotated refresh token revokes the grant.
  • Scopes: ads:read, social:read (default: both). Scope may narrow on refresh, never widen.

Tip: ask the model to call describe_metrics first. It explains that null means "not reported by the platform" and is never a zero — the most common misreading of this data.

Compliance

You may process this data only on behalf of the business that connected the Meta account, and only for that business. Do not sell, license, aggregate across businesses, or use it to build or augment profiles of individuals (Meta Platform Terms §5).