Conventions, errors and rate limits
Request and response formats, pagination, identifiers, dates and money, HTTP status codes, and the 60 requests per minute limit.
Requests
- Base URL
https://app.fsaskaita.lt/api. - Headers on every request:
Authorization: Bearer <token>andAccept: application/json. - Invoice endpoints take a JSON body (
Content-Type: application/json). Expense endpoints takemultipart/form-databecause a file travels with them. PUTandPATCHare equivalent on this API. Both replace the whole resource with the body you send, so always send every field.
Responses
A single resource is wrapped in data:
{ "data": { "id": "…", "…": "…" } }A list is wrapped in data with a meta block:
{
"data": [ … ],
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"path": "https://app.fsaskaita.lt/api/invoices",
"per_page": 50,
"to": 50,
"total": 132
}
}Deletion returns 200 with an empty body.
Pagination
Lists return 50 items per page, newest first, and accept only ?page=N. There are no filters, sort parameters or page-size options. To sync, walk the pages until current_page equals last_page. GET /currencies is not paginated.
Identifiers, dates, money
| Kind | Format | Example |
|---|---|---|
| Identifiers | UUID string | "9c1f7b2e-3a6d-4d5e-9f0a-2b7c8d9e0f11" |
| Dates in requests and responses | YYYY-MM-DD | "2026-09-08" |
created_at, updated_at | Unix timestamp, seconds, integer | 1757318400 |
| Money | JSON number | 60.5 |
| Currency | uppercase ISO 4217 code accepted by GET /currencies | "EUR" |
| Invoice numbers | string, zero-padded to three digits in responses | "007" |
Enumerated values are lowercase snake_case strings, for example vat_invoice or not_paid. The reference lists the allowed values for every field.
Errors
| Status | Meaning | Body |
|---|---|---|
401 | Missing, invalid or deleted token | {"message":"Unauthenticated."} |
404 | Unknown id, or the resource belongs to another business | {"message":"…"} |
422 | Validation failed | see below |
429 | Rate limit exceeded | {"message":"Too Many Attempts."} plus Retry-After |
500 | Unexpected server error | {"message":"Server Error"} |
Validation errors list every failing field. Nested fields use dot paths. Messages are in Lithuanian.
{
"message": "Laukas type yra privalomas. (and 2 more errors)",
"errors": {
"type": ["Laukas type yra privalomas."],
"buyer.company_name": ["…"],
"products.0.quantity": ["…"]
}
}There is no 403. A token either works for its business or is rejected with 401.
Rate limits
Each business may make 60 requests per minute across all of its tokens. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. When the limit is hit, the response is 429 with Retry-After in seconds and X-RateLimit-Reset as a Unix timestamp. Back off until then; retrying earlier only returns more 429s.
Idempotency and retries
The API has no idempotency key. A POST that timed out on the network may still have created the resource. Before retrying, list the newest items and check whether yours is there. PUT and DELETE are safe to retry.
Localisation
Validation messages and the type label inside PDF file names are in Lithuanian unless the invoice language says otherwise. There is no Accept-Language negotiation.