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

# Quickstart

> Create a key, resolve a symbol with stock_search, then read a verified stock_financials response — values and refusals.

By the end of this page you have a key in your environment, a resolved symbol, and a verified financials response you know how to read — including how a refused value looks.

Every tool is a `POST` to `https://api.stockcontext.com/v1/tools/{name}` with a JSON body and your key in the `X-API-Key` header.

<Note>
  This quickstart uses schema 2, the default wire. Add `{ "schema": 1 }` only if you intentionally need the frozen legacy shape.
</Note>

<Steps>
  <Step>
    ### Create an API key

    Open the dashboard keys page at `https://stockcontext.com/dashboard/keys`, create a key, and copy it before you close the dialog — the secret is shown once. Send it in the `X-API-Key` header on every request.

    <Warning>
      Keep your key server-side. Never ship it in frontend code, browser bundles, public repos, logs, screenshots, or prompts.
    </Warning>
  </Step>

  <Step>
    ### Set your environment

    ```bash theme={null}
    export STOCKCONTEXT_API_BASE_URL="https://api.stockcontext.com"
    export STOCKCONTEXT_API_KEY="<your_api_key>"
    ```
  </Step>

  <Step>
    ### Resolve a symbol

    Start with `stock_search` to resolve a ticker, name, or CIK to a security and confirm it is covered.

    ```bash theme={null}
    curl -sS "$STOCKCONTEXT_API_BASE_URL/v1/tools/stock_search" \
      -H "X-API-Key: $STOCKCONTEXT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "AAPL"}'
    ```

    ```json title="stock_search (trimmed)" theme={null}
    {
      "data": {
        "query": "AAPL",
        "matches": [
          {
            "security_id": "sec_0000320193_aapl",
            "ticker": "AAPL",
            "entity": { "cik": "0000320193", "name": "Apple Inc.", "shape": "operating_company" },
            "coverage": { "financials": true, "prices": true }
          }
        ]
      },
      "meta": { "schema_version": "2" }
    }
    ```

    `coverage.financials: true` means fundamentals are ingested and served. An unrecognized ticker or an uncovered security returns a typed refusal or a coverage reason; do not guess a value.
  </Step>

  <Step>
    ### Fetch verified financials

    Ask for one annual period of Apple's financials. `detail: "full"` adds the full provenance (sources, hashes) to each cell; the default `concise` omits it.

    ```bash theme={null}
    curl -sS "$STOCKCONTEXT_API_BASE_URL/v1/tools/stock_financials" \
      -H "X-API-Key: $STOCKCONTEXT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"symbol": "AAPL", "statements": ["income"], "periods": 1, "detail": "core"}'
    ```

    ```json title="stock_financials (trimmed)" theme={null}
    {
      "subject": {
        "entity": { "cik": "0000320193", "name": "Apple Inc.", "shape": "operating_company" },
        "security": { "security_id": "sec_0000320193_aapl", "ticker": "AAPL" }
      },
      "data": {
        "statement": "income_statement",
        "shape": "operating_company",
        "periods": [
          { "id": "FY2025", "start": "2024-09-29", "end": "2025-09-27", "restated": false }
        ],
        "source": { "form": "10-K", "accession": "0000320193-25-000079", "filed": "2025-10-31" },
        "reporting": { "period_kind": "annual", "vintage": "latest_restated", "reporting_currency": "USD" },
        "fields": {
          "revenue": ["416161000000"],
          "net_income": ["112010000000"],
          "eps_diluted": ["7.46"],
          "effective_tax_rate": { "derived": "income_tax_expense / pretax_income", "values": [0.1561] }
        },
        "unavailable_fields": {
          "interest_expense": {
            "unavailable": "not_reported",
            "recovery": { "action": "use_full_document", "accession": "0000320193-25-000079" }
          }
        },
        "periods_available": 3
      },
      "meta": {
        "schema_version": "2",
        "as_of": { "sec": "2026-06-26" },
        "published_at": "2026-06-26T18:42:30.172304Z"
      }
    }
    ```
  </Step>

  <Step>
    ### Read values and refusals

    Financial statements are columnar. `data.periods` is the header, and each `data.fields.<name>` array aligns to that header. A cell is either an exact decimal string, a JSON number for a computed ratio, or a typed refusal object.

    A value that is present:

    ```json theme={null}
    "112010000000"
    ```

    * Exact money, share-count, and per-share magnitudes are **decimal strings**. Parse them with a decimal type, not a float.
    * Computed ratios such as `effective_tax_rate.values[0]` can be plain JSON numbers.
    * Money units come from `data.reporting.reporting_currency` and field metadata. Do not assume money is USD.

    Overview headline values use compact cells when a display twin helps:

    ```json theme={null}
    { "v": "112010000000", "d": "≈$112B" }
    ```

    Parse `v`; `d` is display-only.

    A value that could not be proven from the filing:

    ```json theme={null}
    {
      "unavailable": "not_reported",
      "recovery": { "action": "use_full_document", "accession": "0000320193-25-000079" }
    }
    ```

    Check `unavailable` first. When it is present, there is no value — do not substitute `0` or `null`. The token tells you why and `recovery.action` tells an agent what to do next. The catalog of every refusal and recovery action is served by `stock_reference` with `{ "catalog": "refusal_tokens" }`.
  </Step>
</Steps>

## Call it from code

Both clients branch on schema-2 refusal objects before using a cell.

<Tabs>
  <Tab title="Python">
    ```python title="financials.py" theme={null}
    import os
    from decimal import Decimal

    import httpx

    base_url = os.environ.get("STOCKCONTEXT_API_BASE_URL", "https://api.stockcontext.com")
    api_key = os.environ["STOCKCONTEXT_API_KEY"]


    def call(tool: str, body: dict) -> dict:
        resp = httpx.post(
            f"{base_url}/v1/tools/{tool}",
            headers={"X-API-Key": api_key},
            json=body,
            timeout=15.0,
        )
        resp.raise_for_status()
        return resp.json()


    def cell(value: object) -> Decimal | None:
        if isinstance(value, dict) and "unavailable" in value:
            return None
        return Decimal(str(value))


    data = call("stock_financials", {"symbol": "AAPL", "statements": ["income"], "periods": 1})["data"]
    period = data["periods"][0]
    fields = data["fields"]
    print(period["id"], cell(fields["revenue"][0]), cell(fields["net_income"][0]))
    ```
  </Tab>

  <Tab title="TypeScript">
    ```ts title="financials.ts" theme={null}
    const baseUrl = process.env.STOCKCONTEXT_API_BASE_URL ?? "https://api.stockcontext.com";
    const apiKey = process.env.STOCKCONTEXT_API_KEY;
    if (!apiKey) throw new Error("Missing STOCKCONTEXT_API_KEY");

    type ValueCell =
      | string
      | number
      | { unavailable: string; recovery?: { action: string } };

    async function call(tool: string, body: unknown) {
      const resp = await fetch(`${baseUrl}/v1/tools/${tool}`, {
        method: "POST",
        headers: { "X-API-Key": apiKey, "Content-Type": "application/json" },
        body: JSON.stringify(body),
        signal: AbortSignal.timeout(15_000),
      });
      if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
      return resp.json();
    }

    // Keep exact money as strings unless your app has a decimal library.
    function cell(v: ValueCell): string | number | null {
      return typeof v === "object" && "unavailable" in v ? null : v;
    }

    const { data } = await call("stock_financials", {
      symbol: "AAPL",
      statements: ["income"],
      periods: 1,
    });
    const period = data.periods[0];
    console.log(period.id, cell(data.fields.revenue[0]), cell(data.fields.net_income[0]));
    ```
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={3}>
  <Card title="Core concepts" icon="shield" href="/docs/concepts">
    The trust model behind every value.
  </Card>

  <Card title="Choose a tool" icon="route" href="/docs/guides/choose-endpoints">
    Map a question to the smallest set of calls.
  </Card>

  <Card title="Errors and refusals" icon="rotate-cw" href="/docs/guides/errors-and-retries">
    Handle auth, rate limits, and refused values.
  </Card>
</CardGroup>
