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:read to read, and users.subscription:write to create or update.
  • revenue.subscriptions:write to cancel or withdraw a cancellation.
  • A Person or service account that is not an impersonation session. Cancel and withdraw return 403 for impersonation sessions.

Endpoints

PurposeMethod and path
List subscriptionsGET /v3/platform/subscriptions
Get a subscriptionGET /v3/platform/subscriptions/{subscriptionId}
Create a subscriptionPOST /v3/platform/subscriptions
Update a subscriptionPATCH /v3/platform/subscriptions/{subscriptionId}
Cancel a subscriptionPOST /v3/platform/subscriptions/{subscriptionId}/cancel
Withdraw a cancellationPOST /v3/platform/subscriptions/{subscriptionId}/withdraw-cancellation
Get payment historyGET /v3/platform/subscriptions/{subscriptionId}/payment-history

The Subscription object

FieldNotes
id, accountId
planId, planVersion, planName, planTypeplanType is Service or Benefit.
statusCreated, PendingActivation, Active, Suspended, PendingCancellation, Cancelled, Lapsed, Failed or Superseded.
subscriptionVersion
termstartAt, currentPeriodStart, currentPeriodEnd, renewalMode (AutoRenew, ManualRenew or NonRenewing).
projectedCancellationEffectiveAt, cancellationEffectiveAtWhen a cancellation takes effect.
cancelReasoncode, 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.

StatusCause
403You called as an impersonation session.
404No service subscription with that ID on this Account.
409The subscription's current state does not allow the change.
422cancelReason 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.


Did this page help you?