Skip to main content

Subscriptions

A subscription ties a customer to a pricing plan. It’s the thing that says “starting on this date, bill this customer according to this plan’s rules.” Until a customer has a subscription, MarginFront doesn’t know how to charge them — usage events can still be logged, but there’s no pricing rule attached. Creating a subscription is the most complex create in the whole API because it brings together four other objects: a customer, an agent, a pricing plan, and a start date. All four have to already exist before you can create the subscription.

The whole integration chain

Before you can create a subscription, you need (in this order):
  1. A customer — see customers
  2. An agent — see agents
  3. One or more signals attached to that agent — see signals
  4. A pricing plan attached to that agent — see pricing-plans
Once those exist, you create the subscription that glues customer ↔ plan together. After that, every usage event you log gets priced according to the subscribed plan and rolled up into an invoice at the end of the billing period.

Create a subscription

In plain English: Start billing a customer according to a pricing plan. You’re saying “from this date forward, charge this customer for this agent’s usage according to this plan.” Method & URL:
POST /v1/subscriptions
Required fields:
  • name (string) — A human-readable name for the subscription. Useful for identifying it in the dashboard.
  • planId (UUID string) — The pricing plan’s internal ID. From the pricing plan’s create response.
  • agentId (UUID string) — The agent’s internal ID. Must match the agent that the plan belongs to.
  • customerId (UUID string) — The customer’s internal ID. From the customer’s create response.
  • startDate (ISO 8601 date string) — When this subscription starts billing. Can be in the past (for backdating) or the future (for scheduled activation). Example: "2026-04-10T00:00:00.000Z".
Optional fields (most common):
  • status ("upcoming" | "active" | "ended", default "upcoming") — Current state. Use "active" if you want billing to start immediately.
  • billingCycle ("monthly" | "yearly" | "custom", default "monthly") — How often invoices are generated.
  • billingModel ("subscription" | "usage" | "hybrid", default "subscription") — How billing is calculated.
    • "subscription" = flat recurring fee
    • "usage" = pay only for what you use
    • "hybrid" = base fee + usage
  • netTerms (number, default 30) — Payment terms in days after invoice issued.
  • autoCollectPayment (boolean, default false) — Whether to automatically charge the customer’s saved payment method when an invoice is generated.
Other optional fields:
  • endDate (ISO date) — Fixed end date if this is a time-limited subscription
  • isForever (boolean, default false) — Set true for subscriptions with no end date (ignores endDate)
  • subscriptionDetails (object) — Free-form metadata specific to this subscription
  • seatsCount (number, default 0) — For per-seat pricing
  • customCycleDays (number) — Only when billingCycle is "custom"; how many days between invoices
  • proratedAmount (number) — Proration adjustment for mid-cycle starts
  • timezone (string) — Override for billing period calculations
  • billingDay (1-31) — Day of the month invoices are generated
  • invoiceMemo (string) — A note that appears on every invoice for this subscription
  • metadata (object) — Custom key/value pairs; stored but not interpreted
Example curl call (the minimum to get a working subscription):
curl -X POST https://api.marginfront.com/v1/subscriptions \
  -H "x-api-key: mf_sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Pro Subscription",
    "planId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "agentId": "b47e12fa-abcd-4567-8901-234567890abc",
    "customerId": "5e7f8a3d-1234-5678-9abc-def012345678",
    "startDate": "2026-04-10T00:00:00.000Z",
    "status": "active",
    "billingCycle": "monthly"
  }'
What you get back (201 Created):
{
  "id": "sub_9a8b7c6d-...",
  "name": "Acme Pro Subscription",
  "planId": "a1b2c3d4-...",
  "agentId": "b47e12fa-...",
  "customerId": "5e7f8a3d-...",
  "startDate": "2026-04-10T00:00:00.000Z",
  "status": "active",
  "billingCycle": "monthly",
  "createdAt": "2026-04-10T14:30:00.000Z"
}
Common errors:
  • 400 Bad Request — Missing one of the required fields, or a UUID is the wrong format, or startDate isn’t a valid ISO date.
  • 404 Not Found — One of the referenced objects (customer, agent, plan) doesn’t exist in this org.
  • 409 Conflict — This customer already has an overlapping active subscription for this plan, depending on your org’s rules.
When to call this: When a customer upgrades, signs up for a paid plan, or activates a trial. This is the “billing starts now” moment.

Read a subscription

Method & URL:
GET /v1/subscriptions/{subscriptionId}

List subscriptions

Method & URL:
GET /v1/subscriptions
Useful query parameters: customerId, status, agentId (check the controller for the full list).

Update a subscription

Method & URL:
PATCH /v1/subscriptions/{subscriptionId}
Fields: Most fields from create are updatable. The structural fields (planId, agentId, customerId) generally should NOT be changed — if a customer switches plans, it’s usually cleaner to end the current subscription and create a new one rather than mutating the existing subscription, because it preserves a clean audit trail for accounting.

Update invoice dates

Method & URL:
PATCH /v1/subscriptions/{subscriptionId}/invoice-dates
What it does: Adjusts when future invoices will be generated for this subscription. Use this for things like “customer wants to move their billing day from the 1st to the 15th.”

Read the subscription changelog

Method & URL:
GET /v1/subscriptions/{subscriptionId}/changelog
What it returns: A history of all changes made to this subscription — plan changes, price updates, date adjustments, status transitions. Useful for audit trails and for customer support when someone asks “when did that price change?”

Using the Node SDK

// List all subscriptions
const { data } = await mf.subscriptions.list();

// Read a specific subscription
const sub = await mf.subscriptions.get("sub_9a8b7c6d-...");
Subscription CREATE is not yet wrapped by the @marginfront/sdk npm package. For now, create subscriptions through the HTTP API using curl or your language of choice — see the “Create a subscription” section above.