# Invoices

> The invoice model, invoice types, numbering and series, the create and update requests, and downloading the PDF.

An invoice in F-sąskaita is a finalized, numbered document issued by your business (the **seller**) to a **buyer**, with one or more **lines** (`products`) and optional **payment options**. The API only ever sees finalized invoices; drafts made in the app are invisible here.

## Endpoints

| Method | Path | Summary |
|---|---|---|
| `GET` | [`/invoices`](/reference/invoices/listInvoices/) | List invoices |
| `POST` | [`/invoices`](/reference/invoices/createInvoice/) | Create an invoice |
| `GET` | [`/invoices/{invoice}`](/reference/invoices/getInvoice/) | Get an invoice |
| `DELETE` | [`/invoices/{invoice}`](/reference/invoices/deleteInvoice/) | Delete an invoice |
| `PUT` | [`/invoices/{invoice}`](/reference/invoices/updateInvoice/) | Replace an invoice |
| `GET` | [`/invoices/{invoice}/download`](/reference/invoices/downloadInvoicePdf/) | Download the invoice PDF |

## Invoice types

| `type` | VAT | Use |
|---|---|---|
| `regular_invoice` | no | Standard invoice for a non-VAT payer |
| `vat_invoice` | yes | VAT invoice |
| `preliminary_invoice` | no | Proforma |
| `preliminary_vat_invoice` | yes | Proforma with VAT |
| `credit_invoice` | no | Credit note |
| `credit_vat_invoice` | yes | Credit note with VAT |

VAT types require a `vat_percentage` on every line and a seller VAT code. When you use your own profile as the seller, the VAT code comes from the profile.

## Series and numbering

Every invoice belongs to a **series**, a short code such as `SF`, and has a number unique within that series for your business.

- Omit `invoice_number` on create and the API assigns the next number of the series. A series that does not exist yet starts at `1`.
- Send `invoice_number` explicitly when you manage numbering yourself. It must be unique in the series. Padded (`"007"`) and unpadded (`"7"`) forms are compared exactly as sent, so use one form consistently within a series.
- **On update, always send the current `invoice_number`.** An update without it assigns a fresh number from the series counter.
- Responses return the number zero-padded to three digits (`"7"` is returned as `"007"`).

## Create an invoice

The shortest useful request uses your own profile as the seller and prices per line:

```bash tab="cURL" tab-group="request"
curl -X POST https://app.fsaskaita.lt/api/invoices \
  -H "Authorization: Bearer $FSASKAITA_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d @- <<'JSON'
{
  "type": "vat_invoice",
  "invoice_date": "2026-09-08",
  "pay_until_date": "2026-09-22",
  "series": "SF",
  "currency": "EUR",
  "language": "lt",
  "use_default_seller_info": true,
  "buyer": {
    "type": "company",
    "company_name": "Pirkėjas, UAB",
    "company_code": "300000001",
    "vat_code": "LT100000000011",
    "address": "Konstitucijos pr. 7, Vilnius",
    "email": "buhalterija@pirkejas.lt"
  },
  "products": [
    { "name": "Konsultacija", "units": "val.", "quantity": 2, "price": 50, "vat_percentage": 21 }
  ],
  "payment_options": [
    { "type": "bank", "bank_name": "Swedbank", "bank_account": "LT12 7300 0100 0000 0001", "swift_bic_code": "HABALT22" }
  ]
}
JSON
```

```js tab="JavaScript" tab-group="request"
const response = await fetch('https://app.fsaskaita.lt/api/invoices', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FSASKAITA_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    type: 'vat_invoice',
    invoice_date: '2026-09-08',
    pay_until_date: '2026-09-22',
    series: 'SF',
    currency: 'EUR',
    language: 'lt',
    use_default_seller_info: true,
    buyer: {
      type: 'company',
      company_name: 'Pirkėjas, UAB',
      company_code: '300000001',
      vat_code: 'LT100000000011',
      address: 'Konstitucijos pr. 7, Vilnius',
      email: 'buhalterija@pirkejas.lt',
    },
    products: [
      { name: 'Konsultacija', units: 'val.', quantity: 2, price: 50, vat_percentage: 21 },
    ],
    payment_options: [
      { type: 'bank', bank_name: 'Swedbank', bank_account: 'LT12 7300 0100 0000 0001', swift_bic_code: 'HABALT22' },
    ],
  }),
});

console.log(response.status, await response.json());
```

```go tab="Go" tab-group="request"
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

const invoice = `{
  "type": "vat_invoice",
  "invoice_date": "2026-09-08",
  "pay_until_date": "2026-09-22",
  "series": "SF",
  "currency": "EUR",
  "language": "lt",
  "use_default_seller_info": true,
  "buyer": {
    "type": "company",
    "company_name": "Pirkėjas, UAB",
    "company_code": "300000001",
    "vat_code": "LT100000000011",
    "address": "Konstitucijos pr. 7, Vilnius",
    "email": "buhalterija@pirkejas.lt"
  },
  "products": [
    { "name": "Konsultacija", "units": "val.", "quantity": 2, "price": 50, "vat_percentage": 21 }
  ],
  "payment_options": [
    { "type": "bank", "bank_name": "Swedbank", "bank_account": "LT12 7300 0100 0000 0001", "swift_bic_code": "HABALT22" }
  ]
}`

func main() {
	req, _ := http.NewRequest("POST", "https://app.fsaskaita.lt/api/invoices", strings.NewReader(invoice))
	req.Header.Set("Authorization", "Bearer "+os.Getenv("FSASKAITA_TOKEN"))
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(res.Status, string(body))
}
```

```python tab="Python" tab-group="request"
import os

import requests

response = requests.post(
    "https://app.fsaskaita.lt/api/invoices",
    headers={
        "Authorization": f"Bearer {os.environ['FSASKAITA_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "type": "vat_invoice",
        "invoice_date": "2026-09-08",
        "pay_until_date": "2026-09-22",
        "series": "SF",
        "currency": "EUR",
        "language": "lt",
        "use_default_seller_info": True,
        "buyer": {
            "type": "company",
            "company_name": "Pirkėjas, UAB",
            "company_code": "300000001",
            "vat_code": "LT100000000011",
            "address": "Konstitucijos pr. 7, Vilnius",
            "email": "buhalterija@pirkejas.lt",
        },
        "products": [
            {"name": "Konsultacija", "units": "val.", "quantity": 2, "price": 50, "vat_percentage": 21},
        ],
        "payment_options": [
            {"type": "bank", "bank_name": "Swedbank", "bank_account": "LT12 7300 0100 0000 0001", "swift_bic_code": "HABALT22"},
        ],
    },
)

print(response.status_code, response.json())
```

```java tab="Java" tab-group="request"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CreateInvoice {
    public static void main(String[] args) throws Exception {
        String invoice = """
            {
              "type": "vat_invoice",
              "invoice_date": "2026-09-08",
              "pay_until_date": "2026-09-22",
              "series": "SF",
              "currency": "EUR",
              "language": "lt",
              "use_default_seller_info": true,
              "buyer": {
                "type": "company",
                "company_name": "Pirkėjas, UAB",
                "company_code": "300000001",
                "vat_code": "LT100000000011",
                "address": "Konstitucijos pr. 7, Vilnius",
                "email": "buhalterija@pirkejas.lt"
              },
              "products": [
                { "name": "Konsultacija", "units": "val.", "quantity": 2, "price": 50, "vat_percentage": 21 }
              ],
              "payment_options": [
                { "type": "bank", "bank_name": "Swedbank", "bank_account": "LT12 7300 0100 0000 0001", "swift_bic_code": "HABALT22" }
              ]
            }
            """;

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.fsaskaita.lt/api/invoices"))
            .header("Authorization", "Bearer " + System.getenv("FSASKAITA_TOKEN"))
            .header("Accept", "application/json")
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(invoice))
            .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println(response.statusCode() + " " + response.body());
    }
}
```

```csharp tab="C#" tab-group="request"
using System.Net.Http.Headers;
using System.Text;

var invoice = """
    {
      "type": "vat_invoice",
      "invoice_date": "2026-09-08",
      "pay_until_date": "2026-09-22",
      "series": "SF",
      "currency": "EUR",
      "language": "lt",
      "use_default_seller_info": true,
      "buyer": {
        "type": "company",
        "company_name": "Pirkėjas, UAB",
        "company_code": "300000001",
        "vat_code": "LT100000000011",
        "address": "Konstitucijos pr. 7, Vilnius",
        "email": "buhalterija@pirkejas.lt"
      },
      "products": [
        { "name": "Konsultacija", "units": "val.", "quantity": 2, "price": 50, "vat_percentage": 21 }
      ],
      "payment_options": [
        { "type": "bank", "bank_name": "Swedbank", "bank_account": "LT12 7300 0100 0000 0001", "swift_bic_code": "HABALT22" }
      ]
    }
    """;

using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("FSASKAITA_TOKEN"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = await client.PostAsync(
    "https://app.fsaskaita.lt/api/invoices",
    new StringContent(invoice, Encoding.UTF8, "application/json"));
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");
```

Key rules:

- `buyer.type` is `company` or `individual`. Companies need `company_name`; individuals use `first_name` and `last_name`. Do not send company fields for an individual or personal names for a company.
- Each line needs `name`, `units`, `quantity` and **exactly one** of `price` (unit price excluding VAT), `total` (line total excluding VAT) or `total_incl_vat`. The server computes the others.
- `payment_options` entries are either `type: "bank"` with `bank_account` and `bank_name` (plus optional `routing_or_sort_number`, `swift_bic_code`) or `type: "other"` with a `fields` list of `{ "label", "value" }` pairs.
- `payment_status` defaults to `not_paid` on create and is left unchanged when omitted on update. Set `"paid"` to mark the invoice paid.
- `language` (`lt`, `en`, `es`, `de`, `fr`) decides the language of the PDF. Default `lt`.
- `notes` is free text up to 255 characters printed on the invoice.

### Providing your own seller block

Set `use_default_seller_info` to `false` (or omit it) and send `seller`. The required seller fields depend on how your business is registered: companies send `company_name` and `company_code`; individual activity sends `first_name`, `last_name` and `individual_activity_id`. VAT types additionally require `seller.vat_code`. `seller.custom_fields` accepts extra `{ "label", "value" }` pairs printed under the seller details.

## The response

```json
{
  "data": {
    "id": "6f1e9d2a-0b3c-4e5f-8a9b-1c2d3e4f5a6b",
    "business_id": "9c1f7b2e-3a6d-4d5e-9f0a-2b7c8d9e0f11",
    "invoice_type": "vat_invoice",
    "series": "SF",
    "invoice_number": "007",
    "invoice_date": "2026-09-08",
    "pay_until_date": "2026-09-22",
    "language": "lt",
    "subtotal": 100,
    "vat": 21,
    "total_incl_vat": 121,
    "currency": "EUR",
    "payment_status": "not_paid",
    "notes": null,
    "share_link": "https://app.fsaskaita.lt/invoice/share/…",
    "seller": { "business_type": "small_partnership", "company_name": "Pavyzdys, MB", "…": "…", "custom_fields": [] },
    "buyer": { "type": "company", "company_name": "Pirkėjas, UAB", "…": "…" },
    "items": [
      { "id": "…", "name": "Konsultacija", "price": 50, "vat_percentage": 21, "quantity": 2, "units": "val." }
    ],
    "payment_options": [
      { "type": "bank", "bank_account": "LT12 7300 0100 0000 0001", "bank_name": "Swedbank", "routing_or_sort_number": null, "swift_bic_code": "HABALT22", "fields": [] }
    ],
    "created_at": 1757318400,
    "updated_at": 1757318400
  }
}
```

`share_link` is a public page where the buyer can view and download the invoice without signing in. `items[].price` is the unit price excluding VAT; line totals are not returned.

## Update an invoice

`PUT /invoices/{id}` takes the same body as create and replaces every part of the invoice: lines, payment options and seller block included. Read the invoice first, modify the fields you need, and send the whole document back with its `invoice_number`. Changing `series` moves the invoice and re-synchronises both series counters.

## Download the PDF

```bash tab="cURL" tab-group="request"
curl -L https://app.fsaskaita.lt/api/invoices/$ID/download \
  -H "Authorization: Bearer $FSASKAITA_TOKEN" \
  -H "Accept: application/json" \
  -o invoice.pdf
```

```js tab="JavaScript" tab-group="request"
import { createWriteStream } from 'node:fs';
import { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';

const id = '6f1e9d2a-0b3c-4e5f-8a9b-1c2d3e4f5a6b';
const response = await fetch(`https://app.fsaskaita.lt/api/invoices/${id}/download`, {
  headers: {
    Authorization: `Bearer ${process.env.FSASKAITA_TOKEN}`,
    Accept: 'application/json',
  },
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);

await pipeline(Readable.fromWeb(response.body), createWriteStream('invoice.pdf'));
```

```go tab="Go" tab-group="request"
package main

import (
	"io"
	"net/http"
	"os"
)

func main() {
	id := "6f1e9d2a-0b3c-4e5f-8a9b-1c2d3e4f5a6b"
	req, _ := http.NewRequest("GET", "https://app.fsaskaita.lt/api/invoices/"+id+"/download", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("FSASKAITA_TOKEN"))
	req.Header.Set("Accept", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(res.Body)
		panic(res.Status + " " + string(body))
	}

	file, err := os.Create("invoice.pdf")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	if _, err := io.Copy(file, res.Body); err != nil {
		panic(err)
	}
}
```

```python tab="Python" tab-group="request"
import os

import requests

invoice_id = "6f1e9d2a-0b3c-4e5f-8a9b-1c2d3e4f5a6b"

with requests.get(
    f"https://app.fsaskaita.lt/api/invoices/{invoice_id}/download",
    headers={
        "Authorization": f"Bearer {os.environ['FSASKAITA_TOKEN']}",
        "Accept": "application/json",
    },
    stream=True,
) as response:
    response.raise_for_status()
    with open("invoice.pdf", "wb") as file:
        for chunk in response.iter_content(chunk_size=65536):
            file.write(chunk)
```

```java tab="Java" tab-group="request"
import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class DownloadInvoice {
    public static void main(String[] args) throws Exception {
        String id = "6f1e9d2a-0b3c-4e5f-8a9b-1c2d3e4f5a6b";
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://app.fsaskaita.lt/api/invoices/" + id + "/download"))
            .header("Authorization", "Bearer " + System.getenv("FSASKAITA_TOKEN"))
            .header("Accept", "application/json")
            .GET()
            .build();

        HttpResponse<InputStream> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofInputStream());

        try (InputStream body = response.body()) {
            if (response.statusCode() != 200) {
                throw new IllegalStateException(response.statusCode() + " " + new String(body.readAllBytes()));
            }
            Files.copy(body, Path.of("invoice.pdf"), StandardCopyOption.REPLACE_EXISTING);
        }
    }
}
```

```csharp tab="C#" tab-group="request"
using System.Net.Http.Headers;

var id = "6f1e9d2a-0b3c-4e5f-8a9b-1c2d3e4f5a6b";

using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("FSASKAITA_TOKEN"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

using var response = await client.GetAsync(
    $"https://app.fsaskaita.lt/api/invoices/{id}/download",
    HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();

await using var file = File.Create("invoice.pdf");
await response.Content.CopyToAsync(file);
```

The response is `application/pdf` with a `Content-Disposition: attachment` file name built from the type label, series and number. If the PDF is not ready yet, the download waits up to about 20 seconds for it. There is no `Content-Length` header, so stream the body rather than preallocating.

## Side effects to expect

- Creating or updating fires the `invoice.created` or `invoice.updated` [webhook](/guides/webhooks). Deleting fires `invoice.deleted`.
- The buyer is saved to your client list in the app.
- API access requires the Premium plan.
