List run rate movements
curl "https://api.summerbase.com/v1/run_rate_movements" \ -H "Authorization: Bearer sb_..."const response = await fetch("https://api.summerbase.com/v1/run_rate_movements", { headers: { Authorization: "Bearer sb_...", },})const data = await response.json()Every change to revenue in the project, newest first — or one customer’s,
with customer_id, or one subscription’s, with subscription_id.
One row per change to a subscription item: they subscribed, they upgraded, they moved plan, they left, they came back. Each row carries what the item was on and worth before and after, so it explains itself. These are the same changes the metrics report’s movement values add up, so a month’s movement and the rows inside it always agree.
A customer’s rows sharing a counts_at are one movement, because the
project’s collapse window folds changes made close together into one: a
customer who cancels one plan and takes another two days later has not
changed what they are worth, so both rows read no_change. Rows come
ordered by counts_at, then customer, then occurred_at, so a
movement’s rows are next to each other; group by counts_at and
customer_id to see movements, and read the rows to see what made them.
A page boundary can fall inside a movement.
Amounts are in the currency the customer is billed in. Expand customer,
price, previous_price, plan and previous_plan to get them on each
row. A row’s plans are its prices’ as they stand now, so a price moved to
another plan reads under that plan as far back as it goes.
Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Only this customer’s. A Summerbase id, or any source’s identity for
them like stripe:cus_123. A customer nobody has is a 404, not an
empty list.
Only this subscription’s: the rows of changes to its items. A
Summerbase id, or any source’s identity for it like stripe:sub_123.
A subscription nobody has is a 404, not an empty list. A row’s
movement_type is still its customer’s movement, which may tell a
different story from this subscription’s own delta.
Only rows of movements of this type.
How many records to return, 1 to 100. Defaults to 20.
The next_cursor of the previous page, to read the page after it.
Relationships to include in the response instead of fetching separately. A dotted path expands what an expanded record can expand in turn — at most 4 deep, 10 paths a request, and never back to a record already on the path.
Response
Section titled “Response”Returns a list of run rate movement objects, a page at a time. See Pagination.
Example
{ "data": [ { "arr": "15000.00", "counts_at": "2026-06-12T15:47:09Z", "currency_code": "USD", "customer_id": "0199a7c2-4e1b-7f38-b9d2-5a6c8e0f1d73", "delta": "250.00", "movement_type": "expansion", "mrr": "1250.00", "object": "run_rate_movement", "occurred_at": "2026-06-12T15:47:09Z", "plan_id": "0198f1a4-1d2e-7a40-9b31-5c6d7e8f9a0b", "previous_arr": "12000.00", "previous_mrr": "1000.00", "previous_plan_id": "0198f1a4-1d2e-7a40-9b31-5c6d7e8f9a0b", "previous_price_id": "0198f1a4-2e5f-7b80-a1c2-3d4e5f6a7b8c", "previous_quantity": "20", "previous_status": "active", "price_id": "0198f1a4-2e5f-7b80-a1c2-3d4e5f6a7b8c", "quantity": "25", "revenue_type": "recurring", "status": "active", "subscription_id": "0199a7c2-5b3e-7a14-8c6d-2f9e4b7a1c05", "subscription_item_id": "0199a7c2-5b41-7c62-9d3e-6a1f8b2c4d97" } ], "has_more": false, "next_cursor": null, "object": "list"}