Easy Labs
SDKsNode.jsResources

Products & Pricing

Products and prices — methods, parameters, and examples for @easylabs/node.

Products are the catalog rows ("Pro plan", "Setup fee"); prices attach a currency, amount, and (for recurring prices) an interval to a product. Subscriptions and checkout line items reference prices, not products — a single product typically has several active prices (monthly vs. yearly, USD vs. EUR, etc.).

Methods

Products

easy.createProduct(body);                 // POST /products
easy.getProduct(productId);               // GET /products/:id
easy.getProducts(params?);                // GET /products
easy.updateProduct(productId, body);      // PATCH /products/:id
easy.archiveProduct(productId);           // PATCH /products/:id/archive
easy.getProductWithPrices(productId);     // GET /products/:id/prices
easy.getProductWithPrice(productId, priceId); // GET /products/:id/prices/:priceId

createProduct payload:

await easy.createProduct({
  name: "Pro plan",
  active: true,
  description: "Everything in Free, plus team seats.",
  image_url: "https://cdn.example.com/pro.png",
  statement_descriptor: "EXAMPLE PRO",
  unit_label: "seat",
  metadata: { tier: "pro" },
  default_price_id: undefined, // set after you create a price
});

updateProduct accepts Partial<CreateProduct> — including switching default_price_id once you have one. archiveProduct flips it to inactive without deleting historical orders.

Prices

easy.createPrice(body);                   // POST /product-prices
easy.getPrice(priceId);                   // GET /product-prices/:id
easy.getPrices(params?);                  // GET /product-prices
easy.updatePrice(priceId, body);          // PATCH /product-prices/:id
easy.archivePrice(priceId);               // PATCH /product-prices/:id/archive

CreatePrice is a discriminated union on recurring:

// Recurring
await easy.createPrice({
  product_id: "PD_...",
  active: true,
  recurring: true,
  currency: "USD",
  unit_amount: 2900,                // $29.00
  interval: "month",
  interval_count: 1,
  tax_behavior: "exclusive",
  pricing_model: "per_unit",
  trial_period_days: 14,
});

// One-time
await easy.createPrice({
  product_id: "PD_...",
  active: true,
  recurring: false,
  currency: "USD",
  unit_amount: 4999,
  tax_behavior: "exclusive",
});

updatePrice accepts only the fields the API treats as editable in flight: active, metadata, description. Everything else (amount, currency, interval) is immutable — create a new price and switch the product's default_price_id.

Object shape

ProductData

id, name, description, active, image_url, statement_descriptor, unit_label, default_price_id, metadata, created_at, updated_at, plus company_id (stripped on the nested getProductWithPrices response via PickExcept).

PriceData

FieldTypeNotes
idstring
product_idstring
currencyCurrencyCodeISO 4217.
unit_amountnumberSmallest currency unit.
recurringboolean
interval"day" | "week" | "month" | "year" | nullNull on one-time prices.
interval_countnumber | nullE.g. 3 with interval: "month" for quarterly.
pricing_model"per_unit" | "tiered_volume" | "tiered_graduated" | "package" | "metered" | "flat_rate" | null
trial_period_daysnumber | null
tax_behavior"exclusive" | "inclusive"
tax_rate_idstring | null
descriptionstring | null
metadataRecord<string, unknown>
activeboolean

Examples

Spin up a new monthly plan

const product = await easy.createProduct({ name: "Team plan", active: true });
const price = await easy.createPrice({
  product_id: product.data.id,
  active: true,
  recurring: true,
  currency: "USD",
  unit_amount: 4900,
  interval: "month",
  interval_count: 1,
  tax_behavior: "exclusive",
});
await easy.updateProduct(product.data.id, { default_price_id: price.data.id });

Migrate to a new price (deprecate the old one)

const newPrice = await easy.createPrice({ /* … */ });
await easy.updateProduct(productId, { default_price_id: newPrice.data.id });
await easy.archivePrice(oldPriceId);

Read product + every price in one round-trip

const { data } = await easy.getProductWithPrices(productId);
for (const p of data.prices) {
  console.log(p.id, p.unit_amount, p.interval);
}

On this page