# Quickstart The five-minute path from clone to first extraction. For depth on every step, see the [full integration guide](/integration-guide/). ## 1. Boot the stack Required env (in `.env`): ```bash POSTGRES_PASSWORD= MINIO_ROOT_USER= MINIO_ROOT_PASSWORD= ARTIFACT_SIGNING_SECRET= SESSION_SECRET=$(python -c "import secrets; print(secrets.token_urlsafe(32))") # Bootstrap the first platform admin BOOTSTRAP_PLATFORM_ADMIN_ENABLED=true BOOTSTRAP_PLATFORM_ADMIN_EMAIL=admin@yourcompany.com BOOTSTRAP_PLATFORM_ADMIN_PASSWORD= # Point the LLM row at a model server. These are first-boot seeds only. LLM_URL=https://your-vllm.internal:8000 LLM_MODEL=qwen3-8b-instruct LLM_BACKEND_KIND=vllm ``` For Ollama, OpenAI, Gemini, credentials, and runtime edits after first boot, see [Infrastructure setup](/infrastructure-setup/). ```bash # Application + infra (no GPU model servers in stack): docker compose -f docker/docker-compose.yml up -d # Or include the bundled local PaddleOCR-VL + GLM-OCR servers # (single-GPU, 24 GiB): docker compose -f docker/docker-compose.yml \ -f docker/docker-compose.local-models.yaml up -d ``` ## 2. Confirm health ```bash curl http://localhost:8080/v1/health ``` ```json { "status": "ok", "components": { "database": true, "redis": true, "worker": true, "storage": true, "providers": { "paddleocr-vl": true, "glmocr-vl": true, "llm": true } }, "queue_depth": 0 } ``` ## 3. Create a tenant + invite a user ```bash docstack-admin tenant create --id acme --name "Acme Corp" \ --initial-admin-email admin@acme.com docstack-admin user invite --tenant-id acme \ --email integrator@acme.com --role tenant_admin ``` Open the invite URL the CLI prints to set a password. ## 4. Mint an API key ```bash docstack-admin api-keys create --tenant-id acme \ --user-email integrator@acme.com --name backlog-sync # → printed once: rk__ ``` The secret is unrecoverable — capture it now. ## 5. Submit a document ```bash API="http://localhost:8080" KEY="rk__" JOB=$(curl -s -X POST "$API/v1/documents" \ -H "Authorization: Bearer $KEY" \ -F "file=@invoice.pdf" \ | jq -r .job_id) echo "submitted: $JOB" ``` ## 6. Poll for completion ```bash while true; do RESPONSE=$(curl -s -H "Authorization: Bearer $KEY" \ "$API/v1/documents/$JOB") STATUS=$(echo "$RESPONSE" | jq -r .status) echo "status: $STATUS" case "$STATUS" in completed|needs_review|rejected|failed) break ;; esac sleep 2 done echo "$RESPONSE" | jq .canonical.markdown ``` That's it. The response includes the full `CanonicalOcrDocument` (per-page blocks, tables, formulas, charts, seals) plus, if a template was applied, the structured `extraction.parsed` payload and any validation flags. ## Where to go next - **[Full integration guide](/integration-guide/)** — every endpoint, every parameter, every failure mode. - **[Infrastructure setup](/infrastructure-setup/)** — configure OCR and LLM endpoints across vLLM, Ollama, OpenAI, and Gemini. - **[API reference](/api-reference/)** — interactive OpenAPI browser. - **[Contract testing](/contract-testing/)** — keep your integration aligned with the API spec automatically.