# Quickstart

This workflow goes from authentication to a point-in-time financial query using real Arche routes.

## Step 1 - Set your API key

Create a key in the [developer portal](https://app.arche.fi/keys?ref=quickstart),
then export it locally. No account yet? [Get a free API key](https://app.arche.fi/sign-up)
first; the Free plan needs no card. Arche authenticates requests with the `X-Api-Key` header.

**Export a local API key**

```bash
export ARCHE_API_KEY="YOUR_API_KEY"
```

```ts
const apiKey = process.env.ARCHE_API_KEY
```

```python
import os

api_key = os.environ["ARCHE_API_KEY"]
```

Every example below also sends `X-Request-ID`. It is optional, but it is what
lets you correlate a failed call with your own logs later — see
[Request IDs](https://docs.arche.fi/troubleshooting/request-ids).

## Step 2 - Resolve a company

Resolve a ticker to a canonical issuer record and save the `cik`.

**Resolve ticker to company**

```bash
curl -X GET "https://api.arche.fi/v1/edgar/companies:resolve?ticker=MSFT" \
  -H "X-Api-Key: $ARCHE_API_KEY" \
  -H "X-Request-ID: $(uuidgen)" \
  -H "Accept: application/json"
```

```ts
const resolved = await fetch(
  'https://api.arche.fi/v1/edgar/companies:resolve?ticker=MSFT',
  {
    headers: {
      'X-Api-Key': apiKey!,
      'X-Request-ID': crypto.randomUUID(),
      Accept: 'application/json',
    },
  },
).then((r) => r.json())
```

```python
import requests
import uuid

resolved = requests.get(
    "https://api.arche.fi/v1/edgar/companies:resolve",
    params={"ticker": "MSFT"},
    headers={
        "X-Api-Key": api_key,
        "X-Request-ID": str(uuid.uuid4()),
        "Accept": "application/json",
    },
    timeout=30,
).json()
```

Representative response:

```json
{
  "data": {
    "ticker": "MSFT",
    "exchange": "XNAS",
    "as_of": "2026-10-14",
    "cik": "0000789019"
  }
}
```

Take the `cik` and keep it. The issuer's name is not on this route. Request
`/v1/edgar/companies/{cik}` when you need `entity_name`, `tickers`,
`exchanges`, or `sic`.

## Step 3 - Retrieve statements

Once you have a `cik`, list statements for a reporting shape you care about.

**List statements**

```bash
curl -X GET "https://api.arche.fi/v1/edgar/companies/0000789019/statements?statement_type=INCOME_STATEMENT&page=1&page_size=10" \
  -H "X-Api-Key: $ARCHE_API_KEY" \
  -H "X-Request-ID: $(uuidgen)" \
  -H "Accept: application/json"
```

```ts
const statements = await fetch(
  'https://api.arche.fi/v1/edgar/companies/0000789019/statements?statement_type=INCOME_STATEMENT&page=1&page_size=10',
  {
    headers: {
      'X-Api-Key': apiKey!,
      'X-Request-ID': crypto.randomUUID(),
      Accept: 'application/json',
    },
  },
).then((r) => r.json())
```

```python
statements = requests.get(
    "https://api.arche.fi/v1/edgar/companies/0000789019/statements",
    params={
        "statement_type": "INCOME_STATEMENT",
        "page": 1,
        "page_size": 10,
    },
    headers={
        "X-Api-Key": api_key,
        "X-Request-ID": str(uuid.uuid4()),
        "Accept": "application/json",
    },
    timeout=30,
).json()
```

The current schema defines this route as a paginated collection:

- top-level fields: `items`, `page`, `page_size`, `total`
- item type: `EdgarStatementHTTP`

Each item is one SEC filing's statement. It is identified by `cik`,
`statement_type`, `fiscal_year`, `fiscal_period` and the filing's
`accession_id`, and carries its provenance (`filing_type`, `filing_date`,
`accepted_at`), whether it restated an earlier filing (`is_restated`),
whether the filing is an amendment (`is_amendment`, `amendment_sequence`), how
it was prepared (`accounting_standard`, `currency`), and the figures
themselves in `values`: one decimal string per metric code, with each one's
unit in `units`. Add `detail=true` for each figure's fact, provenance and the
statement's `quality` block. Each filing appears once.

Two of those decide whether figures are comparable and are easy to skip:
`accounting_standard` is `US_GAAP` or `IFRS` **per filing**, not per company,
and `currency` is the filing's own reporting currency. See
[Data model](https://docs.arche.fi/data-model).

## Step 4 - Run an as_of query

Ask what was knowable on a specific historical date.

**Point-in-time financials**

```bash
curl -X GET "https://api.arche.fi/v1/edgar/as-of/2024-03-31/financials/0000320193" \
  -H "X-Api-Key: $ARCHE_API_KEY" \
  -H "X-Request-ID: $(uuidgen)" \
  -H "Accept: application/json"
```

```ts
const pit = await fetch(
  'https://api.arche.fi/v1/edgar/as-of/2024-03-31/financials/0000320193',
  {
    headers: {
      'X-Api-Key': apiKey!,
      'X-Request-ID': crypto.randomUUID(),
      Accept: 'application/json',
    },
  },
).then((r) => r.json())
```

```python
pit = requests.get(
    "https://api.arche.fi/v1/edgar/as-of/2024-03-31/financials/0000320193",
    headers={
        "X-Api-Key": api_key,
        "X-Request-ID": str(uuid.uuid4()),
        "Accept": "application/json",
    },
    timeout=30,
).json()
```

## Step 5 - Inspect the response

Look for point-in-time fields and the filing each statement came from, not just financial values.

The snapshot covers every period knowable at that boundary, not just the most
recent one: this call returns 182 statements reaching back to Apple's FY2008.
Here is one of them, Apple's FY2023 income statement, with `values` and
`units` abridged:

```json
{
  "data": {
    "cik": "0000320193",
    "as_of_date": "2024-03-31",
    "as_of_timestamp": "2024-03-31T23:59:59.999999Z",
    "audit_mode": false,
    "snapshot_hash": "fad9c0202e7cf234dcc8f892f3e79654033ff7a1b7743195cbd7c8a0b8b8d1da",
    "_meta": null,
    "statements": [
      {
        "accession_id": "0000320193-23-000106",
        "cik": "0000320193",
        "company_name": "Apple Inc.",
        "statement_type": "INCOME_STATEMENT",
        "accounting_standard": "US_GAAP",
        "statement_date": "2023-09-30",
        "fiscal_year": 2023,
        "fiscal_period": "FY",
        "period_start": "2022-09-25",
        "reporting_entity": "REGISTRANT",
        "currency": "USD",
        "is_restated": false,
        "filing_type": "10-K",
        "is_amendment": false,
        "amendment_sequence": null,
        "filing_date": "2023-11-03",
        "accepted_at": "2023-11-02T22:08:27Z",
        "values": {
          "DILUTED_EPS": "6.13",
          "GROSS_PROFIT": "169148000000",
          "NET_INCOME": "96995000000",
          "OPERATING_INCOME": "114301000000",
          "REVENUE": "383285000000",
          "WEIGHTED_AVERAGE_SHARES_DILUTED": "15812547000"
        },
        "units": {
          "DILUTED_EPS": "USD/share",
          "GROSS_PROFIT": "USD",
          "NET_INCOME": "USD",
          "OPERATING_INCOME": "USD",
          "REVENUE": "USD",
          "WEIGHTED_AVERAGE_SHARES_DILUTED": "SHARE"
        },
        "content": null,
        "quality": null
      }
    ]
  }
}
```

Interpretation:

- `as_of_date` tells you the historical cutoff
- `as_of_timestamp` captures the exact point-in-time boundary
- `snapshot_hash` identifies the filings selected: two responses carry the same
  hash exactly when they select the same filings, so record it with your results
- `audit_mode` reports whether a restated period's statement as first reported
  was returned beside the restated one
- `values` holds the statement's consolidated figures for its own period, one
  decimal string per metric code, as filed; FY2023 revenue is
  `values["REVENUE"]`. A metric the filing did not report is absent

> **Note:** Add `detail=true` to see how far to trust each figure. Each
> statement then carries `content`, its facts with where each came
> from, and its `quality` block: how complete its metrics are, the
> reconciliation results recorded for it, its data-quality findings and how
> its metrics were mapped. This FY2023 income statement serves 17 of its 22
> canonical metrics and passes every check run on it. The response also
> carries `_meta.reconciliation` and
> `_meta.data_quality`, which summarize the snapshot as a whole: 6
> of the 449 accounting identities that could be evaluated fail, and 219 of
> the 671 reconciliation rules in scope were skipped. There is no single
> score; read `failed_rules` and `skipped_rules` before
> relying on a figure, and see
> [Coverage and data quality](https://docs.arche.fi/coverage) for every field.

> **Tip:** A latest-state query can change after new filings arrive. Use `as_of` retrieval when
> your workflow depends on a historical boundary.

## Next steps

- [Overview](https://docs.arche.fi/): Start here for the product model, first request path, and key entry points.
- [Authentication](https://docs.arche.fi/authentication): Send API keys correctly and handle authentication failures.
- [Environments](https://docs.arche.fi/environments): Base URLs, deployment expectations, and operational environment guidance.
