Quickstart
Five-minute path from “I have a PDF” to “I have structured JSON on my
webhook.” We’ll use cURL here; the same calls work from any HTTP
client.
Prerequisites
- A merchant account at app-dev.inferio.xyz (signup is free, trial credits land in your dashboard automatically)
- An API token — Dashboard → Settings → API keys. Format:
inf_dev_... - Your
merchant_id— Dashboard → Settings → top of page - A webhook receiver URL (use webhook.site for this walkthrough; swap to your real receiver later)
Set your env vars
export INFERIO_TOKEN="inf_dev_yourkeyhere"
export MERCHANT_ID="merchant_abc123"
export WEBHOOK_URL="https://webhook.site/your-unique-id"Create an upload session
curl -sX POST https://api-dev.inferio.xyz/api/v1/ocr/upload-sessions \
-H "Authorization: Bearer $INFERIO_TOKEN" \
-H "X-Merchant-ID: $MERCHANT_ID"Response:
{
"session_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"merchant_id": "merchant_abc123",
"limit_file": 20,
"limit_size_mb": 10
}Grab session_id — you’ll need it for the next two steps.
Upload a file
Drop any PDF, JPG, or PNG. For a quick test, save the JP sample invoice
from the dashboard’s onboarding flow as sakura.pdf and upload it:
export SESSION_ID="f47ac10b-58cc-4372-a567-0e02b2c3d479"
curl -sX POST \
"https://api-dev.inferio.xyz/api/v1/ocr/upload-sessions/$SESSION_ID/files" \
-H "Authorization: Bearer $INFERIO_TOKEN" \
-H "X-Merchant-ID: $MERCHANT_ID" \
-F "[email protected]"Response:
{
"files": [
{
"key": "sakura.pdf",
"url": "https://api-dev.inferio.xyz/api/v1/media/f47ac10b-58cc-.../sakura.pdf"
}
]
}Kick off OCR
curl -sX POST https://api-dev.inferio.xyz/api/v1/ocr/requests \
-H "Authorization: Bearer $INFERIO_TOKEN" \
-H "X-Merchant-ID: $MERCHANT_ID" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"My first batch\",
\"session_id\": \"$SESSION_ID\",
\"document_type\": \"trade_invoice_jp\",
\"validate_t_number\": true,
\"webhook_url\": \"$WEBHOOK_URL\"
}"Response:
{
"id": "req_3fa1c4e2b9d1",
"status": "queued",
"total_images": 1,
"created_at": "2026-04-30T03:18:02Z"
}Watch the webhook fire
In a few seconds (typically < 5s for a single page), your webhook receiver gets a signed POST:
// POST $WEBHOOK_URL
// Headers:
// X-Inferio-Signature: t=1735634283,v1=4f5a...
// X-Inferio-Event: ocr.document.completed
{
"event": "ocr.document.completed",
"request_id": "req_3fa1c4e2b9d1",
"document_id": "doc_8a7c2e0fa912",
"status": "completed",
"fields": {
"vendor": "株式会社サクラ商事",
"t_number": "T1234567890123",
"t_number_valid": true,
"issue_date": "2026-04-30",
"total": "¥495,800",
"tax_10_amount": "¥45,000",
"tax_8_amount": "¥8,800"
},
"confidence": {
"vendor": 0.99,
"t_number": 0.99,
"total": 0.99
}
}🎉 You just ran OCR end-to-end.
What just happened
- The upload session bounded a batch (default 20 files, 10 MB / file)
- The file landed in your session’s staging bucket, NOT yet processed
- The request enqueued the page; the worker picked it up; Claude Vision extracted the fields; the T-number was verified live against the National Tax Agency API
- Inferio signed the webhook payload with HMAC and POSTed it to your
webhook_url
Always verify the HMAC signature before trusting webhook payloads in production. See Webhooks → Signature verification.
Next steps
- Wire a real webhook receiver → Webhooks → Overview
- Process multi-page PDFs and learn the request state machine → Concepts → Requests & documents
- Define a custom JSON schema for documents we haven’t pre-tuned → API reference → Overview