Subscriptions
A subscription places a customer on a plan. It is the central object in Driptab: it drives billing period management, event aggregation, and invoice generation.
Creating a subscription
dtab subs create \
--external-id your-system-sub-id \
--customer <customer_id_or_external_id> \
--plan <plan_code_or_id>
Or via the API:
POST /v1/subscriptions
X-Project-Id: <project_id>
Authorization: Bearer dtab_…
{
"external_id": "your-system-sub-id",
"customer_id": "uuid-of-customer",
"plan_id": "uuid-of-plan"
}
When a subscription is created:
- A
SubscriptionMeterDurable Object is initialised for this subscription. current_period_startis set to now (UTC);current_period_endis calculated from the plan's interval.- An alarm is scheduled on the DO to fire at
current_period_end. - Status is set to
active.
Subscription properties
Some plans use quantity_formula: subscription_property.node_count on a charge,
which means the quantity for that charge comes from the subscription's properties
object. Set properties at creation time:
{
"external_id": "k8s-cluster-prod",
"customer_id": "...",
"plan_id": "...",
"properties": { "node_count": 5 }
}
Properties are stored as JSON on the subscription row and are immutable after creation. To change the node count, terminate and re-create the subscription.
Statuses
| Status | Meaning |
|---|---|
pending |
Created but not yet started. Not currently in use at MVP. |
active |
Billing is running. Events are accepted. Period alarms are scheduled. |
suspended |
Billing is paused. Events are rejected. Invoked by dunning; your system decides when to suspend. |
terminated |
Permanently ended. The current period's usage is invoiced; no further billing. |
canceled |
Administratively closed with no final invoice. |
Status transitions:
pending → active → suspended → active (if payment received)
→ terminated
active → terminated
active → canceled
Driptab does not automatically suspend or terminate subscriptions. It fires webhooks at
dunning milestones; your system calls POST /v1/subscriptions/:id/terminate when it
decides to act. This is intentional — suspension and termination are business decisions
that depend on grace periods, retry logic, and customer communication that Driptab does
not own.
Billing periods
Periods are owned by the SubscriptionMeter Durable Object, not by SQL. The D1
subscriptions table reflects the last known period boundaries but the DO is
authoritative.
With billing_time: 'calendar' (the only mode in MVP), periods align to calendar
boundaries:
monthly— 1st of the month at 00:00:00 UTC to the last day at 23:59:59 UTC.yearly— Jan 1 to Dec 31 UTC.weekly— Monday 00:00 UTC to Sunday 23:59 UTC.
The first period starts when the subscription is created. If a subscription starts on the 15th of the month with a monthly plan, the first period is the 15th to the last day of that month (prorated in future; full period in MVP). The second period starts on the 1st of the following month.
Terminating a subscription
dtab subs terminate <subscription_id>
Termination:
- Marks the subscription
terminated_atand sets status toterminated. - The DO generates a final invoice for any usage accrued in the current period.
- No further period alarms are scheduled.
A terminated subscription cannot be reactivated. Create a new subscription if the customer restarts.
External IDs
external_id is your system's ID for this subscription. It must be unique per project.
The recommended convention is to use your internal subscription record's primary key.
Use external_id (prefixed with ext:) anywhere the API accepts a subscription ID:
dtab subs get ext:your-system-sub-id
dtab ev ingest --subscription ext:your-system-sub-id ...
This avoids storing Driptab's UUID in your system.
Querying a subscription
dtab subs get <id_or_external_id>
Response includes current_period_start, current_period_end, status, plan,
and a summary of charges. It does not include live in-period usage counters (those
live in the DO). To see usage mid-period, use the analytics endpoint or query the
events table.