Backend APIEndpoints
Subscription
Stripe subscription management — checkout, webhook, and status
Subscription
GET /api/subscription
Get the user's current subscription status.
| Method | Path | Auth | Tier |
|---|---|---|---|
| GET | /api/subscription | JWT Bearer | Free |
Response 200 OK
{
"tier": "pro",
"status": "active",
"stripe_subscription_id": "sub_...",
"valid_until": "2024-02-15T00:00:00Z",
"cancel_at_period_end": false
}tier values: free | pro | family
status values: active | cancelled | past_due | trialing
POST /api/subscription/checkout
Create a Stripe Checkout session to start or upgrade a subscription.
| Method | Path | Auth | Tier |
|---|---|---|---|
| POST | /api/subscription/checkout | JWT Bearer | Free |
Request body
{
"tier": "pro",
"success_url": "https://app.cookest.app/subscription/success",
"cancel_url": "https://app.cookest.app/subscription/cancel"
}Response 200 OK
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_..."
}Redirect the user to checkout_url. After payment, Stripe calls the webhook and the user's tier is updated automatically.
POST /api/subscription/portal
Create a Stripe Customer Portal session for managing billing.
| Method | Path | Auth | Tier |
|---|---|---|---|
| POST | /api/subscription/portal | JWT Bearer | Pro |
Request body
{
"return_url": "https://app.cookest.app/settings"
}Response 200 OK
{
"portal_url": "https://billing.stripe.com/session/..."
}POST /api/subscription/webhook
Stripe webhook receiver. Not called by the app — called by Stripe.
| Method | Path | Auth | Tier |
|---|---|---|---|
| POST | /api/subscription/webhook | Stripe signature | — |
This endpoint verifies the Stripe-Signature header using STRIPE_WEBHOOK_SECRET. All events are idempotent — re-delivery of the same event is handled safely.
Handled Stripe events:
customer.subscription.created— activates tiercustomer.subscription.updated— updates tier and validitycustomer.subscription.deleted— reverts to Freeinvoice.payment_failed— marks subscription aspast_due