Skip to Content
Get startedQuickstart

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

  1. The upload session bounded a batch (default 20 files, 10 MB / file)
  2. The file landed in your session’s staging bucket, NOT yet processed
  3. 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
  4. 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