Skip to content

List price migrations

The subscriptions.migrations.list operation: GET /api/v1/subscriptions/migrations in the REST API and the subscriptions_migrations_list tool in the MCP server.

GET/api/v1/subscriptions/migrations

Lists the brand's price migrations in the request's mode, newest first, with their progress. Filter by fromPriceId.

Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).

At a glance

  • REST: GET /api/v1/subscriptions/migrations
  • MCP tool: subscriptions_migrations_list
  • Operation ID: subscriptions.migrations.list
  • Scope: Brand
  • Permission: subscriptions:read
  • Risk tier: read
  • Dry run: Not supported
  • Idempotency: Not needed (read only)
  • Modes: Test and live
  • Pagination: limit (at most 100) and starting_after
  • Authentication: API key with the subscriptions:read scope
  • Since: M5

Request

Query parameters

FieldTypeRequiredDescription
fromPriceIdprice_… IDNoOnly migrations away from this price.
limitinteger (1 to 100)No
starting_aftersmig_… IDNo

Response

200 OK with a JSON object, a page of the list (newest first):

FieldTypeDescription
object"list"
dataarray of object
data[].idsmig_… ID
data[].object"subscription_migration"
data[].livemodeboolean
data[].brandIdbrd_… ID
data[].fromPriceIdprice_… ID
data[].toPriceIdprice_… ID
data[].currencystring
data[].effectiveone of next_renewal, date
data[].effectiveDatedate-time or null
data[].noticeDaysinteger
data[].filterobject
data[].filter.statusesarray of one of incomplete, incomplete_expired, trialing, active, past_due, unpaid, paused, canceled
data[].filter.customerIdsarray of cus_… ID or null
data[].statusone of scheduled, completedscheduled while changes are still waiting for their renewal; completed once none is.
data[].countsobjectProgress (spec §16.14).
data[].counts.matchedinteger (at least 0)Subscriptions on the old price that the filter matched.
data[].counts.scheduledinteger (at least 0)Of those, the ones given the change.
data[].counts.notifiedinteger (at least 0)Customers sent their notice.
data[].counts.appliedinteger (at least 0)Changes applied at a renewal.
data[].counts.pendinginteger (at least 0)Changes still waiting for their renewal.
data[].counts.skippedinteger (at least 0)Matched but not changed: skipped at once (skippedAtCreation), or dropped before their renewal because the subscription was canceled or changed again.
data[].skippedAtCreationobjectWhy matching subscriptions weren't changed: pending_update (another change was already waiting), cancel_scheduled (set to end at its period end).
data[].revenueobjectThe monthly recurring amount of the changed items before and after (licensed items; metered items are billed from usage).
data[].revenue.mrrBeforemoney
data[].revenue.mrrAftermoney
data[].revenue.mrrDeltamoney
data[].firstChangeAtdate-time or nullThe first scheduled change.
data[].lastChangeAtdate-time or nullThe last scheduled change.
data[].versioninteger
data[].createdAtdate-time
data[].updatedAtdate-time
has_moreboolean
next_cursorsmig_… ID or null

Examples

A price's migrations

HTTP
GET /api/v1/subscriptions/migrations?fromPriceId=price_01jacq4m3xf0v8w9zq2y7k5n6p
Authorization: Bearer or_test_…

Response (200):

JSON
{
  "object": "list",
  "data": [
    {
      "id": "smig_01jacq4m3xf0v8w9zq2y7k5n6h",
      "object": "subscription_migration",
      "livemode": false,
      "brandId": "brd_01jacq4m3xf0v8w9zq2y7k5n6b",
      "fromPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6p",
      "toPriceId": "price_01jacq4m3xf0v8w9zq2y7k5n6q",
      "currency": "EUR",
      "effective": "next_renewal",
      "effectiveDate": null,
      "noticeDays": 30,
      "filter": {
        "statuses": ["trialing", "active", "past_due"],
        "customerIds": null
      },
      "status": "scheduled",
      "counts": {
        "matched": 42,
        "scheduled": 40,
        "notified": 0,
        "applied": 0,
        "pending": 40,
        "skipped": 2
      },
      "skippedAtCreation": {
        "pending_update": 2,
        "cancel_scheduled": 0
      },
      "revenue": {
        "mrrBefore": {
          "amount": "400000000",
          "currency": "EUR"
        },
        "mrrAfter": {
          "amount": "480000000",
          "currency": "EUR"
        },
        "mrrDelta": {
          "amount": "80000000",
          "currency": "EUR"
        }
      },
      "firstChangeAt": "2026-11-20T10:00:00.000Z",
      "lastChangeAt": "2026-12-19T10:00:00.000Z",
      "version": 2,
      "createdAt": "2026-10-20T09:00:00.000Z",
      "updatedAt": "2026-10-20T09:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Errors

CodeHTTP statusWhenWhat to do
validation_failed400A filter or pagination value is malformed.Fix the fields listed in details.issues and send the request again.
permission_denied403The credentials can't read this brand's subscriptions.Ask an organization owner or admin for a role or scope that allows this action.

It can also return these common errors: api_version_unsupported, authentication_required, api_key_invalid, scope_required, resource_not_found, dry_run_not_supported, rate_limited, internal_error.