Skip to content

Billing API

Inklet uses Stripe for subscription management. The billing endpoints let users subscribe, manage their payment methods, and view invoices. All endpoints require authentication unless otherwise noted.

Endpoints


GET /auth/subscription

:material-lock: Requires authentication

Retrieve the authenticated user's current subscription information.

Request Headers:

Authorization: Bearer {accessToken}

Response: 200 OK

{
  "status": "active",
  "plan": "pro",
  "interval": "monthly",
  "currentPeriodStart": "2026-01-15T10:30:00Z",
  "currentPeriodEnd": "2026-02-15T10:30:00Z",
  "cancelAtPeriodEnd": false,
  "stripeCustomerId": "cus_abc123",
  "stripeSubscriptionId": "sub_xyz789"
}
{
  "status": "none",
  "plan": null,
  "interval": null,
  "currentPeriodStart": null,
  "currentPeriodEnd": null,
  "cancelAtPeriodEnd": false,
  "stripeCustomerId": "cus_abc123",
  "stripeSubscriptionId": null
}
Field Type Description
status string One of none, active, past_due, canceled, trialing
plan string or null Subscription plan name
interval string or null monthly or yearly
currentPeriodStart timestamp or null Start of the current billing period
currentPeriodEnd timestamp or null End of the current billing period
cancelAtPeriodEnd boolean Whether the subscription cancels at the end of the current period
stripeCustomerId string Stripe Customer ID
stripeSubscriptionId string or null Stripe Subscription ID (null if no subscription)

Errors:

Code Cause
401 Missing or invalid access token

POST /auth/subscription/checkout

:material-lock: Requires authentication

Create a Stripe Checkout session for starting a new subscription. Returns a URL to redirect the user to Stripe's hosted checkout page.

Request Headers:

Authorization: Bearer {accessToken}

Request Body:

{
  "interval": "monthly"
}
Field Type Required Description
interval string Yes monthly or yearly

Response: 200 OK

{
  "url": "https://checkout.stripe.com/c/pay/cs_live_abc123..."
}

Client Integration

Redirect the user to the returned url using window.location.href or open it in a new tab. After successful payment, Stripe redirects the user back to your portal.

Errors:

Code Cause
400 Invalid interval value
401 Missing or invalid access token
409 User already has an active subscription

POST /auth/subscription/portal

:material-lock: Requires authentication

Create a Stripe Billing Portal session. The billing portal lets users manage their payment methods, view invoices, and cancel or modify their subscription.

Request Headers:

Authorization: Bearer {accessToken}

Response: 200 OK

{
  "url": "https://billing.stripe.com/p/session/abc123..."
}

Redirect the user to the returned url. The portal provides a Stripe-hosted UI for self-service billing management.

Errors:

Code Cause
401 Missing or invalid access token

GET /auth/subscription/invoices

:material-lock: Requires authentication

Retrieve the authenticated user's invoice history from Stripe.

Request Headers:

Authorization: Bearer {accessToken}

Response: 200 OK

{
  "invoices": [
    {
      "id": "in_1abc2def3ghi",
      "date": "2026-01-15T10:30:00Z",
      "amount": 999,
      "currency": "usd",
      "status": "paid",
      "invoiceUrl": "https://invoice.stripe.com/i/acct_123/live_abc",
      "pdfUrl": "https://pay.stripe.com/invoice/acct_123/live_abc/pdf"
    },
    {
      "id": "in_4jkl5mno6pqr",
      "date": "2025-12-15T10:30:00Z",
      "amount": 999,
      "currency": "usd",
      "status": "paid",
      "invoiceUrl": "https://invoice.stripe.com/i/acct_123/live_def",
      "pdfUrl": "https://pay.stripe.com/invoice/acct_123/live_def/pdf"
    }
  ]
}
Field Type Description
id string Stripe Invoice ID
date timestamp Invoice creation date
amount integer Amount in the smallest currency unit (e.g., cents for USD)
currency string Three-letter ISO currency code
status string One of draft, open, paid, void, uncollectible
invoiceUrl string URL to the hosted invoice page
pdfUrl string URL to download the invoice PDF

Amount Format

The amount field is in the smallest currency unit. For USD, 999 means $9.99. Divide by 100 for display.

Errors:

Code Cause
401 Missing or invalid access token

POST /auth/webhook/stripe

Stripe webhook endpoint. This is called by Stripe's servers when subscription events occur --- it is not called by clients.

No Authentication Required

This endpoint does not use Bearer token authentication. Instead, it verifies the request using the Stripe-Signature header and the webhook signing secret configured in the backend.

Handled Events:

Event Action
checkout.session.completed Activates the subscription in the database
invoice.paid Updates the billing period
invoice.payment_failed Marks subscription as past_due
customer.subscription.updated Syncs plan, interval, and cancellation status
customer.subscription.deleted Marks subscription as canceled

Response: 200 OK

Returns an empty 200 response to acknowledge receipt. Stripe retries on non-2xx responses.