Start a plan checkout or change the current plan

posthttps://api.expiryedge.com/v1/createSubscription
admin60/minAny method
Request
curl -X POST 'https://api.expiryedge.com/v1/createSubscription' \
  -H "Authorization: Bearer $EXPIRYEDGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "subscription_plan_id": "prod_SJbWzGAm137eGN",
  "frequency": "Year",
  "price": 348,
  "withdrawal_consent": true,
  "withdrawal_consent_at": "2026-09-27T14:05:00.000Z"
}'
Response
{
  "status": "success",
  "type": "upgrade",
  "subscription_id": "sub_1QfT8sLm2Northwind",
  "message": "Your plan has been updated. The prorated difference has been charged to your card on file."
}

With no active plan subscription, creates a Stripe Checkout session (201) - redirect to url. With an active/trialing/past_due subscription, swaps the price in place with an immediate prorated charge (200). Referral, promo and early-bird discounts are applied server-side from the organization's state.

Body parameters

application/json
  • subscription_plan_idstringrequired
    Stripe product id of a self-serve plan. Unknown products are rejected.
  • frequencystring
    Month or Year (Yearly/Annual also accepted). Default Month.
    Default Month
  • pricenumber
    Amount the client displayed, in USD. Must match a server-side price for the plan and interval, otherwise 400 INVALID_PRICE.
  • apply_referral_discountboolean
    When price is sent, apply the org referral discount on top of it.
  • subscription_periodinteger
    Metadata only.
  • billing_cyclesinteger
    Metadata only.
  • period_unitstring
    Metadata only (max 20 chars).
  • customer_emailstring
    Used only when the token carries no email.
    format: email
  • withdrawal_consentboolean
    EU withdrawal-right consent, recorded on the Stripe session.
  • withdrawal_consent_atstring | null
    format: date-time
  • user_idstringDeprecated
    Ignored; the caller is always the purchaser.
  • currencystringDeprecated
    Ignored; plans are always charged in USD.

Returns

200
Existing subscription changed in place; the prorated difference was charged.
  • statusstringrequired
    Allowedsuccess
  • typestringrequired
    Allowedupgrade
  • subscription_idstringrequired
  • messagestring

Errors

201
Stripe Checkout session created.
400
Unknown plan, price mismatch, or another failure (code: SUBSCRIPTION_ERROR).
401
Missing, expired or invalid bearer token.
403
Authenticated, but your role or organization does not allow this action.
429
Too many requests for this endpoint from your IP. Wait Retry-After seconds.
500
Existing subscription is in an inconsistent state.