Version

Analytics API

Read-only analytics under /v1/analytics/ surface the same figures the creator dashboard renders.

Read-only analytics under /v1/analytics/* surface the same figures the creator dashboard renders. Every endpoint delegates to the same service layer the dashboard uses, so the dashboard, the MCP tools and REST callers see identical numbers.

All eight reads are tenant-scoped by the token's team, need no Idempotency-Key, and share the token's general rate limit.

Background

Common query parameters

Most reads share the same window selection:

  • period: a preset window, one of 7d, 14d, 30d, 60d, 90d, mtd, qtd, ytd, 1y, all. Defaults to 30d. Ignored when both from and to are supplied; an unknown value falls back to the default rather than failing.
  • from, to: an explicit YYYY-MM-DD range. Takes precedence over period when both ends are provided.
  • project_id: an optional project id. Scopes the response to a single project; omit for every project visible to the token. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

The dashboard, earnings and transaction-breakdown reads additionally accept filter allow-lists: plan_ids, statuses, payment_method_ids. Pass each as an array (?plan_ids[]=uuid1&plan_ids[]=uuid2) or as one comma-separated string (?plan_ids=uuid1,uuid2).

Caching

All reads share the same 5-minute cache the creator dashboard uses. A REST call warms the human-facing view and vice versa; consecutive calls with identical filters hit the cache until it rotates.

The service layer returns USD-normalised totals for cross-currency comparability. Per-plan or per-payment rows still carry their original currency alongside the USD-normalised amount.

Endpoints

Headline figures

GET

Total revenue, total transactions, total users and MRR, each with a trend relative to the compare_period window and a sparkline. The Recurring Monthly Income tile counts only active subscriptions on recurring plans, normalised to a monthly figure; one-time and lifetime plans are excluded.

curl "https://api.subscriby.net/v1/analytics/dashboard?period=30d&compare_period=previous" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"
GET
/v1/analytics/dashboard

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id?string

Scope the figures to one project the token may see; omit for every project visible to it. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
compare_period?string

previous (the default) compares each tile with the window just before it and fills trend; none leaves the trend out.

Default"previous"
plan_ids[]?array<string>

Count only these plans. Send it as plan_ids[]=a&plan_ids[]=b or as one comma-separated string.

statuses[]?array<string>

Count only payments in these states: successful, failed, pending, refunded. Send them as statuses[]=a&statuses[]=b or as one comma-separated string.

payment_method_ids[]?array<string>

Count only payments taken through these payment methods. Send them as payment_method_ids[]=a&payment_method_ids[]=b or as one comma-separated string.

Responses

200OK

The headline tiles.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Earnings report

GET

The full earnings breakdown (gross, fees, net, transaction count) plus a timeseries bucketed by granularity: day (the default), week or month.

curl "https://api.subscriby.net/v1/analytics/earnings?granularity=week" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

Every money figure is USD-normalised so buckets in different currencies add up; totals.currency says so.

GET
/v1/analytics/earnings

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id?string

Scope the figures to one project the token may see; omit for every project visible to it. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
granularity?string

The bucket size of the timeseries: day (the default), week or month. Anything else is 422 VALIDATION_FAILED.

Default"day"
plan_ids[]?array<string>

Count only these plans. Send it as plan_ids[]=a&plan_ids[]=b or as one comma-separated string.

statuses[]?array<string>

Count only payments in these states: successful, failed, pending, refunded. Send them as statuses[]=a&statuses[]=b or as one comma-separated string.

payment_method_ids[]?array<string>

Count only payments taken through these payment methods. Send them as payment_method_ids[]=a&payment_method_ids[]=b or as one comma-separated string.

Responses

200OK

Gross, fees and net per bucket.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

422Validation failed

When granularity is not day, week or month, or project_id is not a UUID.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Subscriber analytics

GET

New sign-ups, cancellations, churn rate, trial-to-paid conversion and the status distribution of the window. The filter allow-lists do not apply: the figures describe the whole membership of the scope, which is what retention is measured against.

curl "https://api.subscriby.net/v1/analytics/subscribers?project_id=$PROJECT_ID" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"
GET
/v1/analytics/subscribers

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id?string

Scope the figures to one project the token may see; omit for every project visible to it. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate

Responses

200OK

New, canceled, churn, trials and the status mix.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

422Validation failed

When project_id is not a UUID.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

List transactions

GET

A keyset-paginated list of payments for one project. project_id is required.

curl "https://api.subscriby.net/v1/analytics/transactions?project_id=$PROJECT_ID&limit=100" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

Every row carries its owning project, plan and subscriber, so a payment can be attributed without a follow-up lookup. Follow meta.next_cursor on the next call to paginate. A null or missing cursor means the end of the range has been reached.

GET
/v1/analytics/transactions

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id*string

The project whose payments to list. Required: transactions are always read for one project.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
statuses[]?array<string>

Only payments in these states: successful, failed, pending, refunded. Send them as statuses[]=a&statuses[]=b or as one comma-separated string; an unknown state is ignored.

provider_ids[]?array<string>

Only payments taken through these payment methods. Send them as provider_ids[]=a&provider_ids[]=b or as one comma-separated string.

plan_ids[]?array<string>

Count only these plans. Send it as plan_ids[]=a&plan_ids[]=b or as one comma-separated string.

currency_ids[]?array<string>

Only payments in these currencies, by currency id. Send them as currency_ids[]=a&currency_ids[]=b or as one comma-separated string.

cursor?string

The opaque keyset cursor a previous page returned as meta.next_cursor. Omit for the first page.

limit?integer

Rows per page, 1 to 200; a value outside the range clamps. Defaults to 50.

Default50

Responses

200OK

One keyset page of transactions.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

422Validation failed

When project_id is missing or not a UUID.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Transaction breakdown

GET

USD-normalised successful-payment totals grouped by one dimension: plan, payment_provider, currency or project. dimension is required.

curl "https://api.subscriby.net/v1/analytics/transactions/breakdown?dimension=payment_provider&period=90d" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"
GET
/v1/analytics/transactions/breakdown

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

dimension*string

What to group the settled revenue by: plan, payment_provider, currency or project. Required.

project_id?string

Scope the figures to one project the token may see; omit for every project visible to it. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
plan_ids[]?array<string>

Count only these plans. Send it as plan_ids[]=a&plan_ids[]=b or as one comma-separated string.

statuses[]?array<string>

Count only payments in these states: successful, failed, pending, refunded. Send them as statuses[]=a&statuses[]=b or as one comma-separated string.

payment_method_ids[]?array<string>

Count only payments taken through these payment methods. Send them as payment_method_ids[]=a&payment_method_ids[]=b or as one comma-separated string.

Responses

200OK

Gross revenue grouped by the dimension.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

422Validation failed

When dimension is missing or not one of the four, or project_id is not a UUID.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Plan performance

GET

A per-plan breakdown for one project: active subscribers, revenue in the window, payments in the window and the average ticket. project_id is required.

curl "https://api.subscriby.net/v1/analytics/plan-performance?project_id=$PROJECT_ID&period=30d" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"

Figures are in the plan's own currency. meta.range is the window the preset resolved to.

GET
/v1/analytics/plan-performance

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id*string

The project whose plans to report on. Required: the figures are per plan of one project.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate

Responses

200OK

Per-plan activity in the plan's own currency.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

422Validation failed

When project_id is missing or not a UUID.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

By connector

GET

Members, access and revenue per connector: one row for every connector the scope's projects run or ever granted access on. The figures behind the dashboards' By Connector panel.

curl "https://api.subscriby.net/v1/analytics/connectors?project_id=$PROJECT_ID&period=30d" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"
  • installations counts the live, not uninstalled, installations of the connector in the scope; members the members holding at least one account linked on it; members_linked_in_window those who linked one inside the window.
  • live_grants and pending_grants read the access ledger now (pending covers pending, pending_identity and held); granted_in_window and revoked_in_window count the ledger's moves inside the window.
  • gross_usd is every settled payment in the window whose purchase granted access on the connector, converted to USD; share_percent is its part of total_gross_usd. A purchase that grants access on two connectors counts toward both, so shares can exceed 100 in total; attribution says so in the creator's language.
  • The filter allow-lists (plan_ids, statuses, payment_method_ids) do not apply here: installations and linked accounts are not subscriptions.
GET
/v1/analytics/connectors

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id?string

Scope the figures to one project the token may see; omit for every project visible to it. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate

Responses

200OK

One row per connector: installations, members, grants, revenue and share.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

Revenue composition

GET

How the window's revenue and payments are composed, as the five donuts the dashboards draw: transaction fees by payment provider, settled transactions by plan kind, gross revenue by currency, payment attempts by outcome, and the monthly recurring revenue split by plan.

curl "https://api.subscriby.net/v1/analytics/composition?project_id=$PROJECT_ID&period=30d" \  -H "Authorization: Bearer $SUBSCRIBY_TOKEN"
  • Every dataset carries total, unit (usd or count) and slices sorted largest first; each slice has its key, label, value, share_percent and the color the dashboard draws it in, so a client can render the same donut.
  • fees_by_provider, transactions_by_kind and revenue_by_currency read the same settled payments, so they agree with each other to the cent; payment_outcomes reads every attempt in the window, because a failed charge is exactly what it exists to show.
  • mrr_by_plan ignores the window: MRR is a balance, not a flow. It counts every active subscription on a recurring plan, normalised to a monthly USD figure, filed under its plan.
  • Labels come back in the creator's language.
GET
/v1/analytics/composition

Requires ability

The token must hold this ability, or the call is refused with 403.

Runs the same action from an agent, behind the same ability.

Authorization

bearerToken
AuthorizationBearer <token>

A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.

In: header

Query Parameters

project_id?string

Scope the figures to one project the token may see; omit for every project visible to it. A project outside the token's scope:project: allow-list is 404 TENANT_MISMATCH, an unknown one 404 RESOURCE_NOT_FOUND.

Formatuuid
period?string

The preset window: 7d, 14d, 30d (the default), 60d, 90d, mtd, qtd, ytd, 1y or all. Ignored when both from and to are given; an unknown value falls back to the default rather than failing.

Default"30d"
from?string

The first day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate
to?string

The last day of an explicit window, YYYY-MM-DD. Both from and to are needed to override period.

Formatdate

Responses

200OK

The four dashboard donuts for the window plus the MRR base split by plan, each as total, unit and slices.

401Unauthorized

The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).

403Forbidden

The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.

429Too many requests

The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.

How is this guide?

Version

On this page

Subscriby is a product
designed by you — for you.
No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request