A subscription is a recurrence wrapper, not a new money object: each period funds a FRESH, mode-identical budget with the declared allowance graph, exactly as if you had opened it by hand. On the card rail that means a fresh hard-hold every period — never a card-on-file drawdown. A renewal that cannot fund fails closed: no period N+1 accrual, the subscription parks in declined with the objective decline detail.
The published 2.0.0 wire client does not yet expose subscribe() — recurrence is an engine capability of every core (shipped at DP6), and it reaches the wire surface in a future minor version per the versioning promise (rule 18: additive change, minor bump, CHANGELOG entry). This page documents the semantics that already govern the engine, because they are law today, not a proposal.
Until then, the pattern is one openBudget per period from your own scheduler — which is exactly what the wrapper automates, with the same fail-closed renewal behavior.
| Question | Answer |
|---|---|
| What recurs? | The funding act. Every period is a fresh budget + streams from the same template |
| Unspent ceiling at period end? | release (default) returns it; roll adds it to the next period's cap |
| Renewal declines? | Fail closed. No accrual for the unfunded period; state declined; the decline detail is the backend's objective error, nothing else |
| Who drives time? | The subscription owner (or their scheduler): a tick closes ended periods and funds next ones |
| Card specifics? | Each period is a fresh manual-capture authorization (card rail); Dynamo never stores a drawable balance |
Webhook events for the lifecycle (subscription.period_opened, subscription.renewal_declined, subscription.closed) shipped in webhook schema 1.1.0 — see webhooks.