_Version: 2.0_

> This document is the LLM-friendly export of the API. It is regenerated on every request from the live OpenAPI spec. Use it as context when asking an AI assistant for help.

# fature.al API v2

Version 2 covers three groups: **invoices**, **clients** and **warehouse transfer notes**. Only these
change shape from v1, so only these have a second address. Everything else (purchase invoices,
products, cash register, reports and registration) stays on `v1` and is called from there even by
an integration that sends its invoices with `v2`.

Both versions share the token, the application credentials, the response format and the rate
limits. Concepts, identification and the shared rules are in the v1 documentation, at
[`/docs/api`](/docs/api). If you have not read it, start there.

## Servers

| Environment | URL |
| --- | --- |
| **Live** | `https://fature.al/api/v2` |
| **Sandbox** | `https://demo.fature.al/api/v2` |

## What changes from v1

### Invoice payment is always a list

The invoice sends its payment as `payment_methods`, with one element per method. An invoice paid with
a single method sends a one-element list, so there is only one shape to learn.

```json
"payment_methods": [
  {"type": "BANKNOTE", "amount": 1200},
  {"type": "CARD", "amount": 800}
]
```

| Rule | Limit |
| --- | --- |
| Methods per invoice | 10 |
| Value of an `amount` | Any number the CIS accepts, including 0 and negative |
| Same method twice | Not allowed |
| Sum of `amount` | Equal to the invoice total, with the discount already applied |

The `payment_method`, `company_card` and `vouchers` fields on the invoice are not accepted: the company card
goes in `payment_methods[].company_card` and vouchers in `payment_methods[].vouchers`, inside the
element that requires them. Invoices returned by lists and details carry the same list, so
payment reconciliation always reads a single shape.

An order invoice carries no payment at all: it opens the table, and the summary invoice pays for it.

### The client is split into objects

- **Objects instead of flat fields.** The data comes in `company`, `person`, `address` and
  `contact`, and the `type` field (`company` or `person`) says which of the first two is filled in.
- **The identifier is an object.** `id` with `type` (`nuis`, `vat`, `tax` for companies; `id`,
  `passport`, `social` for persons) and `value`, instead of `nipt` or `document_number`.
- **Values are lowercase.** `company` instead of `COMPANY`, `nuis` instead of `NUIS`.
- **Updates use `PATCH`**, not `PUT`, and `type` does not change: a `type` different from
  the existing one is rejected with `422`.

`GET /clients` in v2 still returns the flat v1 format, because the mobile app was built on it.
Details, creation and updates use the new format, and a client created with `v1` can be read with
`v2` with no extra step.

### The warehouse transfer note requires internalId

`POST /invoice/wtn` requires `internalId`, the note's identifier in your system, whereas in v1 it
is optional. The rest of the note is exactly the same as in v1.

Keep it unique within the company for the year. A second request with the same `internalId` does not issue
a second note; it returns the first note with `200`, so retrying after a timeout is safe.
Read the note later with `GET /invoice/wtn/details/{internalId}`, without storing our `id`.

The note carries no fiscal device: the CIS registers it with the business unit, the operator code and
the software code, so it can be issued even by a user without a TCR.

## Servers

- `https://fature.al/api/v2` - Live
- `https://demo.fature.al/api/v2` - Sandbox

## Endpoints

### GET /clients

**Summary:** List clients

Returns the company's clients, newest first, with text search. Each client comes
with the same fields as in `GET /clients/{id}/details`.

Use it to find the `id` of a saved client, or to sync your
records with those in fature.al.

- Pagination with `limit` and `offset`. `limit` is capped at `100`; a larger value is lowered without
  an error. `pagination` returns `total`, so continue with `offset += limit` until `offset`
  reaches `total`.
- `query` searches by partial match on the company name, first name, last name, NIPT,
  document number, email, phone and client number.
- A second request from the same token, while the first has not finished, is rejected immediately with
  `429`.

`company_type` is returned `null` for a person, and `first_name` and `surname` for a company;
`name` always holds the full name.

**Tags:** Clients

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `limit` | query | no | How many clients to return per page, up to 100. |
| `offset` | query | no | Which client to start from, counting from 0. |
| `query` | query | no | Search in the company name, first name, last name, NIPT, document number, email, phone or client number. |

**Responses:**

- `200` - The page's clients in `items`, with `pagination`; `items` is empty when no client matches.
- `401`
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.

---

### POST /clients

**Summary:** Create a client

Creates a client in the v2 format. The body is split by the `type` field, which accepts `company` or
`person`, and only the object matching the type is filled in.

| `type` | Object | Required fields |
| --- | --- | --- |
| `company` | `company` | `name`, `id` |
| `person` | `person` | `first_name`, `last_name`, `id` |

## Identifier

Always sent as an `id` object with `type` and `value`, and the allowed values depend on the type:

- company: `nuis`, `vat`, `tax`;
- person: `id`, `passport`, `social`.

## Shared objects

`address` (`line`, `city`, three-letter `country`) and `contact` (`phone`, `email`) are
optional and apply to both types. `company.category` accepts `business`, `bank` or
`exchange`.

Store the returned `id`: with it the client is found and updated again. A second request
from the same token while the first has not finished is rejected immediately with `429`.

**Tags:** Clients

**Request body content types:** application/json

**Responses:**

- `200` - The created client in `data.client`, with its `id` in fature.al; store it for invoices and updates.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `409` - A client with the same data already exists.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.

---

### GET /clients/{id}

**Summary:** Get a client by id

Returns the client in the v2 format: `company` or `person` depending on `type`, plus `address`,
`contact`, `customer_number` and `verified`.

It is the same client that `v1` returns, only structured differently. A client created with
`v1` can be read here with no extra step.

**Tags:** Clients

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The client id. |

**Responses:**

- `200` - The client in `data.client`, with `company` or `person` filled in according to its type.
- `401`
- `404` - The client was not found, or does not belong to your company.
- `500` - Unexpected server error.

---

### PATCH /clients/{id}

**Summary:** Update a client

Updates a client with `PATCH` and the same body as creation, with one restriction: `type`
does not change. A company does not become a person, nor the other way around; a `type` different from the
existing one is rejected with `422`.

A second request from the same token while the first has not finished is rejected immediately with
`429`.

**Tags:** Clients

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The client id. |

**Request body content types:** application/json

**Responses:**

- `200` - The updated client in `data.client`, in full, not just the fields sent.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field. Only a `type` different from the existing one is returned in the standard error format.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `404` - The client was not found, or does not belong to your company.
- `409` - A client with the same data already exists.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.

---

### GET /invoice

**Summary:** List invoices

The same list as in `v1`, where each invoice carries `payment_methods` instead of `payment_method`.
Filters and pagination are those of [`GET /api/v1/invoice`](/docs/api).

**Tags:** Invoices

**Responses:**

- `200` - The period's invoices in `items`, newest first, with `pagination`; `items` is empty when there are no invoices.
- `401`

---

### POST /invoice/bulk-noncash

**Summary:** Issue bulk non-cash invoices

The same bulk as in `v1`, where each invoice in `invoices` carries its own payment as a
`payment_methods` list. The response is an object with one entry per `internalId`, and the HTTP
status stays `200` even when some invoice fails: check `status` inside each entry and
retry only the ones that failed.

**Tags:** Invoices

**Responses:**

- `200` - An object with one entry per `internalId`. An invoice that fails carries the error format inside its own entry, and the response status stays 200.
- `401`
- `403` - The subscription has expired, or the action is not allowed for this account.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.

---

### POST /invoice/cancel-by-internal-id/{internalId}

**Summary:** Cancel an invoice by internalId

The same cancellation as in `v1`, finding the invoice by the `internalId` you sent when you issued it:
without a body the whole invoice is canceled; with `lines`, only part of it, which is possible **only for
cash invoices**. The full rules are in
[`POST /api/v1/invoice/cancel-by-internal-id/{internalId}`](/docs/api).

The response is the corrective document, with its own `iic` and `fic` and with `payment_methods`
alongside. When the CIS cannot be reached, the cancellation is saved with `fic: null` and is fiscalized automatically
later.

**Tags:** Invoices

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `internalId` | path | yes | Your identifier for the invoice, sent when it was issued. |

**Request body content types:** application/json

**Responses:**

- `200` - The corrective document, with its own `iic` and `fic`; `fic` is `null` when the CIS could not be reached and fiscalization will complete automatically.
- `401`
- `422` - The invoice cannot be canceled in its current state, or the lines sent do not match the original. `errors` says why.
- `404` - The invoice was not found, or does not belong to your company.
- `500` - Unexpected server error, including when the cancellation could not be registered with the CIS.
- `429` - The cancellation limit was reached, or another cancellation of the same type is still in progress. When the cancellation limit is hit, the response carries only `message` and the `Retry-After` header.

---

### POST /invoice/cancel/{id}

**Summary:** Cancel an invoice by id

The same cancellation as in `v1`: without a body the whole invoice is canceled; with `lines`, only part of
it, which is possible **only for cash invoices**. The full rules are in
[`POST /api/v1/invoice/cancel/{id}`](/docs/api).

The response is the corrective document, with its own `iic` and `fic` and with `payment_methods`
alongside. When the CIS cannot be reached, the cancellation is saved with `fic: null` and is fiscalized automatically
later. Cancellations have their own rate limit: 30 per minute and 600 per hour per token.

**Tags:** Invoices

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The invoice's id in fature.al. |

**Request body content types:** application/json

**Responses:**

- `200` - The corrective document, with its own `iic` and `fic`; `fic` is `null` when the CIS could not be reached and fiscalization will complete automatically.
- `401`
- `422` - The invoice cannot be canceled in its current state, or the lines sent do not match the original. `errors` says why.
- `404` - The invoice was not found, or does not belong to your company.
- `500` - Unexpected server error, including when the cancellation could not be registered with the CIS.
- `429` - The cancellation limit was reached, or another cancellation of the same type is still in progress. When the cancellation limit is hit, the response carries only `message` and the `Retry-After` header.

---

### POST /invoice/cash

**Summary:** Issue a cash invoice

The same invoice as in `v1`, with the payment as a list. For the buyer, lines, discounts and
self-invoicing, the rules of [`POST /api/v1/invoice/cash`](/docs/api) apply.

## Payment

`payment_methods` carries one element per method and is required even when the invoice
is paid entirely with one method.

```json
"payment_methods": [
  {"type": "BANKNOTE", "amount": 1200},
  {"type": "CARD", "amount": 800}
]
```

| Rule | Limit |
| --- | --- |
| Methods per invoice | 10 |
| Same method twice | Not allowed |
| Sum of `amount` | Equal to the invoice total, with the discount already applied |

Only the `COMPANY` element carries `company_card`, and only the `SVOUCHER` element carries `vouchers`.
A list that does not add up to the total is rejected with `400`, because the sum is checked only after
the discount on the invoice has been applied.

Self-invoicing is paid from the cash register, as in `v1`: when the cash register does not cover the total, the invoice is not saved and
the response comes with HTTP 200 and `status: false`.

**Tags:** Invoices

**Request body content types:** application/json

**Responses:**

- `200` - When the user has no fiscal device, when the cash register does not cover a self-invoice, or when the invoice is rejected after validation by the CIS or while saving, the response comes back with HTTP 200 and `status: false`; the reason is in `message`.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field. Only a missing `internalId` comes back in the standard error format.
- `400` - Incomplete or invalid data for fiscalization. `errors` says exactly what needs to be filled in. The invoice was not saved; retry with the same `internalId`.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `409` - A request with this `internalId` is still in progress. Wait a moment and retry, or read the state with `POST /invoice/details/{internalId}`.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.
- `503` - The fiscalization service could not be reached and the invoice was not saved. Retry with the same `internalId`.

---

### POST /invoice/details/{internalId}

**Summary:** Get an invoice by internalId

The same issuing result as in `v1`, with `payment_methods` alongside. Use it to read
the state after a timeout or after a `409`.

**Tags:** Invoices

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `internalId` | path | yes | Your identifier for the invoice, sent when it was issued. |

**Responses:**

- `200` - The issuing result of the invoice with this `internalId`, the same one the issue call returned, with `payment_methods`.
- `401`

---

### POST /invoice/e-invoice

**Summary:** Issue an e-invoice

The same e-invoice as in `v1`, with the payment as a `payment_methods` list. For the buyer, the document
type (`doc_type` and `process`) and correction notes, the rules of
[`POST /api/v1/invoice/e-invoice`](/docs/api) apply.

**Tags:** Invoices

**Request body content types:** application/json

**Responses:**

- `200` - When the invoice is rejected after validation, by the CIS or while saving, the response comes back with HTTP 200 and `status: false`; the reason is in `message`.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field. Only a missing `internalId` comes back in the standard error format.
- `400` - Incomplete or invalid data for fiscalization. `errors` says exactly what needs to be filled in. The invoice was not saved; retry with the same `internalId`.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `409` - A request with this `internalId` is still in progress. Wait a moment and retry, or read the state with `POST /invoice/details/{internalId}`.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.
- `503` - The fiscalization service could not be reached and the invoice was not saved. Retry with the same `internalId`.

---

### POST /invoice/noncash

**Summary:** Issue a non-cash invoice

The same invoice as in `v1`, with the payment as a `payment_methods` list. For the buyer, the bank
account, correction notes and discounts, the rules of
[`POST /api/v1/invoice/noncash`](/docs/api) apply.

The allowed methods are `ACCOUNT`, `COMPENSATION`, `FACTORING`, `KIND`, `OTHER`, `TRANSFER`
and `WAIVER`; none of them carries a company card or vouchers. When the method paying the largest
share is `ACCOUNT`, the invoice requires the bank account, as in `v1`.

**Tags:** Invoices

**Request body content types:** application/json

**Responses:**

- `200` - When the invoice is rejected after validation, by the CIS or while saving, the response comes back with HTTP 200 and `status: false`; the reason is in `message`.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field. Only a missing `internalId` comes back in the standard error format.
- `400` - Incomplete or invalid data for fiscalization. `errors` says exactly what needs to be filled in. The invoice was not saved; retry with the same `internalId`.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `409` - A request with this `internalId` is still in progress. Wait a moment and retry, or read the state with `POST /invoice/details/{internalId}`.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.
- `503` - The fiscalization service could not be reached and the invoice was not saved. Retry with the same `internalId`.

---

### POST /invoice/order

**Summary:** Issue an order invoice

The same order as in `v1`. The order opens the table and pays nothing, so it carries neither
`payment_method` nor `payment_methods`: payment comes later, with the summary invoice that
closes the table. The rules are those of [`POST /api/v1/invoice/order`](/docs/api).

**Tags:** Invoices

**Request body content types:** application/json

**Responses:**

- `200` - When the user has no fiscal device, or when the invoice is rejected after validation by the CIS or while saving, the response comes back with HTTP 200 and `status: false`; the reason is in `message`.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field. Only a missing `internalId` comes back in the standard error format.
- `400` - Incomplete or invalid data for fiscalization. `errors` says exactly what needs to be filled in. The invoice was not saved; retry with the same `internalId`.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `409` - A request with this `internalId` is still in progress. Wait a moment and retry, or read the state with `POST /invoice/details/{internalId}`.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.
- `503` - The fiscalization service could not be reached and the invoice was not saved. Retry with the same `internalId`.

---

### GET /invoice/print-eic/{eic}

**Summary:** Download the e-invoice PDF by EIC

Returns the official e-invoice PDF from the e-invoicing platform, by the EIC code that issuing
returned to you.

Check `Content-Type` before saving it as a PDF: an EIC that is not found returns the text
`Document not found.` with status `200` and `text/html`, not a PDF.

**Tags:** Invoices

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `eic` | path | yes | The e-invoice EIC code, a UUID. |

**Responses:**

- `200` - The e-invoice PDF. Check `Content-Type` before saving it: an EIC that is not found is still returned with status 200, but as `text/html`.
- `401`

---

### GET /invoice/print/{id}

**Summary:** Download the invoice document

Returns the invoice document to give to the buyer or to print. Without parameters, the default
format for the type is returned: a thermal receipt for cash invoices (58 or 80 mm, per the
user's configuration), an A4 document for non-cash invoices and estimates, and the official PDF
from the e-invoicing platform for e-invoices.

With the `format` parameter you get the same versions the fature.al dashboard offers:

| `format` | Invoice type | Result | Content-Type |
| --- | --- | --- | --- |
| `a4` | Cash | A4 invoice document | application/pdf |
| `thermal` | Non-cash | Thermal receipt | application/pdf |
| `v2` | Non-cash, estimate | A4 document, wide version | application/pdf |
| `receipt` | Estimate | Thermal receipt | application/pdf |
| `local` | E-invoice | A4 document generated by fature.al, without requesting the official PDF | application/pdf |
| `local-thermal` | E-invoice | Thermal receipt generated by fature.al | application/pdf |
| `html` | Cash | The thermal receipt as HTML, to send to the printer yourself | text/html |
| `json` | All | The document data as JSON, to format the invoice yourself | application/json |

`lang` (`en`, `it`, `de`) translates the A4 document of non-cash invoices, estimates and
e-invoices, and combines with `format`. Without it, the document is returned in Albanian. Thermal receipts and
cash invoices always stay in Albanian, because they are fiscal documents.

For cash invoices, `copy_only=1` returns the copy of the receipt instead of the original.

A `format` that does not apply to the invoice type does not return an error: the default format of
that type is returned.

**Tags:** Invoices

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The invoice's id in fature.al. |
| `copy_only` | query | no | Cash invoices only: returns the copy of the receipt instead of the original. |
| `format` | query | no | The document version per the table above: `a4`, `thermal`, `v2`, `receipt`, `local`, `local-thermal`, `html`, `json`. |
| `lang` | query | no | The language of the A4 document: `en`, `it` or `de`. Without it, the document is returned in Albanian. |

**Responses:**

- `200` - The content type depends on `format`: PDF by default, `text/html` with `format=html`, and the invoice document as JSON with `format=json`, ready for you to format yourself.
- `401`
- `404` - The invoice was not found, or does not belong to your company.

---

### POST /invoice/summary

**Summary:** Issue a summary invoice

Settles the payment of one or more order invoices with a single document, as in `v1`, with the
payment as a `payment_methods` list. A table paid half in cash and half by
card sends a two-element list; one paid entirely by card, a one-element list.
Only `BANKNOTE` and `CARD` are allowed. The rules for `order_invoices` and the discount are those of
[`POST /api/v1/invoice/summary`](/docs/api).

**Tags:** Invoices

**Request body content types:** application/json

**Responses:**

- `200` - When the user has no fiscal device, or when the invoice is rejected after validation by the CIS or while saving, the response comes back with HTTP 200 and `status: false`; the reason is in `message`.
- `401`
- `422` - The data failed validation. This response uses the `success` field, not `status`, and `errors` is an object keyed by field. Only a missing `internalId` comes back in the standard error format.
- `400` - An order was not found, is not an order invoice, or is already closed; or the data is incomplete for fiscalization. `errors` says exactly which. The invoice was not saved; retry with the same `internalId`.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `409` - A request with this `internalId` is still in progress. Wait a moment and retry, or read the state with `POST /invoice/details/{internalId}`.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.
- `503` - The fiscalization service could not be reached and the invoice was not saved. Retry with the same `internalId`.

---

### POST /invoice/wtn

**Summary:** Issue a warehouse transfer note

Issues a warehouse transfer note (WTN) and fiscalizes it with the CIS. The note is not a sale: it accompanies
goods moving from one point to another, and the law requires it even when nothing is sold.

Lines are sent as `invoice_lines`, not `lines` as on invoices, and each line has
`product_name`, `product_code`, `unit` and `quantity`.

## Required fields

- `internalId`, the note's identifier in your system;
- `vehPlates`, the vehicle's license plate;
- `valueOfGoods`, the value of the goods in transit;
- `invoice_lines`, at least one line.

## internalId

This is the only change from [`POST /api/v1/invoice/wtn`](/docs/api), where the field is
optional. Keep it unique within the company for the year: a second request with the same
`internalId` does not issue a second note; it returns the first note with `200`. This makes retrying after a
timeout safe, and the note can be read later with
`GET /invoice/wtn/details/{internalId}`.

## Allowed values

| Field | Values | Default |
| --- | --- | --- |
| `type` | `WTN`, `SALE` | `WTN` |
| `transaction` | `TRANSFER`, `EXAMINATION`, `SALES`, `DOOR` | `TRANSFER` |
| `vehOwnership` | `OWNER`, `THIRDPARTY` | `OWNER` |
| `startPoint`, `destinPoint` | `ANOTHER`, `CUSTOMS`, `EXHIBITION`, `OTHER`, `SALE`, `STORE`, `WAREHOUSE` | `WAREHOUSE`, `STORE` |
| `carrier_id_type` | `NUIS`, `ID` | `NUIS` |

The departure and arrival addresses (`startCity`, `startAddr`, `destinCity`, `destinAddr`) and
the carrier (`carrier_name`, `carrier_id_num`, `carrier_town`, `carrier_address`) are taken from
your business unit and company when not sent. `startDateTime` and `destinDateTime` take the issue
time when missing.

## After issuing

The response carries `id`, `internalId`, `number`, `iic`, `fic`, `fiscalStatus`, `verifyURL` and
`print`. When the CIS cannot be reached, the note is saved unfiscalized, with `fic: null` and
`fiscalStatus: UNFISCALIZED`; fiscalization is done later from the fature.al dashboard, and you read the state
in `fiscal.status` with `GET /invoice/wtn/details/{internalId}`. When the CIS rejects the
note, it is not saved and the response is `500` with the reason in `message`.

A second request from the same token while the first is still running is rejected immediately with
`429`. The slot frees up as soon as the response is returned, or after 30 seconds if the request was interrupted.

**Tags:** Warehouse transfer notes

**Request body content types:** application/json

**Responses:**

- `200` - When the CIS cannot be reached, the note is saved unfiscalized: the response carries `invoice` with `fic: null` and `fiscalStatus: UNFISCALIZED`, and fiscalization happens later.
- `401`
- `422` - The data failed validation, including a missing `internalId`. This response uses the `success` field, not `status`, and `errors` is an object keyed by field.
- `403` - The subscription has expired, or the action is not allowed for this account.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error, or the CIS rejected the note; the reason is in `message`. The note was not saved.

---

### GET /invoice/wtn

**Summary:** List warehouse transfer notes

The same list as [`GET /api/v1/invoice/wtn`](/docs/api): the company's notes, newest
first, filtered by creation date. Each note comes in full, with `origin`,
`destination`, `carrier`, `fiscal` and `lines`, so the lines need no second
call, and with `internalId` as it was sent.

- Pagination with `limit` and `offset`. `pagination` does not return `total`, so stop when a page
  comes back shorter than `limit`.
- A second request from the same token, while the first has not finished, is rejected immediately with
  `429`. The slot is released as soon as the response returns, or after 30 seconds if the request was interrupted.

**Tags:** Warehouse transfer notes

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `limit` | query | no | How many notes to return per page. |
| `offset` | query | no | Which note to start from, counting from 0. |
| `fromDate` | query | no | The start date, `YYYY-MM-DD`, by creation date. |
| `toDate` | query | no | End date, `YYYY-MM-DD`. |

**Responses:**

- `200` - The period's notes, with `pagination`; `items` is empty when there are no notes.
- `401`
- `422` - The dates are not in `YYYY-MM-DD` format.
- `429` - Rate limit reached. From the global limit, the response carries only `message` and the `Retry-After` header; from the endpoint's limit, it has the standard error format.
- `500` - Unexpected server error.

---

### GET /invoice/wtn/details/{internalId}

**Summary:** Get a warehouse transfer note by internalId

Returns the same object as `GET /invoice/wtn/{id}/details`, but by the identifier you
sent in `internalId` when the note was issued, without storing our `id`. Since in v2 `internalId`
is required, every note issued by this version can be read this way.

When the same `internalId` has been used in more than one year, the most recent note is returned.

**Tags:** Warehouse transfer notes

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `internalId` | path | yes | Your identifier for the note, sent when it was issued. |

**Responses:**

- `200` - The full note in `invoice`, the same one `GET /invoice/wtn/{id}/details` returns.
- `401`
- `404` - No note with this `internalId` in your unit.
- `422` - `internalId` is empty.
- `500` - Unexpected server error.

---

### GET /invoice/wtn/print/{id}

**Summary:** Get the warehouse transfer note for printing

Returns the note's data as document-ready JSON, not as a PDF: the company with its logo,
the carrier, departure and arrival, and in `invoice` the number, fiscal codes, lines,
`amounts` and `verifyUrl`.

Use it when you format the document yourself, in your own printing system. The address of this
endpoint comes in the `print` field of the list and of the details.

**Tags:** Warehouse transfer notes

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The id of the warehouse transfer note in fature.al. |

**Responses:**

- `200` - The note document as JSON, ready for you to format: the company with its logo, the carrier, departure, arrival and `invoice` with the lines and fiscal codes.
- `401`
- `404` - The note was not found, or it does not belong to your company.

---

### GET /invoice/wtn/{id}/details

**Summary:** Get a warehouse transfer note by id

Returns the full note by its `id` in fature.al: the vehicle, the departure and
arrival points, the carrier, the fiscal codes and the goods lines. It is the same object the
list returns.

**Tags:** Warehouse transfer notes

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The id of the warehouse transfer note in fature.al. |

**Responses:**

- `200` - The full note in `invoice`: departure and arrival points, the carrier, the fiscal codes and the goods lines.
- `401`
- `404` - The note was not found, or does not belong to your unit.
- `500` - Unexpected server error.

---

### GET /invoice/{id}/details

**Summary:** Get an invoice by id

The same details as in `v1`, where the payment comes as a `payment_methods` list. When the invoice is not found,
`data.invoice` is `null` with status `200`.

**Tags:** Invoices

**Parameters:**

| Name | In | Required | Description |
|------|----|----------|-------------|
| `id` | path | yes | The invoice's id in fature.al. |

**Responses:**

- `200` - The full invoice in `data.invoice`, or `null` when it is not found.
- `401`

---

## Full OpenAPI specification

For complete schemas, examples and request/response bodies, fetch the JSON spec:

```
https://fature.al/docs/api/v2/en.json
```
