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

# Conventions

> The response envelope, decimal-string levels, timestamp formats, staleness labels, history clamping, and request ids – the shared rules behind every endpoint.

Rules that hold across every `/v1` endpoint. The four that most often surprise people are decimal strings, the volatility timestamp format, staleness, and clamping.

## The envelope

Every success is `{ data, meta }`.

| Field                 | Always present     | Carries                                         |
| --------------------- | ------------------ | ----------------------------------------------- |
| `data`                | Yes                | The payload. Shape varies by endpoint           |
| `meta.attribution`    | Yes                | The attribution line to reproduce verbatim      |
| `meta.license`        | Yes                | Production and redistribution terms             |
| `meta.termsUrl`       | Yes                | Terms of Service                                |
| `meta.generatedAt`    | Yes                | When the response was generated                 |
| `meta.effectiveStart` | History only       | The start actually served, after clamping       |
| `meta.effectiveEnd`   | Index history only | The end actually served                         |
| `meta.clamped`        | History only       | Whether the requested start predated the window |
| `meta.historyMaxDays` | History only       | The trailing window in force                    |

Failures replace both keys with a single `error` object. There is no partial response: you get `data` and `meta`, or you get `error`.

<h2 id="levels-are-decimal-strings">
  Levels are decimal strings
</h2>

`indexLevel` and `baseIndexLevel` are JSON **strings**, not numbers.

```json theme={null}
{ "indexLevel": "36.11697608", "baseIndexLevel": "100.00000000" }
```

They are exact as published. A float round-trip silently changes the last digits, and a level that fails to reconcile against a published figure by one ulp is worse than useless in a benchmark. Parse them with a decimal type.

<CodeGroup>
  ```python Python theme={null}
  from decimal import Decimal

  level = Decimal(data["indexLevel"])          # exact
  level = float(data["indexLevel"])            # loses published precision
  ```

  ```javascript JavaScript theme={null}
  // Numbers are fine for display and charting.
  const forChart = Number(data.indexLevel);

  // For arithmetic you intend to reconcile, keep it exact.
  import { Decimal } from "decimal.js";
  const exact = new Decimal(data.indexLevel);
  ```
</CodeGroup>

Every index is based at `100` on its inception date, which is what lets a level read on its own without a reference point.

## Timestamps

Timestamps are UTC with microsecond precision.

| Where                                        | Format               | Example                       |
| -------------------------------------------- | -------------------- | ----------------------------- |
| Index endpoints, and all `meta`              | `Z`-suffixed         | `2026-08-31T13:44:44.963697Z` |
| Volatility `tick.computedAt` and history `t` | **No offset suffix** | `2026-08-31T13:59:35.599223`  |

<Warning>
  The volatility computation timestamps ship without a `Z` or offset. They are still UTC. A strict RFC 3339 parser will reject them, so attach the timezone yourself.
</Warning>

```python theme={null}
from datetime import datetime, timezone

# Index endpoints and meta
datetime.fromisoformat("2026-08-31T13:44:44.963697Z")

# Volatility computation timestamps
naive = datetime.fromisoformat("2026-08-31T13:59:35.599223")
aware = naive.replace(tzinfo=timezone.utc)
```

## Staleness is labeled, not hidden

`stale` is `true` when a level rests on inputs older than the freshness threshold. The level still publishes, and `dataQuality` on the latest endpoint reports how many constituents were fresh:

```json theme={null}
{
  "stale": false,
  "dataQuality": {
    "freshMarketsCount": 24,
    "staleMarketsCount": 0,
    "totalMarketsCount": 24,
    "freshDataPct": 100.0
  }
}
```

A stale reading is disclosed rather than suppressed, so decide what to do with it rather than assuming every value you receive is fresh.

## History windows clamp, they do not fail

History reaches back **90 days**. A request for a longer window is clamped, not rejected: a chart that asked for a year still renders, and `meta` reports what it actually got.

```json theme={null}
"meta": {
  "effectiveStart": "2026-06-02T14:01:38.530876Z",
  "effectiveEnd": "2026-08-31T00:00:00.000000Z",
  "clamped": true,
  "historyMaxDays": 90
}
```

Read `clamped` before labeling a chart with the range you asked for. A window falling entirely before the floor returns an empty `points` array with `clamped: true` rather than an error.

An `end` in the future is clamped to now as well. What is a real error is a window that is empty once clamped – a `start` at or after `end` – because that is a mistake in your input rather than a limit of the free tier. It returns [`invalid_window`](/api-reference/limits#invalid-window), quoting both values as parsed, and names the future-`end` case outright when that is what emptied the window.

Full history since inception is in the free [snapshot bundles](/data-access/downloads).

## Ordering

| Endpoint           | Order        |
| ------------------ | ------------ |
| Index history      | Oldest first |
| Volatility history | Newest first |
| Reconstitutions    | Newest first |

There is no cursor pagination. History is bounded by the window; `limit` bounds the list endpoints that take one.

## Tickers

Tickers are case-insensitive: `conflict` and `CONFLICT` resolve to the same index. Responses always echo the canonical uppercase form.

An unknown ticker, an unlisted series, and a series with no published values yet all return the same `404`. A ticker that is not on the API is not distinguishable from one that does not exist.

## Request ids

`X-Request-Id` is on every response, including the two pre-authentication rejections. On an error it is also in the body as `error.requestId`.

Quote it in any support message. It is what turns "I got a 500 around 14:02" into a single log lookup.

## Versioning

`/v1` is additive. New fields may appear in `data` or `meta`; existing fields will not change type or disappear without a new version. Parse defensively: ignore fields you do not recognize rather than rejecting the response.

[Data boundaries](/api-reference/boundaries) states what each lane carries and how `/v1` changes over time.
