> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sumvin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Limits and narrowing

> How a Stamped Mandate states spending ceilings, time limits and expiry, and why a mandate can only ever be narrowed.

A mandate's limits live in two places: parameters on its scopes, and the mandate's own expiry. Both are signed. Neither can be raised after you sign.

## Spending ceilings

A spending ceiling is the `max` parameter on a spend scope. It is the most the mandate can ever authorise.

**`max` is an amount in the display unit of the currency or asset the scope names.** It is written the way you would read it on a receipt, never in cents, pence or other minor units.

| Written | Means |
| - | - |
| `max=25&currency=USD` | 25.00 US dollars |
| `max=25.00&currency=USD` | 25.00 US dollars |
| `max=25.50&currency=USD` | 25.50 US dollars |
| `max=2500&currency=JPY` | 2,500 yen |

Rules for a ceiling:

* **Fractions are allowed** up to the currency's own precision: two places for USD and EUR, none for JPY, three for KWD.
* **Too precise is refused.** `max=25.001&currency=USD` is refused, never rounded or cut down. Rounding either way would sign a different number from the one you read. This holds for every currency a limit can be written in, including BRL, INR and MXN, which take two places like USD. It holds for the `min` of a [balance proof](/concepts/mandates/scopes#proofs-facts-about-your-money) too.
* **Plain decimals.** A ceiling follows the [number rules](/concepts/mandates/language#numbers): ASCII digits with at most one `.`, and no `+` sign, spaces, `_` separators or exponent. `max=1e3` and `max=1_000` are refused.
* **Positive only.** A draft with a ceiling of zero or less is refused before you are asked to sign it. A minus sign is refused outright, so `max=-0` is refused too.
* **Stated once.** A scope states `max` once. `max=1&asset=USDC&max=1000` is refused as malformed rather than read as either number.
* **Exactly one per draft.** A spending mandate your agent drafts for you states exactly one ceiling. A draft with none, or with two, is refused. A [read mandate](/concepts/mandates/scopes#read-mandates) spends nothing and states no ceiling. A mandate that limits several assets separately is a different shape: see [Several spending scopes](#several-spending-scopes-on-one-mandate).
* **Written one way.** When Sumvin writes a ceiling itself, it uses exactly the currency's precision: 25 US dollars is written `max=25.00`, and 2,500 yen is written `max=2500`.

The approval page shows the ceiling in plain words at the currency's own precision, such as "Authorise spending of up to 25.00 USD."

<Note>
  Anything that reports a ceiling back to you or to a verifier reports it in the same display unit, such as `12.50`, never `1250`. A ceiling that can't be read back is reported as unreadable, never as unlimited.
</Note>

## Several spending scopes on one mandate

Some spending scopes name the asset they spend. `spend:execute` is one: it moves an on-chain asset, up to its `max`. A mandate can carry more than one of them, for example one for each asset:

```text Two scopes, two assets theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sr:us:pint:spend:execute?max=10&asset=USDC@sei
sr:us:pint:spend:execute?max=100&asset=USDT@sei
```

These rules are for `spend:execute` scopes. Other spending scopes are each checked by their own rules.

A `spend:execute` scope that names an asset covers only that asset, with or without a `max`. A scope with no `asset` and no `max` covers every asset; a `max` must name the asset it is stated in, or the payment is refused with a 403. When a payment is made, every `spend:execute` scope on the mandate that covers the asset being moved applies at once, and the payment has to fit inside all of them.

* **The tightest `max` wins.** Two scopes for the same asset with `max=10` and `max=25` leave a limit of 10.
* **The order never matters.** Shuffling the `spend:execute` scopes, or signing them in a different order, never changes the limit or which assets are covered.
* **A scope without `max` never loosens another.** If one scope for an asset states no `max`, a capped scope for the same asset still caps it.
* **Naming an asset is a limit too.** `spend:execute?asset=USDC@sei`, with no `max`, lets a payment in USDC through at any amount, and refuses a payment in any other asset.
* **Each asset is held to its own limit.** With the two scopes above, a payment in USDC is held to 10 and a payment in USDT to 100. The limits are never added together, and one asset's limit never applies to another.
* **A payment in an asset no scope covers is refused.** The request comes back as a 422.
* **A scope naming an asset Sumvin doesn't know is refused.** If a `spend:execute` scope names an asset Sumvin can't find on the payment's chain, a payment under that mandate is refused with a 403 (`PINT-403-001`), whether or not that scope states a `max`: nobody can tell which payments it covers.
* **A scope that can't be read refuses the payment.** If any `spend:execute` scope on the mandate can't be read, a payment under that mandate is refused with a 403 (`PINT-403-001`), even when another scope would have covered it. An unreadable scope has a limit nobody can know, so Sumvin neither skips it nor assumes it is looser.
* **No `max` and no `asset` means no bound.** A mandate whose `spend:execute` scopes name no asset and state no `max` doesn't limit the payment's asset or amount.

If you read a mandate's ceilings yourself, apply the same rule: read every scope, refuse an asset that no scope covers, hold each asset to the tightest limit that covers it, and treat a scope you can't read as a refusal. See [Reading scopes](/sdk/verify/reading-scopes).

## Time limits

| Limit | Where | Unit |
| - | - | - |
| Expiry | The mandate itself | A point in time. After it, the mandate no longer stands. |
| Search window | `time` on `errand:search` | A length of time, in **seconds**. `604800` is seven days. |
| Date range | `from_date`, `to_date` on `transactions:read` | Points in time, in Unix **seconds**. |
| Purchase window | `not_before`, `not_after` on a `time_window` condition | Points in time, in Unix **milliseconds**. |

An expiry must be in the future when the mandate is made. A search window is also capped by Sumvin's own upper limit, and the shorter of the two applies.

### How long a mandate lasts

When your agent asks you for a mandate directly, two clocks start:

* **The time to answer.** You have 24 hours to sign or decline. If the request lapses unanswered, nothing is granted.
* **The mandate's own expiry.** Once you sign, the mandate lasts 90 days by default. Your agent may ask for any length from 1 to 90 days. The approval page shows the date it lapses before you sign.

A mandate can't be extended. In the last 7 days before a read mandate lapses, your agent is told so and can offer to ask you for a new one. Renewing means signing a new mandate; until you do, the old one keeps working to its expiry.

## A mandate only narrows

A mandate can never grant more than what you signed. Every rule below takes authority away; none adds it.

* **Your agent can't widen a mandate.** More authority always means a new mandate that you sign.
* **Each parameter narrows its scope.** A ceiling, a currency, a card, a date range, a provider: each one limits what the scope allows.
* **Resources and conditions narrow the whole mandate.**
* **Revocation and expiry end it.** Neither can be undone.

### Narrowing one mandate into a smaller one

A mandate can be narrowed into a smaller one, for example so that one purchase draws a part of a larger spending mandate. The smaller mandate:

* names the larger one in its [resources](/concepts/mandates/resources);
* has a ceiling at or below the larger one's;
* keeps the same currency, and the same pinned card if there is one;
* can't expire later than the larger one;
* stops standing the moment the larger one is revoked or expires.

A smaller mandate that breaks any of these rules is refused. When you revoke a mandate, every smaller mandate drawn from it that is still in use is revoked with it.

## Next

<Columns cols={2}>
  <Card title="What a verifier checks" icon="shield-check" href="/concepts/mandates/verification">
    How a counterparty reads these limits.
  </Card>

  <Card title="Set limits" icon="sliders-horizontal" href="/guides/set-limits">
    Choose the limits for your agent.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.