Subscriptions
Read an Account's Wingspan service subscriptions, cancel one, and withdraw a pending cancellation with the V3 API.
A Subscription is an Account's ongoing right to a Plan. It starts when you create a Purchase. These routes cover service-plan subscriptions only. A benefit plan is not returned here: it uses the partner-managed flow described in Benefit enrollments.
Prerequisites
users.subscription:readto read, andusers.subscription:writeto create or update.revenue.subscriptions:writeto cancel or withdraw a cancellation.- A Person or service account that is not an impersonation session. Cancel and withdraw return
403for impersonation sessions.
Endpoints
| Purpose | Method and path |
|---|---|
| List subscriptions | GET /v3/platform/subscriptions |
| Get a subscription | GET /v3/platform/subscriptions/{subscriptionId} |
| Create a subscription | POST /v3/platform/subscriptions |
| Update a subscription | PATCH /v3/platform/subscriptions/{subscriptionId} |
| Cancel a subscription | POST /v3/platform/subscriptions/{subscriptionId}/cancel |
| Withdraw a cancellation | POST /v3/platform/subscriptions/{subscriptionId}/withdraw-cancellation |
| Get payment history | GET /v3/platform/subscriptions/{subscriptionId}/payment-history |
The Subscription object
| Field | Notes |
|---|---|
id, accountId | |
planId, planVersion, planName, planType | planType is Service or Benefit. |
status | Created, PendingActivation, Active, Suspended, PendingCancellation, Cancelled, Lapsed, Failed or Superseded. |
subscriptionVersion | |
term | startAt, currentPeriodStart, currentPeriodEnd, renewalMode (AutoRenew, ManualRenew or NonRenewing). |
projectedCancellationEffectiveAt, cancellationEffectiveAt | When a cancellation takes effect. |
cancelReason | code, freeText, competitor. |
Lists are returned newest first and are not cached. A subscription that belongs to another Account, or to a benefit plan, returns 404 from Get a subscription.
Cancel a subscription
cancelReason.code is required: TooExpensive, MissingCapability, SwitchedProvider, BusinessClosed or Other. freeText and competitor are optional.
curl -X POST https://api.wingspan.app/v3/platform/subscriptions/Vd5xHn7RcT2mKq9wLb4PsA/cancel \
-H "Authorization: Bearer $WINGSPAN_TOKEN" \
-H "X-Wingspan-Account: Nw7kQ2pLx9RtVb3mHc5dZa" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "cancelReason": { "code": "SwitchedProvider", "competitor": "Acme Pay" } }'The response is 200 with the subscription. Wingspan sets the effective date from the service period that is current when it processes the request, and returns it as cancellationEffectiveAt. Read that field, not your own calculation. You do not send If-Match.
While the cancellation is pending, status is PendingCancellation. Withdraw a cancellation takes no body and keeps the subscription active, if the policy still allows it.
| Status | Cause |
|---|---|
403 | You called as an impersonation session. |
404 | No service subscription with that ID on this Account. |
409 | The subscription's current state does not allow the change. |
422 | cancelReason or cancelReason.code is missing or not one of the values above. |
Create, update and payment history
Create a subscription takes planId and optional metadata, and answers 201 with the subscription. Update a subscription takes planId and metadata. Cancellation uses its own route. To buy a Plan with consent and pricing, use Plans and purchases.
Get payment history lists payment attempts. Each has id, accountId, amount, currency, status (Succeeded, Failed, Pending or Refunded), periodStart, periodEnd and events.createdAt.
Webhook events
Subscription lifecycle events are published as webhooks. See Webhooks and events to subscribe.
Updated 12 minutes ago