Subscriptions & seats
Recurring subscription charges, quantity, seat-based subscriptions and proration.
A subscription is a recurring line on a contract, priced by a SUBSCRIPTION product's rate, which sets its billing_frequency. Quantity is the number of subscriptions, usually seats.
Metronome's reference: Edit a contract · Get a contract (v2) · Get subscription quantity history · Get subscription seats history. These pages are the source of truth for every field; metro's page covers how metro handles it. What metro wraps, endpoint by endpoint: Metronome API coverage.
Each subscription has a collection schedule (ADVANCE or ARREARS), proration settings, and a quantity mode:
| Mode | Set at create | Change later |
|---|---|---|
QUANTITY_ONLY (default) | initial_quantity | quantity_updates: an absolute quantity or a quantity_delta |
SEAT_BASED | seat_config.seat_group_key, initial_seat_ids | seat_updates: add or remove seat IDs, or unassigned seats |
Seats aren't a separate object. They're a view of a SEAT_BASED subscription. A seat ID is whatever you assign, usually your own user ID. You can switch from QUANTITY_ONLY to SEAT_BASED once, and it can't be undone.
How it connects
The subscription rate's product_id points at a SUBSCRIPTION product on the contract's rate card. The subscription_id comes from the contract, at data.subscriptions[].id. All changes go through a contract edit.
Proration
- Increases are prorated.
BILL_IMMEDIATELY(needsADVANCE) charges right away.BILL_ON_NEXT_COLLECTION_DATEadds the amount to the next invoice. - Decreases take effect at the next billing boundary.
- Proration is set per subscription, not per seat.
Gotchas
quantity_updateson aSEAT_BASEDsubscription returns400.- On a
SEAT_BASEDsubscription the contract's quantity schedule shows only the initial state. Use the seats history for current state. subscription_idchanges when a plan change creates a new contract. Look it up again; don't cache it.- A subscription bills on its own
billing_frequency, not the commit's. A subscription-rate override withoutbilling_frequencyis silently ignored. - Past-dated quantity changes don't restate finalized invoices.
- Removing a seat that isn't assigned does nothing, with no error.
How metro handles it
| Command | Does |
|---|---|
metro subscription add preflight --product-id=<id> --billing-frequency=MONTHLY --quantity=10 | Adds a QUANTITY_ONLY subscription. Refuses a non-subscription product, a missing rate at that frequency, or a duplicate unless --allow-duplicate. |
metro subscription add preflight --file=subscription.yaml | Any subscription, including SEAT_BASED |
metro subscription set-quantity preflight --subscription-id=<id> --quantity=12 | Changes quantity. --delta= works too; metro always sends the absolute quantity. |
metro subscription seats preflight --subscription-id=<id> --add-seat-ids=a,b | Adds or removes seats, assigned or unassigned |
metro subscription history inspect --customer-id <id> --contract-id <id> --subscription-id <id> --sandbox --plan | A read plan for a subscription's history |