> ## Documentation Index
> Fetch the complete documentation index at: https://octo-98895abd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Your first screen

> From a publishable key to a real chart of Brazilian market data, in four calls.

### Overview

Four calls: find out what exists, resolve an identifier, pull a series, then put two different things on one axis. Everything here runs anonymously with the shared testing key.

```bash theme={null}
export SILO_URL="https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1"
export SILO_ANON_KEY="sb_publishable__yfFQsykAglrvc9GS6_PYw_B24ex437"
```

That key is shared — it identifies the project, not you, and goes on `apikey` only. See [Quickstart](/api-docs/quickstart).

### 1. Find out what is actually there

```bash theme={null}
curl -s -X POST "$SILO_URL/rpc/coverage" \
  -H "apikey: $SILO_ANON_KEY" -H "Content-Type: application/json" -d '{}'
```

Read `as_of` (newest elapsed period landed) and `complete_through` (newest *complete* period, what default windows serve). A `complete_through` trailing today by a month or two for a fund dataset is CVM's filing calendar, not an outage. [Market coverage](/api-docs/market-coverage) explains all four date columns.

### 2. Resolve an identifier

```bash theme={null}
curl -s -X POST "$SILO_URL/rpc/lookup" \
  -H "apikey: $SILO_ANON_KEY" -H "Content-Type: application/json" \
  -d '{"p_query": "PETR4"}'
```

You get `id`, `id_type`, `asset_class`, `name`, `isin`, `cnpj` and any B3 `tickers` — the last from CVM's published FCA map, never a guessed ticker↔CNPJ join.

**Note**: an unknown identifier returns an **empty array**, not an error and never a substitute. If `lookup` gives you nothing, stop there rather than assuming the next call will work.

### 3. Pull a series

<CodeGroup>
  ```bash curl theme={null}
  curl -s -X POST "$SILO_URL/rpc/quote_history" \
    -H "apikey: $SILO_ANON_KEY" -H "Content-Type: application/json" \
    -d '{"p_ticker": "PETR4", "p_from": "2025-01-01", "p_to": "2025-12-31"}'
  ```

  ```python Python theme={null}
  import os, requests

  URL = "https://zcjbtpxuhdekpwcxmepn.supabase.co/rest/v1"
  H = {"apikey": os.environ["SILO_ANON_KEY"]}

  rows = requests.post(f"{URL}/rpc/quote_history", headers=H, json={
      "p_ticker": "PETR4", "p_from": "2025-01-01", "p_to": "2025-12-31",
  }).json()
  print(len(rows), rows[0]["trade_date"], rows[-1]["close"])
  ```

  ```javascript JavaScript theme={null}
  import { createClient } from '@supabase/supabase-js'

  const supabase = createClient(
    'https://zcjbtpxuhdekpwcxmepn.supabase.co',
    process.env.SILO_ANON_KEY,
    { db: { schema: 'api' } },
  )

  const { data } = await supabase.rpc('quote_history', {
    p_ticker: 'PETR4', p_from: '2025-01-01', p_to: '2025-12-31',
  })
  ```
</CodeGroup>

One year of daily prices is \~250 rows, comfortably inside the 1,000-row page. Ask for five years and the call **refuses** with `22023` rather than handing you the oldest 1,000 — page it with `p_after`. See [the pagination guide](/api-docs/guides/pagination) before you write a loop.

**Note**: prices are unadjusted (`adjusted: false` on every row). A return computed across a split date will be wrong unless you handle it yourself.

### 4. Put two different things on one axis

`panel` returns a long `(id, date, metric, value)` frame, so a listed company's price and a fund's NAV line up without a join.

```bash theme={null}
curl -s -X POST "$SILO_URL/rpc/panel" \
  -H "apikey: $SILO_ANON_KEY" -H "Content-Type: application/json" \
  -d '{
        "p_ids": ["PETR4", "VALE3"],
        "p_metrics": ["close"],
        "p_from": "2025-01-01",
        "p_freq": "month"
      }'
```

Mix identifier kinds freely — tickers, option and termo codnegs, and fund CNPJs in one `p_ids` array. The fourteen metrics are `close`, `volume`, `close_unit`, `close_return`, `nav`, `quota`, `delinquency`, `yield`, `inflows`, `redemptions`, `quotaholders`, `receivables`, `sacado_top1` and `sacado_top25`.

**Note**: anonymously `panel` takes at most **3 ids per call** — a fourth raises `22023` rather than quietly dropping one. Signing in raises it to 50.

### Reading a null correctly

On this API a null is information, with three distinct meanings:

| You see | It means |
| - | - |
| `null` outside a family's applicable columns | **not applicable** — set by construction, e.g. `quota` for a FIDC |
| `null` inside them | a blank in that month's filing |
| an empty array | no rows in that window, or an unknown id |

None is ever filled with a guess. No forward-fill, no last known close, no interpolation. `catalog().applicability` lists which columns each family files; `metric_coverage()` gives the filed span per metric.

### Next

<CardGroup cols={2}>
  <Card title="Paging without losing rows" icon="list-ol" href="/api-docs/guides/pagination">
    Two cursors, one silent ceiling, and how to tell which cut you.
  </Card>

  <Card title="Reading a fundamental" icon="file-invoice-dollar" href="/api-docs/guides/fundamentals">
    A company's financial statements end to end.
  </Card>

  <Card title="Market coverage" icon="calendar-range" href="/api-docs/market-coverage">
    How far back each domain goes — and the one that is a ratchet.
  </Card>

  <Card title="For agents" icon="robot" href="/api-docs/agents">
    The machine-readable contract, for tool-using models.
  </Card>
</CardGroup>


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