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

# The time model

> Financial Data API is bi-temporal. Every value carries both the period it describes and the moment it became known, so you can reconstruct what was knowable at any point in time.

Financial Data API is a point-in-time data API. The core differentiator is that every observation is **bi-temporal**: it records both *what period a value describes* and *when that value became known*. Keeping those two axes separate is what lets you answer questions like "what was the latest US CPI reading that I could have seen on 2026-03-15?" without contaminating the answer with data that was published later.

This page explains the three time axes, how to filter on each, and the honest limits of the current `as_of` implementation.

## Three axes, never conflated

<Columns cols={3}>
  <Card title="Described period" icon="calendar">
    `period`, `period_start`, `period_end`. The slice of real-world time the value is *about*: May 2026 CPI, Q1 2026 GDP, the trading day for a daily series.
  </Card>

  <Card title="Knowledge time" icon="bell">
    `start_date`, `end_date`. Bounds on `observed_at`: *when* the value became known to Financial Data API. This is the axis that prevents lookahead.
  </Card>

  <Card title="Vintage cutoff" icon="camera">
    `as_of`. Returns the latest vintage known on or before a timestamp. Revisions are retained, never overwritten, so you can replay history.
  </Card>
</Columns>

The mistake most data APIs make is collapsing these into one timestamp. A figure released in June that describes May, then revised in July, has at least three distinct timestamps attached to it. Financial Data API keeps them apart so each query means exactly one thing.

### 1. The described period

The period is the real-world interval a value measures. It does not move when the value is revised.

* `period` is a convenience filter and accepts `YYYY`, `YYYY-MM`, or `YYYY-Qn`.
* `period_start` and `period_end` are the explicit bounds on the response object.

```bash theme={"theme":"css-variables"}
# All 2026 readings for US headline inflation, by described period
curl -G "https://api.financialdatapi.com/observations" \
  -H "x-api-key: $FINANCIALDATA_API_KEY" \
  --data-urlencode "country=USA" \
  --data-urlencode "indicator=cpi_inflation_yoy" \
  --data-urlencode "period=2026"
```

<Note>
  `period=2026-Q1` selects observations whose described period falls in the first quarter. Use it for quarterly series such as GDP; use `period=2026-05` for monthly series such as CPI.
</Note>

### 2. Knowledge time (the no-lookahead axis)

`observed_at` is the moment a value became known to Financial Data API. You bound it with `start_date` and `end_date`. This is the axis you filter on when you care about *what was knowable*, not *what period it covers*.

```bash theme={"theme":"css-variables"}
# Everything that became known in March 2026, regardless of which period it describes
curl -G "https://api.financialdatapi.com/observations" \
  -H "x-api-key: $FINANCIALDATA_API_KEY" \
  --data-urlencode "country=USA" \
  --data-urlencode "indicator=cpi_inflation_yoy" \
  --data-urlencode "start_date=2026-03-01T00:00:00Z" \
  --data-urlencode "end_date=2026-03-31T23:59:59Z"
```

A May CPI release that lands on 2026-06-11 has `period = 2026-05` but `observed_at` in June. Filtering on `period` and filtering on knowledge time answer different questions. Pick the one that matches your intent.

### 3. Vintage cutoff with `as_of`

`as_of` asks: "give me the data as it stood at this moment." It returns, for each matching series, the latest vintage known on or before the supplied timestamp. Because Financial Data API retains revisions instead of overwriting them, two `as_of` queries with different cutoffs can return different values for the same period.

<CodeGroup>
  ```bash cURL theme={"theme":"css-variables"}
  curl -G "https://api.financialdatapi.com/observations/latest" \
    -H "x-api-key: $FINANCIALDATA_API_KEY" \
    --data-urlencode "country=USA" \
    --data-urlencode "indicator=cpi_inflation_yoy" \
    --data-urlencode "as_of=2026-03-15T00:00:00Z"
  ```

  ```python Python theme={"theme":"css-variables"}
  import os, requests

  resp = requests.get(
      "https://api.financialdatapi.com/observations/latest",
      headers={"x-api-key": os.environ["FINANCIALDATA_API_KEY"]},
      params={
          "country": "USA",
          "indicator": "cpi_inflation_yoy",
          "as_of": "2026-03-15T00:00:00Z",
      },
  )
  resp.raise_for_status()
  print(resp.json()["data"])
  ```

  ```typescript TypeScript theme={"theme":"css-variables"}
  import { FinancialDataApiClient } from "@financialdatapi/client";

  const client = new FinancialDataApiClient({ apiKey: process.env.FINANCIALDATA_API_KEY });

  const { data } = await client.getLatestObservations({
    country: "USA",
    indicator: "cpi_inflation_yoy",
    as_of: "2026-03-15T00:00:00Z",
  });
  console.log(data);
  ```
</CodeGroup>

The same query with `as_of=2026-07-01T00:00:00Z` may return a different number for the same described period, because a revision became known in between. Both answers are correct, each for its own cutoff.

<Warning>
  **Honest caveat about `as_of`.** Today, `as_of` approximates the **ingestion timestamp**: the moment Financial Data API recorded a value. It is not yet a full provider-vintage reconstruction. If a provider published a figure before Financial Data API ingested it, the `as_of` cutoff reflects when Financial Data API knew, not the instant the provider released it. Full provider-vintage reconstruction is planned future work. For most backtests this distinction is small, but if your strategy is sensitive to intraday release timing, account for it.
</Warning>

## Why this matters for backtests

Lookahead bias is the silent killer of historical research. If your backtest on 2026-03-15 quietly uses a CPI value that was only revised into existence in July, your results are fiction.

Financial Data API removes that risk in two ways:

<Steps>
  <Step title="Pin the cutoff" icon="thumbtack">
    Run each historical query with `as_of` set to the simulated decision time. You receive only the vintage that was known on or before that moment.
  </Step>

  <Step title="Or bound knowledge time" icon="bracket-curly">
    Alternatively, constrain `end_date` to the decision time. Anything that became known later is excluded by construction.
  </Step>
</Steps>

```python theme={"theme":"css-variables"}
import os, requests

API = "https://api.financialdatapi.com"
HEADERS = {"x-api-key": os.environ["FINANCIALDATA_API_KEY"]}

def latest_known_at(decision_time: str):
    """The CPI vintage that was knowable at decision_time. No lookahead."""
    resp = requests.get(
        f"{API}/observations/latest",
        headers=HEADERS,
        params={
            "country": "USA",
            "indicator": "cpi_inflation_yoy",
            "as_of": decision_time,
        },
    )
    resp.raise_for_status()
    return resp.json()["data"]

# Walk the decision dates of your backtest; each call is point-in-time clean.
for t in ["2026-01-15T00:00:00Z", "2026-02-15T00:00:00Z", "2026-03-15T00:00:00Z"]:
    print(t, latest_known_at(t))
```

<Tip>
  Treat `period` as the x-axis of your chart and `as_of` (or `end_date`) as the lens you view it through. The period tells you *which* point you are plotting; the cutoff tells you *which vintage* of that point you are allowed to see.
</Tip>

## Quick reference

| Axis             | Parameters                             | Answers                                           | Use when                                                       |
| ---------------- | -------------------------------------- | ------------------------------------------------- | -------------------------------------------------------------- |
| Described period | `period`, `period_start`, `period_end` | Which real-world interval the value is about      | You want a specific month, quarter, or year                    |
| Knowledge time   | `start_date`, `end_date`               | When the value became known                       | You need a clean as-of-then view or a release window           |
| Vintage cutoff   | `as_of`                                | The latest vintage known on or before a timestamp | You are reconstructing a point-in-time snapshot for a backtest |

<Info>
  All three axes compose. You can request a specific `period` while pinning `as_of` to see how that exact reading looked at an earlier moment. Unknown query parameters fail closed with `bad_request`, so a typo in a time parameter is rejected rather than silently ignored.
</Info>

## Related

<Columns cols={2}>
  <Card title="Provenance" icon="link" href="/concepts/provenance">
    Trace any observation back to its named source and ingestion run.
  </Card>

  <Card title="Freshness and liveness" icon="signal" href="/concepts/freshness-and-liveness">
    Understand the freshness label and how silently-frozen feeds are detected.
  </Card>
</Columns>
