Quickstart

From zero to your first result in five steps.

1. Create an account

Sign up at app.hotdoc.io — no credit card required.

2. Create a hotdoc API key

In the dashboard, under “API keys.” The full key is shown once, at creation — save it. Format: hotdoc_<id>.<secret>.

3. Have your BYOK keys ready

Document processing needs two keys:

  • Model provider key (neural.apiKey) — from one of the supported providers: OpenAI, Anthropic (Claude), xAI (Grok), Together, DeepSeek, Xiaomi, or OpenRouter. Used at the LLM stage.
  • OCR provider key (ocr.providerKey) — a BYOK key for the OCR stage. Pass the provider via ocr.provider (e.g. NEURAL_CLIENT_TYPE_MISTRAL) and the model via ocr.model (e.g. mistral-ocr-latest). Required on every request.

Both keys are accepted as input only; neither is stored in plaintext — the encrypted copies are deleted along with the job (~7 days).

4. Create a job

Pass your file URLs, prompts, and model configuration:

curl -X POST https://api.hotdoc.io/v1/jobs \
  -H "Authorization: Bearer hotdoc_<id>.<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceUrls": ["https://example.com/invoice.pdf"],
    "title": "Invoice #42",
    "prompts": ["Extract the invoice number, date, supplier, line items, and total. Return strict JSON."],
    "ocr": { "provider": "NEURAL_CLIENT_TYPE_MISTRAL", "model": "mistral-ocr-latest", "providerKey": "<YOUR_KEY>" },
    "neural": {
      "type": "NEURAL_CLIENT_TYPE_XIAOMI",
      "model": "mimo-v2-flash",
      "apiKey": "<YOUR_PROVIDER_KEY>",
      "reasoningEffort": "low"
    }
  }'

Which model should you use? Compare intelligence, per-token price and providers side by side in the LLM comparison, then set the model accordingly.

You’ll get back a job in status JOB_STATUS_NEW, with its id.

5. Wait for the result

Poll the job status until it reaches a terminal state (JOB_STATUS_COMPLETE, JOB_STATUS_PARTIAL, or JOB_STATUS_FAILED):

curl https://api.hotdoc.io/v1/jobs/JOB_ID \
  -H "Authorization: Bearer hotdoc_<id>.<secret>"

Once the job is done, fetch the full result with the recognized text and the model’s answers:

curl https://api.hotdoc.io/v1/jobs/JOB_ID/result \
  -H "Authorization: Bearer hotdoc_<id>.<secret>"

Example response:

{
  "result": {
    "job": { "status": "JOB_STATUS_COMPLETE" },
    "ocr": [{ "status": "JOB_OCR_STATUS_DONE", "content": "<p>Invoice #42 dated 2026-06-01…</p>" }],
    "llm": [{ "status": "JOB_LLM_STATUS_DONE", "content": "{\"number\": \"42\", \"date\": \"2026-06-01\", \"total\": \"15000\"}" }]
  }
}

You don’t have to host the file at a public URL — you can upload it directly. See “Uploading files.”

Example model strings

Passed to the provider as-is (current as of 2026-06-17, check the provider’s catalog): Xiaomi — mimo-v2-flash (verified); OpenAI — gpt-4o-mini; Anthropic — claude-3-5-sonnet-latest. hotdoc doesn’t validate this value — if you mistype it, the provider returns an error in llm[].error.