# Request & response conventions

Arche is an HTTP JSON API with consistent conventions across the public surface.

## Request shape

Typical requests combine:

- a versioned path under `/v1`
- route parameters such as `cik` or `accession_id`
- query parameters such as `as_of`, `page`, `page_size`, or fiscal filters
- the `X-Api-Key` header for authenticated access

Representative request:

```http
GET /v1/edgar/companies:resolve?ticker=AAPL&as_of=2024-03-31
X-Api-Key: YOUR_API_KEY
Accept: application/json
```

## Unrecognized query parameters

A query parameter the route does not accept is refused with `400
VALIDATION_ERROR` rather than ignored. An ignored filter looks exactly like a
filter that matched everything: `fiscal_year` on the statement listing, for
example, would otherwise return the company's whole history. The error lists
what the route does accept:

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "http_status": 400,
    "message": "Unrecognized query parameter(s): fiscal_year. The request was refused rather than answered without them.",
    "details": {
      "unknown_parameters": ["fiscal_year"],
      "accepted_parameters": [
        "detail",
        "from_date",
        "include_restated",
        "include_usd",
        "page",
        "page_size",
        "per_page",
        "statement_type",
        "to_date"
      ]
    },
    "trace_id": "…"
  }
}
```

This check runs before authentication, so a misspelled parameter returns `400`
even when the key is also wrong. The one exception is `_`, which proxies and
browsers append to defeat caching and which every route accepts.

## Response envelopes

Most singleton responses are wrapped in `data`.

```json
{
  "data": {
    "cik": "0000320193",
    "entity_name": "Apple Inc.",
    "tickers": ["AAPL"],
    "exchanges": ["XNAS"],
    "sic": "3571",
    "fiscal_year_end": "0926"
  }
}
```

The envelope is the convention; the fields inside it belong to the route. This
one is `/v1/edgar/companies/{cik}`. See [Data model](https://docs.arche.fi/data-model) for how it
differs from the resolve route, which does not return the name.

Collection responses may include paging fields and an `items` array.

```json
{
  "page": 1,
  "page_size": 50,
  "total": 2,
  "items": []
}
```

## Field naming

Public JSON fields use `snake_case`.

Representative examples:

- `accession_id`
- `accepted_at`
- `fiscal_year`
- `as_of_date`
- `as_of_timestamp`

## Timestamps and dates

Arche uses both date-only and timestamp fields.

- Use date fields such as `as_of_date` when the API is expressing a calendar date.
- Use timestamp fields such as `accepted_at` or `as_of_timestamp` when event order matters.
- Expect timestamps to be ISO 8601 strings in UTC.

## Nullability and precision

Not every field is populated on every route or every issuer.

> **Warning:** Treat nullable fields as a normal part of the contract. Do not coerce missing data into zero
> unless your downstream model explicitly requires that transformation.

Financial values may be represented as decimal strings. Preserve them as strings or high-precision numeric types until you control the conversion boundary.

## Ordering and pagination

Do not assume every collection route shares one global sort order or one universal pagination model.

- Use the route-level documentation in [API reference](https://docs.arche.fi/reference) for exact parameters.
- Persist the full request, including filters and pagination inputs, when building reproducible jobs.
- Prefer [Pagination](https://docs.arche.fi/pagination) guidance for multi-page collection reads.

## Next steps

- [Concepts](https://docs.arche.fi/concepts): Understand point-in-time retrieval, restatements, and deterministic datasets.
- [Data model](https://docs.arche.fi/data-model): Learn how companies, filings and statements relate.
- [Versioning](https://docs.arche.fi/versioning): Work with latest, version history, and as_of semantics without historical drift.
