Billing & Webhooks
Manage subscriptions, checkout sessions, usage, and Polar webhooks.
Administrative endpoints to manage billing subscriptions, quotas, checkout processes, and handle incoming payment notifications from Polar.
Session JWT Required
All billing routes except the webhook require the user's Supabase Auth session JWT. Webhooks use cryptographic signature verification.
1. Create Checkout Session
Create a checkout session for Polar plan subscriptions (e.g. Pro or Team).
Request URL
POST /billing/create-checkoutRequest Body Schema
{
"productId": "polar_prod_12345",
"successUrl": "https://sovseal.com/success"
}Response (200 OK)
{
"url": "https://sandbox.polar.sh/checkout/12345"
}2. Customer Portal Link
Retrieve a redirect link to the Polar customer billing portal.
Request URL
POST /billing/customer-portalRequest Body Schema
{
"returnUrl": "https://sovseal.com/dashboard"
}Response (200 OK)
{
"url": "https://sandbox.polar.sh/customer-portal/98765"
}3. Retrieve Subscription
Fetch current plan configurations and quota states for the user.
Request URL
GET /billing/subscriptionResponse (200 OK)
{
"subscription": {
"user_id": "0x123456789...",
"plan": "pro",
"status": "active",
"quota_sync_ops": 100000,
"quota_storage_bytes": 10737418240,
"quota_subkeys": 10,
"quota_devices": 20,
"polar_customer_id": "cust_123",
"polar_subscription_id": "sub_456",
"current_period_end": "2026-07-09T16:45:30Z",
"updated_at": "2026-06-09T16:45:30Z"
}
}4. Retrieve Usage Metrics
Retrieve cumulative usage statistics across all of the user's API keys for the current billing cycle.
Request URL
GET /billing/usageResponse (200 OK)
{
"usage": {
"sync_ops": 4252,
"store_ops": 4252,
"recall_requests": 14205,
"bytes_stored": 4582103,
"devices": 3
}
}5. Polar Webhook Handler
Receives cryptographically signed webhook calls from Polar to update user subscriptions on-the-fly.
Request URL
POST /billing/webhook- Security: Signature verification using Standard Webhooks HMAC. Rejects missing or invalid signatures with
403 invalid_webhook_signature. - Events Handled:
subscription.created/subscription.active— Upsert active plan and reset quotas.subscription.updated— Sync period boundaries and subscription statuses.subscription.canceled/subscription.revoked— Reset status to canceled, drop quotas back to the Free plan.