Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Analytics API


Private preview

Analytics API Private preview

Programmatically access Stripe-defined metrics.

The Analytics API gives you synchronous, programmatic access to Stripe-defined metrics such as monthly recurring revenue (MRR), annual recurring revenue (ARR), and usage revenue. Use it to build your own dashboards, query metrics from an AI agent, or integrate Stripe data into your internal tools.

Stripe offers three programmatic data products. Choose the one that matches the type of data you need:

  • The Analytics API (this product) : Returns Stripe-defined metrics synchronously, as JSON. For example, choose this when you want a small set of prebuilt metrics on demand, to get metrics you can use in a live dashboard, or to expose metrics to an AI agent.
  • The Reports API : Returns large, pre-built datasets asynchronously as CSV files. Choose this when you need a bulk export of raw transaction data on a schedule.
  • The Query Runs API : Runs freeform SQL against your raw Stripe data asynchronously and returns CSV files. Choose this when you need full SQL flexibility on top of your underlying data.

Request to join the preview for the Analytics API.

Enter your email to request access.

Concepts

Metrics

A metric is a quantitative value computed by aggregating raw Stripe data—for example, MRR, ARR, or usage revenue.

You can reference a metric by either its ID (for example, metric_61Sud3n5oAGVCWiSr5) or its common name (for example, revenue.mrr). Each metric has a separate ID for live mode and sandbox mode; the common name is the same in both modes. If you provide both id and name, they must refer to the same metric.

Monetary metric values are returned in minor units (for example, cents for USD). Percentage metric values are returned in basis points (for example, 100 for 1%). The unit returned by each metric is listed in Supported metrics.

Metrics often have dimensions —categorical attributes such as customer, product, or price —that you can filter or group results by.

Metric namespaces

A metric namespace is a group of metrics that share the same dimensions. All metrics in a single metric_query request must belong to the same namespace.

For example, the revenue namespace contains revenue.mrr and revenue.arr. Both share the dimensions price, product, customer, and subscription, which you can use to filter or group results.

Time ranges and granularity

Each metric_query returns a time series at the specified granularity. The supported granularities are day, week, month, and year. The maximum time range you can query depends on the granularity:

  • day : up to 92 days
  • week : up to 397 days
  • month and year : no fixed limit

For granularities other than day, the API snaps starts_at and ends_at to the nearest bucket boundary, so any timestamp within a bucket produces the same result. For example, a monthly query with starts_at=2026-01-15T00:00:00Z returns buckets starting on the first of each month.

Weeks are bucketed Sunday through Saturday.

Gap-filled time series

Metric-query responses are chart-oriented time series. If a time bucket in the requested range has no data, the API adds a zero-valued row for it.

Suppose you make a query between three days for two products where data only exists on some of the days. The response still includes a row for every day and product. Buckets with no underlying data have a value of 0.

{
 "data": [
 { "timestamp": "2026-03-07T00:00:00Z", "dimensions": { "product": "prod_a" }, "results": [{ "value": 0 }] },
 { "timestamp": "2026-03-07T00:00:00Z", "dimensions": { "product": "prod_b" }, "results": [{ "value": 200 }] },
 { "timestamp": "2026-03-08T00:00:00Z", "dimensions": { "product": "prod_a" }, "results": [{ "value": 100 }] },
 { "timestamp": "2026-03-08T00:00:00Z", "dimensions": { "product": "prod_b" }, "results": [{ "value": 0 }] },
 { "timestamp": "2026-03-09T00:00:00Z", "dimensions": { "product": "prod_a" }, "results": [{ "value": 0 }] },
 { "timestamp": "2026-03-09T00:00:00Z", "dimensions": { "product": "prod_b" }, "results": [{ "value": 300 }] }
 ]
}

For an ungrouped query with no underlying rows, the API returns one zero-valued row for each requested bucket:

{
 "data": [
 { "timestamp": "2026-03-07T00:00:00Z", "dimensions": {}, "results": [{ "value": 0 }] },
 { "timestamp": "2026-03-08T00:00:00Z", "dimensions": {}, "results": [{ "value": 0 }] },
 { "timestamp": "2026-03-09T00:00:00Z", "dimensions": {}, "results": [{ "value": 0 }] }
 ]
}

For a grouped query with no returned groups, the API doesn’t create dimension groups, so the response is empty:

{
 "data": []
}

Sandboxes

The Analytics API works in sandboxes. Use the sandbox ID for a metric (or its common name, which is the same in both modes) when querying from a sandbox.

Metric versioning

Metric versions are tied to API versions. When a metric’s definition changes, the new version receives a new ID and the common name points to the new version. Previous versions remain accessible by their ID.

Supported metrics

See Supported metrics for the complete list of available metrics, their dimensions, and the units that results are returned in.

Required permissions

To call the Analytics API, your API key must have the Data → Metrics → Read permission.

To grant this permission:

  1. Go to the API keys page in the Dashboard.
  2. Create or edit a restricted key.
  3. Enable Data > Metrics > Read .

Example

Send a POST request to /the relevant part of the product to retrieve metric data. The request body is JSON; you must include the Stripe-Version header.

Example request

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

Example response

{
 "id": "mqr_UQTLLvlABBZlw0",
 "object": "v2.data.analytics.metric_query_result",
 "livemode": true,
 "refreshed_at": "2026-03-04T02:34:15Z",
 "created": "2026-03-04T18:00:00Z",
 "next_page_url": null,
 "previous_page_url": null,
 "data": [
 {
 "id": "mqdr_UQTLKfAhfsdatx",
 "timestamp": "2026-03-01T00:00:00Z",
 "dimensions": { "price": "price_HG4jxINMyHorkI" },
 "results": [
 {
 "metric": "metric_61Sud3n5oAGVCWiSr5",
 "name": "revenue.mrr",
 "currency": "usd",
 "value": 9000
 }
 ]
 },
 {
 "id": "mqdr_UQTLXYtgGM7TNp",
 "timestamp": "2026-03-01T00:00:00Z",
 "dimensions": { "price": "price_HG4UtyJbuJIsVt" },
 "results": [
 {
 "metric": "metric_61Sud3n5oAGVCWiSr5",
 "name": "revenue.mrr",
 "currency": "usd",
 "value": 12000
 }
 ]
 },
 {
 "id": "mqdr_UQTLcb70nAS3vR",
 "timestamp": "2026-03-02T00:00:00Z",
 "dimensions": { "price": "price_HG4jxINMyHorkI" },
 "results": [
 {
 "metric": "metric_61Sud3n5oAGVCWiSr5",
 "name": "revenue.mrr",
 "currency": "usd",
 "value": 9150
 }
 ]
 }
 ]
}

For the full request and response schemas, see the MetricQueryResult API reference.

Use the Stripe MCP

You can use the Stripe Model Context Protocol (MCP) server ’s execute_analytics tool to query analytics metrics from an AI agent or code editor. The MCP tool calls the POST /the relevant part of the product endpoint for you, so you can retrieve metrics by describing what you want in natural language rather than constructing API requests manually.

Use cases

Build an internal MRR dashboard

Query daily MRR for a few prices, grouped by price, to power an internal revenue dashboard.

const stripe = require('stripe')('sk_test_...', {
 apiVersion: '2026-04-22.preview',
});

const response = await stripe.v2.data.analytics.metricQuery.create({
 metrics: [{ name: 'revenue.mrr' }],
 starts_at: '2026-01-01T00:00:00Z',
 ends_at: '2026-01-31T00:00:00Z',
 granularity: 'day',
 currency: 'usd',
 filters: {
 price: ['price_HG4jxINMyHorkI', 'price_HG4UtyJbuJIsVt'],
 },
 group_by: ['price'],
});

response.data.forEach((row) => {
 const date = new Date(row.timestamp).toISOString().split('T')[0];
 const priceId = row.dimensions.price;
 const mrrDollars = (row.results[0].value / 100).toFixed(2);
 const currency = row.results[0].currency.toUpperCase();
 console.log(`${date} | ${priceId} | ${currency} ${mrrDollars}`);
});

Track multiple metrics in the same namespace

Query MRR and ARR together to display recurring revenue trends in a single chart. Both metrics live in the revenue namespace, so you can request them in a single call.

const stripe = require('stripe')('sk_test_...', {
 apiVersion: '2026-04-22.preview',
});

const response = await stripe.v2.data.analytics.metricQuery.create({
 metrics: [
 { name: 'revenue.mrr' },
 { name: 'revenue.arr' },
 ],
 starts_at: '2026-01-01T00:00:00Z',
 ends_at: '2026-01-31T00:00:00Z',
 granularity: 'month',
 currency: 'usd',
});

response.data.forEach((row) => {
 const month = row.timestamp.slice(0, 7);
 row.results.forEach((result) => {
 const dollars = (result.value / 100).toFixed(2);
 console.log(`${month} | ${result.name}: ${dollars} ${result.currency}`);
 });
});

Pagination and the limit parameter

Stripe doesn’t support pagination. Instead, next_page_url and previous_page_url are always null. The limit parameter caps the number of rows returned but doesn’t trigger pagination. The API sorts results deterministically by timestamp, then by dimension values when group_by is specified, so a smaller limit returns the earliest rows in that order.

Errors

Error codeHTTP statusDescription
not_found404The specified metric doesn’t exist, or the metric is only accessible in live mode (when queried in a sandbox).
metric_inaccessible403Your API key doesn’t have the **Data > Metrics > Read permission required to call this endpoint. Go to the API keys page in the Dashboard, and enable Data > Metrics > Read on your restricted key.
metric_invalid_parameter_use400The metrics in a single request don’t share the same namespace, or you tried to group by or filter on a dimension that doesn’t exist on the metric, or a filter value isn’t valid for the specified dimension.
metric_invalid_parameter_value400A parameter value isn’t valid—for example, an unsupported granularity, an unsupported currency or timezone, more than 1 group_by dimension, more than 2 filter dimensions, more than 10 values per filter, or a limit greater than 1,000.
metric_invalid_time_range400The time range is invalid—for example, starts_at is after ends_at, either is in the future, or the range exceeds the maximum for the requested granularity.
metric_query_rate_limit_exceeded429Too many metric queries per second.
metric_query_concurrency_limit_exceeded429Too many concurrent metric queries.
metric_query_metric_rate_limit_exceeded429Too many queries per second for this specific metric.
metric_query_metric_concurrency_limit_exceeded429Too many concurrent queries for this specific metric.
Last verified 2026-09-24

Is this helpful?