# Integrating as an AI agent

> Compact, agent-oriented description of the F-sąskaita API. Base URL, authentication, spec location, pagination, error handling and rules that prevent common mistakes.

This page is written for LLM agents and coding assistants. It is intentionally dense. Humans may prefer the [guides](/guides/authentication).

## Facts

- Base URL: `https://app.fsaskaita.lt/api`
- OpenAPI 3.1 specification: `https://docs.fsaskaita.lt/openapi.json`
- Full documentation as text: `https://docs.fsaskaita.lt/llms-full.txt`
- Authentication: `Authorization: Bearer <token>`. The token belongs to one business; there is no user-level or multi-business token.
- Always send `Accept: application/json`. Without it, unauthenticated and rate-limited requests return an HTML redirect or page instead of JSON.
- Content type for invoices and profile: `application/json`. Expenses use `multipart/form-data` because they carry a file.
- Rate limit: 60 requests per minute per business, shared by all of its tokens. Read `X-RateLimit-Remaining`; on `429` wait for `Retry-After` seconds.
- Pagination: `?page=N`, fixed 50 items per page, no filtering or sorting parameters. Response shape `{ "data": [...], "meta": { "current_page", "last_page", "per_page", "total", "from", "to", "path" } }`.
- Single resources are wrapped: `{ "data": { ... } }`.
- Identifiers are UUID strings. Dates are `YYYY-MM-DD`. `created_at` and `updated_at` are Unix timestamps in seconds. Money values are JSON numbers. Currency codes are uppercase ISO 4217 and must exist in `GET /currencies`.
- Deleting returns `200` with an empty body.
- Validation errors return `422` with `{ "message": "...", "errors": { "field.path": ["..."] } }`. Messages are in Lithuanian.
- Resources that belong to another business return `404`.

## Rules that prevent mistakes

1. When updating an invoice with `PUT /invoices/{id}`, send the full invoice, including its current `invoice_number`. Omitting the number assigns a new one from the series counter.
2. For each invoice line send exactly one of `price`, `total` or `total_incl_vat`. The server derives the other two.
3. `type` values ending in `vat_invoice` are VAT invoices. They require `vat_percentage` on every line and a seller `vat_code` (yours from the profile when `use_default_seller_info` is `true`).
4. Prefer `use_default_seller_info: true` unless the caller explicitly wants to override seller details.
5. Draft invoices never appear in the API. Everything the API creates is a finalized, numbered invoice.
6. If the PDF is not ready yet, `GET /invoices/{id}/download` waits up to about 20 seconds for it, so call it after creation rather than expecting the file inside the create response.
7. Webhook payloads are `{ "event": "<name>", "data": { ... } }`, signed with HMAC-SHA256 of the raw body in the `Signature` header. Verify with the subscription secret before trusting the payload. Deliveries are attempted up to 3 times (two retries, after 10 s and 100 s); treat them as at-least-once.
8. There is no API for managing tokens or webhook subscriptions. Both are created by a human in the app under Settings, Integrations.
9. There is no idempotency key. Do not retry a `POST` that returned a network error without first listing recent invoices.

## Instructions for your agent

Paste this into your coding agent, or point it at `https://docs.fsaskaita.lt/agents/prompt.md`.

```text
Implement invoicing in this project with the F-sąskaita API.

Read first, in this order:
1. https://docs.fsaskaita.lt/llms.txt — the index of every documentation page. Fetch the Invoices and Conventions guides from it.
2. https://docs.fsaskaita.lt/openapi.json — the Spec: every endpoint, field and enum.
Take field names and behaviour from the Spec. Where this prompt and the Spec disagree, the Spec wins.

Facts
- Base URL: https://app.fsaskaita.lt/api. JSON in, JSON out.
- Authentication: a Business token, scoped to one business, sent as `Authorization: Bearer <token>`. Read it from the FSASKAITA_TOKEN environment variable and keep it out of code, logs and version control.
- Send `Accept: application/json` on every request; without it, 401 and 429 responses are HTML.
- Rate limit: 60 requests per minute per business. On 429, wait `Retry-After` seconds, then retry.
- Validation errors: 422 with `{ "message", "errors": { "field.path": ["..."] } }`. Messages are in Lithuanian; show them to the user unchanged.
- Lists: `?page=N`, 50 per page, newest first, no filters. Single resources are wrapped in `{ "data": ... }`.
- Identifiers are UUIDs, dates are `YYYY-MM-DD`, money values are JSON numbers, currency codes are uppercase ISO 4217 and must appear in `GET /currencies`.

Build
1. One client module with a narrow interface: base URL, both headers, JSON encoding, and typed errors for 401, 404, 422, 429 and 500. Retry only on 429, and only GET, PUT and DELETE.
2. createInvoice(input): `POST /invoices`. Default `use_default_seller_info: true`. For each line in `products` send exactly one of `price`, `total` or `total_incl_vat`. Types ending in `vat_invoice` need `vat_percentage` on every line. Omit `invoice_number` so the series assigns the next one. Return `data` from the 201 response; it includes `share_link`, a public page where the buyer views and downloads the invoice.
3. downloadInvoicePdf(id): `GET /invoices/{id}/download`, called after create. Stream the body: there is no Content-Length, and the response can take up to about 20 seconds if the PDF is not ready yet.
4. updateInvoice(id, input): `PUT /invoices/{id}` replaces the whole invoice. Read it first, change what you need, and send it back including the current `invoice_number`; an update without it renumbers the invoice.
5. Webhooks, when the project needs them: an HTTPS endpoint that verifies the `Signature` header (hex HMAC-SHA256 of the raw body with the subscription secret) before parsing, and treats deliveries as at-least-once.

Rules
- There is no idempotency key. After a network error on POST, list recent invoices with `GET /invoices` and check before creating again.
- Every invoice the API creates is final and numbered; drafts exist only in the app.
- Tokens and webhook subscriptions have no API. A person creates them in the app under Settings, Integrations, and the integration reads them from configuration.

Done when
- Unit tests with recorded responses cover 201, 422 and 429.
- A live check runs only when FSASKAITA_TOKEN is set. It creates a real, numbered invoice, so ask before running it and delete the invoice afterwards with `DELETE /invoices/{id}`.
- Your report names what you built, which endpoints you used, and what in the Spec you left out.
```

## Minimal request

```bash
curl https://app.fsaskaita.lt/api/profile \
  -H "Authorization: Bearer $FSASKAITA_TOKEN" \
  -H "Accept: application/json"
```

## Where to look next

- Endpoint shapes and every field: the [OpenAPI specification](/openapi.json) or the [Reference](/reference).
- Worked invoice payloads: [Invoices](/guides/invoices).
- Signature verification code: [Webhooks](/guides/webhooks).
- Behaviour changes over time: the [Changelog](/changelog), also available as RSS at `/changelog.xml`.
