> ## Documentation index
> Fetch the complete documentation index at: https://docs.predictefy.com/llms.txt
> Use it to discover every available page before exploring further.

# Capability-honest data

> The three fields on every record — asOf, provenance, capabilities — and why NOT_SUPPORTED is an answer.

Every record this API returns carries three fields that describe the data rather than the
market. They exist because a normalized interface over eighteen different venues can either
hide the differences between them or state them, and hiding them produces integrations that
are quietly wrong.

```json
{
  "marketId": "…",
  "title": "…",
  "asOf": "2026-07-03T09:15:00.000Z",
  "provenance": { "source": "venue-rest" },
  "capabilities": { "read": true, "trade": false, "depth": true, "history": false }
}
```

## asOf — when this was true

`asOf` is the moment the data was captured, not the moment you asked. A cached catalog read
and a live order-book read both return successfully; only `asOf` distinguishes a snapshot
taken seconds ago from one taken minutes ago.

Use it rather than your own clock when displaying freshness. A timestamp you generate on
receipt describes your request, not the data.

## provenance — where it came from

`provenance.source` records how the value was obtained. The values you will encounter
include `venue-rest` (fetched from the venue's own API), `predictefy-live` (served from our
live engine), and `fixture` (test data — you should never see this in production).

This matters when values disagree. Two reads of the same market with different `asOf` and
different `provenance` are not a contradiction; they are two different observations, and
provenance tells you which pipeline produced each.

## capabilities — what this venue actually supports

`capabilities` is a per-venue map: `read`, `trade`, `depth`, `history`. It is the field to
branch on before assuming a verb will work.

The flags are **conservative by design**. `history: false` means a history lane has not
been proven for that venue, not that no data could ever exist. `trade: false` on a catalog
record does not mean trading is impossible — public execution availability is documented
separately per venue in [Trading & execution](/guides/trading/).

For the full per-verb picture, read the venue's `has` map or the
[coverage matrix](/reference/venues/).

## NOT_SUPPORTED is an answer

When a venue genuinely does not expose something — no public trades tape, no per-address
order list — the API returns `NOT_SUPPORTED` rather than an empty array.

This distinction is the point:

- An **empty array** means the query ran and found nothing. A market with no trades today
  returns an empty tape.
- **`NOT_SUPPORTED`** means the query cannot run here. The venue has no tape at all.

Collapsing the two loses real information. An integration that treats `NOT_SUPPORTED` as
"no results" will report "no recent trades" for a venue that has never published a single
one, which is a different and more misleading statement.

Handle it explicitly:

```ts
try {
  const trades = await client.gemini.fetchTrades(marketId);
  render(trades); // may legitimately be empty
} catch (err) {
  if (err instanceof NotSupportedError) {
    renderUnavailable('This venue does not publish a public trades tape.');
  } else {
    throw err;
  }
}
```

## Synthetic books

A venue without an order book — an automated market maker, or a pari-mutuel pool — still
returns a book-shaped response so that one integration works everywhere. That response is
labelled **synthetic**.

A synthetic book is a faithful representation of price. It is **not executable depth**, and
must never be presented as orders a user could fill against, or fed into a sizing
calculation as though it were. [Venue coverage](/reference/venues/) records which venues
have a real book.

## The same discipline applies to cross-venue output

Price differences between venues are reported as **indicative price discrepancies** —
observed gaps, not opportunities. Only `fetchArbitrage` performs a live executable
assessment, against live asks, open status, real depth, the fee model, and
resolution-equivalence. See [Cross-venue data](/guides/cross-venue/).

The rule underneath all of this is the same: the API states what it knows and how well it
knows it, and expects the integration to preserve that rather than flatten it.
