---
title: "2026-08-09 · Grant intervals run on their own schedule"
description: "daily, weekly and monthly grant intervals now fire on their own clock instead of waiting for the billing cycle, and a new endpoint lists a variant's grants."
order: 1
date: "2026-08-09"
---

# Grant intervals run on their own schedule

`grant_interval` now means what it says. `daily`, `weekly` and `monthly` fire on
their own schedule, counted from the moment the subscription starts. That
schedule does not have to match the variant's billing cycle.

So a yearly plan can refresh credits every month. A monthly plan can refresh
credits every day. Only `billing_cycle` waits for a renewal.

## What changed

Before today, those three keywords behaved the same as `billing_cycle`. A
`monthly` grant on a yearly variant fired once a year. A `monthly` grant on a
daily variant fired every single day. The keyword you picked changed nothing.

If your grant interval already matches your billing cycle, nothing changes for
you. That is the common setup, and it worked correctly before.

## Calendar months

`monthly` is a real calendar month, anchored to the day the subscription
started. A subscription that starts on the 30th grants on 28 February, then on
30 March. A short month does not move the date for good.

The same rule holds for the 31st, and for 29 February in a leap year.

## Three fixes that came with it

`accumulation_cap` and `rollover_percentage` now apply to grants on an ISO 8601
interval, such as `PT5H`. They were ignored on those grants before, so a cap did
not cap and rollover did not roll.

A grant with `expires_after_seconds` set now expires the previous block from the
same rule before issuing a new one. Grants on an ISO 8601 interval used to rely
on the expiry clock alone, so a block could still be live when the next one
landed. Blocks from one rule no longer overlap. If you deliberately set a long
expiry so windows would stack, they no longer stack — use `accumulation_cap`, or
leave `expires_after_seconds` empty, to let credits build up.

A grant on an interval that does not match the billing cycle now also fires when
the subscription starts. It used to grant nothing until the first renewal.

## Reading a variant's grants

`GET /v1/plans/{id}/variants/{vid}/grants` is new. It lists every grant schedule
on a variant. The collection accepted `POST` only before, so a grant could be
created and never read back.

## Write P7D, not P1W

The duration form takes days, hours, minutes and seconds. Weeks were never
accepted, though the docs listed `P1W`. Use `P7D`, or the `weekly` keyword.
