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

# Token metering

> How a run's executed tokens are counted, so hosts can price and limit scripts by the code they actually run.

Hosts can price and limit scripts by the **tokens** they execute. [Stellarium](https://docs.stellarium.sh/concepts/api-clients) nodes, for example, charge API clients per million tokens a run executes.

A token is one lexer token: an identifier, keyword, number, operator or punctuation mark, or a whole string literal however long. Comments and whitespace aren't tokens.

## What counts

Every statement and expression owns the tokens it was written with, apart from those that belong to the statements and expressions inside it. A node's tokens are counted just before it runs, so a run counts exactly the code it executed:

* **Declarations are free.** `request Name`, a contract's name, version and parameter list, and the body's outer braces aren't counted.
* **`if` counts what it evaluates.** Each condition is counted when it is evaluated, together with its `if` or `else if`, its parentheses and its braces. Then only the body of the branch taken is counted. `else` and its braces count only when the else body runs. Untaken branches cost nothing.
* **Short circuits skip.** The operand that `&&` or `||` doesn't evaluate isn't counted.
* **Strings are one token**, plus the tokens inside each `${}` interpolation as it is evaluated.
* **Parentheses** count with the expression that encloses them, and an assignment's target counts with the assignment.

```kotlin theme={null}
request Grade {
    const score = 95
    if (score >= 90) {
        return "A, with distinction: " + score
    } else {
        return "B"
    }
}
```

| Executed | Tokens |
| - | - |
| `const score = 95` | 4 |
| `if ( ) { }` and `score >= 90` | 5 + 3 |
| `return "A, with distinction: " + score` | 4 |
| **Total** | **16** |

The `else` branch would have cost 5 (`else { }` and `return "B"`), so the most any run of this script can execute is 4 + 8 + 5 = 17.

## The most a script can execute

RequestScript has no loops and no user-defined functions, so every script has a finite maximum, known before it runs: every statement counted once, with each `if` taking its costliest path. A host can price the worst case up front, then charge only what a run used.

## In the library

`requestscript` 1.2.0 and later exports the meter:

```ts theme={null}
import { interpret, maxTokens, parseScript, TokenLimitError, TokenMeter } from "requestscript";

maxTokens(parseScript(source)); // 17 for the script above

const meter = new TokenMeter(10_000); // the limit is optional
const result = await interpret(source, { meter, signal });
result.usage.tokens; // 16
```

* `result.usage.tokens` is the count for a run that finished. `meter.tokens` holds it too, including for a run that failed partway.
* With a limit, a node that would take the count past it isn't run or counted, and the run fails with `TokenLimitError`, a `RuntimeError`.
* `signal` is an optional `AbortSignal`, checked before each statement, expression and resource call.

Every statement and expression in the syntax tree carries its own token count as `tokens`. An `if` statement's tokens are on its branches (`tokens`) and its `elseTokens`.


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