# Fetch provisions

`POST https://api.azta.ai/v1/provisions/fetch`

Read provisions by `unit_id`, from a source record or a search hit: at most 20 per call. A `unit_id` names a provision, not a version, so it keeps working after the law is amended.

`as_of` picks the version in force that day, today in UTC without it; each record echoes the date it used. `text` is cut to 20,000 characters. An id that was not found, or that this API does not serve (`us`, an add-on corpus, a country whose ids are not yet stable), is in `not_found` and free.

Charged per provision returned; a call that returns none is not charged. `X-Jurisdiction` is checked as for a search and narrows nothing.

## Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | header | no | Makes a retry safe. A repeat of the same request answers with the stored result and `Idempotent-Replayed: true`, and is never charged again; the same key on a different request is `idempotency_key_reused`. Without it, a retry is a new, charged request. |
| `X-Jurisdiction` | header | no | The countries whose law is read, comma-separated, in any case and spacing; `hu` without it. Allowed: `at`, `be`, `ch`, `cz`, `de`, `dk`, `es`, `fi`, `fr`, `gb`, `ge`, `hr`, `hu`, `ie`, `it`, `li`, `lu`, `mc`, `nl`, `no`, `pl`, `pt`, `ro`, `rs`, `se`, `si`, `sk`. Any other code, `us`, `oecd` and `ifrs` included, is `unsupported_jurisdiction`. |

## Request body

Required. Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `as_of` | string or null | no | The day whose version is read, `YYYY-MM-DD`; today in UTC when absent. |
| `ids` | array of string | yes | The `unit_id`s to read, from a source record or a search hit. |

## Responses

### 200

The provisions found, and the ids that were not.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `data` | array of object | yes |  |
| `data[].act` | object | yes | The act a provision belongs to. |
| `data[].act.identifier` | string or null | yes |  |
| `data[].act.short_title` | string or null | yes |  |
| `data[].act.title` | string | yes | Empty when the act has none. |
| `data[].as_of` | string | yes | The day whose version was read. |
| `data[].country` | string | yes | A lower-case country code. |
| `data[].excerpt` | string or null | yes | At most 300 characters, whitespace collapsed. |
| `data[].kind` | string (`provision`) | yes |  |
| `data[].section` | string or null | yes |  |
| `data[].text` | string | yes | The provision and its subsections, cut to 20,000 characters. |
| `data[].title` | string | yes | A display label: the act's short title, then the section. |
| `data[].truncated` | boolean | yes | Whether `text` was cut. |
| `data[].unit_id` | string | yes | A provision's id, the same across versions and re-ingestion: pass it to `POST /v1/provisions/fetch`. A Hungarian id is `hu:njt:&lt;njt id>:&lt;path>`. |
| `data[].url` | string | yes | An absolute URL, always present. |
| `data[].url_kind` | string (`official`, `viewer`) | yes | `official` is the publisher's own page, `viewer` our provision or document viewer. |
| `data[].version` | object or null | yes | The version read. Null for a version that never commenced. |
| `not_found` | array of string | yes | The requested `ids` that were not read, in request order. They cost nothing. |
| `object` | string (`list`) | yes |  |
| `usage` | object | yes | What a provision lookup cost. |
| `usage.cost` | object | yes | An amount billed, in the account's currency. |
| `usage.cost.amount` | string | yes | Two decimals, as a string. |
| `usage.cost.currency` | string (`EUR`, `HUF`) | yes |  |

### 400

The request was refused.

- `invalid_request`: The body or a header is invalid; `param` names the field.
- `unsupported_jurisdiction`: `X-Jurisdiction` names `us`, `oecd`, `ifrs` or an unknown code; on a search, also when none of the countries it names can be searched by provision.
- `idempotency_key_reused`: The `Idempotency-Key` was used for a different request.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 401

The request was refused.

- `invalid_api_key`: The key is missing, malformed, unknown, revoked or expired.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 402

The request was refused.

- `insufficient_credits`: Not enough credit, or no credit account.
- `spend_cap_reached`: A company, key or postpaid monthly spend cap would be exceeded.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 403

The request was refused.

- `account_suspended`: The credit account is suspended or closed.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 409

The request was refused.

- `idempotency_key_in_use`: A request with this `Idempotency-Key` is still being processed.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 429

The request was refused.

- `rate_limit_exceeded`: The key's requests-per-minute limit is used up.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 500

The request was refused.

- `server_error`: Anything else. It never carries exception text.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |

### 503

The request was refused.

- `ledger_unavailable`: The credit ledger could not answer, so the request fails closed. A `503` at the start of a request charges nothing; a lookup's `503` after its provisions were read may have charged it, and a retry with the same `Idempotency-Key` never charges it twice.

Content type: `application/json`.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | object | yes | What a refused request says. Branch on `code`; `message` is English and names no internal detail. |
| `error.code` | string (`invalid_request`, `unsupported_parameter`, `unsupported_jurisdiction`, `idempotency_key_reused`, `invalid_api_key`, `insufficient_credits`, `spend_cap_reached`, `account_suspended`, `not_found`, `idempotency_key_in_use`, `response_finished`, `rate_limit_exceeded`, `concurrency_limit_exceeded`, `server_error`, `ledger_unavailable`) | yes |  |
| `error.message` | string | yes |  |
| `error.param` | string or null | yes | The field or header at fault, or null when no one is. |
| `error.type` | string (`invalid_request_error`, `authentication_error`, `billing_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`) | yes |  |
