Arche Python SDK
Typed, production-grade Python SDK for Arche public data APIs.
This initial release covers the primary public data surface:
- Companies
- Filings
- Statements
- Narratives
- Bulk export (Scale and Enterprise plans)
It does not include protected control-plane, billing, org/team/project/environment admin, usage, webhook, MCP, or internal ops routes.
Installation
pip install arche-sdk
For local monorepo usage:
pip install -e sdks/python
Authentication
API key
from arche_sdk import ArcheClient
client = ArcheClient(api_key="your_api_key")
Bearer token for protected portal/control-plane routes
from arche_sdk import ArcheClient
client = ArcheClient(bearer_token="your_jwt_or_token")
Use bearer auth only for protected portal/control-plane or internal routes that
explicitly require it. Public runtime API examples and quickstarts should use
api_key.
api_key and bearer_token are mutually exclusive; passing both raises
ValueError.
Quickstart
Companies
from arche_sdk import ArcheClient
with ArcheClient(api_key="...") as client:
company = client.companies.get("0000320193")
resolved = client.companies.resolve("AAPL")
completeness = client.companies.get_completeness("0000320193")
Naming a company
Every method that takes a cik also accepts a ticker symbol in its place, and a
ciks list accepts tickers. Digits are sent as a CIK and anything else as a
ticker, which the API resolves to the company whose filings hold its statements
on the request's date; one list must hold CIKs only or tickers only. A
company_id (narratives) takes the company UUID, the CIK or the ticker.
with ArcheClient(api_key="...") as client:
versions = client.statements.list("AAPL", statement_type="INCOME_STATEMENT")
derived = client.statements.get_derived_metrics_time_series(
ciks=["AAPL", "MSFT"],
statement_type="INCOME_STATEMENT",
metrics=["GROSS_MARGIN"],
frequency="annual",
)
Filings
with ArcheClient(api_key="...") as client:
page = client.filings.list("0000320193", filing_types=["10-K"], page=1, page_size=20)
filing = client.filings.get("0000320193", "0000320193-24-000001")
statements = client.filings.list_statements("0000320193", "0000320193-24-000001")
Statements
with ArcheClient(api_key="...") as client:
versions = client.statements.list("0000320193", statement_type="INCOME_STATEMENT")
timeline = client.statements.get_restatement_timeline(
"0000320193", "INCOME_STATEMENT", 2024, "FY"
)
derived = client.statements.get_derived_metrics_time_series(
ciks=["0000320193"],
statement_type="INCOME_STATEMENT",
metrics=["GROSS_MARGIN"],
frequency="annual",
)
# As known at a date, only the statements asked for: here the FY2024
# income statement. snapshot_hash still names the full as-of selection.
as_of = client.statements.get_as_of_financials_page(
"2025-03-31",
"AAPL",
limit=10,
statement_type="INCOME_STATEMENT",
fiscal_year_from=2024,
fiscal_year_to=2024,
fiscal_period="FY",
)
Narratives
with ArcheClient(api_key="...") as client:
narratives = client.narratives.list(
"11111111-1111-1111-1111-111111111111",
as_of="2024-12-31",
narrative_type="CHANGE_SUMMARY",
)
Bulk export
Scale and Enterprise plans can take a complete local copy of the served corpus
as Parquet files instead of paging the API. sync() fetches only what changed:
with ArcheClient(api_key="...") as client:
result = client.bulk.sync("./arche-corpus")
print(result.snapshot_id, len(result.downloaded), "downloaded")
print(len(result.skipped), "already held")
Download URLs are issued under the bulk-data license, which the organization
accepts once per license version. Until it has, sync() raises
BulkLicenseNotAcceptedError. Read the license and accept it from the SDK; the
person named confirms they may bind the organization:
with ArcheClient(api_key="...") as client:
current = client.bulk.license()
print(current.license_version, current.accepted)
if not current.accepted:
print(current.text)
client.bulk.accept_license(name="Jane Doe", email="jane@example.com")
accept_license() accepts the version and SHA-256 that license() returns, so
the acceptance is of the text served at that moment. Accepting a version the
organization already accepted returns the existing record unchanged.
Run it again tomorrow against the same directory and it transfers only the
partitions whose bytes moved. A file is skipped when the local copy already
hashes to the sha256 the snapshot's manifest records, so the skip is a
statement about the bytes on disk rather than about a timestamp, and an
interrupted sync resumes correctly. Digests are remembered in
<destination>/.arche-bulk-sync.json so a second sync does not reread
gigabytes to prove nothing changed; a file whose size or modification time
differs from the record is rehashed rather than trusted, and rehash=True
ignores the record entirely.
Restrict the sync, or watch it:
def show(event):
print(f"[{event.index}/{event.total}] {event.action} {event.path}")
with ArcheClient(api_key="...") as client:
client.bulk.sync("./arche-corpus", datasets=["statements", "financials"], progress=show)
Read the contract, browse snapshots, or fetch one file:
with ArcheClient(api_key="...") as client:
for dataset in client.bulk.datasets():
print(dataset.dataset, dataset.partition_column, [c.name for c in dataset.columns])
manifest = client.bulk.snapshot() # "latest" by default
print(manifest.snapshot_id, manifest.read_at, manifest.bytes)
changed = [item.path for item in manifest.files if item.changed]
client.bulk.download_file(manifest.snapshot_id, changed[0], "./arche-corpus")
Every download is verified against the manifest's checksum and raises
ChecksumMismatchError on a mismatch, removing the partial file. A manifest
path that would write outside the destination is refused rather than resolved. The URLs are
presigned and carry their own credentials: the SDK fetches them without an API
key, and each one is charged its file's full size against the organization's
daily download allowance when it is issued, not when the bytes move. Past the
allowance the API answers RateLimitError with code
BULK_DOWNLOAD_BUDGET_EXCEEDED.
Read the files with any Parquet reader. Partition directories are named
fiscal_year_2025, not Hive's fiscal_year=2025, because the files already
carry the partition as a column:
import duckdb
duckdb.sql("SELECT * FROM './arche-corpus/financials/*/*.parquet' LIMIT 5").show()
Agent tools
arche_sdk.tools.TOOLS defines four tools an agent can call: resolve a
ticker, list a company's statements, read them as they were known on a past
date (client.as_of.financials), and verify an earlier answer by its replay
token (client.query.verify). Each has a name, a description and a Pydantic
argument model, and tool.call(client, **arguments) returns JSON-ready data.
The same four tools ship for agent frameworks as langchain-arche,
llama-index-tools-arche and crewai-arche, each exposing
arche_tools(api_key=...).
Pagination
List endpoints return Page[T] with page, page_size, total, and items.
with ArcheClient(api_key="...") as client:
first_page = client.filings.list("0000320193", page=1, page_size=50)
if first_page.has_next:
second_page = client.filings.list("0000320193", page=2, page_size=50)
for filing in client.filings.iter_all("0000320193", page_size=100):
print(filing.accession_id)
Error handling
from arche_sdk import ArcheClient
from arche_sdk.errors import APIError, RateLimitError
try:
with ArcheClient(api_key="...") as client:
client.companies.get("0000000000")
except RateLimitError as exc:
print(exc.retry_after, exc.rate_limit_remaining)
except APIError as exc:
print(exc.status_code, exc.code, exc.message, exc.trace_id, exc.request_id)
Request ID and trace ID
- The SDK sends
X-Request-IDon every request (auto-generated when missing). - On API errors, the SDK exposes:
request_idfrom responseX-Request-IDtrace_idfrom canonical error envelope (error.trace_id)
License
Apache License 2.0. See LICENSE.
Metadata
Release files for arche-sdk 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| arche_sdk-0.2.1.tar.gz | 52.8 kB | With provenance | Details for arche_sdk-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| arche_sdk-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for arche_sdk-0.2.1-py3-none-any.whl |
Total release size: 97.5 kB
Release files / arche_sdk-0.2.1.tar.gz
| Download URL | arche_sdk-0.2.1.tar.gz |
|---|---|
| Size | 52.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
abe52cfa240e83b3ae7ab4a4906f9b5ecca29521b1eeadc360fc822e583b8c7d
|
|
BLAKE2b-256 checksum How to use checksums |
0d86daa0b96fb9af4935f5c13061b0d95cee8eb311345567a521f763a3489d22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / arche_sdk-0.2.1-py3-none-any.whl
| Download URL | arche_sdk-0.2.1-py3-none-any.whl |
|---|---|
| Size | 44.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8259bf7fae5b335d89fa3e79c447591d888da8a8a8d039423444c675ca0850c0
|
|
BLAKE2b-256 checksum How to use checksums |
0c7beec8e20f1a7a9311df160aff51bdb343226f7b3bb5e7d9fb2066df5398e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logSecurity for arche-sdk 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for arche_sdk-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.