Skip to Content
SDKsNode / Python / Go

Node / Python / Go

Inferio’s REST API is plain HTTP + JSON. Idiomatic SDKs for Node, Python, and Go are in development — sign up via the Developers section  for the beta invite.

Until they ship, the snippets below show the recommended request idioms per language.

The browser is NOT a supported client. API tokens grant full read/write on your merchant; never embed them in a frontend bundle. Always proxy through your own server.

Node (axios)

import axios from "axios"; import FormData from "form-data"; import fs from "node:fs"; const inferio = axios.create({ baseURL: "https://api-dev.inferio.xyz", headers: { Authorization: `Bearer ${process.env.INFERIO_TOKEN}`, "X-Merchant-ID": process.env.MERCHANT_ID, }, }); // 1. Create upload session const { data: session } = await inferio.post("/api/v1/ocr/upload-sessions"); // 2. Upload file const form = new FormData(); form.append("files", fs.createReadStream("./sakura.pdf")); await inferio.post( `/api/v1/ocr/upload-sessions/${session.session_id}/files`, form, { headers: form.getHeaders() }, ); // 3. Kick off OCR const { data: request } = await inferio.post("/api/v1/ocr/requests", { session_id: session.session_id, document_type: "trade_invoice_jp", webhook_url: process.env.WEBHOOK_URL, }); console.log("queued →", request.id);

Python (requests)

import os import requests BASE = "https://api-dev.inferio.xyz" HEADERS = { "Authorization": f"Bearer {os.environ['INFERIO_TOKEN']}", "X-Merchant-ID": os.environ["MERCHANT_ID"], } # 1. Create upload session session = requests.post(f"{BASE}/api/v1/ocr/upload-sessions", headers=HEADERS).json() # 2. Upload file with open("sakura.pdf", "rb") as f: requests.post( f"{BASE}/api/v1/ocr/upload-sessions/{session['session_id']}/files", headers=HEADERS, files={"files": f}, ) # 3. Kick off OCR request = requests.post( f"{BASE}/api/v1/ocr/requests", headers={**HEADERS, "Content-Type": "application/json"}, json={ "session_id": session["session_id"], "document_type": "trade_invoice_jp", "webhook_url": os.environ["WEBHOOK_URL"], }, ).json() print("queued →", request["id"])

Go (net/http)

package main import ( "bytes" "encoding/json" "fmt" "io" "mime/multipart" "net/http" "os" ) const base = "https://api-dev.inferio.xyz" func setHeaders(req *http.Request) { req.Header.Set("Authorization", "Bearer "+os.Getenv("INFERIO_TOKEN")) req.Header.Set("X-Merchant-ID", os.Getenv("MERCHANT_ID")) } func main() { // 1. Create upload session req, _ := http.NewRequest("POST", base+"/api/v1/ocr/upload-sessions", nil) setHeaders(req) res, _ := http.DefaultClient.Do(req) var session struct{ SessionID string `json:"session_id"` } json.NewDecoder(res.Body).Decode(&session) // 2. Upload file body := &bytes.Buffer{} w := multipart.NewWriter(body) f, _ := os.Open("sakura.pdf") defer f.Close() part, _ := w.CreateFormFile("files", "sakura.pdf") io.Copy(part, f) w.Close() req2, _ := http.NewRequest("POST", fmt.Sprintf("%s/api/v1/ocr/upload-sessions/%s/files", base, session.SessionID), body) setHeaders(req2) req2.Header.Set("Content-Type", w.FormDataContentType()) http.DefaultClient.Do(req2) // 3. Kick off OCR payload, _ := json.Marshal(map[string]string{ "session_id": session.SessionID, "document_type": "trade_invoice_jp", "webhook_url": os.Getenv("WEBHOOK_URL"), }) req3, _ := http.NewRequest("POST", base+"/api/v1/ocr/requests", bytes.NewReader(payload)) setHeaders(req3) req3.Header.Set("Content-Type", "application/json") http.DefaultClient.Do(req3) }

Retry idioms

All three snippets above are happy-path. In production:

  • Timeouts — set explicit client timeouts (Inferio responds in <500ms for control-plane endpoints; OCR happens async via webhook)
  • Retries on 5xx + 429 — exponential backoff, 3 attempts; bail on 4xx (those are bugs, not transients)
  • Idempotency-Key — pass Idempotency-Key: <uuid> on retried POSTs to avoid double-creates

Coming SDK features

When the official SDKs ship, they’ll add:

  • Built-in retry with idempotency keys
  • Typed responses (TypeScript types, Python dataclasses, Go structs)
  • Webhook helpers (signature verification, parsed event types)
  • Streaming download for large extraction results

Until then, the REST API alone gets you to production.