Quickstart

Run your first invoice.

Start with a synthetic invoice, inspect its structured result, then try one of your own. Use the CLI below, or choose the integration that fits your workflow.

On this page

Choose your tools

Using n8n? Use the published n8n template to connect your invoice source, then follow the setup guide.

Before you start

  • Start a trial. After signup, create an API key in your account console.
  • For the CLI, install Node.js 22 or later (includes npm).
  • Replace inv_live_your_key in the command with your key. Keep it on a server or in your automation runtime.
  • One upload is one invoice; supporting material is allowed, but multiple distinct invoices are not.
  • Supported sources are PDF, JPEG, and PNG through 20 MiB and 20 pages.
  • Trial provides 100 processed pages for 30 days with no card.

Run a sample invoice

Choose a scenario and your shell. Each command downloads its synthetic PDF, submits it, and waits for the result. Replace inv_live_your_key with your API key before running. Requires Node.js 22 or later.

clean-us.pdf · Expected sample outcome: completed

Terminal
curl -fsSL --proto '=https' --proto-redir '=https' \
  -o ./clean-us.pdf \
  https://temlavo.com/fixtures/v1/clean-us.pdf &&
INVOICE_API_KEY='inv_live_your_key' \
  npm exec --yes --package=@temlavo/sdk@1 -- \
  temlavo process ./clean-us.pdf \
  --idempotency-key temlavo-fixture-v1-clean

The expected outcomes assume a fresh duplicate namespace with no prior matching document. These are precomputed examples; a live run may differ.

Rerunning a sample and using your own invoices

Rerunning a sample reuses its key, so you get the same document back for seven days. After that, the same file may become a new document and be flagged as a duplicate. Use a new key for each real invoice; never reuse a sample’s key in production.

Understand your result

The command waits for one of the three outcomes below. Read extracted invoice fields and line items under data, and the declared checks under validation.checks.

completed
A usable result with no blocking check. Warnings may remain. Review any warnings, then apply your business rules.
needs_review
A usable result with at least one blocking check. Use the checks to find what needs attention in your review step.
failed
No usable result was produced. This status is final. Read the document's error code to choose your next step.

For a result that needs review, use each check's message and paths to find the affected data. Completed means no blocking declared check was found; it does not independently verify the extracted values.

Understand errors and recovery

Try your own invoice

Choose one PDF, JPEG, or PNG containing a single invoice. Use a new, stable idempotency key for that invoice and reuse it only for exact retries. Do not reuse a sample's key for your own document.

Keep API keys on your server or in your automation runtime. Save the results your workflow needs before processing.result_expires_at. Live runs use your plan's page allowance, including results that need review.

HTTP details, when you need them

The SDK and CLI handle these calls for you. Building an integration in another language? Follow the HTTP guide, or expand the lifecycle below.

How the four API calls and recovery work

Every integration follows these steps. Your file goes directly to private storage without passing through the public API.

1 · Create the document

Code example
POST /v1/documents
{
  "filename": "invoice.pdf",
  "content_type": "application/pdf",
  "file_size_bytes": 84213,
  "policy": { "required_fields": [], "line_items": "advisory", "checks": { "duplicate_detection": true } }
}

Send one stable Idempotency-Key header. A timeout may have created the resource, so retries reuse the exact key and body.

The first run uses the default policy. Before processing your own invoices, see the available review policy settings.

Create response · excerpt
201 Created
{
  "id": "doc_9f3kc28d",
  "object": "document",
  "status": "awaiting_upload",
  "document_type": "invoice",
  "schema_version": "invoice.v1",
  "policy": { "required_fields": [], "line_items": "advisory", "checks": { "duplicate_detection": true } },
  "upload": {
    "method": "PUT",
    "url": "https://<private-storage>/...",
    "headers": { "…": "…" },
    "expires_at": "2026-08-27T15:30:00.000Z"
  }
}

2 · Upload the bytes directly

PUT the file to the returned URL with exactly the returned headers. Invoice API credentials never reach the upload origin, and redirects are not followed automatically.

3 · Confirm the upload

POST /v1/documents/{document_id}/upload-complete verifies the stored object and queues processing. Final billing admission happens asynchronously after page inspection. Uploading bytes alone never starts processing.

4 · Poll until a terminal status

Result response · excerpt
GET /v1/documents/{document_id}
{
  "status": "needs_review",
  "validation": {
    "review_required": true,
    "checks": [
      {
        "code": "total_consistency",
        "status": "fail",
        "message": "The invoice total does not equal the subtotal less discount, plus shipping, other charges and any tax the subtotal does not already include."
      }
    ]
  },
  "processing": { "result_expires_at": "…" }
}

Treat Retry-After as a minimum delay. Terminal statuses are completed, needs_review, and failed. A terminal failed document carries its processing error on the document resource. HTTP request errors use a separate typed envelope, for example:

Code example
{
  "error": {
    "type": "invalid_request",
    "code": "unsupported_content_type",
    "message": "Supported content types are PDF, JPEG, and PNG.",
    "request_id": "req_c81e728d",
    "retryable": false,
    "docs_url": "https://temlavo.com/docs/errors-recovery#error-unsupported_content_type"
  }
}
Read the HTTP guide, including retries and recovery