Skip to main content
A subscription binds one or more recurring-price items to a customer and bills them automatically on each renewal date. Your backend creates the subscription; Ionic creates each subsequent invoice. On Node, npm install @ionicfi/sdk gives you typed calls for every request below; the server SDK guide has details. Each example also shows raw curl.

Lifecycle

1

Create the subscription

Your server calls POST /v1/subscriptions with a customer ID, one or more recurring-price items, and a collection method. An initial invoice is issued immediately unless the subscription opens with a trial.
2

Trial period (optional)

When trial_end is set, the subscription starts in trialing and no invoice is issued. At trial_end, Ionic charges default_payment_method and advances the status to active.
3

Automatic renewals

At each current_period_end, Ionic issues a renewal invoice and advances the period. A failed renewal moves the subscription to past_due; exhausting the retry period moves it to unpaid.
4

Gate access with entitlement

Call GET /v1/subscriptions/{id}/entitlement on each access check. Listen for subscription.updated and subscription.canceled webhooks to react to state changes.

Create a subscription

Request fields

Item fields

For a charge_automatically subscription with a trial, provide default_payment_method at creation. If it is absent when the trial ends, the renewal invoice cannot be collected automatically.

The billing cycle

Each subscription exposes these period fields on the response object:

Status values

Cancel a subscription

Pass at_period_end: true to let the current period run out before canceling. Omit the field or pass false for an immediate cancellation.
An immediate cancellation transitions the subscription to canceled. A period-end cancellation sets cancel_at_period_end: true on the subscription; the status remains unchanged until the period ends, when the subscription is canceled automatically.
A period-end cancellation fires subscription.updated, not subscription.canceled. Do not revoke access when cancel_at_period_end flips to true. Revoke access only when you receive subscription.canceled.

Resume a scheduled cancellation

Reverses a period-end cancellation that has not yet taken effect. Only valid when cancel_at_period_end is true.

Update items

Replaces the subscription’s billed items. Items with a known id (si_…) are updated in place; items without an id are added as new items. All items must share the subscription’s existing currency and billing cadence.

Update collection method

Update default payment method

Pass null for default_payment_method to clear it.

Update metadata

Replaces the metadata map entirely. Keys absent from the request are removed.

Check entitlement

Call the entitlement endpoint to check whether the subscription currently includes access. Use entitled as the gate.
Gate access on entitled, not on access_until. The access_until timestamp is informational — it can be null or in the past while entitled is true, for example during a dunning retry or when a renewal sweep is pending.

Retrieve and list

The list endpoint accepts customer, status, limit (default 20, max 100), and offset.

Webhooks

Read data.object on every event for the full subscription snapshot. Do not infer access from the event type alone.
A period-end cancellation fires subscription.updated with cancel_at_period_end: true. The subscription.canceled event arrives later, when the period ends. Keep the subscriber’s access open between these two events.
See Webhook events for the full event catalog and delivery guarantees.

Operational guidance

  • Always send an Idempotency-Key on write requests. Network retries can otherwise create duplicate subscriptions, double item updates, or duplicate cancellations.
  • A 409 Conflict response means the subscription was modified concurrently. Retry the same request with the same Idempotency-Key.
  • For charge_automatically subscriptions, keep default_payment_method current. An expired card causes the renewal to fail and moves the subscription to past_due.
  • Store your plan IDs, seat counts, or feature flags in metadata. Update metadata from your application layer; do not derive access decisions from it.
  • Use the entitlement endpoint for runtime access checks. Use webhooks to react to state changes asynchronously in your provisioning and access-control systems.