| Method | Path | Summary |
|---|---|---|
| GET | …/ledger-entries | List ledger entries in the workspace |
| POST | …/ledger-entries/encode-bank-transaction | Apply a set of cash-coding operations to a bank transaction |
| POST | …/ledger-entries/batch-encode-from-transaction-suggestions | Code one or more bank transactions from their accounting suggestion |
| POST | …/ledger-entries/export | Export ledger entries to a downloadable file |
| GET | …/ledger-entries/pre-export | Run pre-export checks on ledger entries before exporting |
| POST | …/ledger-entries/reorder | Reorder ledger entries attached to a bank transaction |
Paths start with /workspaces/{workspaceId}. GET endpoints need ledger-entries:read, the others ledger-entries:write.
The LedgerEntry object
firestoreIdstringrequiredID of the ledger entry.
workspaceIdstringrequiredID of the workspace.
milliAmountnumberrequiredcreditAccountstringcreditAccountSourcestringValuesmanualaibank_accountimportrule
creditBankTransactionobjectShow 3 child fields
firestoreIdstringrequiredID of the bank transaction.
bankAccountIdstringrequiredID of the bank account.
orderintegerrequireddebitAccountstringShow all 18 fieldsHide the field list
debitAccountSourcestringValuesmanualaibank_accountimportrule
debitBankTransactionobjectShow 3 child fields
firestoreIdstringrequiredID of the bank transaction.
bankAccountIdstringrequiredID of the bank account.
orderintegerrequiredtaxRatenumbertaxMilliAmountnumbertaxCodestringtaxIdstringtaxAccountstringtaxDirectionstringValuescreditdebit
descriptionstringdatestringrequiredcreationobjectrequiredWhen and by whom the resource was created.
Show 2 child fields
creationDateTimestringdate-timerequiredDate and time when the resource was created.
createdBystringID of the user who created the resource, when recorded.
{
"firestoreId": "Le3wN8qT5xKr1mZv7pBd",
"workspaceId": "Wk7fQ2xR9bLm4tZp8sNv",
"milliAmount": 0,
"creditAccount": "string",
"creditAccountSource": "manual",
"creditBankTransaction": {
"firestoreId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"order": 0
},
"debitAccount": "string",
"debitAccountSource": "manual",
"debitBankTransaction": {
"firestoreId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"order": 0
},
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"taxDirection": "credit",
"description": "string",
"date": "2026-03-02",
"creation": {
"creationDateTime": "2026-03-02T09:15:00.000Z",
"createdBy": "Xq3vT9mB2kLpR7sN4wYc8dZf1aHj"
}
}/workspaces/{workspaceId}/ledger-entriesList ledger entries in the workspace
Scopeledger-entries:read
Path parameters
workspaceIdstringrequiredID of the workspace.
Query parameters
limitintegerMaximum number of items to return, from 1 to 100. A missing, invalid or non-positive value falls back to 20, and a larger value to 100.
Default20
startAfterstringCursor of the page to return: the nextCursor of the previous page.
fieldsstringComma-separated property paths to include in the response, or in each item of a list. Use dots for nested paths.
idsstring[]Comma-separated IDs of the items to return, up to 30. When set, limit, startAfter and the filters are ignored.
Returns
List of items
Items of the page, in list order.
limitintegerrequiredPage size of the request, or the number of requested ids.
nextCursorstringCursor of the next page, to pass as startAfter. Absent when the page holds fewer items than limit; a full last page still has one, and the page it points to is empty.
curl 'https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries' \
-H "Authorization: Bearer $SWAY_API_KEY"const response = await fetch('https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries', {
headers: {
Authorization: `Bearer ${process.env.SWAY_API_KEY}`,
},
});
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries",
headers={"Authorization": f"Bearer {os.environ['SWAY_API_KEY']}"},
)
print(response.json()){
"data": [
{
"firestoreId": "Le3wN8qT5xKr1mZv7pBd",
"workspaceId": "Wk7fQ2xR9bLm4tZp8sNv",
"milliAmount": 0,
"creditAccount": "string",
"creditAccountSource": "manual",
"creditBankTransaction": {
"firestoreId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"order": 0
},
"debitAccount": "string",
"debitAccountSource": "manual",
"debitBankTransaction": {
"firestoreId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"order": 0
},
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"taxDirection": "credit",
"description": "string",
"date": "2026-03-02",
"creation": {
"creationDateTime": "2026-03-02T09:15:00.000Z",
"createdBy": "Xq3vT9mB2kLpR7sN4wYc8dZf1aHj"
}
}
],
"limit": 0,
"nextCursor": "string"
}{
"error": {
"code": "invalid-argument",
"message": "Invalid request"
}
}{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired credentials"
}
}{
"error": {
"code": "permission-denied",
"message": "Missing required scope: invoices:read"
}
}{
"error": {
"code": "not-found",
"message": "Resource not found"
}
}{
"error": {
"code": "internal",
"message": "An internal error occurred"
}
}/workspaces/{workspaceId}/ledger-entries/encode-bank-transactionApply a set of cash-coding operations to a bank transaction
Created ledger entries are appended after the existing ones, in the order they are listed.
Scopeledger-entries:write
Path parameters
workspaceIdstringrequiredID of the workspace.
Query parameters
fieldsstringComma-separated property paths to include in the response, or in each item of a list. Use dots for nested paths.
Request body
bankAccountIdstringrequiredID of the bank account.
bankTransactionIdstringrequiredID of the bank transaction.
operationsobject[]requiredtype: create
descriptionstringtaxRatenumbertaxMilliAmountnumbertaxCodestringtaxIdstringtaxAccountstringsignedMilliAmountnumberrequiredaccountstringtypestringrequiredValuescreate
type: update
ledgerEntryIdstringrequiredID of the ledger entry.
signedMilliAmountnumberaccountstring | nulldescriptionstring | nulltaxRatenumber | nulltaxMilliAmountnumber | nulltaxCodestring | nulltaxIdstring | nulltaxAccountstring | nulltypestringrequiredValuesupdate
type: delete
typestringrequiredValuesdelete
ledgerEntryIdstringrequiredID of the ledger entry.
existingLedgerEntryIdsstring[]ID of the ledger entry.
Returns
Successful response
dataCashCodingResultrequiredShow 2 child fields
entriesobject[]requiredShow 11 child fields
descriptionstringtaxRatenumbertaxMilliAmountnumbertaxCodestringtaxIdstringtaxAccountstringsignedMilliAmountnumberrequiredaccountstringledgerEntryIdstringrequiredID of the ledger entry.
orderintegerrequiredaccountSourcestringValuesmanualaibank_accountimportrule
accountingStatusstringrequiredValuespendingpartially_bookedbooked
curl -X POST 'https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/encode-bank-transaction' \
-H "Authorization: Bearer $SWAY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"operations": [
{
"description": "string",
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"signedMilliAmount": 0,
"account": "string",
"type": "create"
}
],
"existingLedgerEntryIds": [
"Le3wN8qT5xKr1mZv7pBd"
]
}'const response = await fetch('https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/encode-bank-transaction', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SWAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"operations": [
{
"description": "string",
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"signedMilliAmount": 0,
"account": "string",
"type": "create"
}
],
"existingLedgerEntryIds": [
"Le3wN8qT5xKr1mZv7pBd"
]
}),
});
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/encode-bank-transaction",
headers={"Authorization": f"Bearer {os.environ['SWAY_API_KEY']}"},
json={
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"operations": [
{
"description": "string",
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"signedMilliAmount": 0,
"account": "string",
"type": "create",
},
],
"existingLedgerEntryIds": [
"Le3wN8qT5xKr1mZv7pBd",
],
},
)
print(response.json()){
"data": {
"entries": [
{
"description": "string",
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"signedMilliAmount": 0,
"account": "string",
"ledgerEntryId": "Le3wN8qT5xKr1mZv7pBd",
"order": 0,
"accountSource": "manual"
}
],
"accountingStatus": "pending"
}
}{
"error": {
"code": "invalid-argument",
"message": "Invalid request"
}
}{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired credentials"
}
}{
"error": {
"code": "permission-denied",
"message": "Missing required scope: invoices:read"
}
}{
"error": {
"code": "not-found",
"message": "Resource not found"
}
}{
"error": {
"code": "internal",
"message": "An internal error occurred"
}
}/workspaces/{workspaceId}/ledger-entries/batch-encode-from-transaction-suggestionsCode one or more bank transactions from their accounting suggestion
Scopeledger-entries:write
Path parameters
workspaceIdstringrequiredID of the workspace.
Query parameters
fieldsstringComma-separated property paths to include in the response, or in each item of a list. Use dots for nested paths.
Request body
bankAccountIdstringrequiredID of the bank account.
bankTransactionsobject[]requiredShow 2 child fields
bankTransactionIdstringrequiredID of the bank transaction.
existingLedgerEntryIdsstring[]requiredID of the ledger entry.
Returns
Successful response
dataBatchCodingResultrequiredShow 1 child field
resultsobject[]requiredstatus: approved
entriesobject[]requiredShow 11 child fields
descriptionstringtaxRatenumbertaxMilliAmountnumbertaxCodestringtaxIdstringtaxAccountstringsignedMilliAmountnumberrequiredaccountstringledgerEntryIdstringrequiredID of the ledger entry.
orderintegerrequiredaccountSourcestringValuesmanualaibank_accountimportrule
accountingStatusstringrequiredValuespendingpartially_bookedbooked
bankTransactionIdstringrequiredID of the bank transaction.
statusstringrequiredValuesapproved
status: skipped
bankTransactionIdstringrequiredID of the bank transaction.
statusstringrequiredValuesskipped
reasonstringrequiredValuesout-of-datecannot-accept-suggestion
status: failed
bankTransactionIdstringrequiredID of the bank transaction.
statusstringrequiredValuesfailed
errorCodestringrequiredcurl -X POST 'https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/batch-encode-from-transaction-suggestions' \
-H "Authorization: Bearer $SWAY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"bankTransactions": [
{
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"existingLedgerEntryIds": [
"Le3wN8qT5xKr1mZv7pBd"
]
}
]
}'const response = await fetch('https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/batch-encode-from-transaction-suggestions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SWAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"bankTransactions": [
{
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"existingLedgerEntryIds": [
"Le3wN8qT5xKr1mZv7pBd"
]
}
]
}),
});
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/batch-encode-from-transaction-suggestions",
headers={"Authorization": f"Bearer {os.environ['SWAY_API_KEY']}"},
json={
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"bankTransactions": [
{
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"existingLedgerEntryIds": [
"Le3wN8qT5xKr1mZv7pBd",
],
},
],
},
)
print(response.json()){
"data": {
"results": [
{
"entries": [
{
"description": "string",
"taxRate": 0,
"taxMilliAmount": 0,
"taxCode": "string",
"taxId": "string",
"taxAccount": "string",
"signedMilliAmount": 0,
"account": "string",
"ledgerEntryId": "Le3wN8qT5xKr1mZv7pBd",
"order": 0,
"accountSource": "manual"
}
],
"accountingStatus": "pending",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"status": "approved"
}
]
}
}{
"error": {
"code": "invalid-argument",
"message": "Invalid request"
}
}{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired credentials"
}
}{
"error": {
"code": "permission-denied",
"message": "Missing required scope: invoices:read"
}
}{
"error": {
"code": "not-found",
"message": "Resource not found"
}
}{
"error": {
"code": "internal",
"message": "An internal error occurred"
}
}/workspaces/{workspaceId}/ledger-entries/exportExport ledger entries to a downloadable file
Scopeledger-entries:write
Path parameters
workspaceIdstringrequiredID of the workspace.
Query parameters
fieldsstringComma-separated property paths to include in the response, or in each item of a list. Use dots for nested paths.
Request body
bankAccountIdstringrequiredID of the bank account.
fromDatestringtoDatestringbankTransactionIdsstring[]ID of the bank transaction.
exportTypestringrequiredFormat of the ledger entry export.
tsv_cresusTab-separated file to import into Crésus.
csv_winbizCSV file to import into Winbiz.
tsv_wineurTab-separated file to import into WinEUR.
csv_internal_ledger_entryCSV file with one row per ledger entry, with its debit, credit and tax accounts.
csv_internal_general_ledgerCSV file in general ledger layout, with one row per account and separate debit and credit columns.
xlsx_abacusExcel file to import into Abacus.
configobjectVariant 1
winbizVatSchemestringrequiredValuesCASHVAT_NETNO_VATACCRUAL
winbizSuspenseAccountCodestringVariant 2
abacusMandantNumbernumberisWorkspaceFilebooleangenerateHeadersbooleantransliteratebooleanReturns
Successful response
dataLedgerEntryExportrequiredShow 4 child fields
startedbooleanrequiredworkspaceIdstringrequiredbankAccountIdstringrequiredfilesobject[]requiredShow 4 child fields
exportIdstringrequiredtargetFileNamestringrequireddownloadUrlstringurirequiredTime-limited URL to download the file. The file may not be ready the moment the export call returns: poll this URL and retry while it responds with 404 until the download succeeds.
expiresAtstringrequiredInstant after which downloadUrl stops working.
curl -X POST 'https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/export' \
-H "Authorization: Bearer $SWAY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"fromDate": "2026-01-01",
"toDate": "2026-03-31",
"exportType": "tsv_cresus"
}'const response = await fetch('https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/export', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SWAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"fromDate": "2026-01-01",
"toDate": "2026-03-31",
"exportType": "tsv_cresus"
}),
});
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/export",
headers={"Authorization": f"Bearer {os.environ['SWAY_API_KEY']}"},
json={
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"fromDate": "2026-01-01",
"toDate": "2026-03-31",
"exportType": "tsv_cresus",
},
)
print(response.json()){
"data": {
"started": true,
"workspaceId": "string",
"bankAccountId": "string",
"files": [
{
"exportId": "string",
"targetFileName": "string",
"downloadUrl": "https://example.com",
"expiresAt": "2026-03-02T09:30:00.000Z"
}
]
}
}{
"error": {
"code": "invalid-argument",
"message": "Invalid request"
}
}{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired credentials"
}
}{
"error": {
"code": "permission-denied",
"message": "Missing required scope: invoices:read"
}
}{
"error": {
"code": "not-found",
"message": "Resource not found"
}
}{
"error": {
"code": "internal",
"message": "An internal error occurred"
}
}/workspaces/{workspaceId}/ledger-entries/pre-exportRun pre-export checks on ledger entries before exporting
Scopeledger-entries:read
Path parameters
workspaceIdstringrequiredID of the workspace.
Query parameters
fieldsstringComma-separated property paths to include in the response, or in each item of a list. Use dots for nested paths.
bankAccountIdstringrequiredID of the bank account.
fromDatestringtoDatestringbankTransactionIdsstring[]ID of the bank transaction.
Returns
Successful response
dataLedgerEntryExportCheckrequiredShow 5 child fields
uncodedBankTransactionIdsstring[]requireduncodedLedgerEntryIdsPerBankTransactionRecord<string, string[]>requiredimbalancedBankTransactionIdsstring[]requiredbankTransactionCountnumberrequiredledgerEntryCountnumberrequiredcurl 'https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/pre-export?bankAccountId=bacc_Q0gzMTA4NzY1NDM' \
-H "Authorization: Bearer $SWAY_API_KEY"const response = await fetch('https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/pre-export?bankAccountId=bacc_Q0gzMTA4NzY1NDM', {
headers: {
Authorization: `Bearer ${process.env.SWAY_API_KEY}`,
},
});
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/pre-export?bankAccountId=bacc_Q0gzMTA4NzY1NDM",
headers={"Authorization": f"Bearer {os.environ['SWAY_API_KEY']}"},
)
print(response.json()){
"data": {
"uncodedBankTransactionIds": [
"string"
],
"uncodedLedgerEntryIdsPerBankTransaction": {
"key": [
"string"
]
},
"imbalancedBankTransactionIds": [
"string"
],
"bankTransactionCount": 0,
"ledgerEntryCount": 0
}
}{
"error": {
"code": "invalid-argument",
"message": "Invalid request"
}
}{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired credentials"
}
}{
"error": {
"code": "permission-denied",
"message": "Missing required scope: invoices:read"
}
}{
"error": {
"code": "not-found",
"message": "Resource not found"
}
}{
"error": {
"code": "internal",
"message": "An internal error occurred"
}
}/workspaces/{workspaceId}/ledger-entries/reorderReorder ledger entries attached to a bank transaction
Scopeledger-entries:write
Path parameters
workspaceIdstringrequiredID of the workspace.
Request body
ledgerEntryIdstringrequiredID of the ledger entry.
bankTransactionIdstringrequiredID of the bank transaction.
bankAccountIdstringrequiredID of the bank account.
newOrderintegerrequiredReturns
No content
curl -X POST 'https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/reorder' \
-H "Authorization: Bearer $SWAY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"ledgerEntryId": "Le3wN8qT5xKr1mZv7pBd",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"newOrder": 0
}'const response = await fetch('https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/reorder', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SWAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"ledgerEntryId": "Le3wN8qT5xKr1mZv7pBd",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"newOrder": 0
}),
});
console.log(response.status);import os
import requests
response = requests.post(
"https://api.business.swayapp.io/v1/workspaces/Wk7fQ2xR9bLm4tZp8sNv/ledger-entries/reorder",
headers={"Authorization": f"Bearer {os.environ['SWAY_API_KEY']}"},
json={
"ledgerEntryId": "Le3wN8qT5xKr1mZv7pBd",
"bankTransactionId": "trx_MjAyNjAzMDJUMDk",
"bankAccountId": "bacc_Q0gzMTA4NzY1NDM",
"newOrder": 0,
},
)
print(response.status_code){
"error": {
"code": "invalid-argument",
"message": "Invalid request"
}
}{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired credentials"
}
}{
"error": {
"code": "permission-denied",
"message": "Missing required scope: invoices:read"
}
}{
"error": {
"code": "not-found",
"message": "Resource not found"
}
}{
"error": {
"code": "internal",
"message": "An internal error occurred"
}
}