# Subscriptions

Use `Subscriptions` for paid, time-bounded access with optional recurring payment consent. A subscription collection defines what one period costs; the subscriber separately authorizes renewal. Use [payment obligations](https://docs.bitbadges.io/standards/payments) for a finite installment schedule or a reusable payment link without recurring access.

## Configuration and variants

| Variant | Configuration | Meaning |
| --- | --- | --- |
| One tier | `--interval`, `--price`, `--denom`, `--recipient` | One faucet, token ID 1, one fixed payout per claim |
| Multiple recipients | `--payouts` array of `{recipient,amount,denom}` | Every payout executes for each period; all must resolve to the same denomination |
| Multiple tiers | `--tiers N` | IDs 1 through N, approvals `subscription-tier-1` through `subscription-tier-N` |
| Transferable access | `--transferable` | Adds post-mint holder transfers; user approvals still apply |
| Editable faucet | `--updatable-mint` | Explicitly leaves mint approvals editable; automatic review reports the resulting risk |

The simple multi-tier builder repeats the same interval and payout configuration across tiers. It does not accept a separate price array per tier. The parser recognizes multiple single-ID faucets whose combined IDs match the collection's contiguous valid range; the standard is not limited to token ID 1.

Durations are fixed millisecond lengths: `daily` is 24 hours, `monthly` is 30 days, and `annually` is 365 days. They do not follow calendar-month lengths or daylight-saving transitions. Each faucet mints amount 1 of its tier for `durationFromTimestamp`; timestamp override supports the recurring schedule. Amount scaling is disabled. Mixed-denomination payout arrays are rejected.

```bash
bb build subscription --interval monthly --price 10 --denom USDC \
  --recipient "$RECIPIENT" --creator "$CREATOR" --uri "$METADATA_URI"
bb subscriptions list "$COLLECTION_ID"
bb subscriptions status "$COLLECTION_ID" --address "$SUBSCRIBER"
```

These are command templates: substitute real addresses, a deployed collection ID, and hosted metadata. Build amounts are display-unit numbers resolved through the builder's coin registry; inspect the emitted base-unit coin amounts before signing.

## Access and renewal lifecycle

| Command | Result |
| --- | --- |
| `bb subscriptions claim <collection-id> --creator <address>` | Builds one paid faucet claim |
| `bb subscriptions enable-renewal <collection-id> --creator <address>` | Adds a recurring incoming approval; does not itself purchase access |
| `bb subscriptions subscribe <collection-id> --creator <address>` | Builds claim plus recurring consent in one message wrapper |
| `bb subscriptions cancel <collection-id> --creator <address>` | Removes matching renewal consent, preserving unrelated recurring approvals |
| `bb subscriptions charge-due <collection-id> --creator <operator> --dry-run` | Lists due subscribers without emitting the charge batch |
| `bb subscriptions charge-due <collection-id> --creator <operator>` | Builds due renewal messages for an operator to submit |

Pass `--tier subscription-tier-2` to choose among multiple faucets. `subscribe` and `enable-renewal` accept `--approval-id` and `--tip`. `cancel` selects by tier and removes every recognized recurring approval matching that tier; it does not accept `--approval-id`. The tip is an integer base-unit amount in the subscription denomination, despite the historical `ubadge` option label; do not treat it as a display-unit amount or a separate BADGE payment.

Consent does not run a scheduler. A transaction-submitting operator is still needed, and charges can fail if funds, approvals, timing, or current chain state no longer permit them. Cancellation stops future use of the removed consent after that update executes. It does not refund prior charges or erase access already held for an ownership-time interval.

## Tracking and boundaries

Determine access from the tier's actual balance and ownership times. Determine renewal authorization from the matching user incoming approval. Neither alone proves the other. Recurring consent permits one transfer per reset interval and carries its own tracker; the collection faucet is a separate approval.

Intervals are inclusive: an interval starting at `s` with length `L` ends at `s + L - 1`. The next interval starts at the previous end plus one. A tracker last updated before the current interval start needs a reset. The renewal charge window is capped at the smaller of one interval and seven days. Before the configured reset start, the helper treats the preceding time as its own interval.

The default builder locks mint approval changes and prevents forceful post-mint transfers. This protects existing access semantics; it does not promise refunds, prorating, automatic upgrades, or calendar billing. Inspect current consent and simulate before renewal submission, especially after a manager-configurable price change.

See [subscription primitives](https://docs.bitbadges.io/agents/skills/subscription), [predetermined balances](https://docs.bitbadges.io/token-standard/approval-criteria/predetermined-balances), [approval trackers](https://docs.bitbadges.io/token-standard/approval-criteria/approval-trackers), and [permissions](https://docs.bitbadges.io/token-standard/concepts/permissions). The current builder/parser tier behavior described here supersedes older single-token wording in primitive examples.

## Subscription JSON

Save the following input as `subscription.json`, replace the demo addresses and metadata, then build it with the CLI command below. `interval` is a fixed duration, `price` is a display-unit number, and `tiers` creates the same faucet configuration for each ID. To split each charge, replace `price`, `denom`, and `recipient` with `payouts: [{recipient, amount, denom}]`; all denominations must resolve identically. Recurring user consent is a later action, not a field in this collection input.

<!-- sdk-example: buildSubscription -->
```json
{
  "interval": "monthly",
  "price": 10,
  "denom": "BADGE",
  "recipient": "bb1xvenxvenxvenxvenxvenxvenxvenxvenlrd2nm",
  "tiers": 2,
  "transferable": false,
  "updatableMint": false,
  "uri": "https://example.com/metadata.json"
}
```

```bash
bb build subscription --json subscription.json \
  --interval "$(jq -r '.interval' subscription.json)" \
  --creator "$CREATOR" --output-file subscription-proposal.json
```

The repeated required flags are read from the same JSON file because CLI argument validation runs before loading JSON. Review the resulting proposal using the [CLI lifecycle](https://docs.bitbadges.io/standards/lifecycle). SDK reference: `buildSubscription`.
