API reference

Vexless API

Resource-oriented HTTP and JSON. Every response is typed in the OpenAPI document and enforced by the server; this page is generated from it. Every endpoint names the scope it needs.

The guides explain how the pieces fit. The essentials are short: Authentication for keys and actors, Idempotency for retries, Errors for every rule, Webhooks for events, Grants for scopes.

Conventions

Moneyobject

{ amount, currency }. Amounts are integers in minor units, never floats. A bare amount field in a request body is minor units in the origin's currency.

Sign

Ledger postings and balances: debit positive, credit negative. Bank transactions: positive is money in. Open items and reports present absolute amounts with a direction.

Datesstring

YYYY-MM-DD for business dates. RFC 3339 with milliseconds and Z for timestamps.

Idsstring

Prefixed and time-sortable: cmp_, org_, ent_, pst_, pty_, pay_, stl_, alc_, int_, att_, fy_, whk_, grt_, con_, xac_.

Listsobject

Every list returns { items, next }. Pass next back as cursor; limit is 1 to 200, default 50. Bounded lists return next: null.

Nullable

Every field is present in every response. Fields that can be absent are null, and marked | null here.

https://api.vexless.io/v1        # reserved; not live yet
Authorization: Bearer vx_…
X-Actor: user:mikko              # every write
Idempotency-Key: <unique>        # every POST
Content-Type: application/json
{ "amount": 125500, "currency": "EUR" }          # Money
"2026-09-03"                                     # date
"2026-09-03T10:16:37.767Z"                       # timestamp
{ "items": [ … ], "next": "pst_…" | null }       # list
{ "rule": "ENTRY_MUST_BALANCE", "message": "…", "path": "/postings" }

Common objects

Shapes every endpoint shares.

Objects

The Money object

Attributes

amountinteger

Integer minor units

currencystring
{
  "amount": integer,
  "currency": string
}

The Error object

Attributes

rulestring
messagestring
pathstring
{
  "rule": string,
  "message": string,
  "path"?: string
}

The Company object

Attributes

idstring
namestring
businessIdentifierstring
jurisdictionstring
currencystring
lockDatestring | null
sandboxboolean
createdAtstring

RFC 3339 timestamp

connectionsobject[]
connections[].idstring
connections[].kindstring
connections[].providerstring
connections[].statusstring
connections[].consentUrlstring | null
externalAccountsobject[]
externalAccounts[].idstring
externalAccounts[].connectionIdstring
externalAccounts[].kindstring
externalAccounts[].externalIdstring
externalAccounts[].accountNumberstring
fiscalYearsFiscalYear[]
{
  "id": string,
  "name": string,
  "businessIdentifier": string,
  "jurisdiction": string,
  "currency": string,
  "lockDate": string | null,
  "sandbox": boolean,
  "createdAt": string,
  "connections": [
    {
      "id": string,
      "kind": string,
      "provider": string,
      "status": string,
      "consentUrl": string | null
    }
  ],
  "externalAccounts": [
    {
      "id": string,
      "connectionId": string,
      "kind": string,
      "externalId": string,
      "accountNumber": string
    }
  ],
  "fiscalYears": [ FiscalYear ]
}

The CompanySummary object

Attributes

idstring
namestring
businessIdentifierstring
jurisdictionstring
currencystring
lockDatestring | null
sandboxboolean
createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "name": string,
  "businessIdentifier": string,
  "jurisdiction": string,
  "currency": string,
  "lockDate": string | null,
  "sandbox": boolean,
  "createdAt": string
}

The FiscalYear object

Attributes

idstring
startDatestring

ISO date YYYY-MM-DD

endDatestring

ISO date YYYY-MM-DD

closedAtstring | null
closedBystring | null
resultAmountinteger | null
closingOriginIdstring | null
openingOriginIdstring | null
{
  "id": string,
  "startDate": string,
  "endDate": string,
  "closedAt": string | null,
  "closedBy": string | null,
  "resultAmount": integer | null,
  "closingOriginId": string | null,
  "openingOriginId": string | null
}

Create a company

POST/v1/companies

scope · any key

Body parameters

namestringrequired
businessIdentifierstringrequired
jurisdictionFIrequired
sandboxboolean
fiscalYearStartstring

Returns

201 Company. Errors 400401403404409413422 as Error.

POST /v1/companies
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "name": string,
  "businessIdentifier": string,
  "jurisdiction": "FI",
  "sandbox"?: boolean,
  "fiscalYearStart"?: string
}
Company {
  "id": string,
  "name": string,
  "businessIdentifier": string,
  "jurisdiction": string,
  "currency": string,
  "lockDate": string | null,
  "sandbox": boolean,
  "createdAt": string,
  "connections": [ { … } ],
  "externalAccounts": [ { … } ],
  "fiscalYears": [ FiscalYear ]
}

List the companies your partner holds a grant on

GET/v1/companies

scope · any key

Query parameters

cursorstring
limitinteger

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies?cursor=&limit=
Authorization: Bearer vx_…
{
  "items": [ CompanySummary ],
  "next": string | null
}

Get a company with its connections, external accounts and fiscal years

GET/v1/companies/{companyId}

scope · ledger:read

Path parameters

companyIdstring

Returns

200 Company. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}
Authorization: Bearer vx_…
Company {
  "id": string,
  "name": string,
  "businessIdentifier": string,
  "jurisdiction": string,
  "currency": string,
  "lockDate": string | null,
  "sandbox": boolean,
  "createdAt": string,
  "connections": [ { … } ],
  "externalAccounts": [ { … } ],
  "fiscalYears": [ FiscalYear ]
}

Grant scopes on a company to a partner

POST/v1/companies/{companyId}/grants

scope · grants:manage

Path parameters

companyIdstring

Body parameters

granteeKindVERTICAL | OFFICE | AGENT | OWNERrequired
granteeIdstringrequired

Partner id

scopesorigins:write | ledger:read | settlements:write | payments:write | connections:manage | review:write | accounts:manage | close:manage | grants:manage[]required

Returns

201. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/grants
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "granteeKind": "VERTICAL" | "OFFICE" | "AGENT" | "OWNER",
  "granteeId": string,
  "scopes": [ "origins:write" | "ledger:read" | "settlements:write" | "payments:write" | "connections:manage" | "review:write" | "accounts:manage" | "close:manage" | "grants:manage" ]
}
{
  "id": string
}

Revoke a grant

DELETE/v1/companies/{companyId}/grants/{grantId}

scope · grants:manage

Path parameters

companyIdstring
grantIdstring

Returns

200. Errors 400401403404409413422 as Error.

DELETE /v1/companies/{companyId}/grants/{grantId}
Authorization: Bearer vx_…
X-Actor: user:mikko
{
  "ok": true
}

The Account object

Attributes

idstring
numberstring
namestring
typestring
openItemsboolean
statusstring
reportingCodestring | null
createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "number": string,
  "name": string,
  "type": string,
  "openItems": boolean,
  "status": string,
  "reportingCode": string | null,
  "createdAt": string
}

The TaxCode object

Attributes

jurisdictionstring
codestring

The identity of a tax code; postings store this

namestring
kindstring
rateBpsinteger
validFromstring

ISO date YYYY-MM-DD

validTostring | null
returnLinestring
vatAccountNumberstring
{
  "jurisdiction": string,
  "code": string,
  "name": string,
  "kind": string,
  "rateBps": integer,
  "validFrom": string,
  "validTo": string | null,
  "returnLine": string,
  "vatAccountNumber": string
}

The DimensionCategory object

Attributes

idstring
namestring
requiredOnAccountsobject[]
requiredOnAccounts[].fromstring
requiredOnAccounts[].tostring
dimensionsobject[]
dimensions[].idstring
dimensions[].namestring
{
  "id": string,
  "name": string,
  "requiredOnAccounts": [
    {
      "from": string,
      "to": string
    }
  ],
  "dimensions": [
    {
      "id": string,
      "name": string
    }
  ]
}

List the chart of accounts

GET/v1/companies/{companyId}/accounts

scope · ledger:read

Path parameters

companyIdstring

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/accounts
Authorization: Bearer vx_…
{
  "items": [ Account ],
  "next": string | null
}

Add an account

POST/v1/companies/{companyId}/accounts

scope · accounts:manage

Path parameters

companyIdstring

Body parameters

numberstringrequired
namestringrequired
typeASSET | LIABILITY | EQUITY | REVENUE | EXPENSErequired
openItemsboolean
reportingCodestring

Returns

201. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/accounts
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "number": string,
  "name": string,
  "type": "ASSET" | "LIABILITY" | "EQUITY" | "REVENUE" | "EXPENSE",
  "openItems"?: boolean,
  "reportingCode"?: string
}
{
  "id": string
}

List tax codes for a jurisdiction

GET/v1/tax-codes

scope · any key

Query parameters

jurisdictionstring

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/tax-codes?jurisdiction=
Authorization: Bearer vx_…
{
  "items": [ TaxCode ],
  "next": string | null
}

List dimension categories and dimensions

GET/v1/companies/{companyId}/dimensions

scope · ledger:read

Path parameters

companyIdstring

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/dimensions
Authorization: Bearer vx_…
{
  "items": [ DimensionCategory ],
  "next": string | null
}

Create a dimension, and its category on first use

POST/v1/companies/{companyId}/dimensions

scope · origins:write

Path parameters

companyIdstring

Body parameters

categorystringrequired
namestringrequired
requiredOnAccountsobject[]
requiredOnAccounts[].fromstringrequired
requiredOnAccounts[].tostringrequired

Returns

201. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/dimensions
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "category": string,
  "name": string,
  "requiredOnAccounts"?: [
    {
      "from": string,
      "to": string
    }
  ]
}
{
  "id": string,
  "categoryId": string
}

The Party object

Attributes

partyIdstring

Also the paging cursor

namestring

The name this company knows the party by

countrystring | null
rolesstring[]
externalIdstring | null
defaultAccountNumberstring | null
defaultTaxCodestring | null
identifiersobject[]

Identifiers this company supplied

identifiers[].schemestring
identifiers[].valuestring
identifiers[].sourcestring
createdAtstring

RFC 3339 timestamp

{
  "partyId": string,
  "name": string,
  "country": string | null,
  "roles": [ string ],
  "externalId": string | null,
  "defaultAccountNumber": string | null,
  "defaultTaxCode": string | null,
  "identifiers": [
    {
      "scheme": string,
      "value": string,
      "source": string
    }
  ],
  "createdAt": string
}

List parties as this company knows them

GET/v1/companies/{companyId}/parties

scope · ledger:read

Path parameters

companyIdstring

Query parameters

externalIdstring
cursorstring
limitinteger

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/parties?externalId=&cursor=&limit=
Authorization: Bearer vx_…
{
  "items": [ Party ],
  "next": string | null
}

Update your name, external id, IBAN or defaults for a party

PATCH/v1/companies/{companyId}/parties/{partyId}

scope · origins:write; defaults need accounts:manage

Path parameters

companyIdstring
partyIdstring

Body parameters

namestring

The name this company knows the party by

externalIdstring | null
defaultAccountNumberstring | null
defaultTaxCodestring | null
ibanstring

Returns

200 Party. Errors 400401403404409413422 as Error.

PATCH /v1/companies/{companyId}/parties/{partyId}
Authorization: Bearer vx_…
X-Actor: user:mikko
Content-Type: application/json

{
  "name"?: string,
  "externalId"?: string | null,
  "defaultAccountNumber"?: string | null,
  "defaultTaxCode"?: string | null,
  "iban"?: string
}
Party {
  "partyId": string,
  "name": string,
  "country": string | null,
  "roles": [ string ],
  "externalId": string | null,
  "defaultAccountNumber": string | null,
  "defaultTaxCode": string | null,
  "identifiers": [ { … } ],
  "createdAt": string
}

Start a bank connection; returns a consent link

POST/v1/companies/{companyId}/connections

scope · connections:manage

Path parameters

companyIdstring

Body parameters

kindBANKrequired
providerstringrequired

Returns

201. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/connections
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "kind": "BANK",
  "provider": string
}
{
  "id": string,
  "status": string,
  "consentUrl": string | null
}

Origins

The document behind every entry: sales invoice, purchase invoice, bank transaction or manual entry. Sent with postings it posts in the same call; without them it waits.

The Origin object

Attributes

idstring
typestring
statusstring

RECEIVED | POSTED | SETTLED | REJECTED | REVERSED

partiesobject[]
parties[].rolestring
parties[].partyIdstring
parties[].namestring | null
parties[].externalIdstring | null
counterpartyIdstring | null
documentDatestring

ISO date YYYY-MM-DD

dueDatestring | null
currencystring
totalMoney
externalReferencestring | null
paymentReferencestring | null
invoiceNumberinteger | null
linesobject[]
dataobject
settlementSettlementState | null
settlement.stateunpaid | partial | settled
settlement.paidinteger
settlement.remaininginteger
settlement.paidAtstring | null
settlement.paidBystring[]

Origins that paid this one

settlement.currencystring
deliveryobject | null
delivery.channelstring
delivery.statusstring
currentInterpretationIdstring | null

The accepted interpretation behind the current entry; null until the origin is interpreted

attachmentsAttachment[]
createdBystring
createdAtstring

RFC 3339 timestamp

updatedAtstring

RFC 3339 timestamp

entriesEntry[]
paymentsobject[]
payments[].idstring
payments[].statusstring
payments[].amountMoney
payments[].executeOnstring

ISO date YYYY-MM-DD

payments[].bankTransactionOriginIdstring | null
interpretationsInterpretation[]

Present with ?explain=true

{
  "id": string,
  "type": string,
  "status": string,
  "parties": [
    {
      "role": string,
      "partyId": string,
      "name": string | null,
      "externalId": string | null
    }
  ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": {
    "channel": string,
    "status": string
  } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [
    {
      "id": string,
      "status": string,
      "amount": Money,
      "executeOn": string,
      "bankTransactionOriginId": string | null
    }
  ],
  "interpretations"?: [ Interpretation ]
}

The Attachment object

Attributes

idstring
originIdstring
filenamestring
mediaTypestring
sizeinteger
hashstring
retentionUntilstring | null
createdBystring
createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "originId": string,
  "filename": string,
  "mediaType": string,
  "size": integer,
  "hash": string,
  "retentionUntil": string | null,
  "createdBy": string,
  "createdAt": string
}

The Interpretation object

Attributes

idstring
versioninteger
actorstring

Who authored these postings

statusstring

ACCEPTED | SUPERSEDED

postingsobject[]
reasonstring | null
createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "version": integer,
  "actor": string,
  "status": string,
  "postings": [ { … } ],
  "reason": string | null,
  "createdAt": string
}

The SettlementState object

Attributes

stateunpaid | partial | settled
paidinteger
remaininginteger
paidAtstring | null
paidBystring[]

Origins that paid this one

currencystring
{
  "state": "unpaid" | "partial" | "settled",
  "paid": integer,
  "remaining": integer,
  "paidAt": string | null,
  "paidBy": [ string ],
  "currency": string
}

Send a document: sales invoice, purchase invoice, bank transaction or manual entry

POST/v1/companies/{companyId}/origins

scope · origins:write

Path parameters

companyIdstring

Query parameters

dryRunboolean

Body parameters

type = SALES_INVOICE
typeSALES_INVOICErequired
externalReferencestring

Your id for the invoice

buyerobjectrequired

Any one identifier is enough; Vexless resolves or creates the party

buyer.partyIdstring
buyer.namestring
buyer.businessIdstring

Y-tunnus / business identifier

buyer.vatIdstring
buyer.ibanstring
buyer.einvoiceAddressstring
buyer.externalIdstring

Your id for this party

buyer.countrystring
documentDatestring
dueDatestringrequired
currencystring
fxRatenumber

Required when currency differs from the company currency

linesobject[]required
lines[].descriptionstringrequired
lines[].netintegerrequired

Net amount in the origin currency; negative on credit notes

lines[].taxCodestring

e.g. FI_SALE_25_5; company default when omitted

lines[].vatinteger

Explicit VAT; authoritative on purchase invoices

lines[].dimensionIdsstring[]
lines[].quantitynumber
lines[].unitstring
totalinteger

Gross total as issued; validated against lines

postingsobject[]

What this origin means in the ledger. Omit to leave the origin awaiting an interpretation

postings[].accountNumberstringrequired
postings[].amountintegerrequired

Integer minor units (cents)

postings[].partyIdstring
postings[].taxCodestring
postings[].dimensionIdsstring[]
postings[].descriptionstring
dataobject
type = PURCHASE_INVOICE
typePURCHASE_INVOICErequired
externalReferencestring

Supplier's invoice number

sellerobjectrequired

Any one identifier is enough; Vexless resolves or creates the party

seller.partyIdstring
seller.namestring
seller.businessIdstring

Y-tunnus / business identifier

seller.vatIdstring
seller.ibanstring
seller.einvoiceAddressstring
seller.externalIdstring

Your id for this party

seller.countrystring
documentDatestringrequired
dueDatestring
currencystring
fxRatenumber
linesobject[]required
lines[].descriptionstringrequired
lines[].netintegerrequired

Net amount in the origin currency; negative on credit notes

lines[].taxCodestring

e.g. FI_SALE_25_5; company default when omitted

lines[].vatinteger

Explicit VAT; authoritative on purchase invoices

lines[].dimensionIdsstring[]
lines[].quantitynumber
lines[].unitstring
totalinteger

Gross total as printed; validated against lines

paymentReferencestring

Supplier's payment reference (RF or Finnish)

postingsobject[]

What this origin means in the ledger. Omit to leave the origin awaiting an interpretation

postings[].accountNumberstringrequired
postings[].amountintegerrequired

Integer minor units (cents)

postings[].partyIdstring
postings[].taxCodestring
postings[].dimensionIdsstring[]
postings[].descriptionstring
dataobject
type = BANK_TRANSACTION
typeBANK_TRANSACTIONrequired
externalIdstringrequired

The bank's transaction id

externalAccountIdstring
ibanstring

The company's own account; alternative to externalAccountId

amountintegerrequired

Signed; positive = money in

bookingDatestringrequired
valueDatestring
counterpartyobject

Any one identifier is enough; Vexless resolves or creates the party

counterparty.partyIdstring
counterparty.namestring
counterparty.businessIdstring

Y-tunnus / business identifier

counterparty.vatIdstring
counterparty.ibanstring
counterparty.einvoiceAddressstring
counterparty.externalIdstring

Your id for this party

counterparty.countrystring
referencestring
messagestring
currencystring
fxRatenumber
postingsobject[]

What this origin means in the ledger. Omit to leave the origin awaiting an interpretation

postings[].accountNumberstringrequired
postings[].amountintegerrequired

Integer minor units (cents)

postings[].partyIdstring
postings[].taxCodestring
postings[].dimensionIdsstring[]
postings[].descriptionstring
settlesobject[]

Origins whose open items these postings clear; needs postings

settles[].originIdstringrequired
settles[].amountinteger

Integer minor units (cents)

type = MANUAL
typeMANUALrequired
descriptionstringrequired
documentDatestringrequired
externalReferencestring
counterpartyobject

Any one identifier is enough; Vexless resolves or creates the party

counterparty.partyIdstring
counterparty.namestring
counterparty.businessIdstring

Y-tunnus / business identifier

counterparty.vatIdstring
counterparty.ibanstring
counterparty.einvoiceAddressstring
counterparty.externalIdstring

Your id for this party

counterparty.countrystring
postingsobject[]required
postings[].accountNumberstringrequired
postings[].amountintegerrequired

Integer minor units (cents)

postings[].partyIdstring
postings[].taxCodestring
postings[].dimensionIdsstring[]
postings[].descriptionstring
dataobject

Returns

200, 201 Origin. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/origins?dryRun=
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "type": "SALES_INVOICE",
  "externalReference"?: string,
  "buyer": {
    "partyId"?: string,
    "name"?: string,
    "businessId"?: string,
    "vatId"?: string,
    "iban"?: string,
    "einvoiceAddress"?: string,
    "externalId"?: string,
    "country"?: string
  },
  "documentDate"?: string,
  "dueDate": string,
  "currency"?: string,
  "fxRate"?: number,
  "lines": [
    {
      "description": string,
      "net": integer,
      "taxCode"?: string,
      "vat"?: integer,
      "dimensionIds"?: [ string ],
      "quantity"?: number,
      "unit"?: string
    }
  ],
  "total"?: integer,
  "postings"?: [
    {
      "accountNumber": string,
      "amount": integer,
      "partyId"?: string,
      "taxCode"?: string,
      "dimensionIds"?: [ string ],
      "description"?: string
    }
  ],
  "data"?: { … }
}
POST /v1/companies/{companyId}/origins?dryRun=
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "type": "PURCHASE_INVOICE",
  "externalReference"?: string,
  "seller": {
    "partyId"?: string,
    "name"?: string,
    "businessId"?: string,
    "vatId"?: string,
    "iban"?: string,
    "einvoiceAddress"?: string,
    "externalId"?: string,
    "country"?: string
  },
  "documentDate": string,
  "dueDate"?: string,
  "currency"?: string,
  "fxRate"?: number,
  "lines": [
    {
      "description": string,
      "net": integer,
      "taxCode"?: string,
      "vat"?: integer,
      "dimensionIds"?: [ string ],
      "quantity"?: number,
      "unit"?: string
    }
  ],
  "total"?: integer,
  "paymentReference"?: string,
  "postings"?: [
    {
      "accountNumber": string,
      "amount": integer,
      "partyId"?: string,
      "taxCode"?: string,
      "dimensionIds"?: [ string ],
      "description"?: string
    }
  ],
  "data"?: { … }
}
POST /v1/companies/{companyId}/origins?dryRun=
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "type": "BANK_TRANSACTION",
  "externalId": string,
  "externalAccountId"?: string,
  "iban"?: string,
  "amount": integer,
  "bookingDate": string,
  "valueDate"?: string,
  "counterparty"?: {
    "partyId"?: string,
    "name"?: string,
    "businessId"?: string,
    "vatId"?: string,
    "iban"?: string,
    "einvoiceAddress"?: string,
    "externalId"?: string,
    "country"?: string
  },
  "reference"?: string,
  "message"?: string,
  "currency"?: string,
  "fxRate"?: number,
  "postings"?: [
    {
      "accountNumber": string,
      "amount": integer,
      "partyId"?: string,
      "taxCode"?: string,
      "dimensionIds"?: [ string ],
      "description"?: string
    }
  ],
  "settles"?: [
    {
      "originId": string,
      "amount"?: integer
    }
  ]
}
POST /v1/companies/{companyId}/origins?dryRun=
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "type": "MANUAL",
  "description": string,
  "documentDate": string,
  "externalReference"?: string,
  "counterparty"?: {
    "partyId"?: string,
    "name"?: string,
    "businessId"?: string,
    "vatId"?: string,
    "iban"?: string,
    "einvoiceAddress"?: string,
    "externalId"?: string,
    "country"?: string
  },
  "postings": [
    {
      "accountNumber": string,
      "amount": integer,
      "partyId"?: string,
      "taxCode"?: string,
      "dimensionIds"?: [ string ],
      "description"?: string
    }
  ],
  "data"?: { … }
}
{
  "id": string,
  "type": string,
  "status": string,
  "parties": [ { … } ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": {
    "channel": string,
    "status": string
  } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [ { … } ],
  "interpretations"?: [ Interpretation ],
  "dryRun": true
}
Origin {
  "id": string,
  "type": string,
  "status": string,
  "parties": [ { … } ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": { … } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [ { … } ],
  "interpretations"?: [ Interpretation ]
}

List origins

GET/v1/companies/{companyId}/origins

scope · ledger:read

Path parameters

companyIdstring

Query parameters

typeSALES_INVOICE | PURCHASE_INVOICE | BANK_TRANSACTION | MANUAL | SYSTEM | PAYROLL
statusRECEIVED | POSTED | SETTLED | REJECTED | REVERSED
partyIdstring
fromstring
tostring
externalReferencestring
settlementStateunpaid | partial | settled
cursorstring
limitinteger

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/origins?type=&status=&partyId=&from=&to=&externalReference=&settlementState=&cursor=&limit=
Authorization: Bearer vx_…
{
  "items": [ Origin ],
  "next": string | null
}

Get an origin with its entries, settlement and payments

GET/v1/companies/{companyId}/origins/{originId}

scope · ledger:read

Path parameters

companyIdstring
originIdstring

Query parameters

explainboolean

Returns

200 Origin. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/origins/{originId}?explain=
Authorization: Bearer vx_…
Origin {
  "id": string,
  "type": string,
  "status": string,
  "parties": [ { … } ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": { … } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [ { … } ],
  "interpretations"?: [ Interpretation ]
}

Reverse a posted origin with a negated entry

POST/v1/companies/{companyId}/origins/{originId}/reverse

scope · origins:write for origins you delivered; review:write for any

Path parameters

companyIdstring
originIdstring

Body parameters

reasonstring

Returns

200 Origin. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/origins/{originId}/reverse
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "reason"?: string
} | null
Origin {
  "id": string,
  "type": string,
  "status": string,
  "parties": [ { … } ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": { … } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [ { … } ],
  "interpretations"?: [ Interpretation ]
}

Attach a file to an origin

POST/v1/companies/{companyId}/origins/{originId}/attachments

scope · origins:write

Path parameters

companyIdstring
originIdstring

Body parameters

filenamestringrequired
mediaTypestringrequired

e.g. application/pdf, image/jpeg

contentBase64stringrequired

File content, base64; at most 10 MB decoded

Returns

201 Attachment. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/origins/{originId}/attachments
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "filename": string,
  "mediaType": string,
  "contentBase64": string
}
Attachment {
  "id": string,
  "originId": string,
  "filename": string,
  "mediaType": string,
  "size": integer,
  "hash": string,
  "retentionUntil": string | null,
  "createdBy": string,
  "createdAt": string
}

List an origin's attachments

GET/v1/companies/{companyId}/origins/{originId}/attachments

scope · ledger:read

Path parameters

companyIdstring
originIdstring

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/origins/{originId}/attachments
Authorization: Bearer vx_…
{
  "items": [ Attachment ],
  "next": string | null
}

Download an attachment

GET/v1/companies/{companyId}/origins/{originId}/attachments/{attachmentId}

scope · ledger:read

Returns the file bytes with its media type; not JSON.

Path parameters

companyIdstring
originIdstring
attachmentIdstring

Returns

200 file bytes.

GET /v1/companies/{companyId}/origins/{originId}/attachments/{attachmentId}
Authorization: Bearer vx_…
File bytes with the attachment's media type

Reject an origin before it is interpreted

POST/v1/companies/{companyId}/origins/{originId}/reject

scope · review:write

Path parameters

companyIdstring
originIdstring

Body parameters

reasonstring

Returns

200 Origin. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/origins/{originId}/reject
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "reason"?: string
} | null
Origin {
  "id": string,
  "type": string,
  "status": string,
  "parties": [ { … } ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": { … } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [ { … } ],
  "interpretations"?: [ Interpretation ]
}

Say what an origin means in postings; posted in the same call

POST/v1/companies/{companyId}/origins/{originId}/interpretations

scope · origins:write for an origin still awaiting its first interpretation, review:write to re-interpret a posted one

Path parameters

companyIdstring
originIdstring

Body parameters

postingsobject[]required
postings[].accountNumberstringrequired
postings[].amountintegerrequired

Integer minor units (cents)

postings[].partyIdstring
postings[].taxCodestring
postings[].dimensionIdsstring[]
postings[].descriptionstring
reasonstring

Returns

201 Origin. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/origins/{originId}/interpretations
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "postings": [
    {
      "accountNumber": string,
      "amount": integer,
      "partyId"?: string,
      "taxCode"?: string,
      "dimensionIds"?: [ string ],
      "description"?: string
    }
  ],
  "reason"?: string
}
Origin {
  "id": string,
  "type": string,
  "status": string,
  "parties": [ { … } ],
  "counterpartyId": string | null,
  "documentDate": string,
  "dueDate": string | null,
  "currency": string,
  "total": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "lines": [ { … } ],
  "data": { … },
  "settlement": SettlementState | null,
  "delivery": { … } | null,
  "currentInterpretationId": string | null,
  "attachments": [ Attachment ],
  "createdBy": string,
  "createdAt": string,
  "updatedAt": string,
  "entries": [ Entry ],
  "payments": [ { … } ],
  "interpretations"?: [ Interpretation ]
}

The Entry object

Attributes

idstring
revisioninteger

Bumped each time the entry is rewritten while its period is open

numberinteger
datestring

ISO date YYYY-MM-DD

descriptionstring
originIdstring
interpretationIdstring

The interpretation these postings came from

actorstring
reversesEntryIdstring | null
createdAtstring

RFC 3339 timestamp

updatedAtstring

RFC 3339 timestamp

postingsPosting[]
{
  "id": string,
  "revision": integer,
  "number": integer,
  "date": string,
  "description": string,
  "originId": string,
  "interpretationId": string,
  "actor": string,
  "reversesEntryId": string | null,
  "createdAt": string,
  "updatedAt": string,
  "postings": [ Posting ]
}

The Posting object

Attributes

idstring
accountIdstring
accountNumberstring
accountNamestring
amountinteger

Book currency, signed; debit positive

currencystring
originalAmountinteger | null
originalCurrencystring | null
fxRatenumber | null
partyIdstring | null
taxCodestring | null
taxRateBpsinteger | null

The rate that applied when this was booked, not the code's rate today

dimensionIdsstring[]
descriptionstring | null
remaininginteger | null

Open-item accounts only; signed like amount

{
  "id": string,
  "accountId": string,
  "accountNumber": string,
  "accountName": string,
  "amount": integer,
  "currency": string,
  "originalAmount": integer | null,
  "originalCurrency": string | null,
  "fxRate": number | null,
  "partyId": string | null,
  "taxCode": string | null,
  "taxRateBps": integer | null,
  "dimensionIds": [ string ],
  "description": string | null,
  "remaining": integer | null
}

The OpenItem object

Attributes

idstring

Posting id; the paging cursor

postingIdstring
originIdstring
originTypestring
entryIdstring
accountNumberstring
accountNamestring
partyIdstring | null
partyNamestring | null
partyExternalIdstring | null
directionreceivable | payable
amountMoney
remainingMoney
externalReferencestring | null
paymentReferencestring | null
invoiceNumberinteger | null
documentDatestring

ISO date YYYY-MM-DD

dueDatestring | null
{
  "id": string,
  "postingId": string,
  "originId": string,
  "originType": string,
  "entryId": string,
  "accountNumber": string,
  "accountName": string,
  "partyId": string | null,
  "partyName": string | null,
  "partyExternalId": string | null,
  "direction": "receivable" | "payable",
  "amount": Money,
  "remaining": Money,
  "externalReference": string | null,
  "paymentReference": string | null,
  "invoiceNumber": integer | null,
  "documentDate": string,
  "dueDate": string | null
}

The Balances object

Attributes

asOfstring | null
fromstring | null

When set, balance is the movement in [from, asOf]

currencystring
accountsobject[]
accounts[].accountIdstring
accounts[].numberstring
accounts[].namestring
accounts[].typestring
accounts[].reportingCodestring | null
accounts[].balanceinteger
{
  "asOf": string | null,
  "from": string | null,
  "currency": string,
  "accounts": [
    {
      "accountId": string,
      "number": string,
      "name": string,
      "type": string,
      "reportingCode": string | null,
      "balance": integer
    }
  ]
}

The IncomeStatement object

Attributes

fromstring | null
tostring | null
currencystring
linesobject[]
lines[].codestring
lines[].labelstring
lines[].amountinteger
resultMoney
{
  "from": string | null,
  "to": string | null,
  "currency": string,
  "lines": [
    {
      "code": string,
      "label": string,
      "amount": integer
    }
  ],
  "result": Money
}

The BalanceSheet object

Attributes

asOfstring | null
currencystring
assetsobject[]
assets[].codestring
assets[].labelstring
assets[].amountinteger
equityAndLiabilitiesobject[]
equityAndLiabilities[].codestring
equityAndLiabilities[].labelstring
equityAndLiabilities[].amountinteger
totalsobject
totals.assetsMoney
totals.equityAndLiabilitiesMoney
{
  "asOf": string | null,
  "currency": string,
  "assets": [
    {
      "code": string,
      "label": string,
      "amount": integer
    }
  ],
  "equityAndLiabilities": [
    {
      "code": string,
      "label": string,
      "amount": integer
    }
  ],
  "totals": {
    "assets": Money,
    "equityAndLiabilities": Money
  }
}

List current ledger entries

GET/v1/companies/{companyId}/entries

scope · ledger:read

Path parameters

companyIdstring

Query parameters

fromstring
tostring
accountstring
cursorstring
limitinteger

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/entries?from=&to=&account=&cursor=&limit=
Authorization: Bearer vx_…
{
  "items": [ Entry ],
  "next": string | null
}

Get an entry

GET/v1/companies/{companyId}/entries/{entryId}

scope · ledger:read

Path parameters

companyIdstring
entryIdstring

Returns

200 Entry. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/entries/{entryId}
Authorization: Bearer vx_…
Entry {
  "id": string,
  "revision": integer,
  "number": integer,
  "date": string,
  "description": string,
  "originId": string,
  "interpretationId": string,
  "actor": string,
  "reversesEntryId": string | null,
  "createdAt": string,
  "updatedAt": string,
  "postings": [ Posting ]
}

Balances per account, cumulative or for a range

GET/v1/companies/{companyId}/balances

scope · ledger:read

Path parameters

companyIdstring

Query parameters

asOfstring
fromstring

With from, balances are movements in [from, asOf]

fiscalYearIdstring

Shorthand for from and asOf of that year

accountsstring

Comma-separated account numbers

dimensionIdstring

Returns

200 Balances. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/balances?asOf=&from=&fiscalYearId=&accounts=&dimensionId=
Authorization: Bearer vx_…
Balances {
  "asOf": string | null,
  "from": string | null,
  "currency": string,
  "accounts": [ { … } ]
}

Open receivables and payables

GET/v1/companies/{companyId}/open-items

scope · ledger:read

Path parameters

companyIdstring

Query parameters

directionreceivable | payable
partyIdstring
dueBeforestring
accountstring
cursorstring
limitinteger

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/open-items?direction=&partyId=&dueBefore=&account=&cursor=&limit=
Authorization: Bearer vx_…
{
  "items": [ OpenItem ],
  "next": string | null
}

Income statement for a range or a fiscal year

GET/v1/companies/{companyId}/reports/income-statement

scope · ledger:read

Path parameters

companyIdstring

Query parameters

fromstring
tostring
fiscalYearIdstring

Returns

200 IncomeStatement. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/reports/income-statement?from=&to=&fiscalYearId=
Authorization: Bearer vx_…
IncomeStatement {
  "from": string | null,
  "to": string | null,
  "currency": string,
  "lines": [ { … } ],
  "result": Money
}

Balance sheet at a date

GET/v1/companies/{companyId}/reports/balance-sheet

scope · ledger:read

Path parameters

companyIdstring

Query parameters

asOfstring

Returns

200 BalanceSheet. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/reports/balance-sheet?asOf=
Authorization: Bearer vx_…
BalanceSheet {
  "asOf": string | null,
  "currency": string,
  "assets": [ { … } ],
  "equityAndLiabilities": [ { … } ],
  "totals": { … }
}

The Settlement object

Attributes

idstring
accountNumberstring
statusstring
closedAtstring | null
closedBystring | null
createdAtstring

RFC 3339 timestamp

allocationsobject[]
allocations[].idstring
allocations[].debitPostingIdstring
allocations[].creditPostingIdstring
allocations[].amountinteger
allocations[].basisstring
allocations[].actorstring
allocations[].createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "accountNumber": string,
  "status": string,
  "closedAt": string | null,
  "closedBy": string | null,
  "createdAt": string,
  "allocations": [
    {
      "id": string,
      "debitPostingId": string,
      "creditPostingId": string,
      "amount": integer,
      "basis": string,
      "actor": string,
      "createdAt": string
    }
  ]
}

Allocate open items explicitly

POST/v1/companies/{companyId}/settlements

scope · settlements:write

Path parameters

companyIdstring

Body parameters

allocationsobject[]required
allocations[].debitPostingIdstringrequired
allocations[].creditPostingIdstringrequired
allocations[].amountintegerrequired

Integer minor units (cents)

Returns

201 Settlement. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/settlements
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "allocations": [
    {
      "debitPostingId": string,
      "creditPostingId": string,
      "amount": integer
    }
  ]
}
Settlement {
  "id": string,
  "accountNumber": string,
  "status": string,
  "closedAt": string | null,
  "closedBy": string | null,
  "createdAt": string,
  "allocations": [ { … } ]
}

Get a settlement with its allocations

GET/v1/companies/{companyId}/settlements/{settlementId}

scope · ledger:read

Path parameters

companyIdstring
settlementIdstring

Returns

200 Settlement. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/settlements/{settlementId}
Authorization: Bearer vx_…
Settlement {
  "id": string,
  "accountNumber": string,
  "status": string,
  "closedAt": string | null,
  "closedBy": string | null,
  "createdAt": string,
  "allocations": [ { … } ]
}

Close a settlement by booking the residual

POST/v1/companies/{companyId}/settlements/{settlementId}/close

scope · review:write

Path parameters

companyIdstring
settlementIdstring

Body parameters

kindWRITE_OFF | FX_DIFFERENCE | FEE | YEAR_END | VAT_SETTLEMENT
datestring

Returns

200 Settlement. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/settlements/{settlementId}/close
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "kind"?: "WRITE_OFF" | "FX_DIFFERENCE" | "FEE" | "YEAR_END" | "VAT_SETTLEMENT",
  "date"?: string
}
Settlement {
  "id": string,
  "accountNumber": string,
  "status": string,
  "closedAt": string | null,
  "closedBy": string | null,
  "createdAt": string,
  "allocations": [ { … } ]
}

The Payment object

Attributes

idstring
originIdstring
statusstring
amountMoney
executeOnstring

ISO date YYYY-MM-DD

payeeIbanstring | null
paymentReferencestring | null
bankReferencestring | null
rejectReasonstring | null
bankTransactionOriginIdstring | null
actorstring
createdAtstring

RFC 3339 timestamp

updatedAtstring

RFC 3339 timestamp

{
  "id": string,
  "originId": string,
  "status": string,
  "amount": Money,
  "executeOn": string,
  "payeeIban": string | null,
  "paymentReference": string | null,
  "bankReference": string | null,
  "rejectReason": string | null,
  "bankTransactionOriginId": string | null,
  "actor": string,
  "createdAt": string,
  "updatedAt": string
}

Pay a purchase invoice; the call is the approval

POST/v1/companies/{companyId}/payments

scope · payments:write

Path parameters

companyIdstring

Body parameters

originIdstringrequired
amountinteger

Integer minor units (cents)

executeOnstring

Returns

201 Payment. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/payments
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "originId": string,
  "amount"?: integer,
  "executeOn"?: string
}
Payment {
  "id": string,
  "originId": string,
  "status": string,
  "amount": Money,
  "executeOn": string,
  "payeeIban": string | null,
  "paymentReference": string | null,
  "bankReference": string | null,
  "rejectReason": string | null,
  "bankTransactionOriginId": string | null,
  "actor": string,
  "createdAt": string,
  "updatedAt": string
}

Get a payment

GET/v1/companies/{companyId}/payments/{paymentId}

scope · ledger:read

Path parameters

companyIdstring
paymentIdstring

Returns

200 Payment. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/payments/{paymentId}
Authorization: Bearer vx_…
Payment {
  "id": string,
  "originId": string,
  "status": string,
  "amount": Money,
  "executeOn": string,
  "payeeIban": string | null,
  "paymentReference": string | null,
  "bankReference": string | null,
  "rejectReason": string | null,
  "bankTransactionOriginId": string | null,
  "actor": string,
  "createdAt": string,
  "updatedAt": string
}

Cancel a payment that has not been sent

POST/v1/companies/{companyId}/payments/{paymentId}/cancel

scope · payments:write

Path parameters

companyIdstring
paymentIdstring

Returns

200 Payment. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/payments/{paymentId}/cancel
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Payment {
  "id": string,
  "originId": string,
  "status": string,
  "amount": Money,
  "executeOn": string,
  "payeeIban": string | null,
  "paymentReference": string | null,
  "bankReference": string | null,
  "rejectReason": string | null,
  "bankTransactionOriginId": string | null,
  "actor": string,
  "createdAt": string,
  "updatedAt": string
}

List fiscal years

GET/v1/companies/{companyId}/fiscal-years

scope · ledger:read

Path parameters

companyIdstring

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/fiscal-years
Authorization: Bearer vx_…
{
  "items": [ FiscalYear ],
  "next": string | null
}

Move the lock date forward

POST/v1/companies/{companyId}/lock

scope · close:manage

Path parameters

companyIdstring

Body parameters

throughstringrequired

Returns

200 Company. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/lock
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "through": string
}
Company {
  "id": string,
  "name": string,
  "businessIdentifier": string,
  "jurisdiction": string,
  "currency": string,
  "lockDate": string | null,
  "sandbox": boolean,
  "createdAt": string,
  "connections": [ { … } ],
  "externalAccounts": [ { … } ],
  "fiscalYears": [ FiscalYear ]
}

Close a fiscal year: result to equity, year locked

POST/v1/companies/{companyId}/fiscal-years/{fiscalYearId}/close

scope · close:manage

Path parameters

companyIdstring
fiscalYearIdstring

Returns

200 FiscalYear. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/fiscal-years/{fiscalYearId}/close
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
FiscalYear {
  "id": string,
  "startDate": string,
  "endDate": string,
  "closedAt": string | null,
  "closedBy": string | null,
  "resultAmount": integer | null,
  "closingOriginId": string | null,
  "openingOriginId": string | null
}

Sandbox: the bank accepts and executes a payment

POST/v1/companies/{companyId}/sandbox/payments/{paymentId}/execute

scope · payments:write; sandbox companies only

Path parameters

companyIdstring
paymentIdstring

Body parameters

bookingDatestring

Defaults to today, or to executeOn when that is in the past

Returns

200 Payment. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/sandbox/payments/{paymentId}/execute
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "bookingDate"?: string
} | null
Payment {
  "id": string,
  "originId": string,
  "status": string,
  "amount": Money,
  "executeOn": string,
  "payeeIban": string | null,
  "paymentReference": string | null,
  "bankReference": string | null,
  "rejectReason": string | null,
  "bankTransactionOriginId": string | null,
  "actor": string,
  "createdAt": string,
  "updatedAt": string
}

Sandbox: the bank rejects a payment

POST/v1/companies/{companyId}/sandbox/payments/{paymentId}/reject

scope · payments:write; sandbox companies only

Path parameters

companyIdstring
paymentIdstring

Body parameters

reasonstring

Returns

200 Payment. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/sandbox/payments/{paymentId}/reject
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "reason"?: string
} | null
Payment {
  "id": string,
  "originId": string,
  "status": string,
  "amount": Money,
  "executeOn": string,
  "payeeIban": string | null,
  "paymentReference": string | null,
  "bankReference": string | null,
  "rejectReason": string | null,
  "bankTransactionOriginId": string | null,
  "actor": string,
  "createdAt": string,
  "updatedAt": string
}

The Webhook object

Attributes

idstring
urlstring
eventsstring[]
statusstring
disabledReasonstring | null

Why delivery was disabled, when it was not disabled by request

lastSuccessAtstring | null

RFC 3339 timestamp

lastFailureAtstring | null

RFC 3339 timestamp

consecutiveFailuresinteger

Failed attempts since the last success

createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "url": string,
  "events": [ string ],
  "status": string,
  "disabledReason": string | null,
  "lastSuccessAt": string | null,
  "lastFailureAt": string | null,
  "consecutiveFailures": integer,
  "createdAt": string
}

Subscribe a URL to events

POST/v1/companies/{companyId}/webhooks

scope · ledger:read

The url must be https and must resolve to a public address.

Path parameters

companyIdstring

Body parameters

urlstring (uri)required
eventsorigin.received | origin.posted | origin.settled | origin.rejected | origin.reversed | invoice.delivered | payment.accepted | payment.rejected | payment.executed | connection.needs_auth | company.locked | fiscal_year.closed | reconciliation.broken | vat_return.filed[]required
secretstring

Returns

201. Errors 400401403404409413422 as Error.

POST /v1/companies/{companyId}/webhooks
Authorization: Bearer vx_…
X-Actor: user:mikko
Idempotency-Key: <unique>
Content-Type: application/json

{
  "url": uri,
  "events": [ "origin.received" | "origin.posted" | "origin.settled" | "origin.rejected" | "origin.reversed" | "invoice.delivered" | "payment.accepted" | "payment.rejected" | "payment.executed" | "connection.needs_auth" | "company.locked" | "fiscal_year.closed" | "reconciliation.broken" | "vat_return.filed" ],
  "secret"?: string
}
{
  "id": string,
  "secret": string
}

List webhooks

GET/v1/companies/{companyId}/webhooks

scope · ledger:read

Path parameters

companyIdstring

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/webhooks
Authorization: Bearer vx_…
{
  "items": [ Webhook ],
  "next": string | null
}

List delivery attempts for a webhook

GET/v1/companies/{companyId}/webhooks/{webhookId}/deliveries

scope · ledger:read

Newest first. One row per event this webhook was sent.

Path parameters

companyIdstring
webhookIdstring

Query parameters

cursorstring
limitinteger

Returns

200. Errors 400401403404409413422 as Error.

GET /v1/companies/{companyId}/webhooks/{webhookId}/deliveries?cursor=&limit=
Authorization: Bearer vx_…
{
  "items": [ Delivery ],
  "next": string | null
}

Disable a webhook

DELETE/v1/companies/{companyId}/webhooks/{webhookId}

scope · ledger:read

Path parameters

companyIdstring
webhookIdstring

Returns

200. Errors 400401403404409413422 as Error.

DELETE /v1/companies/{companyId}/webhooks/{webhookId}
Authorization: Bearer vx_…
X-Actor: user:mikko
{
  "ok": true
}

Liveness check

GET/health

scope · none

Returns

200.

GET /health
Authorization: Bearer vx_…
{
  "ok": boolean
}

The Delivery object

Attributes

idstring
eventIdstring
eventTypestring
statusPENDING | DELIVERED | FAILED
attemptsinteger
lastStatusinteger | null

HTTP status of the last attempt, or null if the request never completed

lastErrorstring | null
nextAttemptAtstring | null

When the next attempt is due; null once delivered or failed

deliveredAtstring | null

RFC 3339 timestamp

failedAtstring | null

Set when the retry ladder ran out; no further attempts are made

createdAtstring

RFC 3339 timestamp

{
  "id": string,
  "eventId": string,
  "eventType": string,
  "status": "PENDING" | "DELIVERED" | "FAILED",
  "attempts": integer,
  "lastStatus": integer | null,
  "lastError": string | null,
  "nextAttemptAt": string | null,
  "deliveredAt": string | null,
  "failedAt": string | null,
  "createdAt": string
}