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

# Trust metadata

> The fields that tell you whether a row is safe to use, and for what.

Every observation carries flags describing its own reliability. They exist because
the failure they prevent is invisible otherwise: a discontinued series looks exactly
like a live one whose next print is merely late, and an annual estimate looks exactly
like a monthly reading once it is in a chart.

Read this page before building anything quantitative. These fields are the difference
between a number and a number you can defend.

## scoringEligible

The single field to check if you are only going to check one.

`true` only when all of the following hold:

* the source is official or market grade, not news and not an unreviewed feed
* the row is not an annual fallback standing in for a live series
* the reading is not stale against its own expected cadence
* the collection behind it has not been discontinued
* the value is denominated in the unit its factor is defined in

It fails closed. When eligibility cannot be established, the answer is `false`.

```json theme={"dark"}
{
  "indicatorId": "cpi_inflation_yoy",
  "actual": 32.1,
  "scoringEligible": true
}
```

<Warning>
  `scoringEligible: false` does not mean the number is wrong. It means it should not
  drive a live model. A ceased series is historically accurate and permanently
  unsuitable as a current reading.
</Warning>

## freshnessStatus

Age relative to the series' own publication cadence, not a fixed window.

| Value     | Meaning                                                               |
| --------- | --------------------------------------------------------------------- |
| `fresh`   | Recent enough for its cadence                                         |
| `stale`   | The publisher is behind by more than the tolerance for this frequency |
| `unknown` | Cannot be assessed, for example a non periodic series                 |

A monthly series tolerates far less lag than a quarterly one. This is why a reading
can be the newest one that exists and still be `stale`: the publisher is late, and
the API says so rather than presenting the last known value as current.

## collectionStatus

`ceased` when the publisher has permanently retired the collection, `null` for a
live series.

This is distinct from `stale` and the distinction matters. **A stale series is
expected to resume. A ceased one never will.** Treating them the same is a real
modelling error: one is a temporary gap, the other is a permanent end that will
otherwise sit in your model looking like current data forever.

Ceased rows carry two companions:

* `ceasedFinalPeriod`: the last period the collection ever published
* `successorIndicatorId`: the replacement, where the publisher named one

```json theme={"dark"}
{
  "indicatorId": "retail_sales_value",
  "country": "AUS",
  "actual": 36094.7,
  "periodEnd": "2025-06-30",
  "collectionStatus": "ceased",
  "ceasedFinalPeriod": "2025-06",
  "successorIndicatorId": "indicator_household_spending",
  "scoringEligible": false
}
```

<Note>
  The successor is a **pointer, not a splice**. It is usually a different concept.
  Australian retail turnover was replaced by household spending, which includes
  services. Joining the two into one series would silently change what is being
  measured partway through its history, so the API never does that for you. The
  decision is yours to make explicitly.
</Note>

## fallbackOnly

`true` for annual World Bank rows, which exist to give context for countries with no
high frequency source.

They are real data. They are also the wrong thing to score, because they are annual,
frequently revised, and often a year or more behind. They are marked so that a
country with only fallback coverage is visibly different from one with a live
national series.

## preferredForFactor

Within a response, the one row to use for a given country, factor and period.

The guarantee is **exactly one**: never two, never zero where an eligible row exists.

This exists because ambiguity is worse than absence. If two rows both look
authoritative, the choice falls to whatever tie break the consumer happens to apply,
and the same query can produce different answers on different runs. A factor score
that changes without the world changing is worse than no score.

Rows are `false` when superseded by a better one: an annual fallback where an
official series exists, a ceased collection where its successor is present, a
harmonised international copy where the compiling agency's own print is available.

<Warning>
  A factor whose only rows are ineligible ends with no preferred row at all. Read that
  as "no scoring grade data", not as "use whatever came back".
</Warning>

## sourceTier

Provenance ranking, used when several publishers carry the same series.

| Tier                      | Meaning                                                |
| ------------------------- | ------------------------------------------------------ |
| `central_bank`            | Central bank, the publisher of record for policy rates |
| `official_national`       | National statistical office                            |
| `official_supranational`  | OECD, Eurostat, BIS, IMF                               |
| `financialdatapi_derived` | Computed by us from public domain inputs               |
| `market_data`             | Market data vendors                                    |
| `world_bank_fallback`     | Annual World Bank context                              |
| `news`                    | News derived                                           |

Where a series has more than one publisher, the API returns **one provider per
period** rather than both. National sources are preferred over harmonised
international copies. Pass `?sources=all` to opt out and receive every provider.

## Putting it together

A defensive filter for a scoring pipeline:

```python theme={"dark"}
usable = [
    row for row in response["data"]
    if row["scoringEligible"]
    and row["preferredForFactor"]
    and row["collectionStatus"] is None
]
```

And the check worth making explicitly, because it is the one that bites quietly:

```python theme={"dark"}
if row["collectionStatus"] == "ceased":
    # Permanently ended. Do not carry the last value forward as current.
    # Follow successorIndicatorId, and recalibrate: it is a different concept.
    ...
```
