Journal lines

Ledger lines, journal by journal, written and read back. Journal lines explain the figures the trial balance carries — they never move them, so a difference between the two is reported and never blocks a write.

Writing journal lines

The endpoints

MethodPathWhat it does
POST/api/v1/organisations/{organisation}/transactions Writes the lines
POST/api/v1/organisations/{organisation}/transactions/validate The same checks; nothing is written

Needs a bearer token, a credential issued for that company, and the credential's transactions.write scope.

The body

{
  "declarations": {
    "source_reference": "netsuite-gl",
    "period": "2026-09",
    "value_basis": "company_base",
    "rate_direction": "document_to_base",
    "base_currency": "SGD",
    "mode": "replace_period"
  },
  "records": [
    {
      "journal_external_id": "JE-2026-0912",
      "journal_number": "J-0912",
      "line_external_id": "JE-2026-0912-1",
      "date": "2026-09-14",
      "account_code": "4000",
      "side": "credit",
      "amount_base": 1090.00,
      "document_external_id": "INV-10241",
      "document_line_id": "INV-10241-1",
      "description": "Freight forwarding, September"
    },
    {
      "journal_external_id": "JE-2026-0912",
      "journal_number": "J-0912",
      "line_external_id": "JE-2026-0912-2",
      "date": "2026-09-14",
      "account_code": "1100",
      "side": "debit",
      "amount_base": 1090.00,
      "description": "Invoice INV-10241"
    }
  ]
}

Declarations

DeclarationRequiredValue
source_referenceyesYour own id for the feed, 1–64 characters.
periodyesThe month, YYYY-MM.
value_basisyescompany_base when amount_base is already in the reporting currency, document when it is not.
rate_directionyesWhich way exchange_rate converts.
base_currencyyesThe company's reporting currency.
scenarionoActual (default), Budget or Forecast.
modenoreplace_period (default), replace_all or merge.
webhook_urlnoCalled once when the request finishes or fails.

The fields

FieldTypeRequiredWhat it means
journal_external_idstringyesThe journal this line belongs to. Half of the record's identity.
line_external_idstringyesThe line's own identity within the journal. The other half.
journal_numberstringnoThe number a reader sees for the journal.
datedateyesThe posting date.
account_codestringyesThe code in this company's accounts. An unknown code is refused with account_not_found.
account_namestringnoStated beside the code, as a reader sees it.
sidestringyesdebit or credit.
amount_basenumberyesThe amount in the reporting currency, a positive number on its own side.
currency_codestringnoThe document currency, when it is not the base currency.
exchange_ratenumbernoThe rate the line was posted at, in the direction declared.
document_amountnumbernoThe amount in the document currency.
tax_amount, tax_typenumber, stringnoThe tax the line states and the source's tax code for it.
reference, descriptionstringnoStored exactly as sent.
dimensionsarraynoNamed values: tracking, class, reporting tag.
document_external_id, document_line_idstringno The document and line this posting explains, when it names one.

What it does

What it answers

{
  "id": 95, "kind": "transactions", "source_reference": "netsuite-gl",
  "period": "2026-09", "status": "written", "records_received": 2,
  "counts": { "created": 2, "updated": 0, "unchanged": 0, "rejected": 0 },
  "suppressed": 0,
  "result": { "control_total": { "compared": true, "accounts": [] } },
  "recalculation": null,
  "written_at": "2026-10-23T06:40:18+00:00",
  "links": { "self": "…/requests/95", "results": "…/requests/95/results" }
}

Refusals

CodeWhen
journal_does_not_balanceThe journal's two sides differ
account_not_foundThe code is not in this company's accounts
invalid_valueside is not debit or credit
invalid_valueamount_base is not a positive number
duplicate_record_identityTwo records state the same journal and line id

Reading journal lines

The journal lines this API was sent, journal by journal, answered as they were accepted. They explain the figures the trial balance carries rather than moving them, so a month's lines and its trial balance can differ: the write side reports that difference as control_total and never blocks on it. A line a document line already explains is answered here too, and its document_external_id says so - anything that totals these lines counts it once.

The endpoint

MethodPathAnswers
GET/api/v1/organisations/{organisation}/transactions The lines, newest journal first

Needs a bearer token, a credential issued for that company, and the transactions.read scope.

The filters

ParameterWhat it does
periodOne month, Mon-YYYY.
journal_external_idOne journal.
account_codeOne account's lines.
document_external_idThe lines a document explains.
page, per_pagePaging, as everywhere.

What it answers

{
  "data": [
    {
      "journal_external_id": "JE-2026-0912", "journal_number": "J-0912",
      "line_external_id": "JE-2026-0912-1",
      "date": "2026-09-14",
      "account_code": "4000", "account_name": "Sales Revenue",
      "side": "credit", "amount_base": 1090.00,
      "currency_code": "USD", "exchange_rate": 1.0, "document_amount": 1090.00,
      "tax_amount": 0.00, "tax_type": null,
      "reference": null, "description": "Freight forwarding, September",
      "dimensions": [],
      "document_external_id": "INV-10241", "document_line_id": "INV-10241-1",
      "source": "API"
    }
  ],
  "page": 1, "per_page": 50, "total": 2, "has_more": false
}
FieldWhat it says
journal_external_id, line_external_idThe line's identity, as the source stated it.
journal_numberThe number a reader sees for the journal.
dateThe posting date.
account_code, account_nameThe account the line moved.
side, amount_basedebit or credit, and the amount in the company's reporting currency.
currency_code, exchange_rate, document_amountThe document's currency, its rate, and the amount in that currency.
dimensionsThe named values the line was posted with: tracking, class, reporting tag.
document_external_id, document_line_idThe document and line the posting explains, when it names one.
sourceWho wrote the line.

An unbalanced journal cannot be stored through the API, so what is read here is arithmetic that balances.