Docs Cards

Limits, warnings and extra room

A Card’s limits are counted over a window: each day, any 24 hours, any hour, or the Card’s whole life. This page covers when a day starts, a total that never resets, how to change a limit or add room for a while, and the warnings KIFF sends before a limit runs out. None of these give an agent authority on their own: a warning never blocks or approves a call, and only an owner or admin changes a limit or adds room.

Day boundaries and time zone

An owner or admin sets the account’s time zone in Settings → Account, using a named zone such as Europe/Paris or America/Bogota. Calendar-day limits reset at midnight in the Card’s own time zone, including daylight saving changes. Rolling hour and 24-hour limits still measure elapsed time.

The account setting is the default for new Cards only. Existing Cards keep their location and window when the account setting changes or their limits are edited. A Card’s Settings and History → Statement show its actual day boundary. Accounts without a saved setting use UTC.

API clients read the default in GET /v1/me (time_zone) and save it with PUT /v1/me/time-zone, for example {"time_zone":"Europe/Paris"}. Runtime and agent-bound keys cannot change it. An explicit location when issuing a Card takes precedence; omitting it on a reissue preserves the existing Card’s location.

A total for the Card’s whole life

For one job with an end date, such as “EUR 200 for this job until Friday”, count the total over the Card’s whole life ("window": "lifetime"). It never resets: calls on Monday, Wednesday and Friday all draw on the same EUR 200, where a daily EUR 200 would allow EUR 600 over three days. Give the Card an expiry so the job ends with it.

A lifetime total counts every draw the Card has ever made. Reissuing the Card, moving its start date or switching a daily total to a lifetime one never gives back what was already used; only a raised limit or extra room adds room. Its statement, warnings and the agent’s own view of the Card read “in total”, and its extra room for this window lasts until the Card ends.

Changing a limit

Limits on the card’s page opens its terms to change, because a change is a re-issue under the same name. Draws already recorded still count, so raising a ceiling adds only the difference rather than opening a fresh window, and the revision records who made the change.

Extra room

For temporary room, Extra room on the card’s page opens Review extra room, which first shows the quantity, measure, base ceiling and fixed expiry. This window only is the default: the next local midnight for a calendar day, or one recorded window duration for a rolling limit. Confirmation preserves that end; retrying cannot renew it. You may explicitly choose an end date or a permanent base increase. Expiry removes the extra allowance and leaves recorded usage in place.

The statement separates gross authorized quantities, trusted releases and net counted quantities. Base ceilings and active extra room are shown separately. Current approved exceptions are already included in the draws; historical approvals made under the earlier accounting model remain labelled outside-budget entries. Old balances are not rewritten, and an unused legacy approval requires fresh consent.

Over HTTP, a management identity can confirm the same revision:

{
  "revision_id": "room-refunds-2026-10-09",
  "quantity": "sum(amount_cents)",
  "measure": "effects",
  "window": "calendar_day",
  "amount": 10000,
  "duration": "this_window"
}

Send it to POST /v1/me/mandates/{id}/extra-room. Reuse the same revision id only for a transport retry of the same confirmation. Setup tooling acts under the administrator’s management authority; the agent’s runtime key cannot grant room or approve work.

Budget warnings

Warnings help you plan without changing the Card’s authority. Every Card has them, with the defaults below. On the Card, an admin can open Settings → Budget warnings to change the defaults or switch notices off. Runtime agent keys cannot change these settings.

  • Day totals: a heads-up when estimated exhaustion is within 25% of the window’s duration, then a notice when the total is spent. For a rolling day, the default runway horizon is six hours.
  • Hourly totals: the forecast goes to the agent through kiff_card. People get spent, unusual-usage and applicable new-Card burst notices, without an hourly runway email.
  • Unusual usage: at least three times the rate in equivalent intervals over the previous seven days. With insufficient baseline history, no ratio is invented.
  • New Cards: more than 50% used in the first 10% of a window during the first week. A rolling window’s burst observation starts with the first draw in a usage episode; it does not have a daily reset.

Notices appear on Needs you, in the bell and in History → Statement. The Overview shows one short active notice beside the balance. Warning settings open on their own one-step screen from the Settings row. Emails go to the same people who receive held-call emails. Supported, configured webhooks whose filters match Card warnings also receive them: explicitly opt in with action card_budget or outcome card_warning. Targets with no filters continue receiving decision alerts only. To register a warning-only target, use POST /v1/me/alert-targets with {"url":"https://example.com/kiff-warnings","action":"card_budget","outcomes":["card_warning"]}. Generic warning payloads use schema_version: "kiff.card-warning.v1" with id, card_id, kind, reason, recorded_at and card_url. Slack targets need the same explicit opt-in and receive a text message instead. A warning links back to the Card: review extra room for this window, change its terms, or review the agent. It takes none of those actions.

kiff_card includes a forecast on each cumulative limit: its state, observation time and interval, and runs_out_at when an estimate can be made. resets_at exists only for calendar-day limits. Rolling forecasts account for each draw aging out and for fixed extra-room expiries. Shared Cards use all holders’ usage. Estimates use the same counted amounts as authorization, including unknown outcomes; eligible trusted no-effect releases follow their original accounting terms.

The recent observation is five minutes for an hourly total and sixty minutes for a day total. Forecasts need three draws spanning at least half that interval. Large or incomplete histories return an unavailable or insufficient-history state instead of a misleading estimate.

Warnings are recorded after accounting commits, once per episode; reads never send them. Delivery retries survive restarts. One failing account backs off without stopping other accounts. Each destination’s result is recorded independently; external sends do not hold a database transaction. Resend email retries use a stable provider idempotency key. Generic webhooks carry a stable event id that receivers should deduplicate; Slack can repeat a notice if its delivery acknowledgement is lost. Recovered or superseded notices leave the active queue and remain on the Card’s statement as history. Warnings never answer a hold, block a call or add budget. Stop or Ask still follows the Card’s limits.

Next