blueport Integration guide · v1 · Aug 2026
PDF2JSON API

PDF in. Clean JSON out.

One endpoint that reads any business document — invoices, contracts, registration forms — and returns structured, semantic JSON. No templates to configure, no fields to map.

Endpoint

POST https://pdf.blueport.io/pdf2json
auth: x-api-key header max 8 MB per PDF typical response 10–25 s nothing stored server-side

Authentication

Every request carries your organisation's API key in the x-api-key header. Your organisation has one key; owners and admins can view (masked) and rotate it any time at app.blueport.io → PDF2JSON → API key. Rotation invalidates the old key immediately — treat the key as a secret, keep it server-side, never ship it in a browser or mobile app.

Request

Send the PDF either way — or import the ready-made Postman collection (File → Import → paste the URL, then set the apiKey variable):

Raw binary — simplest, no encoding step:

curl -X POST https://pdf.blueport.io/pdf2json \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/pdf" \
  --data-binary @invoice.pdf

JSON body — when the PDF is already in memory:

// Node.js
const pdf = fs.readFileSync("invoice.pdf")
  .toString("base64");
const r = await fetch(
  "https://pdf.blueport.io/pdf2json", {
  method: "POST",
  headers: {
    "x-api-key": process.env.PDF2JSON_KEY,
    "content-type": "application/json",
  },
  body: JSON.stringify({ pdf }),
});
const { ok, data } = await r.json();

Response

The data object is the document, understood: a documentType, then logical entity groups with camelCase keys, ISO dates, and real JSON numbers for money. The shape follows the document — an invoice yields dealer/customer/vehicle/pricing groups, a registration form yields its own sections.

{
  "ok": true,
  "data": {
    "documentType": "TAX INVOICE",
    "pages": 2,
    "currency": "AUD",
    "dealer":  { "name": "Example Motors Pty Ltd", "abn": "12 345 678 901",  },
    "invoice": { "invoiceNo": "10023456", "date": "2026-08-01",  },
    "vehicle": { "vin": "6XY12345678900123", "odometer": 1,  },
    "pricing": {  }
  },
  "meta": { "request_id": "req_a1b2c3", "duration_ms": 17000 }
}
Quote meta.request_id in any support conversation — it identifies the exact request in our logs (the document itself is never stored).

Errors

StatusMeaningWhat to do
401Missing or invalid API keyCheck the header name and value; confirm the key wasn't rotated
400Body isn't a PDF / no PDF foundSend raw with content-type: application/pdf or JSON {"pdf": "<base64>"}
413PDF over 8 MBCompress or split the document
422Extraction declinedThe document was rejected by content safety — contact support with the request_id
502Extraction returned unusable outputRare and transient — retry once
500Service errorRetry with backoff; persistent failures → support

Good to know

Latency: extraction is synchronous and typically 10–25 seconds per document — set your HTTP client timeout to 120 s and call it from a background job, not a user-facing request.
Retries: safe to retry on 5xx; every successful call counts one document against your plan.
Usage: your document count and history are on your dashboard at app.blueport.io; you'll be notified as you approach your monthly allowance.
Privacy: documents are processed in-flight and never persisted — only usage counts and timings are recorded.