Quickstart

Extract structured data from a document in five steps.

Step 1

Create an account

Sign up at /signup with Google, GitHub, Microsoft, Apple, or email. Your account is created instantly.

Step 2

Get your API key

Open the Dashboard and click Generate new key. Copy the key immediately — it is shown only once. Your key starts with bloh_.

Step 3

Send your first request

Replace bloh_your_api_key with your real key and invoice.pdf with a path to your document:

curl -X POST https://api.bloh.dev/extract \
  -H "x-api-key: bloh_your_api_key" \
  -F "file=@invoice.pdf" \
  -F "document_type=invoice"
# pip install requests
import requests

with open("invoice.pdf", "rb") as f:
    response = requests.post(
        "https://api.bloh.dev/extract",
        headers={"x-api-key": "bloh_your_api_key"},
        files={"file": f},
        data={"document_type": "invoice"},
    )

print(response.json())
import fs from "node:fs";

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("invoice.pdf")]));
form.append("document_type", "invoice");

const res = await fetch("https://api.bloh.dev/extract", {
  method: "POST",
  headers: { "x-api-key": "bloh_your_api_key" },
  body: form,
});

console.log(await res.json());

Step 4

Parse the response

A successful extraction returns JSON with the extracted fields, document type, and confidence level:

{
  "success": true,
  "document_type": "invoice",
  "data": {
    "vendor_name": "Muller GmbH",
    "invoice_number": "2026-0847",
    "gross_amount": 1992.66,
    "currency": "EUR",
    "line_items": [
      { "description": "Consulting", "quantity": 40, "unit_price": 49.82, "amount": 1992.66 }
    ]
  },
  "confidence": "high",
  "credits_used": 2,
  "processing_time_ms": 1340
}

Step 5

Estimate before extracting (optional)

Use POST /estimate to check how many credits a document will cost before committing to extraction.

Authentication

All API requests require an API key passed in the x-api-key header. Generate keys from the Dashboard.

Header x-api-key: bloh_your_api_key

API keys start with bloh_ followed by a random hex string. Each account can have up to 5 active keys. You can revoke a key at any time from the Dashboard — revoked keys are rejected immediately.

The playground endpoints (/playground/extract and /playground/estimate) do not require an API key. They are rate limited to 3 extractions per day per IP address.

POST /extract

Extracts structured data from a document. Send the file as multipart form data.

multipart/form-data x-api-key
https://api.bloh.dev/extract

Request body

Field Type Required Description
file File Yes Document to extract. PDF, JPG, JPEG, PNG, WEBP, TIFF, DOCX, XLSX, PPTX, CSV, or TSV. Max 20 MB.
document_type String No invoice, receipt, contract, id_document, bank_statement, or auto (default).
schema String No JSON string defining custom fields. See Custom schemas.

Success response 200

{
  "success": true,
  "document_type": "invoice",
  "data": {
    "vendor_name": "Muller GmbH",
    "invoice_number": "2026-0847",
    "date": "2026-01-15",
    "due_date": "2026-02-15",
    "net_amount": 1674.50,
    "vat_rate": 19,
    "vat_amount": 318.16,
    "gross_amount": 1992.66,
    "currency": "EUR",
    "iban": "DE89370400440532013000",
    "line_items": [
      {
        "description": "Consulting — January",
        "quantity": 40,
        "unit": "hours",
        "unit_price": 41.86,
        "amount": 1674.50
      }
    ]
  },
  "confidence": "high",
  "credits_used": 2,
  "processing_time_ms": 1340
}

Response fields

Field Type Description
success Boolean Always true on success.
document_type String Detected or specified document type.
data Object Extracted fields. Structure varies by document type. Missing fields are null.
confidence String high, medium, or low. Reflects text quality and field coverage.
credits_used Number Credits consumed by this extraction.
processing_time_ms Number Server-side processing time in milliseconds.

Error response

{
  "success": false,
  "error": {
    "code": "UNSUPPORTED_FILE_TYPE",
    "message": "File type .zip is not supported. Supported types: pdf, jpg, jpeg, png, webp, tiff, docx, xlsx, pptx, csv, tsv"
  }
}

See Error codes for the full list.

POST /estimate

Estimates how many credits an extraction will cost without running the LLM. Useful for cost control and pre-validation.

multipart/form-data x-api-key
https://api.bloh.dev/estimate

Request body

Same as POST /extract: send a file field, with optional document_type.

Success response 200

{
  "success": true,
  "input_tokens": 1450,
  "estimated_credits": 3,
  "file_size_bytes": 245760,
  "mime_type": "application/pdf"
}

Response fields

Field Type Description
success Boolean Always true on success.
input_tokens Number Approximate token count of the parsed document text.
estimated_credits Number Estimated credits the extraction would consume.
file_size_bytes Number Size of the uploaded file in bytes.
mime_type String Detected MIME type of the file.

Example

curl -X POST https://api.bloh.dev/estimate \
  -H "x-api-key: bloh_your_api_key" \
  -F "file=@contract.pdf"

Custom schemas

By default, Bloh extracts a standard set of fields for each document type. To extract only specific fields, pass a JSON schema in the schema form field.

Schema format

The schema must be a JSON object with a fields array of strings. Each string is a field name to extract.

{
  "fields": ["vendor_name", "total_amount", "currency", "due_date"]
}

Constraints

  • Maximum 50 fields per schema.
  • Field names must be 64 characters or fewer.
  • Field names may only contain letters, numbers, underscores, hyphens, and spaces.

Example request

curl -X POST https://api.bloh.dev/extract \
  -H "x-api-key: bloh_your_api_key" \
  -F "file=@invoice.pdf" \
  -F 'schema={"fields":["vendor_name","total_amount","currency"]}'

Example response

{
  "success": true,
  "document_type": "invoice",
  "data": {
    "vendor_name": "Muller GmbH",
    "total_amount": 1992.66,
    "currency": "EUR"
  },
  "confidence": "high",
  "credits_used": 2,
  "processing_time_ms": 980
}

When a custom schema is provided, the document_type parameter is ignored — the LLM extracts only the fields you specify.

Error codes

All error responses share the same shape:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description"
  }
}
Code HTTP Description
MISSING_FILE 400 No file field in the multipart request body.
UNSUPPORTED_FILE_TYPE 400 File extension is not one of the supported types.
INVALID_SCHEMA 400 The schema field is not valid JSON or does not match the expected format.
UNAUTHORIZED 401 Missing, invalid, or revoked API key.
FILE_TOO_LARGE 413 File exceeds the 20 MB size limit.
PARSING_FAILED 422 The document could not be parsed. It may be corrupted, empty, or password-protected.
EXTRACTION_FAILED 422 The extraction engine could not produce valid structured data from this document.
RATE_LIMITED 429 Too many requests. See Rate limits.
CREDIT_LIMIT_REACHED 429 Monthly credit allowance exhausted. Upgrade your plan or wait for the next billing cycle.
INTERNAL_ERROR 500 Unexpected server error. If this persists, contact hello@bloh.dev.

Rate limits

Context Limit Window
API (per key) 60 requests 1 minute
Playground (per IP) 3 extractions 24 hours

When you exceed a rate limit, the API returns a 429 status with the RATE_LIMITED error code. Wait for the window to reset before retrying.

Monthly credit limits

Plan Credits/month
Free 100
Pro 2,000
Max 20,000

Credit usage is visible on the Dashboard. Use POST /estimate to check costs before extracting.

Supported document types

Pass a document_type to optimize extraction, or use auto (default) to let Bloh detect the type.

Type Key fields extracted
invoice vendor_name, invoice_number, date, due_date, line_items, net_amount, vat_rate, vat_amount, gross_amount, currency, iban, bic
receipt merchant_name, receipt_number, date, time, line_items, subtotal, tax_rate, tax_amount, total_amount, currency, payment_method
contract parties, contract_title, contract_number, effective_date, expiration_date, governing_law, jurisdiction, key_terms, signatures, total_value
id_document document_type, document_number, full_name, date_of_birth, nationality, expiry_date, issue_date, issuing_authority, address
bank_statement bank_name, account_holder, iban, bic, statement_period_start, statement_period_end, opening_balance, closing_balance, transactions
auto Bloh detects the type and extracts the corresponding fields automatically.

All dates are normalized to ISO 8601 (YYYY-MM-DD). All monetary amounts are returned as numbers without currency symbols. Currency is always a separate ISO 4217 field.