Skip to content

Subscriptions ​

List subscriptions ​

Pages through subscriptions bought in the project's funnels, in updatedAt order, oldest first. Subscriptions that never started (incomplete, incomplete_expired) and subscriptions that did not come from a funnel are not listed. A subscription moves to the end of the list whenever it changes, so a cancellation or renewal reaches your next updatedSince sync.

Scope: subscriptions:read

Request ​

http
GET /subscriptions/list?projectId=<project-id>&updatedSince=<iso-timestamp>

Parameters ​

QueryRequiredPurpose
projectIdYesThe project to list.
funnelIdNoLimit the list to one funnel.
updatedSinceNoISO 8601 timestamp. Returns subscriptions whose updatedAt is at or after it.
cursorUpdatedAt, cursorIdNoThe nextCursor values of the previous page. Both are required together.
limitNoPage size, up to 100 (default 50).

Example ​

sh
curl "https://sdk-api.funnelsgrove.com/integration/v1/subscriptions/list?projectId=<project-id>&updatedSince=2026-10-20T00:00:00Z" \
  -H "Authorization: Bearer <api-key>"

Response ​

json
{
  "project": { "id": "<project-id>" },
  "items": [{
    "id": "<subscription-id>",
    "funnelId": "<funnel-id>",
    "funnelUserId": "<funnel-user-id>",
    "userId": "u_123",
    "provider": "stripe",
    "test": false,
    "status": "active",
    "planId": "price_123",
    "cancelAtPeriodEnd": false,
    "currentPeriodStart": "2026-10-01T10:00:00+00:00",
    "currentPeriodEnd": "2026-11-01T10:00:00+00:00",
    "trialStart": null,
    "trialEnd": null,
    "startedAt": "2026-10-01T10:00:00+00:00",
    "canceledAt": null,
    "endedAt": null,
    "createdAt": "2026-10-01T10:00:00+00:00",
    "updatedAt": "2026-10-01T10:00:05.123456+00:00"
  }],
  "nextCursor": null
}

status is the provider's status: active, trialing, past_due, unpaid, paused or canceled. Join a subscription to its user with funnelUserId.

Errors ​

StatusMeaning
400A timestamp is not ISO 8601, or cursorUpdatedAt was sent without a UUID cursorId.

Cancel or renew a subscription ​

/cancel cancels at the end of the current period. /renew removes a scheduled cancellation. Both are trusted server-to-server operations on a Stripe subscription.

Scope: subscriptions:write

Request ​

http
POST /subscriptions/:subscriptionId/cancel?projectId=<project-id>
POST /subscriptions/:subscriptionId/renew?projectId=<project-id>

These two endpoints read the key from X-SDK-Secret-Key only; Authorization: Bearer is not accepted here.

Parameters ​

ParameterInRequiredPurpose
subscriptionIdPathYesThe billing subscription UUID or the Stripe sub_… ID.
projectIdQuery or JSON bodyWith an API keyThe project that owns the subscription.

Example ​

sh
curl -X POST "https://sdk-api.funnelsgrove.com/integration/v1/subscriptions/<subscription-id>/cancel?projectId=<project-id>" \
  -H "X-SDK-Secret-Key: <api-key>"

Response ​

json
{
  "workspace": { "id": "…", "slug": "acme" },
  "funnel": { "id": "<funnel-id>" },
  "subscription": { "…": "…" },
  "paymentProfile": { "id": "…", "providerAccountId": "…", "environment": "live" },
  "user": { "…": "…" }
}

subscription is the updated billing subscription. paymentProfile and user are null when not available.

Errors ​

StatusMeaning
400subscriptionId is neither a UUID nor a sub_… ID.
404The subscription, or its funnel, was not found in the project.

Build. Launch. Grow.