# Invoice Data Extraction API and SDK changelog

**Versioning.** The API is versioned by URL path (`/v1`). Backward-compatible additions ship without a version change and are announced here. Breaking changes, if ever needed, ship as a new version path with at least 6 months of dual operation.

## 2026-09-12: Machine-readable docs, the agent guide and the skill

- The API contract as an OpenAPI 3.1 specification at [/openapi.yaml](https://invoicedataextraction.com/openapi.yaml) and [/openapi.json](https://invoicedataextraction.com/openapi.json).
- The docs as Markdown: [/api.md](https://invoicedataextraction.com/api.md), [/sdk/node.md](https://invoicedataextraction.com/sdk/node.md) and [/sdk/python.md](https://invoicedataextraction.com/sdk/python.md), each the whole reference for its path; [/llms.txt](https://invoicedataextraction.com/llms.txt) indexes them.
- The [agent guide](https://invoicedataextraction.com/agents) at `/agents` and `/agents.md`: when to hand documents to this service, the whole loop including answering questions, and the limits in one place.
- A skill for coding agents and assistants, discoverable from `/.well-known/agent-skills/index.json`: `npx skills add https://invoicedataextraction.com`.
- [/pricing.md](https://invoicedataextraction.com/pricing.md): the offer and the price table as plain text.
- This changelog, at `/changelog` and `/changelog.md`.

## 2026-09-12: Every question says its scope; SDKs 0.6.1

- Every question on an `input_required` status carries `scope`: `level` (`extraction` today) and `applies_to` in words. An answer governs every document in the extraction, not only the one in the question's example; where the right answer differs by document type, say so in `text`.
- The reference describes what a refused answer is: one given in bad faith, screened out and asked again with `previous_answer_rejected`. A vague or undecided answer is applied, and the matter may be asked again as a new question.
- SDKs 0.6.1: the Node.js type declarations carry `scope` on every question. The Python package is at 0.6.1 too, with no change in behaviour.

## 2026-09-11: The extraction can ask you questions; SDKs 0.6.0

- `options.ask_questions` on submit lets the extraction stop and ask when the documents leave something unsettled. The status is then `input_required`, from the moment the questions exist, with every open question and the `answer_by` deadline.
- `POST /v1/extractions/{extraction_id}/answers` takes a choice, a choice with words beside it, words alone, or `accept_recommended`, and answers with the extraction's status. A repeated post after the extraction has moved on is not an error.
- `input_required` in the list filter and on the details record, which also carries the questions.
- Two new cancellation reasons: `unanswered` (nobody answered by `answer_by`) and `answers_rejected` (three refused answers).
- SDKs 0.6.0: `extract(...)` takes `ask_questions` and an `on_questions` handler that answers in your code; without the handler it returns the waiting status for you to answer with `answerQuestions(...)` / `answer_questions(...)`.
- An SDK at 0.5.0 or earlier that polls an extraction submitted from the web app with questions on now meets `input_required`, a status its wait loop does not know, and stops with an error after about five minutes where it used to keep polling. Update to 0.6.0 or later.

## 2026-09-10: Held status requests, rows as JSON, cancel, output options, typed values; SDKs 0.5.0

- `wait` on `GET /v1/extractions/{extraction_id}` (1 to 45 seconds) holds the request until the extraction leaves `processing`, so a handful of calls replaces a polling loop.
- `GET /v1/extractions/{extraction_id}/results`: the extracted rows as JSON, in pages of up to 1,000, with the Review Needed items for each page alongside.
- `credits_balance` and `credits_reserved` on the completed and cancelled status responses.
- `POST /v1/extractions/{extraction_id}/cancel` stops an extraction that is queued or processing; cancelled responses carry `cancellation_reason`, and `cancelled` joins the list filter.
- Per-extraction output options on submit: `output_language`, `review_needed_fill_color`, `affected_field_fill_color` and `send_completion_email`, each defaulting to the account's preferences.
- `options.json_typed_values`: native JSON types in the JSON output file and the results endpoint. Recommended for a new integration that reads the rows; the default stays strings.
- Every error message says what happened and what to do next. `RATE_LIMITED` carries `details.retry_after_seconds` beside the `Retry-After` header, and `VALIDATION_FAILED` is a failure code of its own.
- SDKs 0.5.0: the held status check, `getResults(...)` / `get_results(...)` and the row iterators, `cancelExtraction(...)` / `cancel_extraction(...)`, the output options on `extract(...)` and `submitExtraction(...)` / `submit_extraction(...)`, and retries hardened for non-JSON gateway responses.

## 2026-07-06: API host hardening and docs links

- Requests to paths outside `/v1/` on `api.invoicedataextraction.com` return the standard JSON error envelope instead of plain text.
- `invoicedataextraction.com/docs` redirects to the API reference.

## 2026-07-03: SDKs 0.4.0

- The Node.js and Python SDKs send `X-SDK-Name` and `X-SDK-Version` headers naming the client. Any client may send them.

## 2026-06-21: SDKs 0.3.0

- Review Needed warnings, the `cancelled` status and page failure reasons in the SDKs' responses, matching the API.
