Appearance
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
| Query | Required | Purpose |
|---|---|---|
projectId | Yes | The project to list. |
funnelId | No | Limit the list to one funnel. |
updatedSince | No | ISO 8601 timestamp. Returns subscriptions whose updatedAt is at or after it. |
cursorUpdatedAt, cursorId | No | The nextCursor values of the previous page. Both are required together. |
limit | No | Page 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
| Status | Meaning |
|---|---|
400 | A 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
| Parameter | In | Required | Purpose |
|---|---|---|---|
subscriptionId | Path | Yes | The billing subscription UUID or the Stripe sub_… ID. |
projectId | Query or JSON body | With an API key | The 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
| Status | Meaning |
|---|---|
400 | subscriptionId is neither a UUID nor a sub_… ID. |
404 | The subscription, or its funnel, was not found in the project. |