Subscriptions
Subscriptions — methods, parameters, and examples for @easylabs/node.
A subscription is a recurring billing relationship between a customer and one or more prices. The SDK exposes the full lifecycle — create, update items, pause/resume, apply discounts, report metered usage, preview proration, cancel — plus one-time charges that ride along on the next invoice.
Methods
Lifecycle
easy.createSubscription(body); // POST /subscriptions
easy.getSubscription(id); // GET /subscriptions/:id
easy.getSubscriptions(params?); // GET /subscriptions
easy.updateSubscription(id, body); // PATCH /subscriptions/:id
easy.cancelSubscription(id, { at_period_end? }); // DELETE /subscriptions/:id
easy.pauseSubscription(id, { behavior, resumes_at? }); // POST /subscriptions/:id/pause
easy.resumeSubscription(id); // POST /subscriptions/:id/resume
easy.getSubscriptionProrationPreview(id, params?); // GET /subscriptions/:id/proration-previewconst { data: sub } = await easy.createSubscription({
identity_id: customer.id,
items: [{ price_id: "PR_monthly", quantity: 1 }],
instrument_id: paymentInstrumentId,
proration_behavior: "create_prorations",
trial_period_days: 14,
metadata: { plan: "pro_monthly" },
});
// Schedule cancellation at period end:
await easy.cancelSubscription(sub.id, { at_period_end: true });
// Pause until a date:
await easy.pauseSubscription(sub.id, {
behavior: "mark_uncollectible",
resumes_at: "2026-08-01T00:00:00Z",
});
await easy.resumeSubscription(sub.id);pauseSubscription's behavior is "void" | "keep_as_draft" | "mark_uncollectible" — controls how invoices generated during the pause are handled.
Items
easy.addSubscriptionItem(subId, { price_id, quantity? });
easy.updateSubscriptionItem(subId, itemId, { quantity });
easy.removeSubscriptionItem(subId, itemId);Discounts
easy.applySubscriptionDiscount(subId, body); // POST /subscriptions/:id/discounts
easy.listSubscriptionDiscounts(subId); // GET /subscriptions/:id/discounts
easy.removeSubscriptionDiscount(subId, discountId); // DELETEbody is exactly one of:
{ coupon_id: string; subscription_item_id?: string }
| { promotion_code: string; subscription_item_id?: string }One-time charges
await easy.createOneTimeCharge(subId, {
price_id: "PR_setup_fee",
quantity: 1,
description: "Implementation fee",
due_date: "2026-06-01",
});The charge attaches to the subscription's next invoice without changing recurring items.
Metered usage
await easy.reportSubscriptionUsage(subId, {
subscription_item_id: itemId,
quantity: 42,
action: "increment", // or "set"
timestamp: new Date().toISOString(),
idempotency_key: deliveryEventId,
});
await easy.getSubscriptionUsageSummary(subId, {
subscription_item_id: itemId,
from: "2026-04-01",
to: "2026-04-30",
});
await easy.getSubscriptionUsageReconciliation(subId, {
subscription_item_id: itemId,
period_start: "2026-04-01",
period_end: "2026-04-30",
});Proration preview
Run a dry-run before applying item changes:
const preview = await easy.getSubscriptionProrationPreview(subId, {
items: [{ price_id: "PR_higher_tier", quantity: 1 }],
remove_items: [oldItemId],
proration_date: new Date().toISOString(),
});Object shape
SubscriptionData:
| Field | Type | Notes |
|---|---|---|
id | string | |
identity_id / instrument_id | string | string | null | |
status | SubscriptionStatus | TRIALING, ACTIVE, PAST_DUE, CANCELED, UNPAID, PAUSED, INCOMPLETE, INCOMPLETE_EXPIRED. |
items | SubscriptionItem[] | Each with price_id, optional price, quantity, metadata. |
current_period_start / current_period_end | string | null | ISO timestamps. |
trial_start / trial_end | string | null | |
billing_cycle_anchor | string | null | |
cancel_at / cancel_at_period_end / canceled_at / ended_at | various | Cancellation state. |
pause_collection | { behavior, resumes_at } | null | |
latest_invoice_id | string | null | |
proration_behavior | ProrationBehavior | null | |
credit_balance | number | |
pending_update | SubscriptionPendingUpdate | null |
Examples
Upgrade with proration preview
const previewed = await easy.getSubscriptionProrationPreview(subId, {
items: [{ price_id: "PR_pro_yearly", quantity: 1 }],
remove_items: [currentMonthlyItemId],
});
// Show previewed.data to the user, then commit:
await easy.updateSubscription(subId, {
items: [{ price_id: "PR_pro_yearly", quantity: 1 }],
remove_items: [currentMonthlyItemId],
proration_behavior: "create_prorations",
});Apply a 3-month coupon
const coupon = await easy.createCoupon({
duration: "repeating",
duration_in_months: 3,
percent_off: 25,
name: "Q2 promo",
});
await easy.applySubscriptionDiscount(subId, { coupon_id: coupon.data.id });Idempotent metered usage from a webhook
await easy.reportSubscriptionUsage(subId, {
subscription_item_id: itemId,
quantity: 1,
action: "increment",
idempotency_key: webhookDeliveryId, // repeat-safe
});