Rise API (0.0.2)

Download OpenAPI specification:

Rise API for Rise Bank backend services.

Consistency notes for frontend:

  • Purchase invoice amounts are numbers; sales invoice amounts and rates are strings with two decimals.
  • List endpoints return an object with data and meta fields.
  • Some fields appear only in detail responses (e.g., audit_summary) and not in list summaries.

Authorization:

  • Use header Authorization: Bearer

Glossary:

  • source: How a purchase invoice was received ('manual' or 'einvoice').
  • invoice_channel: Channel describing how a sales invoice was received (sales invoices).
  • invoicing_channel: Channel describing how an invoice will be sent (sales invoices).
  • bank_account_id: Receiving bank account for sales invoices. For purchase invoices, bank accounts are specified on payment records, not invoices.
  • delegated_by_user_id: User who delegated a purchase invoice to its current assignee.
  • current_assignee_user_id: User currently responsible for acting on a purchase invoice.

Bank Accounts

Bank account management operations including listing, creation, and deletion

List banks

Retrieve list of available banks (ASPSPs) from Enable Banking for the given country and PSU type. Response is filtered so every entry is a legitimate authorization target: entries whose psu_types do not include the requested psu_type are excluded, and sandbox/test ASPSPs are excluded entirely in production.

Authorizations:
bearerAuth
query Parameters
country
string = 2 characters
Example: country=FI

Country code to filter banks (default: FI)

psu_type
string (BankPsuType)
Default: "business"
Enum: "personal" "business"
Example: psu_type=business

PSU type to filter banks against. Only ASPSPs whose psu_types include the requested value are returned. Defaults to business so existing company-scoped UIs keep working unchanged.

Responses

Response samples

Content type
application/json
{
  • "country": "string",
  • "banks": [
    ]
}

List bank accounts

Retrieve bank accounts for a company with latest authorization status

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Get bank account

Retrieve bank account details with authorization status

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

bankAccountId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Bank account ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update bank account

Update bank account display name

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

bankAccountId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Bank account ID

Request Body schema: application/json
required

Bank account update data

required
string or null

Responses

Request samples

Content type
application/json
{
  • "display_name": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Revoke bank account

Revoke authorization for a bank account, stopping automatic transaction syncing while preserving all account and transaction history

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

bankAccountId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Bank account ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Authorize bank account

Start an Enable Banking authorization flow for the selected company. Requires both redirect_url and cancel_url as absolute URIs.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Bank account authorization data

aspsp_name
required
string [ 1 .. 255 ] characters
aspsp_country
required
string = 2 characters
psu_type
string
Default: "business"
Enum: "personal" "business"

PSU type the authorization is for. Defaults to business (company-scoped flows) when omitted. Must be supported by the chosen ASPSP; validated against Enable Banking before starting the authorization. Declared .optional() in Zod (so OpenAPI publishes it as non-required and generated SDKs do not force callers to pass it) with an OpenAPI default: annotation for documentation; the handler applies the runtime default.

redirect_url
required
string <uri>
cancel_url
required
string <uri>
consent_duration_seconds
required
number
transaction_start_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Responses

Request samples

Content type
application/json
{
  • "aspsp_name": "string",
  • "aspsp_country": "st",
  • "psu_type": "personal",
  • "redirect_url": "http://example.com",
  • "cancel_url": "http://example.com",
  • "consent_duration_seconds": 0,
  • "transaction_start_date": "2019-08-24"
}

Response samples

Content type
application/json
{}

List company bank transactions

Retrieve transactions across all bank accounts for a company

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
bank_account_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by bank account ID

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return (1-100, default: 10)

cursor
string

Pagination cursor from previous response

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Get company bank transaction

Retrieve transaction details for a company

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

transactionId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Transaction ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Company Management

Company management operations including creation and retrieval of companies

Get company

Retrieve company details including settings and bank accounts

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "business_id": "string",
  • "vat_number": "string",
  • "edi_identifier": "string",
  • "email": "string",
  • "phone": "string",
  • "domicile": "string",
  • "default_locale": "string",
  • "default_approver_user_id": "112108a8-a3eb-4f2a-9b05-1bbb5d7dd275",
  • "business_description": "string",
  • "accountant_notes": "string",
  • "business_targets": "string",
  • "address": {
    },
  • "settings": {
    },
  • "accounts": [
    ]
}

Update company

Update company fields and settings. All fields are optional; omitting a field leaves it unchanged. Pass null for a nullable field to clear it. For address: omit to keep current, pass null to unlink, pass an object to create or update. Within settings.vat, pass null for payable_account_code or receivable_account_code to reset it to the default, or for settlement_account_code to unset it.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Company fields to update (all optional)

name
string

Company name

string or null

Business ID (registration number)

string or null

VAT number

string or null

EDI identifier

string or null

Company email

string or null

Company phone

string or null

Domicile

default_locale
string
Enum: "fi-FI" "en-US"

Default locale

string or null

Default approver user ID; must be a member of the company when non-null

string or null

Freeform business/onboarding summary

string or null

Accountant-authored handling rules

string or null

Freeform business performance targets

object or null

Company address

object

Company settings

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "business_id": "string",
  • "vat_number": "string",
  • "edi_identifier": "string",
  • "email": "string",
  • "phone": "string",
  • "domicile": "string",
  • "default_locale": "fi-FI",
  • "default_approver_user_id": "112108a8-a3eb-4f2a-9b05-1bbb5d7dd275",
  • "business_description": "string",
  • "accountant_notes": "string",
  • "business_targets": "string",
  • "address": {
    },
  • "settings": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "business_id": "string",
  • "vat_number": "string",
  • "edi_identifier": "string",
  • "email": "string",
  • "phone": "string",
  • "domicile": "string",
  • "default_locale": "string",
  • "default_approver_user_id": "112108a8-a3eb-4f2a-9b05-1bbb5d7dd275",
  • "business_description": "string",
  • "accountant_notes": "string",
  • "business_targets": "string",
  • "address": {
    },
  • "settings": {
    },
  • "accounts": [
    ]
}

Create company

Create a new company. Requires a platform-level role with companies.write permission.

Authorizations:
bearerAuth
Request Body schema: application/json
required

Company creation data

name
required
string
business_id
required
string
object
default_locale
string
Enum: "fi-FI" "en-US"
string or null

Freeform business/onboarding summary

string or null

Accountant-authored handling rules

string or null

Freeform business performance targets

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "business_id": "string",
  • "address": {
    },
  • "default_locale": "fi-FI",
  • "business_description": "string",
  • "accountant_notes": "string",
  • "business_targets": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "business_id": "string"
}

List all companies

List all companies on the platform. Requires a platform-level role with companies.read permission.

Authorizations:
bearerAuth
query Parameters
limit
integer [ 1 .. 100 ]
Example: limit=50

Maximum number of results to return (1-100, default: 50)

cursor
string

Pagination cursor from previous response

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Publish company to Netbox

Publish company information to Netbox system.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "is_created_in_netbox": true
}

Documents

Get document relationships tree

Returns a tree of documents related to the specified document via settlements. The depth parameter controls how many levels of relationships to include (1-3). Documents are connected through settlements, showing the network of documents that have been settled together.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

documentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Document ID

query Parameters
depth
integer [ 1 .. 3 ]

Relationship tree depth (1-3, default: 1)

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Expense Claims

Expense claim operations including creation

List expense claims

List expense claims for a company with cursor-based pagination.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
limit
integer [ 1 .. 100 ]

Maximum number of results to return (1-100, default: 10)

cursor
string

Pagination cursor from previous response

status
string (SalesInvoiceItems)
Enum: "draft" "approved" "rejected" "voided"

Filter by document status

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create expense claim

Create a new expense claim document with line items and optional file attachments.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Expense claim creation data

expense_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Expense date (YYYY-MM-DD)

description
required
string non-empty

Expense claim description

expense_type
required
string (ExpenseClaimExpenseType)
Enum: "travel_costs" "representation_events" "refreshments" "meeting_and_negotiation" "accommodation" "travel_tickets" "other_expenses" "parking" "internal_meetings_and_staff_events" "taxi" "office_supplies"

Expense type

currency_code
required
string = 3 characters

Currency code (e.g., EUR)

required
Array of objects non-empty

Expense claim lines

files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

Responses

Request samples

Content type
application/json
{
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "str",
  • "lines": [
    ],
  • "files": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "status": "draft",
  • "claimant": {
    },
  • "approved_by": {
    },
  • "approved_at": "2019-08-24T14:15:22Z",
  • "voided_at": "2019-08-24T14:15:22Z",
  • "voided_by": {
    },
  • "payment_status": "paid",
  • "lines": [
    ],
  • "files": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get expense claim

Retrieve expense claim details by ID

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

expenseClaimId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Expense claim ID (document ID)

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "status": "draft",
  • "claimant": {
    },
  • "approved_by": {
    },
  • "approved_at": "2019-08-24T14:15:22Z",
  • "voided_at": "2019-08-24T14:15:22Z",
  • "voided_by": {
    },
  • "payment_status": "paid",
  • "lines": [
    ],
  • "files": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update expense claim

Partially update an expense claim. When lines or files are provided they replace existing ones and total amount is recalculated. Updates are allowed only while the document is in draft status.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

expenseClaimId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Expense claim ID (document ID)

Request Body schema: application/json
required

Expense claim update data (partial updates supported)

expense_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Expense date (YYYY-MM-DD)

description
string non-empty

Expense claim description

expense_type
string (ExpenseClaimExpenseType)
Enum: "travel_costs" "representation_events" "refreshments" "meeting_and_negotiation" "accommodation" "travel_tickets" "other_expenses" "parking" "internal_meetings_and_staff_events" "taxi" "office_supplies"

Expense type

currency_code
string = 3 characters

Currency code (e.g., EUR)

Array of objects

Expense claim lines (replaces existing lines when provided; pass an empty array to clear all lines)

files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

Responses

Request samples

Content type
application/json
{
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "str",
  • "lines": [
    ],
  • "files": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "status": "draft",
  • "claimant": {
    },
  • "approved_by": {
    },
  • "approved_at": "2019-08-24T14:15:22Z",
  • "voided_at": "2019-08-24T14:15:22Z",
  • "voided_by": {
    },
  • "payment_status": "paid",
  • "lines": [
    ],
  • "files": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Void expense claim

Transitions an approved expense claim to voided status. The audit trail (approved_by, approved_at) is preserved; voided_by and voided_at are set on void. Voiding is blocked if payment has been scheduled.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

expenseClaimId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Expense claim ID (document ID)

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "status": "draft",
  • "claimant": {
    },
  • "approved_by": {
    },
  • "approved_at": "2019-08-24T14:15:22Z",
  • "voided_at": "2019-08-24T14:15:22Z",
  • "voided_by": {
    },
  • "payment_status": "paid",
  • "lines": [
    ],
  • "files": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Claim expense claim

Transitions a draft expense claim to approved status. The caller must be the recorded claimant and the claim must have at least one line. At MVP, the submitter is also the approver (self-approval).

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

expenseClaimId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Expense claim ID (document ID)

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "expense_date": "2019-08-24",
  • "description": "string",
  • "expense_type": "travel_costs",
  • "currency_code": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "status": "draft",
  • "claimant": {
    },
  • "approved_by": {
    },
  • "approved_at": "2019-08-24T14:15:22Z",
  • "voided_at": "2019-08-24T14:15:22Z",
  • "voided_by": {
    },
  • "payment_status": "paid",
  • "lines": [
    ],
  • "files": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Files

File operations

Create file

Create a new file and optionally attach it to a document

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

File creation data

original_filename
required
string [ 1 .. 255 ] characters ^[^\x00-\x1f/\\]{1,250}\.(?:[cC][sS][vV]|[dD]...
document_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Responses

Request samples

Content type
application/json
{
  • "original_filename": "string",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6"
}

Response samples

Content type
application/json
Example
{
  • "id": "7e3e3c32-d6c4-4d90-b1df-cf7bd9f96c98",
  • "type": "document",
  • "mime_type": "application/pdf",
  • "status": "process_completed",
  • "original_filename": "invoice.pdf",
  • "source": "user",
  • "created_at": "2026-03-31T12:00:00.000Z",
  • "company_id": "4f7773af-f70f-4d40-a435-a6299fefbfcb",
  • "kind": "invoice_purchase",
  • "visibility": "company",
  • "size_bytes": "234567",
  • "tags": [
    ],
  • "attached_documents": [ ],
  • "s3_path": "companies/4f7773af-f70f-4d40-a435-a6299fefbfcb/files/invoice.pdf",
  • "ref_file_id": null,
  • "created_by": "73930057-2a35-4b9a-a675-4478e5fd3f4a",
  • "metadata": null,
}

List files

List files visible to the authenticated caller within the company — their own private files plus every company-visible file they have permission to see, including files attached to accounting documents. By default, excludes files with upload_pending status. Breaking change: prior to this version the endpoint returned only the caller's own unattached files. The old behavior can be reproduced by passing ?created_by=me&attached_to=none.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
FileStatus (string) or "all" (string)
Example: status=process_completed

Filter by file status. By default, upload_pending files are excluded. Use "all" to include them.

kind
Array of strings (FileKind) <= 11 items unique
Items Enum: "receipt" "invoice_purchase" "invoice_sales" "contract" "meeting_minutes" "payslip" "legal_document" "bank_statement" "tax_document" "correspondence" "other"
Example: kind=receipt&kind=invoice_purchase

Filter by one or more file kinds using repeated query parameters. OR semantics across values. At most 11 values (one per kind); duplicates (exact-match) are rejected with 400.

type
Array of strings (FileType) <= 9 items unique
Items Enum: "document" "finvoice" "finvoice_attachment" "netbox_message" "pain002" "camt052" "camt053" "camt054" "unknown"
Example: type=netbox_message

Filter by one or more physical file types using repeated query parameters. OR semantics across values. At most 9 values (one per type); duplicates (exact-match) are rejected with 400. Protocol artifacts (netbox_message, pain002, camt052, camt053, camt054, finvoice_attachment, unknown) are transport payloads rather than documents and are excluded from this listing by default; naming one here surfaces it, the same way an explicit status surfaces upload_pending files. They remain fetchable by id either way, so ref_file_id can always be followed.

tag
Array of strings <= 50 items unique [ items [ 1 .. 64 ] characters \S ]
Example: tag=q1-2026&tag=legal

Filter by one or more tag names using repeated query parameters. AND semantics across values — a file must carry every specified tag. Case-insensitive. Each tag is trimmed; 1–64 characters after trimming. At most 50 values per request; duplicates (exact-match) are rejected with 400 (the case-insensitive dedup happens server-side after normalization).

attached_to
Array of strings (FileAttachedToFilter) <= 6 items unique
Items Enum: "purchase_invoice" "sales_invoice" "memo" "expense_claim" "bank_transaction" "none"
Example: attached_to=purchase_invoice&attached_to=none

Filter by document attachment state using repeated query parameters. Use a document kind to match only files attached to that kind of document, or none to match only files not attached to any document. OR semantics across values — combining values returns the union. At most 6 values (five document kinds plus none); duplicates (exact-match) are rejected with 400.

string or "me" (string)
Example: created_by=me

Filter by file creator. Accepts a user UUID or the literal string me (resolved to the caller's user ID). The visibility filter applies before this filter — callers never see another user's private files, even when filtering by their UUID.

q
string [ 1 .. 255 ] characters
Example: q=invoice

Case-insensitive substring search across original_filename and attached tag names. SQL LIKE metacharacters (%, _) in the input are matched literally.

sort_by
string (FileSortBy)
Enum: "uploaded_at" "name" "size" "kind"
Example: sort_by=uploaded_at

Sort order for the returned list. Defaults to uploaded_at (creation timestamp DESC). Other sorts place NULL values at the tail.

cursor
string non-empty

Cursor for fetching the next page of results. Must match the current sort_by; a cursor with a different sort, missing sort_value, or empty value returns 400.

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Get file

Retrieve file details including a presigned download URL. Unattached files are readable only by their owner and require files.read. Files attached to a document inherit that document’s read permission instead of requiring files.read.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fileId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

File ID

Responses

Response samples

Content type
application/json
Example
{
  • "id": "7e3e3c32-d6c4-4d90-b1df-cf7bd9f96c98",
  • "type": "document",
  • "mime_type": "application/pdf",
  • "status": "process_completed",
  • "original_filename": "invoice.pdf",
  • "source": "user",
  • "created_at": "2026-03-31T12:00:00.000Z",
  • "company_id": "4f7773af-f70f-4d40-a435-a6299fefbfcb",
  • "kind": "invoice_purchase",
  • "visibility": "company",
  • "size_bytes": "234567",
  • "tags": [
    ],
  • "attached_documents": [ ],
  • "s3_path": "companies/4f7773af-f70f-4d40-a435-a6299fefbfcb/files/invoice.pdf",
  • "ref_file_id": null,
  • "created_by": "73930057-2a35-4b9a-a675-4478e5fd3f4a",
  • "metadata": null,
}

Edit file

Update file metadata (rename, set kind, replace tags, promote visibility). Renaming is rejected while the file is in upload_pending status. Visibility is one-way: promoting private → company is allowed, demoting is rejected with 400. Tags, when provided, replace the file's entire tag set; omit the field to leave tags unchanged.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fileId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

File ID

Request Body schema: application/json
required

File partial update payload

original_filename
string non-empty

Rename the file. The value must be a non-empty string; there is no "clear filename" semantics exposed on this endpoint. Omit the field to leave the filename unchanged. Not accepted while the file is in upload_pending status (returns 400).

FileKind (string) or null

Business-domain classification. Pass null to clear the current value.

Array of strings or null

Replace the file's tag set with the provided values. Tags are trimmed, then matched against the company pool case-insensitively; new tag values are inserted into the pool. Pass null or an empty array to clear all tags. Each tag must be non-empty after trimming (1–64 characters); whitespace-only values are rejected. At most 50 values per request; duplicates (exact-match) are rejected with 400, and the service additionally dedupes case-insensitively after normalization.

visibility
string (FileVisibility)
Enum: "private" "company"

Promote to company visibility. The only meaningful value is 'company' (private → company promotion). Passing 'private' is accepted as a no-op only when the file is already private; attempting to demote a file from company → private returns 400 (the transition is one-way).

Responses

Request samples

Content type
application/json
{
  • "original_filename": "string",
  • "kind": "receipt",
  • "tags": [
    ],
  • "visibility": "private"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "type": "document",
  • "mime_type": "string",
  • "status": "upload_pending",
  • "original_filename": "string",
  • "source": "user",
  • "created_at": "2019-08-24T14:15:22Z",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "kind": "receipt",
  • "visibility": "private",
  • "size_bytes": "string",
  • "tags": [
    ],
  • "attached_documents": [
    ],
  • "s3_path": "string",
  • "ref_file_id": "4e2990c8-5744-4c5c-bc59-f31c1bdb1a8d",
  • "content_rejection_reason": "string",
  • "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  • "metadata": {
    }
}

Delete file

Delete a file. Unattached files can only be deleted by their owner and require files.write. Files attached to a document require files.write plus the parent document’s write permission.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fileId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

File ID

Responses

Response samples

Content type
application/json
{
  • "error": "Forbidden",
  • "code": "FORBIDDEN",
  • "debug": "User does not have permission to perform this action",
  • "timestamp": "2024-01-15T10:30:00Z"
}

List my files

List files created by the authenticated user across all companies. Excludes files attached to any document (for per-company listing of attached files, see GET /companies/{companyId}/files). By default excludes upload_pending files.

Authorizations:
bearerAuth
query Parameters
FileStatus (string) or "all" (string)
Example: status=process_completed

Filter by file status. By default, upload_pending files are excluded. Use "all" to include them.

kind
Array of strings (FileKind) <= 11 items unique
Items Enum: "receipt" "invoice_purchase" "invoice_sales" "contract" "meeting_minutes" "payslip" "legal_document" "bank_statement" "tax_document" "correspondence" "other"
Example: kind=receipt

Filter by one or more file kinds using repeated query parameters. OR semantics across values. At most 11 values (one per kind); duplicates (exact-match) are rejected with 400.

tag
Array of strings <= 50 items unique [ items [ 1 .. 64 ] characters \S ]
Example: tag=personal

Filter by one or more tag names using repeated query parameters. AND semantics across values. Case-insensitive. Each tag is trimmed; 1–64 characters after trimming. At most 50 values per request; duplicates (exact-match) are rejected with 400 (the case-insensitive dedup happens server-side after normalization).

q
string [ 1 .. 255 ] characters
Example: q=receipt

Case-insensitive substring search across original_filename and attached tag names. SQL LIKE metacharacters (%, _) in the input are matched literally.

sort_by
string (FileSortBy)
Enum: "uploaded_at" "name" "size" "kind"
Example: sort_by=uploaded_at

Sort order for the returned list. Defaults to uploaded_at. Other sorts place NULL values at the tail.

cursor
string non-empty

Cursor for fetching the next page of results. Must match the current sort_by; a cursor with a different sort, missing sort_value, or empty value returns 400.

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Fiscal periods

Create fiscal period

Create a new fiscal period for a company

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Fiscal period creation data. Only fiscal years are created here (period_type must be "year"). Month periods are created automatically when a calendar month is first closed via the close action.

period_type
required
string

Discriminator: year fiscal period

Value: "year"
start_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Start date of the fiscal year (YYYY-MM-DD)

end_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

End date of the fiscal year (YYYY-MM-DD)

is_closed
boolean

Whether the fiscal period is closed (defaults to false)

string or null

Lock date for the fiscal period (YYYY-MM-DD)

parent_fiscal_period_id
null

Must be omitted or null for period_type="year".

Responses

Request samples

Content type
application/json
{
  • "period_type": "year",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": true,
  • "lock_date": "2019-08-24",
  • "parent_fiscal_period_id": null
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": true,
  • "lock_date": "2019-08-24",
  • "period_type": "year",
  • "parent_fiscal_period_id": "1496c68f-bcfd-4760-a31d-e6ddf5c3d75c",
  • "calendar_month": "string",
  • "closed_at": "2019-08-24T14:15:22Z",
  • "closed_by_user_id": "103df14e-9463-40aa-a9b8-62af14cf9cd8",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

List fiscal periods

Retrieve all fiscal periods for a company with optional filtering

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
is_closed
boolean

Filter by closed status

period_type
string (FiscalPeriodPeriodType)
Enum: "year" "month"
Example: period_type=year

Filter by period type ("year" or "month")

parent_fiscal_period_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by parent fiscal year ID. Useful for "list months under this year" queries.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Get fiscal period

Retrieve fiscal period details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal period ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": true,
  • "lock_date": "2019-08-24",
  • "period_type": "year",
  • "parent_fiscal_period_id": "1496c68f-bcfd-4760-a31d-e6ddf5c3d75c",
  • "calendar_month": "string",
  • "closed_at": "2019-08-24T14:15:22Z",
  • "closed_by_user_id": "103df14e-9463-40aa-a9b8-62af14cf9cd8",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Edit fiscal period

Update fiscal period details. Only fiscal years can be edited here; month periods are managed through the close and reopen actions and cannot be edited directly. is_closed, period_type, parent_fiscal_period_id, closed_at, and closed_by_user_id cannot be modified through this endpoint.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal period ID

Request Body schema: application/json
required

Fiscal period update data. Only start_date, end_date, and lock_date are mutable here. Unknown fields are rejected to prevent silent drops of fields like period_type or close-audit columns.

start_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Start date of the fiscal period (YYYY-MM-DD)

end_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

End date of the fiscal period (YYYY-MM-DD)

string or null

Lock date for the fiscal period (YYYY-MM-DD)

Responses

Request samples

Content type
application/json
{
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "lock_date": "2019-08-24"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": true,
  • "lock_date": "2019-08-24",
  • "period_type": "year",
  • "parent_fiscal_period_id": "1496c68f-bcfd-4760-a31d-e6ddf5c3d75c",
  • "calendar_month": "string",
  • "closed_at": "2019-08-24T14:15:22Z",
  • "closed_by_user_id": "103df14e-9463-40aa-a9b8-62af14cf9cd8",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete fiscal period

Delete a fiscal period (only open periods can be deleted; year periods with child months must have their months deleted first)

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal period ID

Responses

Response samples

Content type
application/json
{
  • "error": "Invalid input",
  • "code": "VALIDATION_ERROR",
  • "debug": "Validation failed for field 'invoice_date'",
  • "timestamp": "2024-01-15T10:30:00Z"
}

Close a fiscal month

Close a calendar month under a fiscal year. The path id is the fiscal YEAR; the calendar_month body field selects which month to close. The month fiscal_period row is created on first close (lazy materialization) and reused on a later re-close after a reopen. Sets is_closed, closed_at, and closed_by_user_id atomically and records a close entry in the audit log. Year-level closing is not supported.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal year ID. The month under it is selected by the calendar_month body field.

Request Body schema: application/json
required

Selects the calendar month under the fiscal year to close. The month row is found-or-created from the fiscal year range and this anchor.

calendar_month
required
string^\d{4}-(0[1-9]|1[0-2])$

Calendar month to close, as YYYY-MM. Must fall within the fiscal year range.

Responses

Request samples

Content type
application/json
{
  • "calendar_month": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": true,
  • "lock_date": "2019-08-24",
  • "period_type": "month",
  • "parent_fiscal_period_id": "1496c68f-bcfd-4760-a31d-e6ddf5c3d75c",
  • "calendar_month": "string",
  • "closed_at": "2019-08-24T14:15:22Z",
  • "closed_by_user_id": "103df14e-9463-40aa-a9b8-62af14cf9cd8",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Reopen a closed fiscal month

Reopen a previously closed fiscal month. The path id is the month fiscal_period row created by a prior :close. Clears is_closed, closed_at, and closed_by_user_id atomically and records a reopen entry in the audit log (capturing the close it undoes). Never creates a row. No request body is required.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal month ID (the month row created by a prior :close).

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": false,
  • "lock_date": "2019-08-24",
  • "period_type": "month",
  • "parent_fiscal_period_id": "1496c68f-bcfd-4760-a31d-e6ddf5c3d75c",
  • "calendar_month": "string",
  • "closed_at": null,
  • "closed_by_user_id": null,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Close a fiscal year

Close a fiscal YEAR and post the year-end result transfer. The path id is the fiscal year. Closes the income/expense accounts into account 2371 dated the year-end (so the result shows on its own equity line in the closing balance sheet), carries the result into prior-years retained earnings (account 2251) dated the first day of the next year, then seals the year and records a close entry in the audit log. The following fiscal year must already exist and be open to receive the carry-forward, so years are closed oldest first. No request body.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal year ID to close.

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": true,
  • "lock_date": "2019-08-24",
  • "period_type": "year",
  • "parent_fiscal_period_id": null,
  • "calendar_month": null,
  • "closed_at": "2019-08-24T14:15:22Z",
  • "closed_by_user_id": "103df14e-9463-40aa-a9b8-62af14cf9cd8",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Reopen a closed fiscal year

Reopen a previously closed fiscal YEAR. The path id is the fiscal year. Voids the year-end closing entries (reversing the result transfer so equity returns to its pre-close state), clears the close-audit columns, and records a reopen entry in the audit log. The following fiscal year must not be closed (reopen later years first). No request body.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

fiscalPeriodId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Fiscal year ID to reopen.

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24",
  • "is_closed": false,
  • "lock_date": "2019-08-24",
  • "period_type": "year",
  • "parent_fiscal_period_id": null,
  • "calendar_month": null,
  • "closed_at": null,
  • "closed_by_user_id": null,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

General

General operations

Get current user

Get current user info including roles and permissions. user.locale is the stored copy-locale preference; null means the company default applies (set or cleared via PATCH /me).

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "user": {
    },
  • "permissions": [
    ]
}

Update current user preferences

Updates preferences of the calling user. All fields are optional; omitting a field leaves it unchanged. locale is the preferred copy locale — notification copy renders in it from the next emit on — and passing null clears it so the company default applies again.

Authorizations:
bearerAuth
Request Body schema: application/json
required

Preference fields to update (all optional)

string or null

Preferred copy locale

Responses

Request samples

Content type
application/json
{
  • "locale": "fi-FI"
}

Response samples

Content type
application/json
{
  • "user": {
    }
}

General Ledger

General ledger account operations including listing and filtering

List general ledger accounts

Retrieve general ledger accounts with filtering, pagination, and i18n-resolved names. Supports filtering by type, code (exact/range), currency, and text search on account names.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
type
string (GeneralLedgerAccountType)
Enum: "asset" "equity" "expense" "liability" "revenue"
Example: type=asset

Filter by account type

code
string non-empty
Example: code=1000

Filter by exact account code

code_from
string non-empty
Example: code_from=1000

Filter by account code range (from)

code_to
string non-empty
Example: code_to=2000

Filter by account code range (to)

currency
string = 3 characters
Example: currency=EUR

Filter by currency code

query
string non-empty
Example: query=cash

Text search on account names (partial match)

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return (1-100)

offset
integer [ 0 .. 9007199254740991 ]

Number of results to skip for pagination

locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en"). Only the language portion is used. The effective locale falls back to the company's default locale, then "fi". Account names fall back to the account code when the effective locale has no translation.

include_balances
boolean
Example: include_balances=true

Include balance information for accounts (requires from_date and to_date)

from_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: from_date=2024-01-01

Start date for balance calculation (ISO date format: YYYY-MM-DD). Required when include_balances=true.

to_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: to_date=2024-12-31

End date for balance calculation (ISO date format: YYYY-MM-DD). Required when include_balances=true.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Get general ledger account tree

Retrieve the full chart of accounts as a nested hierarchy with optional period activity balances.

Consumer note: This endpoint has two client-visible modes. When start_date and end_date are omitted, the response returns the full tree with period: null and nodes without period_* fields. When both dates are provided, the response returns period balances on every node and may prune empty branches unless include_empty=true. Tree is sorted in ascending numeric order by codes.

Request examples:

  • GET /companies/{companyId}/general-ledger-account-tree?locale=fi
  • GET /companies/{companyId}/general-ledger-account-tree?start_date=2024-01-01&end_date=2024-03-31&include_empty=false&locale=fi

Migration note: Profit & Loss responses now use period_debit, period_credit, and period_net instead of the old amount field. Consumers should also expect this endpoint to return a validation 400 when only one date is provided or when start_date is after end_date; unexpected failures still return the standard 500 error shape.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
start_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: start_date=2024-01-01

Period start date (ISO date format: YYYY-MM-DD). Must be provided together with end_date. When omitted together, the response is returned in undated mode with period: null and no period_* node fields.

end_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: end_date=2024-03-31

Period end date (ISO date format: YYYY-MM-DD). Must be provided together with start_date. The endpoint returns 400 if only one date is provided or if start_date is after end_date.

include_empty
boolean
Example: include_empty=true

Include accounts and categories with no period activity. Requires both start_date and end_date. Default is false for dated mode, and effectively true when dates are omitted because undated mode returns the full tree.

locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=fi

BCP 47 locale code (e.g. "fi-FI", "en"). Only the language portion is used. The effective locale falls back to the company's default locale, then "fi". Node names fall back to the account code or category id when the effective locale has no translation.

Responses

Response samples

Content type
application/json
Example
{
  • "period": null,
  • "currency": "EUR",
  • "roots": [
    ]
}

Get general ledger account by code

Retrieve a single general ledger account by its code

Authorizations:
bearerAuth
path Parameters
code
required
string^[0-9]{4}$
Example: 1000

Account code (e.g., "1000", "2000")

query Parameters
locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en") for name and description resolution. Only the language portion is used. Falls back to "fi" when omitted. The name falls back to the account code when the effective locale has no translation; the description resolves to null.

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "code": "string",
  • "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",
  • "name": "string",
  • "description": "string",
  • "type": "asset",
  • "currency": "string",
  • "is_active": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

List general ledger lines

Retrieve general ledger lines with filtering and pagination. Supports filtering by GL account code, voucher, and posting date range. Opening balance and running balance are automatically included for account-wide queries (when account_code is provided and voucher_id is not provided) - they are always present regardless of from_date. When from_date is specified, opening balance is the sum before from_date; when from_date is not specified, opening balance is 0.00. Opening balance and running balance are NOT included when voucher_id is provided. Voided vouchers are automatically excluded from results, opening balance, and running balance calculations.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
account_code
string non-empty
Example: account_code=1000

GL account code (e.g., "1000"). Required when voucher_id is not provided. When voucher_id is provided, account_code is optional - if omitted, all lines for the voucher are returned.

voucher_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by voucher ID. When provided, account_code becomes optional. Either account_code or voucher_id must be provided.

from_date
string^\d{4}-\d{2}-\d{2}$
Example: from_date=2024-01-01

Filter by posting date (from, inclusive)

to_date
string^\d{4}-\d{2}-\d{2}$
Example: to_date=2024-12-31

Filter by posting date (to, inclusive)

limit
integer [ 1 .. 100 ]
Default: 10
Example: limit=50

Maximum number of results to return (1-100). Defaults to 10 if not specified.

cursor
string non-empty
Example: cursor=eyJwb3N0aW5nRGF0ZSI6IjIwMjQtMDEtMTUiLCJ2b3VjaGVySWQiOiJ2b3VjaGVyLTEiLCJsaW5lSWQiOiJsaW5lLTEifQ

Cursor for pagination (base64-encoded). Use the nextCursor from the previous response to fetch the next page.

locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en") for gl_account_name resolution. Only the language portion is used. The effective locale falls back to the company's default locale, then "fi". If the effective locale has no translation for a row's account, gl_account_name is null — there is no per-field fallback to another locale.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "opening_balance": "string",
  • "meta": {
    }
}

List open items for GL account

Retrieve open account items for a specific GL account. Each item is anchored on a valid voucher posting to the selected account and includes the linked document context. Results exclude documents with null or zero unsettled amounts.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

code
required
string^\d{4}$
Example: 1910

GL account code

query Parameters
cursor
string non-empty

Cursor for pagination (base64-encoded)

limit
integer [ 1 .. 100 ]
Default: 50
Example: limit=50

Maximum number of results to return (1-100). Defaults to 50.

posting_date_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: posting_date_from=2024-01-01

Filter by posting date (from, inclusive)

posting_date_to
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: posting_date_to=2024-12-31

Filter by posting date (to, inclusive)

document_type
string (GlAccountOpenItemDocumentType)
Enum: "bank_transaction" "expense_claim" "memo" "purchase_invoice" "sales_invoice" "settlement" "year_end_close"
Example: document_type=sales_invoice

Filter by document type

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Invoices

List approved invoices without a voucher

Cursor-paginated operations list of approved purchase and sales invoices that have no GL voucher, with the reason no voucher exists when known (unclassified lines vs. posting-rule gaps). Sorted oldest-first by approval time (rows approved before approval timestamps were recorded lead). Membership is "no voucher row at all": an invoice whose voucher was voided is not listed, because a voided voucher is restored via the voucher :unvoid action rather than regenerated. Invoices leave the list as soon as the :generate-voucher correction action (or the automatic post-approval generation) succeeds.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
cursor
string

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Default: 20

Maximum number of results to return (1-100, default: 20)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Memos

Memo operations including listing, creation, and editing

List memos

Retrieve memos for a company with optional filtering and pagination

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
cursor
string

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return

status
string (SalesInvoiceItems)
Enum: "draft" "approved" "rejected" "voided"
Example: status=draft

Filter by document status

tag
string
Example: tag=urgent

Filter by tag name

search
string
Example: search=rent

Search in memo description (case-insensitive substring)

with_amount
boolean
Example: with_amount=true

Filter by presence of amount (true = has amount, false = no amount)

document_date_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: document_date_from=2026-01-01

Filter by document date, inclusive lower bound (ISO date). Must be <= document_date_to when both are provided; an inverted range returns 400. Memos without a document date fall outside any bounded range.

document_date_to
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: document_date_to=2026-12-31

Filter by document date, inclusive upper bound (ISO date). Must be >= document_date_from when both are provided; an inverted range returns 400. Memos without a document date fall outside any bounded range.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create memo

Create a new memo document. A memo is a manual document with a textual description and optional metadata, used as a workaround source for vouchers when automated sources are unavailable.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Memo creation data

description
required
string non-empty

Memo description (required) - textual description of what the document represents

document_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Document date (YYYY-MM-DD). Required for memo creation. Used as default posting date when creating vouchers.

amount
string^-?[0-9]+(\.[0-9]{1,8})?$

Optional amount (numeric string with up to 8 decimals)

currency_code
string

Optional currency code (e.g., EUR, USD). Required when amount is provided.

files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

tags
Array of strings <= 50 items unique [ items [ 1 .. 64 ] characters \S ]

Optional array of tag names to attach to the memo. Duplicates (exact-match) are rejected with 400.

string or null

Optional internal notes for team visibility only (internal-only field)

object

Optional voucher data. If provided, a GL voucher will be created atomically with the memo.

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "document_date": "2019-08-24",
  • "amount": "string",
  • "currency_code": "string",
  • "files": [
    ],
  • "tags": [
    ],
  • "internal_notes": "string",
  • "voucher": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "description": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "currency_code": "string",
  • "status": "string",
  • "internal_notes": "string",
  • "document_date": "2019-08-24",
  • "files": [
    ],
  • "tags": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "voucher": {
    }
}

Get memo

Retrieve memo details by ID

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

memoId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Memo ID (document ID)

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "description": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "currency_code": "string",
  • "status": "string",
  • "internal_notes": "string",
  • "document_date": "2019-08-24",
  • "files": [
    ],
  • "tags": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update memo

Update an existing memo document. Partial updates are supported - only provided fields will be updated. Business rules: (1) Cannot edit if fiscal period for document_date is locked, (2) Cannot change amount if memo has a linked voucher.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

memoId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Memo ID (document ID)

Request Body schema: application/json
required

Memo update data (partial updates supported)

description
string non-empty

Memo description

string or null

Document date (YYYY-MM-DD). Used as default posting date when creating vouchers.

string or null

Optional amount (numeric string with up to 8 decimals)

string or null

Currency code (e.g., EUR, USD). Required when amount is provided.

files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

File IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

tags
Array of strings <= 50 items unique [ items [ 1 .. 64 ] characters \S ]

Tag names to attach (replaces all existing tags). Duplicates (exact-match) are rejected with 400.

string or null

Optional internal notes for team visibility only (internal-only field)

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "document_date": "2019-08-24",
  • "amount": "string",
  • "currency_code": "string",
  • "files": [
    ],
  • "tags": [
    ],
  • "internal_notes": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "description": "string",
  • "amount": "string",
  • "unsettled_amount": "string",
  • "currency_code": "string",
  • "status": "string",
  • "internal_notes": "string",
  • "document_date": "2019-08-24",
  • "files": [
    ],
  • "tags": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Notifications

List the caller's notifications in a company

Returns the caller's own notifications within the company, newest first, with keyset pagination. unread_count in the meta reflects the caller's total unread notifications in the company regardless of the current page or the unreadOnly filter; the OS app badge instead carries the caller's cross-company unread total (see GET /notifications/unread-counts). Notifications of other users are never visible.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
limit
integer [ 1 .. 100 ]
Example: limit=50

Maximum number of results to return (1-100, default: 50)

cursor
string

Pagination cursor from previous response

unreadOnly
boolean
Example: unreadOnly=true

When true, return only unread notifications

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Per-company unread notification counts for the caller

Returns one entry per company the caller is a member of, ordered by company id — zero counts included — so a company switcher can render every membership's unread badge from a single call. Counts cover live memberships only and always sum to the badge total carried on pushes. Not company-scoped: the caller's identity alone determines the result.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Mark one notification as read

Marks one of the caller's notifications as read. Idempotent: marking an already-read notification keeps the original read time and returns 200. Returns 404 when the notification does not exist or belongs to another user or company — the two cases are indistinguishable by design.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

notificationId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Notification ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "trigger": "purchase_invoice_received",
  • "title": "string",
  • "body": "string",
  • "resource_uri": "string",
  • "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  • "metadata": {
    },
  • "read_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Mark one notification as unread

Restores one of the caller's notifications to unread, the inverse of :mark-read. Idempotent: marking an already-unread notification returns 200 with read_at still null. Returns 404 when the notification does not exist or belongs to another user or company — the two cases are indistinguishable by design. Sends no push and no badge update: the caller's unread count is re-derived from the next inbox fetch.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

notificationId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Notification ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "trigger": "purchase_invoice_received",
  • "title": "string",
  • "body": "string",
  • "resource_uri": "string",
  • "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  • "metadata": {
    },
  • "read_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Mark all of the caller's notifications as read

Marks every unread notification of the caller in the company as read and returns how many were affected. Idempotent: a repeat call returns updated_count 0.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "updated_count": 9007199254740991
}

Parties

Party management operations including listing, creation, and editing

List parties

Retrieve parties for a company with optional search and filtering

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
scope
required
string (PartyScope)
Enum: "registry" "associated"
Example: scope=registry

Scope of parties to return

query
string
Example: query=Acme

Search query (searches in party names)

cursor
string
Example: cursor=eyJzb3J0IjoibmFtZSIsIm5hbWUiOiJBY21lIiwiaWQiOiIxMjM0NSJ9

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return

sort
string (PartySort)
Enum: "name" "updated_at" "last_sales_invoice_created_at"
Example: sort=name

Sort order

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create party

Create a new party

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Party creation data

registration_country_code
required
string^[A-Z]{2}$
business_id
required
string
name
required
string
string or null
object or null
object or null
object
object
string or null
object or null

Responses

Request samples

Content type
application/json
{
  • "registration_country_code": "string",
  • "business_id": "string",
  • "name": "string",
  • "vat_number": "string",
  • "postal_address": {
    },
  • "visiting_address": {
    },
  • "invoicing_address": {
    },
  • "settings": {
    },
  • "invoicing_email": "user@example.com",
  • "einvoice": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "registration_country_code": "string",
  • "business_id": "string",
  • "number": 0,
  • "vat_number": "string",
  • "postal_address": {
    },
  • "visiting_address": {
    },
  • "invoicing_address": {
    },
  • "settings": {
    },
  • "invoicing_email": "string",
  • "einvoice": {
    },
  • "public_registry": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get party

Retrieve party details with optional includes

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

partyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Party ID

query Parameters
include
string
Example: include=settings,address

Comma-separated list of related resources to include

namespace
string
Example: namespace=sales_invoice,purchase_invoice

Comma-separated list of namespaces to include

Responses

Response samples

Content type
application/json
{
  • "id": "string",
  • "name": "string",
  • "registration_country_code": "string",
  • "business_id": "string",
  • "number": 0,
  • "vat_number": "string",
  • "postal_address": {
    },
  • "visiting_address": {
    },
  • "invoicing_address": {
    },
  • "settings": {
    },
  • "invoicing_email": "string",
  • "einvoice": {
    },
  • "public_registry": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Edit party

Update party details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

partyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Party ID

Request Body schema: application/json
required

Party update data

name
string
(string or "" (string)) or null
object or null
object or null
object
object

Settings (can be flat structure for backward compatibility or namespaced like { namespace: { key: value } })

(string or "" (string)) or null
object or null

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "vat_number": "string",
  • "postal_address": {
    },
  • "visiting_address": {
    },
  • "invoicing_address": {
    },
  • "settings": {
    },
  • "invoicing_email": "user@example.com",
  • "einvoice": {
    }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "name": "string",
  • "number": 0
}

Payables

List payables

Unified cursor-paginated list of payable documents (purchase invoices and expense claims) for a company. Sorted by document_date DESC, id ASC. The endpoint owns cross-document sort and stage assignment; clients render whatever they receive without branching on type.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
stage
Array of strings (PayableItems) unique
Items Enum: "ready_to_pay" "paid" "awaiting_approval"

Filter by lifecycle stage. Multiple values allowed (repeated param). awaiting_approval is additive and currently returns an empty list.

cursor
string

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Default: 20

Maximum number of results to return (1-100, default: 20)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Payment batch agreements

Operator management of WS batch-payment agreements (schema, attachments, lifecycle)

List WS batch-payment agreements

List all batch-payment agreements for a company, including currently terminated ones. Active and terminated states are distinguished by terminated_at.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create a WS batch-payment agreement

Create a new batch-payment agreement, attaching at least one bank account. The same bank account may not be attached to more than one live agreement.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Agreement create payload

channel
string
Default: "fi_bank_ws"
Value: "fi_bank_ws"

Batch payment routing channel

ws_provider
required
string
Enum: "op" "nordea" "danske_bank" "aktia" "s_pankki" "pop_pankki" "saastopankki" "oma_saastopankki" "alandsbanken"

WS batch-payment provider — identifies which bank's WS endpoint a batch is submitted to

customer_id
required
string [ 1 .. 35 ] characters
valid_from
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
string or null
bank_account_ids
required
Array of strings <uuid> non-empty unique [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Responses

Request samples

Content type
application/json
{
  • "channel": "fi_bank_ws",
  • "ws_provider": "op",
  • "customer_id": "string",
  • "valid_from": "2019-08-24",
  • "valid_to": "2019-08-24",
  • "bank_account_ids": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a WS batch-payment agreement

Retrieve a single batch-payment agreement by ID.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

agreementId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Payment batch agreement ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a WS batch-payment agreement

Partial update. When bank_account_ids is provided it is the full attached set: accounts present that are not on the agreement are attached, accounts currently on the agreement that are absent are detached. All changes happen in one transaction.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

agreementId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Payment batch agreement ID

Request Body schema: application/json
required

Agreement update payload

channel
string
Value: "fi_bank_ws"

Batch payment routing channel

ws_provider
string
Enum: "op" "nordea" "danske_bank" "aktia" "s_pankki" "pop_pankki" "saastopankki" "oma_saastopankki" "alandsbanken"

WS batch-payment provider — identifies which bank's WS endpoint a batch is submitted to

customer_id
string [ 1 .. 35 ] characters
valid_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
string or null
bank_account_ids
Array of strings <uuid> non-empty unique [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Responses

Request samples

Content type
application/json
{
  • "channel": "fi_bank_ws",
  • "ws_provider": "op",
  • "customer_id": "string",
  • "valid_from": "2019-08-24",
  • "valid_to": "2019-08-24",
  • "bank_account_ids": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Terminate a WS batch-payment agreement

Soft-deletes the agreement: sets terminated_at on the agreement and detached_at on all live association rows in a single transaction. The agreement remains visible in listings.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

agreementId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Payment batch agreement ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Payments

Payment management operations including creation and tracking

List payments

List payments for a company with optional filtering

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
document_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by payable document ID

status
string (PaymentStatus)
Enum: "draft" "pending" "queued" "scheduled" "submitted" "acknowledged" "executed" "failed" "canceled" "rejected"

Filter by payment status

cursor
string

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of records to return (1-100, default: 10)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create payment

Create a payment for a payable document (purchase invoice or approved expense claim).

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Payment creation data

document_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

ID of the payable document (purchase invoice or expense claim)

amount
required
string^(?!0+(?:\.0{1,2})?$)\d+(\.\d{1,2})?$

Payment amount greater than 0 with up to 2 decimal places

currency
required
string = 3 characters

Payment currency (currently only EUR supported)

debtor_bank_account_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Bank account ID for the debtor

string or null

Execution date (ISO 8601 date); null or omitted means no schedule (pay immediately).

Responses

Request samples

Content type
application/json
{
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "amount": "string",
  • "currency": "str",
  • "debtor_bank_account_id": "231a5002-84bd-418b-8831-7cbf4bf000b2",
  • "scheduled_at": "2019-08-24"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "currency": "str",
  • "amount": "string",
  • "status": "draft",
  • "channel": "psd2",
  • "debtor_bank_account_id": "231a5002-84bd-418b-8831-7cbf4bf000b2",
  • "beneficiary_party_id": "string",
  • "beneficiary_iban": "string",
  • "beneficiary_bic": "string",
  • "beneficiary_name": "string",
  • "reference_number": "string",
  • "message": "string",
  • "scheduled_at": "2019-08-24",
  • "executed_at": "2019-08-24T14:15:22Z",
  • "upstream_id": "string",
  • "end_to_end_id": "string",
  • "rejection_code": "string",
  • "failure_reason": "string",
  • "batch_submission": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get payment

Retrieve a payment by ID

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

paymentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Payment ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "currency": "str",
  • "amount": "string",
  • "status": "draft",
  • "channel": "psd2",
  • "debtor_bank_account_id": "231a5002-84bd-418b-8831-7cbf4bf000b2",
  • "beneficiary_party_id": "string",
  • "beneficiary_iban": "string",
  • "beneficiary_bic": "string",
  • "beneficiary_name": "string",
  • "reference_number": "string",
  • "message": "string",
  • "scheduled_at": "2019-08-24",
  • "executed_at": "2019-08-24T14:15:22Z",
  • "upstream_id": "string",
  • "end_to_end_id": "string",
  • "rejection_code": "string",
  • "failure_reason": "string",
  • "batch_submission": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Initiate payment

Initiate an existing draft payment. The channel is resolved from the debtor bank account's active agreement at :initiate time: WS-routed accounts (fi_bank_ws) land in queued (or scheduled if scheduled_at is in the future); PSD2-routed accounts are rejected with 422 in this release.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

paymentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Payment ID

Request Body schema: application/json
required

Payment initiation data

redirect_url
string <uri>

URL to redirect user after successful bank authentication.

cancel_url
string <uri>

URL to redirect user if authentication fails or is canceled.

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "status": "queued",
  • "channel": "fi_bank_ws",
  • "requested_execution_date": "2019-08-24",
  • "redirect_url": null,
  • "rejection_code": null,
  • "failure_reason": null
}

Cancel payment

Cancel a WS payment that is still scheduled or queued (before the submit cycle picks it up). Any other status returns 409.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

paymentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Payment ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "company_id": "b2e6a1c3-1a5e-44ae-a8fd-81f76fd715cf",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "currency": "str",
  • "amount": "string",
  • "status": "draft",
  • "channel": "psd2",
  • "debtor_bank_account_id": "231a5002-84bd-418b-8831-7cbf4bf000b2",
  • "beneficiary_party_id": "string",
  • "beneficiary_iban": "string",
  • "beneficiary_bic": "string",
  • "beneficiary_name": "string",
  • "reference_number": "string",
  • "message": "string",
  • "scheduled_at": "2019-08-24",
  • "executed_at": "2019-08-24T14:15:22Z",
  • "upstream_id": "string",
  • "end_to_end_id": "string",
  • "rejection_code": "string",
  • "failure_reason": "string",
  • "batch_submission": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Payroll

Payroll operations, beginning with employment contracts

List employments

List employment contracts for a company with cursor-based pagination.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
limit
integer [ 1 .. 100 ]
Default: 10

Maximum number of results to return (1-100, default: 10)

cursor
string

Pagination cursor from previous response

employee_user_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by the employed user

manager_user_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by approving manager. Resolves the employments named in a 409 when removing a member who still manages open ones.

status
string (EmploymentStatus)
Enum: "active" "ended"

Filter by lifecycle slot

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create employment

Open an employment contract for a company member. An employee may hold only one open employment at a time, and the period may not overlap any of their earlier ones.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Employment to open

employee_user_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

The employed user; must be a current member of the company. Immutable once set.

string or null
Default: null

The approving manager; must be a current member of the company and cannot be the employee themselves. Null means submitted timesheets auto-approve.

jurisdiction
string
Default: "FI"
Value: "FI"

Employment-law jurisdiction

contract_type
required
string
Enum: "permanent" "fixed_term"

Contract type; a fixed_term contract requires an end_date

schedule_type
required
string
Enum: "full_time" "part_time" "zero_hours"

Working-time schedule; only zero_hours may guarantee 0 standard hours

standard_hours_per_week
required
string^[0-9]+(\.[0-9]{1,2})?$

Contractually guaranteed weekly hours (0-168, up to 2 decimals)

daily_overtime_threshold_hours
string^[0-9]+(\.[0-9]{1,2})?$
Default: "8"

Daily hours beyond which overtime accrues (0-24, exclusive of 0, up to 2 decimals)

overtime_multiplier
string^[0-9]+(\.[0-9]{1,2})?$
Default: "1.5"

Pay multiplier for overtime hours (1-99.99, up to 2 decimals)

start_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

First day of the employment (inclusive)

string or null
Default: null

Last day of the employment (inclusive); required for a fixed_term contract

Responses

Request samples

Content type
application/json
{
  • "employee_user_id": "eb5e2081-3889-49e3-bc18-833472df6511",
  • "manager_user_id": null,
  • "jurisdiction": "FI",
  • "contract_type": "permanent",
  • "schedule_type": "full_time",
  • "standard_hours_per_week": "string",
  • "daily_overtime_threshold_hours": "8",
  • "overtime_multiplier": "1.5",
  • "start_date": "2019-08-24",
  • "end_date": null
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get employment

Retrieve a single employment contract by ID.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

employmentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Employment ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update employment

Partially update an employment. Validation runs against the resulting employment, not the submitted fields alone, so a change that breaks a cross-field rule is rejected even when the field it conflicts with is untouched. The employee and the status cannot be changed here.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

employmentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Employment ID

Request Body schema: application/json
required

Fields to change

string or null

The approving manager; pass null to remove the manager

jurisdiction
string
Value: "FI"
contract_type
string
Enum: "permanent" "fixed_term"
schedule_type
string
Enum: "full_time" "part_time" "zero_hours"
standard_hours_per_week
string^[0-9]+(\.[0-9]{1,2})?$
daily_overtime_threshold_hours
string^[0-9]+(\.[0-9]{1,2})?$
overtime_multiplier
string^[0-9]+(\.[0-9]{1,2})?$
start_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
string or null

Responses

Request samples

Content type
application/json
{
  • "manager_user_id": "8dda3f52-952c-4237-a3a7-321fee65b913",
  • "jurisdiction": "FI",
  • "contract_type": "permanent",
  • "schedule_type": "full_time",
  • "standard_hours_per_week": "string",
  • "daily_overtime_threshold_hours": "string",
  • "overtime_multiplier": "string",
  • "start_date": "2019-08-24",
  • "end_date": "2019-08-24"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

End employment

Close an open employment on the given last working day. The employee may then be removed from the company, and a new employment may be opened for them.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

employmentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Employment ID

Request Body schema: application/json
required

Termination date

end_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Last day of the employment (inclusive)

Responses

Request samples

Content type
application/json
{
  • "end_date": "2019-08-24"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Reopen employment

Undo an :end. end_date states the period the reopened employment has: null for an open-ended contract, a date for a fixed-term one (whose end date the :end may have overwritten, and which cannot be recovered automatically). The employee must be a current member again, and must not already hold another open employment.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

employmentId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Employment ID

Request Body schema: application/json
required

The period the reopened employment has

required
string or null

Last day of the reopened employment (inclusive); null for an open-ended contract

Responses

Request samples

Content type
application/json
{
  • "end_date": "2019-08-24"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

List my timesheets for a year

The caller's twelve months of the given year as summaries (no per-day data): existing timesheets merged with empty version-0 drafts for the months that have no row yet. Reading never creates rows.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
year
required
integer [ 2000 .. 2100 ]

Calendar year (2000-2100)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Get my timesheet month

The caller's fully resolved month: every calendar day with its logged lines and exact day total. A month with no timesheet row reads as an empty draft at version 0 — the version a first PUT must send. Reading never creates rows.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

month
required
string^\d{4}-(0[1-9]|1[0-2])$

Calendar month in YYYY-MM form

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Create or replace my timesheet month

Full-replace write of the caller's month: the submitted workdays become the month's complete line set (an empty array clears it). Resending the set already stored is an idempotent no-op: the version does not move. Only a draft month accepts writes, and the write never touches the lifecycle stamps — submission and approval belong to the workflow endpoints. Concurrency: the request's version must match the stored one (0 when no row exists yet); a mismatch, a non-draft month, or a concurrently created month is rejected with 409, while a missing prerequisite — no employment covering the month — is 422. Creating a month requires an employment whose period overlaps it; future months are allowed. Cross-field rules (a line states hours or a start/end segment, dates inside the month, per-day total at most 24 h, positive net segment span, and no segment running past midnight) are rejected with 422. An overnight shift is entered as two segments split at midnight — 22:00-24:00 on the earlier date, 00:00-06:00 on the later one — which fall in different months when the split crosses a month boundary.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

month
required
string^\d{4}-(0[1-9]|1[0-2])$

Calendar month in YYYY-MM form

Request Body schema: application/json
required

The complete workday set for the month, and the version it is based on

version
required
integer [ 0 .. 9007199254740991 ]

The version this write is based on — what the last GET returned (0 for a month with no timesheet yet). A stale version is rejected with 409

required
Array of objects <= 500 items

The complete workday set for the month; the previous set is replaced wholesale and an empty array clears the month. A date may appear on several lines (split shifts). Each line states hours or a start_time/end_time segment, never both

Responses

Request samples

Content type
application/json
{
  • "version": 9007199254740991,
  • "workdays": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Product registry

Product management operations including creation, listing, editing, and deletion

List products

Retrieve products for a company with optional search and pagination

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
query
string
Example: query=laptop

Search query (searches in product names and descriptions)

offset
integer [ 0 .. 9007199254740991 ]

Number of results to skip for pagination

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return

include_inactive
boolean

Include inactive (deleted) products in results

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create product

Create a new product

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Product creation data

title
required
string <= 255 characters
string or null
string or null
string or null
string or null
string or null
string or null

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "unit_price": "string",
  • "unit_name": "string",
  • "vat_rate": "string",
  • "currency": "str",
  • "type": "services"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "description": "string",
  • "unit_price": "string",
  • "unit_name": "string",
  • "vat_rate": "string",
  • "currency": "string",
  • "type": "services",
  • "is_active": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get product

Retrieve product details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

productId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Product ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "description": "string",
  • "unit_price": "string",
  • "unit_name": "string",
  • "vat_rate": "string",
  • "currency": "string",
  • "type": "services",
  • "is_active": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Edit product

Update product details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

productId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Product ID

Request Body schema: application/json
required

Product update data

title
string <= 255 characters
description
string <= 255 characters
unit_price
string^-?[0-9]+(\.[0-9]{1,8})?$
unit_name
string <= 16 characters
vat_rate
string^(?:100(?:\.0{1,2})?|(?:0|[1-9]\d?)(?:\.\d{1,...
currency
string = 3 characters
type
string
Enum: "services" "goods" "electronic_services"

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "unit_price": "string",
  • "unit_name": "string",
  • "vat_rate": "string",
  • "currency": "str",
  • "type": "services"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "description": "string",
  • "unit_price": "string",
  • "unit_name": "string",
  • "vat_rate": "string",
  • "currency": "string",
  • "type": "services",
  • "is_active": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete product

Delete a product

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

productId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Product ID

Responses

Response samples

Content type
application/json
{
  • "error": "Forbidden",
  • "code": "FORBIDDEN",
  • "debug": "User does not have permission to perform this action",
  • "timestamp": "2024-01-15T10:30:00Z"
}

Reactivate product

Reactivate a deleted (inactive) product

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

productId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Product ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "title": "string",
  • "description": "string",
  • "unit_price": "string",
  • "unit_name": "string",
  • "vat_rate": "string",
  • "currency": "string",
  • "type": "services",
  • "is_active": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Purchase Invoices

Purchase invoice operations including listing and creation

List purchase invoices

Retrieve purchase invoices for a company with optional filtering

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
status
Array of strings (SalesInvoiceItems) unique
Items Enum: "draft" "approved" "rejected" "voided"
Example: status=draft&status=approved

Filter by one or more document statuses using repeated query parameters

payment_status
Array of strings (InvoicePaymentStatus) unique
Items Enum: "paid" "partially_paid" "unpaid"
Example: payment_status=unpaid&payment_status=partially_paid

Filter by one or more payment statuses using repeated query parameters

cursor
string

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return

owner_user_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Filter by owner user ID

party_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...
Example: party_id=123e4567-e89b-12d3-a456-426614174000

Filter by supplier party ID

invoice_date_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: invoice_date_from=2026-01-01

Filter by invoice date, inclusive lower bound (ISO date). Must be <= invoice_date_to when both are provided; an inverted range returns 400.

invoice_date_to
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: invoice_date_to=2026-01-31

Filter by invoice date, inclusive upper bound (ISO date). Must be >= invoice_date_from when both are provided; an inverted range returns 400.

due_date_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: due_date_from=2026-02-01

Filter by due date, inclusive lower bound (ISO date). Must be <= due_date_to when both are provided; an inverted range returns 400.

due_date_to
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: due_date_to=2026-02-28

Filter by due date, inclusive upper bound (ISO date). Must be >= due_date_from when both are provided; an inverted range returns 400.

overdue_as_of
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: overdue_as_of=2026-07-13

Return only overdue rows as of this calendar date: due date strictly before the given day AND payment status not paid (a document due exactly on the given day is not yet overdue; rows without a due date never match). Voided and rejected documents never match. Pass the caller's local calendar today — the server does no timezone math.

party_business_id
string [ 1 .. 64 ] characters
Example: party_business_id=1234567-8

Case-insensitive prefix match on the supplier's business ID: the value must match from the start of the ID, so 1234567 finds 1234567-8 but a mid-ID fragment finds nothing. SQL LIKE metacharacters (%, _) are escaped and matched literally. Whitespace-only input is treated as absent.

amount_min
string^-?[0-9]+(\.[0-9]{1,8})?$
Example: amount_min=100.00

Filter by minimum gross amount (inclusive, plain decimal string). Must be <= amount_max when both are provided; an inverted range returns 400.

amount_max
string^-?[0-9]+(\.[0-9]{1,8})?$
Example: amount_max=5000.00

Filter by maximum gross amount (inclusive, plain decimal string). Must be >= amount_min when both are provided; an inverted range returns 400.

q
string [ 1 .. 255 ] characters
Example: q=acme

Case-insensitive free-text search; the match type fits the field: supplier name and description match as a substring, the supplier business ID matches as a prefix, and invoice number and reference match exactly (a fragment of a number does not match). SQL LIKE metacharacters (%, _) are escaped and matched literally — clients should not rely on wildcard behavior.

sort_by
string (InvoiceSortBy)
Enum: "date" "created_at" "amount" "counterparty"
Example: sort_by=date

Sort order: date (default: invoice_date DESC, tiebroken by document.created_at then document.id; NULL invoice_date rows sort last), created_at (document.created_at DESC — the record creation timestamp), amount (total_amount_gross DESC), or counterparty (supplier name ASC)

Responses

Response samples

Content type
application/json
{
  • "example_query": "/companies/{companyId}/purchase-invoices?owner_user_id=73930057-2a35-4b9a-a675-4478e5fd3f4a&status=draft&payment_status=unpaid&payment_status=partially_paid&limit=10",
  • "data": [
    ],
  • "meta": {
    }
}

Create purchase invoice

Create a new purchase invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Purchase invoice creation data

string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null

Supplier party ID

string or null
string or null
string or null
Array of objects or null
files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

Array of strings or null

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "invoice_number": "string",
  • "currency": "EUR",
  • "total_amount_gross": "string",
  • "total_amount_net": "string",
  • "total_amount_vat": "string",
  • "payment_method": "string",
  • "reference": "string",
  • "supplier_id": "3cb1e20c-c6c9-4e71-ba66-399c468f697c",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "invoice_number": "string",
  • "invoice_date": "2019-08-24",
  • "document_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "currency": "string",
  • "company": {
    },
  • "supplier": {
    },
  • "supplier_stated_name": "string",
  • "supplier_stated_business_id": "string",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "payment_method": "string",
  • "source": "einvoice",
  • "reference": "string",
  • "internal_notes": "string",
  • "delegated_by_user_id": "be8da939-c65d-49cd-9cb4-f522d9d858d8",
  • "total_amount_net": "string",
  • "total_amount_gross": "string",
  • "total_amount_vat": "string",
  • "rounding_amount_gross": "string",
  • "rounding_amount_net": "string",
  • "payable_amount": "string",
  • "unsettled_amount": "string",
  • "ai_summary": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "caution_level": "caution",
  • "status": "draft",
  • "payment_status": "paid",
  • "current_assignee_user_id": "3d697ec3-cb4c-4391-8815-473809da15c5",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "audit_summary": [
    ]
}

Get purchase invoice

Retrieve purchase invoice details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "50345a92-121d-4428-9805-a53b416cfaaf",
  • "description": "Laptop for new hire",
  • "invoice_date": "2024-01-15",
  • "due_date": "2024-02-15",
  • "currency": "EUR",
  • "total_amount_gross": "124",
  • "total_amount_net": "100",
  • "total_amount_vat": "24",
  • "supplier": {
    },
  • "status": "draft"
}

Edit purchase invoice

Update purchase invoice details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Request Body schema: application/json
required

Purchase invoice update data

string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null

Supplier party ID

supplier_iban
string
supplier_bic
string
recipient_name
string
Array of objects or null
files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

Array of strings or null

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "invoice_number": "string",
  • "currency": "EUR",
  • "total_amount_gross": "string",
  • "total_amount_net": "string",
  • "total_amount_vat": "string",
  • "payment_method": "string",
  • "reference": "string",
  • "supplier_id": "3cb1e20c-c6c9-4e71-ba66-399c468f697c",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "invoice_number": "string",
  • "invoice_date": "2019-08-24",
  • "document_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "currency": "string",
  • "company": {
    },
  • "supplier": {
    },
  • "supplier_stated_name": "string",
  • "supplier_stated_business_id": "string",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "payment_method": "string",
  • "source": "einvoice",
  • "reference": "string",
  • "internal_notes": "string",
  • "delegated_by_user_id": "be8da939-c65d-49cd-9cb4-f522d9d858d8",
  • "total_amount_net": "string",
  • "total_amount_gross": "string",
  • "total_amount_vat": "string",
  • "rounding_amount_gross": "string",
  • "rounding_amount_net": "string",
  • "payable_amount": "string",
  • "unsettled_amount": "string",
  • "ai_summary": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "caution_level": "caution",
  • "status": "draft",
  • "payment_status": "paid",
  • "current_assignee_user_id": "3d697ec3-cb4c-4391-8815-473809da15c5",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "audit_summary": [
    ]
}

Delete purchase invoice

Delete a purchase invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Responses

Response samples

Content type
application/json
{
  • "error": "Forbidden",
  • "code": "FORBIDDEN",
  • "debug": "User does not have permission to perform this action",
  • "timestamp": "2024-01-15T10:30:00Z"
}

Approve purchase invoice

Approve a purchase invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "invoice_number": "string",
  • "invoice_date": "2019-08-24",
  • "document_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "currency": "string",
  • "company": {
    },
  • "supplier": {
    },
  • "supplier_stated_name": "string",
  • "supplier_stated_business_id": "string",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "payment_method": "string",
  • "source": "einvoice",
  • "reference": "string",
  • "internal_notes": "string",
  • "delegated_by_user_id": "be8da939-c65d-49cd-9cb4-f522d9d858d8",
  • "total_amount_net": "string",
  • "total_amount_gross": "string",
  • "total_amount_vat": "string",
  • "rounding_amount_gross": "string",
  • "rounding_amount_net": "string",
  • "payable_amount": "string",
  • "unsettled_amount": "string",
  • "ai_summary": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "caution_level": "caution",
  • "status": "draft",
  • "payment_status": "paid",
  • "current_assignee_user_id": "3d697ec3-cb4c-4391-8815-473809da15c5",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "audit_summary": [
    ]
}

Reclassify purchase invoice lines

Re-run AI line-classification enrichment on a draft purchase invoice. Idempotent: lines that are already classified are left untouched. Fire-and-forget.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Responses

Response samples

Content type
application/json
{
  • "status": "reclassification_requested"
}

Correct line classification and generate the voucher

Post-approval recovery for an approved purchase invoice with no GL voucher: optionally set or correct line vat_class_code values (audited with from/to), then synchronously attempt rule-based voucher generation. Corrections and generation run in one transaction — precondition failures (no effective posting rule, non-EUR currency, closed or missing fiscal period) return 400 with nothing applied. Corrections on an already-vouchered invoice are applied and reported as already_exists (the voucher is never regenerated); a request that changes nothing on an already-vouchered invoice returns 409. An empty request retries generation without changing lines.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Request Body schema: application/json
required

Line classification corrections to apply before generating (may be empty)

Array of objects

Line classification corrections to apply before generating. Omit (or send empty) to retry generation without changing any line — the recovery path after posting rules were seeded.

Responses

Request samples

Content type
application/json
{
  • "line_classifications": [
    ]
}

Response samples

Content type
application/json
{
  • "corrected_line_ids": [
    ],
  • "voucher_generation": {
    }
}

Reject purchase invoice

Reject a purchase invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "invoice_number": "string",
  • "invoice_date": "2019-08-24",
  • "document_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "currency": "string",
  • "company": {
    },
  • "supplier": {
    },
  • "supplier_stated_name": "string",
  • "supplier_stated_business_id": "string",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "payment_method": "string",
  • "source": "einvoice",
  • "reference": "string",
  • "internal_notes": "string",
  • "delegated_by_user_id": "be8da939-c65d-49cd-9cb4-f522d9d858d8",
  • "total_amount_net": "string",
  • "total_amount_gross": "string",
  • "total_amount_vat": "string",
  • "rounding_amount_gross": "string",
  • "rounding_amount_net": "string",
  • "payable_amount": "string",
  • "unsettled_amount": "string",
  • "ai_summary": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "caution_level": "caution",
  • "status": "draft",
  • "payment_status": "paid",
  • "current_assignee_user_id": "3d697ec3-cb4c-4391-8815-473809da15c5",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "audit_summary": [
    ]
}

Delegate purchase invoice

Delegate a purchase invoice to another user

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Request Body schema: application/json
required

Delegation data

to_user_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Responses

Request samples

Content type
application/json
{
  • "to_user_id": "bdcaa974-8e23-4fc9-823d-e060850bbef1"
}

Response samples

Content type
application/json
{
  • "error": "string",
  • "code": "string",
  • "debug": "string",
  • "timestamp": "2019-08-24T14:15:22Z",
  • "details": {
    }
}

Send back purchase invoice

Send back a purchase invoice to the company's default approver

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

purchaseInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Purchase invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "invoice_number": "string",
  • "invoice_date": "2019-08-24",
  • "document_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "currency": "string",
  • "company": {
    },
  • "supplier": {
    },
  • "supplier_stated_name": "string",
  • "supplier_stated_business_id": "string",
  • "supplier_iban": "string",
  • "supplier_bic": "string",
  • "recipient_name": "string",
  • "payment_method": "string",
  • "source": "einvoice",
  • "reference": "string",
  • "internal_notes": "string",
  • "delegated_by_user_id": "be8da939-c65d-49cd-9cb4-f522d9d858d8",
  • "total_amount_net": "string",
  • "total_amount_gross": "string",
  • "total_amount_vat": "string",
  • "rounding_amount_gross": "string",
  • "rounding_amount_net": "string",
  • "payable_amount": "string",
  • "unsettled_amount": "string",
  • "ai_summary": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "caution_level": "caution",
  • "status": "draft",
  • "payment_status": "paid",
  • "current_assignee_user_id": "3d697ec3-cb4c-4391-8815-473809da15c5",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "audit_summary": [
    ]
}

Reports

Generate profit and loss report

Generate a hierarchical Profit & Loss report for the specified date range. Returns revenue and expense accounts aggregated by account hierarchy with totals. Tree is sorted in ascending numeric order by codes.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Report generation parameters

start_date
required
string^\d{4}-\d{2}-\d{2}$

Start date of the reporting period (ISO date format: YYYY-MM-DD)

end_date
required
string^\d{4}-\d{2}-\d{2}$

End date of the reporting period (ISO date format: YYYY-MM-DD)

Responses

Request samples

Content type
application/json
{
  • "start_date": "string",
  • "end_date": "string"
}

Response samples

Content type
application/json
{
  • "period": {
    },
  • "currency": "string",
  • "roots": [
    ],
  • "totals": {
    },
  • "presentation_totals": {
    }
}

Generate balance sheet report

Generate a hierarchical Balance Sheet report as of a specific date. Returns asset, liability, and equity accounts aggregated by account hierarchy with totals. Optional comparison dates add parallel per-node and totals figures computed at each comparison date.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Report generation parameters

as_of_date
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Balance sheet date (ISO format: YYYY-MM-DD)

comparisons
Array of strings <date> <= 1 items [ items <date >^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[... ]

Additional snapshot dates to evaluate the balance sheet at alongside as_of_date.

Responses

Request samples

Content type
application/json
{
  • "as_of_date": "2019-08-24",
  • "comparisons": [
    ]
}

Response samples

Content type
application/json
{
  • "as_of_date": "2019-08-24",
  • "currency": "string",
  • "roots": [
    ],
  • "totals": {
    },
  • "presentation_totals": {
    },
  • "comparisons": [
    ]
}

Generate VAT report (ALV-laskelma)

Generate a structured ALV-laskelma (VAT calculation report) for the specified period. Groups GL entries by tax rate into taxes payable (suoritettavat verot) and deductible taxes (vähennettävät verot) sections, with per-account breakdowns and reconciliation against VAT GL accounts.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

VAT report generation parameters

period_start
required
string^\d{4}-\d{2}-\d{2}$

First day of the VAT period (ISO date format: YYYY-MM-DD)

period_end
required
string^\d{4}-\d{2}-\d{2}$

Last day of the VAT period (ISO date format: YYYY-MM-DD)

Responses

Request samples

Content type
application/json
{
  • "period_start": "string",
  • "period_end": "string"
}

Response samples

Content type
application/json
{
  • "period": {
    },
  • "currency": "EUR",
  • "company": {
    },
  • "sections": [
    ],
  • "taxes_payable_total": "string",
  • "deductible_taxes_total": "string",
  • "tax_payable": "string",
  • "vat_payable_account_balance": "string",
  • "vat_receivable_account_balance": "string",
  • "reconciliation": {
    }
}

Prepare (persist) a VAT declaration for a period

Compute the VAT report for the period and persist it as the draft VAT declaration snapshot, returning the persisted snapshot. Idempotent per period; a submitted (filed) declaration is immutable and returned unchanged. Returns 200 (not 201): this is an upsert of the single declaration for the period, which usually refreshes an existing draft rather than creating a new resource.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

VAT declaration period

period_start
required
string^\d{4}-\d{2}-\d{2}$

First day of the VAT period (ISO date format: YYYY-MM-DD)

period_end
required
string^\d{4}-\d{2}-\d{2}$

Last day of the VAT period (ISO date format: YYYY-MM-DD)

Responses

Request samples

Content type
application/json
{
  • "period_start": "string",
  • "period_end": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "period": {
    },
  • "status": "draft",
  • "generated_at": "2019-08-24T14:15:22Z",
  • "submitted_at": "2019-08-24T14:15:22Z",
  • "report": {
    }
}

Get the persisted VAT declaration snapshot for a period

Fetch the persisted VAT declaration snapshot for an exact period (period_start, period_end). A single snapshot exists per period; returns 404 when the period has not been generated yet.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
period_start
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

First day of the VAT period (ISO date format: YYYY-MM-DD)

period_end
required
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Last day of the VAT period (ISO date format: YYYY-MM-DD)

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "period": {
    },
  • "status": "draft",
  • "generated_at": "2019-08-24T14:15:22Z",
  • "submitted_at": "2019-08-24T14:15:22Z",
  • "report": {
    }
}

Get a persisted VAT declaration snapshot by id

Fetch a previously generated VAT declaration snapshot by its id. Returns the full report payload as generated (or frozen as filed) plus its status and timestamps.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

snapshotId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

VAT declaration snapshot ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "period": {
    },
  • "status": "draft",
  • "generated_at": "2019-08-24T14:15:22Z",
  • "submitted_at": "2019-08-24T14:15:22Z",
  • "report": {
    }
}

Sales Invoices

Sales invoice management operations including searching, listing, creating, approval, and posting

List sales invoices

Retrieve sales invoices for a company with optional filtering

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
status
Array of strings (SalesInvoiceItems) unique
Items Enum: "draft" "approved" "rejected" "voided"
Example: status=draft&status=approved

Filter by one or more document statuses using repeated query parameters

kind
string (SalesInvoiceKind)
Enum: "invoice" "credit_note"
Example: kind=invoice

Filter by invoice kind (invoice or credit_note)

party_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...
Example: party_id=123e4567-e89b-12d3-a456-426614174000

Filter by recipient party ID

cursor
string

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return (1-100, default: 10)

invoice_date_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: invoice_date_from=2026-01-01

Filter by invoice date, inclusive lower bound (ISO date). Must be <= invoice_date_to when both are provided; an inverted range returns 400.

invoice_date_to
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: invoice_date_to=2026-01-31

Filter by invoice date, inclusive upper bound (ISO date). Must be >= invoice_date_from when both are provided; an inverted range returns 400.

due_date_from
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: due_date_from=2026-02-01

Filter by due date, inclusive lower bound (ISO date). Must be <= due_date_to when both are provided; an inverted range returns 400.

due_date_to
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: due_date_to=2026-02-28

Filter by due date, inclusive upper bound (ISO date). Must be >= due_date_from when both are provided; an inverted range returns 400.

overdue_as_of
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: overdue_as_of=2026-07-13

Return only overdue rows as of this calendar date: due date strictly before the given day AND payment status not paid (a document due exactly on the given day is not yet overdue; rows without a due date never match). Voided and rejected documents never match. Pass the caller's local calendar today — the server does no timezone math.

party_business_id
string [ 1 .. 64 ] characters
Example: party_business_id=1234567-8

Case-insensitive prefix match on the recipient's business ID: the value must match from the start of the ID, so 1234567 finds 1234567-8 but a mid-ID fragment finds nothing. SQL LIKE metacharacters (%, _) are escaped and matched literally. Whitespace-only input is treated as absent.

amount_min
string^-?[0-9]+(\.[0-9]{1,8})?$
Example: amount_min=100.00

Filter by minimum gross amount (inclusive, plain decimal string). Must be <= amount_max when both are provided; an inverted range returns 400.

amount_max
string^-?[0-9]+(\.[0-9]{1,8})?$
Example: amount_max=5000.00

Filter by maximum gross amount (inclusive, plain decimal string). Must be >= amount_min when both are provided; an inverted range returns 400.

payment_status
Array of strings (InvoicePaymentStatus) unique
Items Enum: "paid" "partially_paid" "unpaid"
Example: payment_status=unpaid&payment_status=partially_paid

Filter by one or more payment statuses using repeated query parameters

q
string [ 1 .. 255 ] characters
Example: q=acme

Case-insensitive free-text search; the match type fits the field: recipient name and description match as a substring, the recipient business ID matches as a prefix, and invoice number, our_reference, and your_reference match exactly (a fragment of a number does not match). SQL LIKE metacharacters (%, _) are escaped and matched literally — clients should not rely on wildcard behavior.

sort_by
string (InvoiceSortBy)
Enum: "date" "created_at" "amount" "counterparty"
Example: sort_by=date

Sort order: date (default: invoice_date DESC, tiebroken by document.created_at then document.id; NULL invoice_date rows sort last), created_at (document.created_at DESC — the record creation timestamp), amount (total_amount_gross DESC), or counterparty (recipient name ASC)

Responses

Response samples

Content type
application/json
{
  • "example_query": "/companies/{companyId}/sales-invoices?status=approved&limit=10",
  • "data": [
    ],
  • "meta": {
    }
}

Create sales invoice

Create a new sales invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Sales invoice creation data

Any of
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
object or null
string or null
object or null
object or null
Array of objects or null
files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

Array of strings or null
"invoice" (string) or null
credit_reason
null
credited_sales_invoice_id
null

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "interest_rate": "string",
  • "our_reference": "string",
  • "your_reference": "string",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "currency": "EUR",
  • "locale": "fi-FI",
  • "invoicing_channel": "einvoice",
  • "recipient": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_invoicing_address": {
    },
  • "recipient_einvoice": {
    },
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "kind": "credit_note",
  • "credit_reason": "string",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_date": "2019-08-24",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_number": "string",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "sender_name": "string",
  • "sender_domicile": "string",
  • "sender_vat_number": "string",
  • "sender_address": {
    },
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "recipient_vat_number": "string",
  • "bank_reference": "string",
  • "gross_amount": "string",
  • "vat_amount": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "status": "draft",
  • "payment_status": "paid",
  • "sending_status": "not_sent",
  • "rejection_code": "string",
  • "rejection_reason": "string",
  • "kind": "invoice",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e",
  • "credit_reason": "string",
  • "unsettled_amount": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get sales invoice

Retrieve sales invoice details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_date": "2019-08-24",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_number": "string",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "sender_name": "string",
  • "sender_domicile": "string",
  • "sender_vat_number": "string",
  • "sender_address": {
    },
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "recipient_vat_number": "string",
  • "bank_reference": "string",
  • "gross_amount": "string",
  • "vat_amount": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "status": "draft",
  • "payment_status": "paid",
  • "sending_status": "not_sent",
  • "rejection_code": "string",
  • "rejection_reason": "string",
  • "kind": "invoice",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e",
  • "credit_reason": "string",
  • "unsettled_amount": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Edit sales invoice

Update sales invoice details

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID

Request Body schema: application/json
required

Sales invoice update data

string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null
string or null

Reason for creating the credit note. Only valid for draft credit_note invoices; regular invoices return 400 if this field is provided.

string or null
object or null
string or null
object or null
object or null
Array of objects or null
files
Array of strings <uuid> [ items <uuid >^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA... ]

Optional array of file IDs to attach (replaces all existing files when provided; pass an empty array to clear all files)

Array of strings or null

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "interest_rate": "string",
  • "our_reference": "string",
  • "your_reference": "string",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "currency": "EUR",
  • "locale": "fi-FI",
  • "credit_reason": "string",
  • "invoicing_channel": "einvoice",
  • "recipient": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_invoicing_address": {
    },
  • "recipient_einvoice": {
    },
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_date": "2019-08-24",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_number": "string",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "sender_name": "string",
  • "sender_domicile": "string",
  • "sender_vat_number": "string",
  • "sender_address": {
    },
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "recipient_vat_number": "string",
  • "bank_reference": "string",
  • "gross_amount": "string",
  • "vat_amount": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "status": "draft",
  • "payment_status": "paid",
  • "sending_status": "not_sent",
  • "rejection_code": "string",
  • "rejection_reason": "string",
  • "kind": "invoice",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e",
  • "credit_reason": "string",
  • "unsettled_amount": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete sales invoice

Delete a sales invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID

Responses

Response samples

Content type
application/json
{
  • "error": "Forbidden",
  • "code": "FORBIDDEN",
  • "debug": "User does not have permission to perform this action",
  • "timestamp": "2024-01-15T10:30:00Z"
}

Approve sales invoice

Approve a sales invoice. If any line items have null product_id, products will be automatically created from the line item data (title, description, unit price, VAT rate, etc.) during approval. All approved line items will have a product_id set.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_date": "2019-08-24",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_number": "string",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "sender_name": "string",
  • "sender_domicile": "string",
  • "sender_vat_number": "string",
  • "sender_address": {
    },
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "recipient_vat_number": "string",
  • "bank_reference": "string",
  • "gross_amount": "string",
  • "vat_amount": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "status": "draft",
  • "payment_status": "paid",
  • "sending_status": "not_sent",
  • "rejection_code": "string",
  • "rejection_reason": "string",
  • "kind": "invoice",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e",
  • "credit_reason": "string",
  • "unsettled_amount": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Send sales invoice

Send a sales invoice via the configured invoicing channel

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_date": "2019-08-24",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "description": "string",
  • "internal_notes": "string",
  • "invoice_number": "string",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "sender_name": "string",
  • "sender_domicile": "string",
  • "sender_vat_number": "string",
  • "sender_address": {
    },
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "recipient_vat_number": "string",
  • "bank_reference": "string",
  • "gross_amount": "string",
  • "vat_amount": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "lines": [
    ],
  • "files": [
    ],
  • "tags": [
    ],
  • "status": "draft",
  • "payment_status": "paid",
  • "sending_status": "not_sent",
  • "rejection_code": "string",
  • "rejection_reason": "string",
  • "kind": "invoice",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e",
  • "credit_reason": "string",
  • "unsettled_amount": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Correct line classification and generate the voucher

Post-approval recovery for an approved sales invoice with no GL voucher: optionally set or correct line vat_class_code values (audited with from/to), then synchronously attempt rule-based voucher generation. Corrections and generation run in one transaction — precondition failures (no effective posting rule, non-EUR currency, closed or missing fiscal period) return 400 with nothing applied. Corrections on an already-vouchered invoice are applied and reported as already_exists (the voucher is never regenerated); a request that changes nothing on an already-vouchered invoice returns 409. An empty request retries generation without changing lines.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID

Request Body schema: application/json
required

Line classification corrections to apply before generating (may be empty)

Array of objects

Line classification corrections to apply before generating. Omit (or send empty) to retry generation without changing any line — the recovery path after posting rules were seeded.

Responses

Request samples

Content type
application/json
{
  • "line_classifications": [
    ]
}

Response samples

Content type
application/json
{
  • "corrected_line_ids": [
    ],
  • "voucher_generation": {
    }
}

Get credit note prefill data

Get pre-filled data for creating a credit note from an existing sales invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Original sales invoice ID

Responses

Response samples

Content type
application/json
{
  • "description": "string",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "lines": [
    ],
  • "tags": [
    ],
  • "kind": "credit_note",
  • "credited_sales_invoice_id": "8fdec0e4-3a29-4ed0-b4d6-d6af3836d63e",
  • "credit_reason": "string"
}

Get copy prefill data

Get pre-filled data for creating a copy of an existing sales invoice

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

salesInvoiceId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Sales invoice ID to copy from

Responses

Response samples

Content type
application/json
{
  • "description": "string",
  • "invoice_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "currency": "string",
  • "invoicing_channel": "einvoice",
  • "bank_account_id": "9335a679-63ab-44d5-9de9-e01e0c5a1fff",
  • "our_reference": "string",
  • "your_reference": "string",
  • "interest_rate": "string",
  • "locale": "string",
  • "recipient": {
    },
  • "recipient_invoicing_address": {
    },
  • "recipient_invoicing_email": "string",
  • "recipient_einvoice": {
    },
  • "lines": [
    ],
  • "tags": [
    ],
  • "kind": "invoice",
  • "credited_sales_invoice_id": null,
  • "credit_reason": null
}

Settings

Settings management operations including listing and editing

Resolve settings

Resolve settings with optional company or party context. Settings are resolved in order: party scope > company scope > global scope.

Authorizations:
bearerAuth
query Parameters
company_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID for company-specific settings

party_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Party ID for party-specific settings (will resolve company_id if not provided)

namespace
string
Example: namespace=sales_invoice,purchase_invoice

Comma-separated list of namespaces to include

Responses

Response samples

Content type
application/json
{
  • "property1": null,
  • "property2": null
}

List tags

Retrieve tags for a company with optional search and pagination

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
query
string
Example: query=important

Search query (searches in tag names)

cursor
string
Example: cursor=eyJuYW1lIjoic29tZS10YWciLCJpZCI6IjEyMzQ1In0

Pagination cursor from previous response

limit
integer [ 1 .. 100 ]
Example: limit=100

Maximum number of results to return (default: 100)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Settlements

Settlement operations for reconciling bank transactions with invoices

List settlements

List settlements for a company with cursor-based pagination. Each entry returns both settled documents (id, type, full amount), the settled amount, currency, match rule, status (active or rejected), and creation time. Supports filtering by status, settlement creation-date range (UTC, inclusive), and a document id (settlements where the document is on either side). Without a status filter, both active and rejected settlements are returned.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
cursor
string

Pagination cursor from a previous response

limit
integer [ 1 .. 100 ]
Example: limit=50

Maximum number of records to return (1-100, default: 50)

status
string (SettlementStatus)
Enum: "active" "rejected"

Filter by settlement status (active or rejected)

from_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Only settlements created on or after this date (UTC, inclusive, YYYY-MM-DD)

to_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Only settlements created on or before this date (UTC, inclusive, YYYY-MM-DD)

document_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Only settlements where this document is on either side

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create settlement between two documents

Create a settlement between any two document types (memo, purchase_invoice, sales_invoice, expense_claim, bank_transaction). This records that a specific amount has been settled between the two documents, updating the relevant unsettled_amount fields. Supports type-aware matching: incoming documents match incoming, outgoing match outgoing, and same-type documents require opposite signs (e.g., invoice and credit note). Memos without amount cannot be reconciled.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Settlement creation data

document_a_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

First document ID (memo, purchase_invoice, sales_invoice, expense_claim, or bank_transaction)

document_b_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Second document ID (memo, purchase_invoice, sales_invoice, expense_claim, or bank_transaction)

amount
required
string^([1-9][0-9]*(\.[0-9]{1,8})?|0\.([1-9][0-9]{0...

Settlement amount (positive decimal string, must be > 0)

Responses

Request samples

Content type
application/json
{
  • "document_a_id": "f5f1b8a4-b413-4922-a4b9-1097ae15b1b0",
  • "document_b_id": "5755b0e6-dd6a-43e3-ae3e-2e974a49f8ff",
  • "amount": "string"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_a_id": "f5f1b8a4-b413-4922-a4b9-1097ae15b1b0",
  • "document_b_id": "5755b0e6-dd6a-43e3-ae3e-2e974a49f8ff",
  • "amount": "string",
  • "updated_unsettled_amount_a": "string",
  • "updated_unsettled_amount_b": "string"
}

Delete (reject) settlement

Soft-delete (reject) a settlement. If the settlement has a linked voucher and the voucher is in a locked or closed fiscal period, returns 409 Conflict. Otherwise marks the settlement as rejected and, if present, voids the voucher. Document unsettled amounts are recalculated. See TECH-569.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

settlementId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Settlement ID

Responses

Response samples

Content type
application/json
{
  • "error": "Invalid input",
  • "code": "VALIDATION_ERROR",
  • "debug": "Validation failed for field 'invoice_date'",
  • "timestamp": "2024-01-15T10:30:00Z"
}

User Settings

Get payment profile

Retrieve payment profile details for the current user

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "iban": "string",
  • "iban_updated_at": "2019-08-24T14:15:22Z"
}

Update IBAN payment profile

Update the IBAN payment profile for the current user

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Payment profile update data

iban
required
string

IBAN (ISO country code + 16 digits)

Responses

Request samples

Content type
application/json
{
  • "iban": "string"
}

Response samples

Content type
application/json
{
  • "iban": "string",
  • "iban_updated_at": "2019-08-24T14:15:22Z"
}

User management

Invite a member to a company

Creates an invitation for a new member to join a company. An invitation email will be sent to the provided address. Returns 400 if the role is not a known company-scoped role, 403 if the caller may not assign the requested role (a caller lacking payments.write cannot assign a role that grants it), and 409 if a pending invitation already exists for the same email and company.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Invitation data

email
required
string <email> ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z...

Email address to invite

role
required
string non-empty

Role to assign (name of a company-scoped role defined in the system)

first_name
string <= 255 characters

First name of the invitee

last_name
string <= 255 characters

Last name of the invitee

phone
string <= 50 characters

Phone number of the invitee

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "role": "string",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string"
}

Response samples

Content type
application/json
{
  • "status": "pending",
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string",
  • "role": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "expires_at": "2019-08-24T14:15:22Z"
}

List company members and invitations

Canonical endpoint for company membership data. Returns active members, pending invitations, and expired invitations in a single paginated list. Use status=active for filtered selection (e.g. approver picker). Omit status for the full member-management view. Expired invitations are included so admins can resend or cancel them. Cancelled and undeliverable invitations are always excluded.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
limit
integer [ 1 .. 100 ]
Example: limit=50

Maximum number of results to return (1-100, default: 50)

status
Array of strings (CompanyMemberItems) unique
Items Enum: "active" "pending" "expired"
Example: status=active&status=pending

Filter by one or more member statuses using repeated query parameters

cursor
string

Pagination cursor from previous response

q
string [ 1 .. 255 ] characters
Example: q=alice

Case-insensitive free-text search across member email, first name, and last name. SQL LIKE metacharacters (%, _) are escaped and matched literally — clients should not rely on wildcard behavior.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Get a single company member by ID

Returns a single company member by member ID. Used by the Members page detail panel when deep-linking to a specific member that may not be on the first page of the paginated list. Cancelled, undeliverable, and accepted invitations are treated as not found.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

memberId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Member ID

Responses

Response samples

Content type
application/json
{
  • "status": "expired",
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string",
  • "role": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "expires_at": "2019-08-24T14:15:22Z"
}

Remove a member from a company

Removes a member from a company. For pending or expired members, their invitation is cancelled. For active members, their company membership is deleted. Returns 409 when an invitation is not in a cancellable state, when a company-local caller tries to remove themselves, or when removing the target would remove the company's last administrator (a provider role such as accountant does not count as the company's own admin). Callers acting via a platform role (superadmins) bypass both the self-removal and last-administrator guards, since they can re-grant access from outside the company.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

memberId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Member ID

Responses

Response samples

Content type
application/json
{
  • "error": "Forbidden",
  • "code": "FORBIDDEN",
  • "debug": "User does not have permission to perform this action",
  • "timestamp": "2024-01-15T10:30:00Z"
}

Resend a pending or expired invitation

Refreshes a pending or expired invitation in place: clears the existing token slot, refreshes the expiry to 7 days from now, sets status back to pending, resets the auto-reminder lifecycle so reminders restart from this point, and re-triggers the invitation email. Returns 409 when the invitation is in a terminal state (accepted, cancelled, undeliverable) — diverges from getMember which returns 404 for those statuses, because resend treats the row as an existing-state-conflict rather than a not-found. Returns 409 also when a pending invitation already exists for the same email and company. Returns 404 when the invitation does not exist or does not belong to the specified company.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

memberId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Invitation ID

Responses

Response samples

Content type
application/json
{
  • "status": "pending",
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string",
  • "role": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "expires_at": "2019-08-24T14:15:22Z"
}

Change the role of an active company member

Changes the role of an active company member. Pending and expired invitations are not supported by this endpoint — those must be cancelled and re-invited with the desired role. Returns 200 with the updated member (idempotent when the role is unchanged). A caller may target their own membership. Returns 403 when the caller may not assign the target role (a caller lacking payments.write cannot assign a role that grants it). Returns 409 when the target is a pending or expired invitation, or when a company-local caller would remove the company's last administrator (a provider role such as accountant does not count as the company's own admin). Callers acting via a platform role (superadmins) bypass the last-administrator guard, since they can re-grant access at any time. Returns 422 when the target role is not a company-scoped role.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

memberId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Member ID

Request Body schema: application/json
required

New role assignment

roleId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

UUID of the role to assign (must be a company-scoped role)

Responses

Request samples

Content type
application/json
{
  • "roleId": "7382d58e-652a-4905-b7c9-bcca1e0e5391"
}

Response samples

Content type
application/json
{
  • "status": "active",
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "email": "user@example.com",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string",
  • "role": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

List assignable roles for a company

Returns the company-scoped roles the caller may assign when inviting or re-roling members. Platform-scoped roles (e.g. superadmin) are never included.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

VAT Classes

List VAT classes

Retrieve all active VAT classes (ALV-tunnisteet) from Netvisor standards. These are predefined codes used in Finnish accounting systems for VAT reporting and compliance. Names and descriptions are returned in the effective locale — see the locale query parameter for the full fallback and null semantics.

Authorizations:
bearerAuth
query Parameters
locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en"). Only the language portion is used. Falls back to "fi" when omitted. If the requested/effective locale has no translation for a given row, its localized fields are returned as null — there is no per-field fallback to another locale.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

VAT Posting Rules

List VAT posting rules

Retrieve VAT posting rules — the line shapes the backend uses to expand a (vatClassCode, documentType) tuple into voucher lines for a given posting date. Rules are system-wide, not company-scoped, and change rarely. When effective_at is omitted, all rules are returned (including past and future epochs) so the client can do its own time-based filtering. When effective_at is provided, only rules effective at that date are returned. A Cache-Control: private, max-age=3600 header is set so authenticated clients can cache the response for an hour.

Authorizations:
bearerAuth
query Parameters
document_type
string (VatPostingRuleDocumentType)
Enum: "purchase_invoice" "sales_invoice" "memo"
Example: document_type=purchase_invoice

Optional filter by document type the rule applies to.

effective_at
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: effective_at=2026-05-07

Optional ISO 8601 date (YYYY-MM-DD). When provided, only rules whose effective window covers this date are returned: effective_from <= effective_at AND (effective_until IS NULL OR effective_until > effective_at).

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

VAT Rates

List VAT rates by country

Retrieve VAT rates for a given country, grouped into historical and current periods ordered newest-first. Returns an empty periods array for unknown country codes. Rate descriptions and period labels are returned in the effective locale — see the locale query parameter for the full fallback and null semantics.

Authorizations:
bearerAuth
query Parameters
country
required
string^[A-Za-z]{2}$
Example: country=FI

ISO 3166-1 alpha-2 country code (e.g. "FI")

locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en"). Only the language portion is used. Falls back to "fi" when omitted. If the requested/effective locale has no translation for a given row, its localized fields are returned as null — there is no per-field fallback to another locale.

Responses

Response samples

Content type
application/json
{
  • "country": "FI",
  • "periods": [
    ]
}

Vouchers

Voucher operations including listing, creation, and editing

List vouchers

List vouchers for a company with cursor-based pagination. Filters by status, date range, document type, and voucher number. All vouchers include their lines.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

query Parameters
status
string (VoucherStatus)
Enum: "valid" "voided"
Example: status=valid

Filter by voucher status

from_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: from_date=2024-01-01

Filter by posting date (from, inclusive)

to_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...
Example: to_date=2024-12-31

Filter by posting date (to, inclusive)

document_type
string (VoucherDocumentType)
Enum: "sales_invoice" "purchase_invoice" "bank_transaction" "memo" "settlement" "year_end_close"
Example: document_type=sales_invoice

Filter by document type

document_id
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...
Example: document_id=12345678-1234-4234-8234-123456789abc

Filter by source document ID (to find voucher for a specific document)

voucher_number
string non-empty
Example: voucher_number=SI-1000

Filter by voucher number

limit
integer [ 1 .. 100 ]
Example: limit=10

Maximum number of results to return (1-100)

cursor
string

Pagination cursor from previous response

locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en") for account_name resolution. Only the language portion is used. The effective locale falls back to the company's default locale, then "fi". If the effective locale has no translation for a line's account, account_name is null — there is no per-field fallback to another locale.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    }
}

Create voucher

Create a new GL voucher for a given document. Each voucher is tied to exactly one document (sales invoice, purchase invoice, bank transaction, memo, settlement). Vouchers are created as valid and are locked via fiscal period locking. Vouchers can be voided but cannot be deleted. Vouchers that are not locked, can be updated. A document can have only one voucher.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

Request Body schema: application/json
required

Voucher creation data

document_id
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Document ID - must exist and must not already have a voucher

posting_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Posting date (YYYY-MM-DD). Defaults to document document_date if not provided. Must be inside a non-locked fiscal period, or no fiscal period must exist for the date.

currency
required
string
Value: "EUR"

Currency code

required
Array of objects >= 2 items

Voucher lines. Must have at least 2 lines. Lines must balance (sum of amounts = 0.00).

Responses

Request samples

Content type
application/json
{
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "posting_date": "2019-08-24",
  • "currency": "EUR",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "document_type": "sales_invoice",
  • "currency": "EUR",
  • "status": "valid",
  • "posting_date": "2019-08-24",
  • "lines": [
    ],
  • "voucher_number": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  • "voided_by": null,
  • "voided_at": null
}

Get voucher

Retrieve a specific GL voucher by ID with all its lines. Returns vouchers regardless of status (valid or voided).

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

voucherId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Voucher ID

query Parameters
locale
string^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8}){0,5}$
Example: locale=en

BCP 47 locale code (e.g. "fi-FI", "en") for account_name resolution. Only the language portion is used. The effective locale falls back to the company's default locale, then "fi". If the effective locale has no translation for a line's account, account_name is null — there is no per-field fallback to another locale.

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "document_type": "sales_invoice",
  • "currency": "EUR",
  • "status": "valid",
  • "posting_date": "2019-08-24",
  • "lines": [
    ],
  • "voucher_number": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  • "voided_by": "5ecfc985-14a9-4a71-a20e-8b1b8395f2ab",
  • "voided_at": "2019-08-24T14:15:22Z"
}

Update voucher

Update an existing GL voucher. Vouchers can only be edited if they have status = "valid" and the voucher's posting_date falls within an unlocked fiscal period (fiscal period's lock_date is null or the voucher date is after the lock date). The endpoint updates both gl_voucher and gl_line tables in a single transaction, replacing all existing lines with the new lines. document_id cannot be changed.

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

voucherId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Voucher ID

Request Body schema: application/json
required

Voucher update data

posting_date
string <date> ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[...

Posting date (YYYY-MM-DD). If provided, must be inside an open/planned fiscal period and unlocked.

required
Array of objects >= 2 items

Voucher lines. Must have at least 2 lines. Lines must balance (sum of amounts = 0.00). All existing lines will be replaced.

Responses

Request samples

Content type
application/json
{
  • "posting_date": "2019-08-24",
  • "lines": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "document_type": "sales_invoice",
  • "currency": "EUR",
  • "status": "valid",
  • "posting_date": "2019-08-24",
  • "lines": [
    ],
  • "voucher_number": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  • "voided_by": null,
  • "voided_at": null
}

Void voucher

Void a GL voucher by transitioning it from "valid" to "voided". Voiding is a status flip: no reversing entry is posted, and the voucher with its lines is retained for the audit trail. Only vouchers with status "valid" can be voided; an already-voided voucher is rejected. Voiding is blocked when the voucher's posting_date falls within a locked or closed fiscal period, mirroring the update rules. A voided voucher is excluded from all reports and balances (the read layer filters status = "valid") but remains retrievable via get/list with status "voided".

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

voucherId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Voucher ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "document_type": "sales_invoice",
  • "currency": "EUR",
  • "status": "voided",
  • "posting_date": "2019-08-24",
  • "lines": [
    ],
  • "voucher_number": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  • "voided_by": "5ecfc985-14a9-4a71-a20e-8b1b8395f2ab",
  • "voided_at": "2019-08-24T14:15:22Z"
}

Unvoid voucher

Unvoid a GL voucher by transitioning it from "voided" back to "valid", the exact inverse of void. The void attribution fields (voided_by, voided_at) are cleared. Only vouchers with status "voided" can be unvoided; a voucher that is not voided is rejected. Unvoiding is blocked when the voucher's posting_date falls within a locked or closed fiscal period, mirroring the void and update rules. Once unvoided, the voucher re-enters all reports and balances (the read layer includes status = "valid").

Authorizations:
bearerAuth
path Parameters
companyId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Company ID

voucherId
required
string <uuid> ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA...

Voucher ID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6",
  • "document_type": "sales_invoice",
  • "currency": "EUR",
  • "status": "valid",
  • "posting_date": "2019-08-24",
  • "lines": [
    ],
  • "voucher_number": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
  • "voided_by": null,
  • "voided_at": null
}