Python SDK

The Arche Python SDK wraps the same public routes documented in the API reference with typed models, pagination helpers, and structured errors. It is the recommended integration path for production workloads.

Install

pip install arche-sdk

Create a client

The client is a context manager. It holds a connection pool, so create one and reuse it rather than constructing a client per request.

import os

from arche_sdk import ArcheClient

with ArcheClient(api_key=os.environ["ARCHE_API_KEY"]) as client:
    company = client.companies.get("0000320193")
    print(company.entity_name)
  • Name
    api_key
    Type
    str | None
    Description

    Sent as the X-Api-Key header. Create one in the developer portal.

  • Name
    base_url
    Type
    str
    Description

    Defaults to https://api.arche.fi.

  • Name
    timeout_seconds
    Type
    float
    Description

    Per-request timeout. Defaults to 30.0.

  • Name
    http_client
    Type
    httpx.Client | None
    Description

    Supply your own transport when you need custom retries, proxies, or connection limits.

Resources

The client exposes four resource groups:

  • Name
    client.companies
    Type
    resource
    Description

    Resolve tickers to canonical issuers, read company profiles, and check reporting completeness.

  • Name
    client.filings
    Type
    resource
    Description

    List filings for a company, read one filing, and list the statements it contains.

  • Name
    client.statements
    Type
    resource
    Description

    Statement versions, restatement timelines and deltas, reconciliation, data-quality overlays, derived metrics, and point-in-time financials.

  • Name
    client.narratives
    Type
    resource
    Description

    Narrative disclosures attached to filings.

The quickstart flow in Python

This mirrors the Quickstart step for step.

import os

from arche_sdk import ArcheClient

with ArcheClient(api_key=os.environ["ARCHE_API_KEY"]) as client:
    # Step 2 - resolve a ticker to a canonical CIK
    resolved = client.companies.resolve("MSFT")

    # Step 3 - list statement versions for that issuer
    statements = client.statements.list(
        resolved.cik,
        statement_type="INCOME_STATEMENT",
        page=1,
        page_size=10,
    )
    print(statements.total, "statement versions")

    # Step 4 - ask what was knowable on a historical date
    point_in_time = client.statements.get_as_of_financials(
        "2024-03-31",
        "0000320193",
    )
    print(point_in_time.snapshot_hash)

Derived metrics come from the same resource:

series = client.statements.get_derived_metrics_time_series(
    ciks=["0000320193"],
    statement_type="INCOME_STATEMENT",
    metrics=["GROSS_MARGIN"],
    frequency="annual",
)
print(len(series.points))

Pagination

Collection methods return a typed Page with page, page_size, total, items, and a has_next property.

page = client.statements.list("0000320193", statement_type="INCOME_STATEMENT")

while True:
    for version in page.items:
        print(version.fiscal_year, version.fiscal_period)
    if not page.has_next:
        break
    page = client.statements.list(
        "0000320193",
        statement_type="INCOME_STATEMENT",
        page=page.page + 1,
    )

For straightforward full scans, iter_all handles the loop and yields items across page boundaries:

for version in client.statements.iter_all("0000320193", statement_type="INCOME_STATEMENT"):
    print(version.fiscal_year, version.fiscal_period)

See Pagination for the underlying wire contract and Rate limits for guidance on how aggressively to iterate.

Request IDs

The SDK sends an X-Request-ID header on every request, generating a UUID when you do not supply one. Pass your own to correlate an API call with a job or task in your own system:

from arche_sdk import RequestOptions

company = client.companies.get(
    "0000320193",
    options=RequestOptions(request_id="nightly-refresh-2026-03-01"),
)

RequestOptions also accepts headers and timeout_seconds for per-request overrides. See Request IDs for how these values are used when escalating a failure.

Error handling

Failures raise typed exceptions. APIError is the base for any error the API reported, and the subclasses map to HTTP status classes: AuthenticationError, PermissionDeniedError, NotFoundError, ValidationError, ConflictError, RateLimitError, and ServerError. Transport failures raise ConnectionError or TimeoutError instead.

from arche_sdk import ArcheClient, APIError, RateLimitError

try:
    with ArcheClient(api_key=os.environ["ARCHE_API_KEY"]) as client:
        client.companies.get("0000000000")
except RateLimitError:
    ...  # back off, then retry
except APIError as exc:
    print(exc.status_code, exc.code, exc.trace_id, exc.request_id)

Every APIError carries both identifiers: request_id is the value the SDK sent, and trace_id is the one Arche returned in the error envelope. Log both.

Was this page helpful?