Subscriptions tie a customer, a plan, and a payment method together. EPD generates renewal orders automatically.

Tools

create_subscription

Create a new subscription. The first charge runs immediately and fires subscription.created (plus an order.succeeded for the underlying order).

readOnlydestructiveidempotentopenWorld
falsefalsetruefalse

Required:

  • customer_id, plan_id, payment_method_id
  • billing_cycle — how often to charge. An object with interval ("day" or "month"), interval_count (number of intervals between charges, e.g. 1 for monthly), and an optional anchor_day.

Optional:

  • end_date — a specific calendar date when the subscription stops (e.g. "2026-12-31").
  • billing_cycles — a fixed number of charges, after which the subscription completes (e.g. 12 for a year of monthly billing). Use one or the other, not both.
  • shipping_address_id / shipping_address — for physical goods.
  • shipping_option_id — delivery method.
  • coupon_code — apply a coupon to the initial charge. Case-insensitive, 4–50 chars, [A-Za-z0-9-]. The discount is captured in the redemption snapshot and persists across later cycles per the coupon’s duration. Ineligible codes (expired, exhausted, wrong plan/currency, first-time-customer rule, etc.) surface as a structured error and the subscription is not created.
  • idempotency_key

Free trials are not currently supported on the API. Implement trial logic in your application, or use a $0 plan in the portal and switch the customer to a paid plan when their trial ends.

list_subscriptions

List subscriptions with filters (customer, status, plan) and cursor pagination.

readOnlydestructiveidempotentopenWorld
truefalsetruefalse

get_subscription

Get one subscription, including its lifecycle history.

readOnlydestructiveidempotentopenWorld
truefalsetruefalse

Pass expand to inline related data: customer, plan, and cycles. cycles returns the full per-cycle billing history (newest-first, no cap) — each entry has cycle_number, amount, currency, status, billing_date, and the order_id for that charge. Expanding cycles on list_subscriptions is supported but costly; prefer it here on a single subscription.

For failure-recovery flows, every subscription also carries failure_reason, attempt_count, and next_retry_at (the next scheduled charge time while a payment is outstanding, not an accelerated retry — null otherwise). To re-attempt a failed cycle’s charge on demand, find its order (cycles[].order_id) and call retry_order.

update_subscription

Patch payment_method_id, billing_cycle, shipping_address_id/shipping_address, or shipping_option_id. Plan changes are not supported on this endpoint — cancel the subscription and create a new one against the new plan.

readOnlydestructiveidempotentopenWorld
falsefalsetruefalse

cancel_subscription

Cancel a subscription. Cancellation is always immediate — there is no at_period_end flag today. The body is empty.

readOnlydestructiveidempotentopenWorld
falsetruetruefalse

active, paused, past_due, and failed subscriptions can all be canceled. A subscription already in a terminal state returns a conflict error: already_canceled if it is already canceled, subscription_completed if it has finished all its billing cycles.

What is not in MCP today

pause_subscription and resume_subscription REST endpoints exist but currently return HTTP 501 Not Implemented — the feature is on the roadmap. They are not exposed as MCP tools yet. To pause-and-resume today, cancel the subscription and create a fresh one when the customer comes back.