API Reference

POST /extract

Extracts structured data from a PDF file according to a configured schema. Only the fields defined in the schema are returned — sensitive content in the document is never exposed.


Endpoint

http
POST https://reliant-production.up.railway.app/extract Headers: X-Reliant-Key: rel_... Content-Type: multipart/form-data ← set automatically by your HTTP client

This endpoint accepts multipart/form-data (not JSON). The PDF is sent as a file field alongside the other parameters as regular form fields. Do not set Content-Type manually — your HTTP client must set the correct multipart boundary.

Form fields

FieldTypeDescription
filefilerequiredThe PDF to extract data from. Max 10 MB.
schema_idstringrequiredID of the schema that defines which fields to extract.
providerstringrequiredanthropic | openai | gemini | groq | mistral
modelstringrequiredModel to use (e.g. claude-sonnet-4-6, gpt-4o).
user_idstringrequiredYour Reliant user ID.
end_user_idstringoptionalEnables persistent memory scoped to this end user.
external_idstringoptionalExtra scope key to isolate memory threads for the same user.

How it works

Reliant extracts all text from the uploaded PDF and sends it as the user prompt to the configured LLM provider. The schema's JSON Schema definition is used as the output contract — the model is instructed to return only the declared fields. The extraction goes through the same reliability pipeline as /execute: automatic retries, provider fallback, quality scoring, and full audit logging.

If the PDF text exceeds approximately 20 000 tokens, the content is truncated and the response will include "truncated": true. Image-based (scanned) PDFs that contain no extractable text will return a 422 error.

Schema example

Define a schema with only the fields you want to expose. For a purchase order you might use:

json — schema definition
{ "type": "object", "required": ["supplier", "total_amount", "issue_date"], "properties": { "supplier": { "type": "string" }, "total_amount": { "type": "number" }, "issue_date": { "type": "string", "format": "date" }, "invoice_number": { "type": ["string", "null"] } } }

Only these four fields will ever appear in the response — any other content in the PDF (bank details, personal data, internal notes) is discarded.

cURL

curl
curl -X POST https://reliant-production.up.railway.app/extract \ -H "X-Reliant-Key: rel_..." \ -F "file=@invoice.pdf" \ -F "schema_id=YOUR_SCHEMA_ID" \ -F "provider=anthropic" \ -F "model=claude-sonnet-4-6" \ -F "user_id=YOUR_USER_ID"

TypeScript / Node.js

typescript
import { readFileSync } from 'fs' const form = new FormData() form.append('file', new Blob([readFileSync('invoice.pdf')], { type: 'application/pdf' }), 'invoice.pdf') form.append('schema_id', 'YOUR_SCHEMA_ID') form.append('provider', 'anthropic') form.append('model', 'claude-sonnet-4-6') form.append('user_id', 'YOUR_USER_ID') const response = await fetch('https://reliant-production.up.railway.app/extract', { method: 'POST', headers: { 'X-Reliant-Key': 'rel_...' }, body: form, }) const data = await response.json() console.log(data.output) // { supplier: "Acme Corp", total_amount: 1250.00, issue_date: "2026-07-07", invoice_number: "NF-00412" }

Python

python
import requests with open('invoice.pdf', 'rb') as f: response = requests.post( 'https://reliant-production.up.railway.app/extract', headers={'X-Reliant-Key': 'rel_...'}, files={'file': ('invoice.pdf', f, 'application/pdf')}, data={ 'schema_id': 'YOUR_SCHEMA_ID', 'provider': 'anthropic', 'model': 'claude-sonnet-4-6', 'user_id': 'YOUR_USER_ID', }, ) data = response.json() print(data['output'])

Response — 200 OK

json
{ "success": true, "status": "SUCCESS", "output": { "supplier": "Acme Corp", "total_amount": 1250.00, "issue_date": "2026-07-07", "invoice_number": "NF-00412" }, "truncated": null, "errors": null, "metadata": { "execution_id": "cmonavlcs0004ph01ska7i1tq", "schema_version": 1, "attempts": 1, "latency_ms": 1240, "tokens_used": 834, "provider": "anthropic", "model": "claude-sonnet-4-6", "quality_score": null, "quality_feedback": null, "quality_passed": null } }

Error responses

StatusErrorCause
400Validation ErrorMissing required field or invalid provider.
413File Too LargePDF exceeds 10 MB.
422PDF Parse ErrorFile is corrupted or image-based (no extractable text).
207All retries failed; safe_fallback was used if configured.