An API that gives the same answer twice
APODEXA is a REST API for validating and normalizing finance files. It's rule-based, so a request is reproducible — the same input returns the same output and the same output_hash.
What you get
- A typed response envelope — every tool returns the same shape: a
decision, the output,output_hash,provenanceand per-field confidence. - Reproducible reruns —
output_hashis a hash of the canonical output, so you can cache, diff and verify results. - Typed errors — failures come back as structured error envelopes with a stable code, not a stack trace.
- Per-workspace Bearer keys — authenticate with
Authorization: Bearer apdx_...; each key is scoped to its workspace. - An OpenAPI schema — generate a client from
/openapi.json, or explore interactively at/docs.
Quickstart — from key to first 200
Create an API key in the dashboard (Settings → API keys — the free plan includes a sandbox key), then validate a bank statement. The sample file below contains fictional data, published for illustration only.
# 1) Download the sample statement (fictional data)
curl -sO https://apodexa.net/assets/sample/sample-statement.csv
# 2) Validate it (multipart upload; paste your key)
curl -s -X POST https://apodexa.net/api/v1/normalize_bank_csv \
-H "Authorization: Bearer apdx_YOUR_KEY" \
-F "file=@sample-statement.csv"
A successful response is the standard envelope. Trimmed to the fields most callers branch on:
{
"data": { "currency": "USD", "row_count": 5, "rows": [ … ] },
"validation": { "passed": true,
"checks": [ { "name": "running_balance_consistent", "passed": true }, … ] },
"provenance": { "parser": "normalize_bank_csv", "transformations": [ … ] },
"uncertain_fields": [],
"decision": "ACCEPTED",
"output_hash": "4acb65733e124eae0d1147785fe7be075b2a67ed42f69fe548830780403ef7d4"
}
Run it twice: the output_hash is identical, because the pipeline is deterministic. Optional form fields (locale, currency, date_format, column_mapping, template_id) are documented at /docs.
Determinism matters most when the answer is no. This second sample (also fictional) has a genuine D/M-vs-M/D conflict on every date — instead of silently guessing, the pipeline refuses to pick and returns decision: "NEEDS_REVIEW":
# 3) Download the ambiguous-dates sample (fictional data)
curl -sO https://apodexa.net/assets/sample/sample-ambiguous-dates.csv
# 4) Validate it — a deterministic refusal, not a guess
curl -s -X POST https://apodexa.net/api/v1/normalize_bank_csv \
-H "Authorization: Bearer apdx_YOUR_KEY" \
-F "file=@sample-ambiguous-dates.csv"
Trimmed response — the failing check, the uncertain field and the repair path are all machine-readable:
{
"data": { "currency": "USD", "row_count": 4, "rows": [ … ] },
"validation": { "passed": false,
"checks": [ …, { "name": "dates_unambiguous", "passed": false,
"detail": "ambiguous dd/mm vs mm/dd" } ] },
"uncertain_fields": [ "transaction_date" ],
"repair_suggestions": [ "Ambiguous dates detected; supply locale or date_format (DMY/MDY) to resolve." ],
"decision": "NEEDS_REVIEW",
"output_hash": "ca79b0b53bb518918820c160b189c748dad2629f19b76d8d1ced44bda1ab3b76"
}
The refusal is reproducible too — every retry returns the same output_hash. Resolve it by re-sending the same file with date_format=DMY (or MDY): the run then returns ACCEPTED.
Read the reference
Interactive docs, or the raw schema for code generation.