Skip to content

API Overview

https://api.factum.pyragogy.org

The API is built on FastAPI/OpenAPI. Marketplace deployment is a proxied distribution channel; the public URL and authentication injection may differ from the origin API contract.

Business endpoints require:

X-API-Key: <your-api-key>

The backend is fail-closed: a missing or invalid key returns 401 Unauthorized. Comparison uses secrets.compare_digest.

Public endpoints:

  • GET /health
  • GET /status

POST /v1/parse accepts exactly one source:

Field Type Required Notes
job_id UUID XOR Job returned by /v1/uploads
text string XOR Stateless input, request-scoped
doc_type enum no auto, fattura, f24, generico; default auto
async_mode boolean no Async mode; not valid with text
callback_url HTTP URL no Webhook for async. Only with async_mode=true

job_id and text are mutually exclusive — exactly one must be present.

POST /v1/uploads accepts a single multipart field:

file=<XML or PDF>

There is no separate filename field in the backend contract; FastAPI receives the filename as UploadFile.filename metadata.

The transport and semantic limit is 10 MiB (max_body_bytes and max_upload_bytes). Supported document classes are FatturaPA XML and invoice PDF.

End-to-end latency, from the moment a document enters the API to the complete response. Logarithmic scale: deterministic paths answer in milliseconds, the LLM path in seconds.

End-to-end latency chart

Path Measured latency Engine Notes
Rule-based extraction (in-memory) ~0.03 ms (P50) Deterministic No LLM
HTTP API — single request ~2.5 ms (P50) Deterministic Real-stack benchmark
FatturaPA XML — end-to-end ~12 ms Deterministic Recommended for integrations
Text PDF (extraction + LLM) ~10–15 s LLM (deepseek-v3) Improvement margin on the roadmap
Scanned PDF not supported — HTTP 422 scanned_document
  • XML integrations (FatturaPA): deterministic path, ~12 ms, no LLM. This is the recommended primary path: low latency, stable cost, guaranteed result from verified arithmetic (total ≈ net + VAT).
  • Text PDF: supported, but the LLM path takes ~10–15 s. Improvement on this latency is on the roadmap — it remains a valid path for unstructured documents (foreign invoices, F24, free text).
  • Scanned PDFs (no selectable text): rejected with 422 (scanned_document). This is a declared architectural choice: Factum processes digital documents, not images. Every path’s latency is measured and monitored via Prometheus.

Recommendation: for production integrations use FatturaPA XML — latency is ~12 ms and the result is deterministic. Use the text/PDF path only when the document is not available as XML.

Rate limiting is environment-configurable. When active (X-Tier header: free | basic | pro), the middleware may emit 429 Too Many Requests.

Current limits (from app/services/ratelimit.py):

Tier Limit Window
free 60 req/min 1 min
basic 100 req/min 1 min
pro 1000 req/min 1 min

There are two distinct contracts:

  1. DocumentResponse — ingestion/job metadata returned by /v1/uploads and /v1/uploads/{job_id}.
  2. ParseResponse — parse execution metadata plus result: DocumentEnvelope | null.

DocumentEnvelope v2 is the canonical structured result inside ParseResponse.result. See Schemas.

The backend currently accepts X-Request-Id on POST /v1/uploads and uses it as the RFC 7807 instance value when an upload error is generated.

A global X-Request-ID response header is not currently implemented across all routes. Do not document it as a universal guarantee until the backend adds and tests that middleware.

This is intentional documentation debt, not a fabricated feature.