> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trassets.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# v1 Accounting Data Model: Booking Header, Positions, and Budgets

> Field-level reference for the v1 Accounting tables booking_header, booking_positions, and budgets, reshaped with period, amount, and amount_per_sqm objects.

The v1 Accounting domain currently covers three tables: `booking_header`,
`booking_positions`, and `budgets`. `booking_header` and `booking_positions` follow the
[response shape conventions](/v1/response-shape-conventions) — nested `period`/`amount`
objects and stable join keys; `budgets` still carries one open artifact, flagged below.

## booking\_header

`GET /v1/accounting/booking_header` — general ledger booking headers. No `period` or
`amount` object here: the table has only a single `booking_date` field and a single
`booking_value` field, so those two conventions don't apply structurally.

<ResponseField name="property_id" type="string" required>
  Unique property identifier.
</ResponseField>

<ResponseField name="booking_header_id" type="integer" required>
  Unique identifier for the booking header. `booking_positions` references this as
  `booking_header_id`.
</ResponseField>

<ResponseField name="booking_nr" type="integer">
  Booking number.
</ResponseField>

<ResponseField name="creditor_id" type="string">
  Creditor linked to the booking. References `Stakeholder.creditor`.
</ResponseField>

<ResponseField name="person_id" type="string">
  Tenant or contact person linked to the booking, using a local per-property numbering
  scheme. Don't treat this as the same identifier space as `person_id` on
  `Operations.notifications`, which is a separate `bigint` sequence from another subsystem.
</ResponseField>

<ResponseField name="booking_date" type="date">
  Date of the booking.
</ResponseField>

<ResponseField name="booking_value" type="number">
  Total value of the booking header.
</ResponseField>

<ResponseField name="m2" type="number">
  Floor area in square metres associated with the booking, if applicable.
</ResponseField>

<ResponseField name="booking_text" type="string">
  Free-text description of the booking.
</ResponseField>

<ResponseField name="initial_booking_text" type="string">
  Original booking text, before any later correction.
</ResponseField>

<ResponseField name="booking_barcode" type="string">
  Barcode reference for the booking document, if scanned.
</ResponseField>

<ResponseField name="dms_link" type="string">
  Link to the booking document in the document management system, if attached.
</ResponseField>

<ResponseField name="cost_center_id_name_concat" type="string">
  Combined cost-centre ID and name — the only source of this label; there's no separate
  ID/name pair to join against instead.
</ResponseField>

<ResponseField name="ledger_id_name_concat" type="string">
  Combined ledger ID and name, for the same reason as `cost_center_id_name_concat`.
</ResponseField>

<ResponseField name="person_name_concat" type="string">
  Combined person ID and name, for the same reason as `cost_center_id_name_concat`.
</ResponseField>

<ResponseField name="property_structure_account_id" type="string">
  Foreign key into `Property.property_structure`, matching `property_structure.account_id`.
</ResponseField>

## booking\_positions

`GET /v1/accounting/booking_positions` — individual booking line items, joined to a header
via `booking_header_id`.

<ResponseField name="property_id" type="integer" required>
  Unique property identifier.
</ResponseField>

<ResponseField name="booking_position_id" type="integer" required>
  Unique identifier for the line item.
</ResponseField>

<ResponseField name="booking_header_id" type="integer" required>
  Identifier of the parent booking header. Joins to `booking_header.booking_header_id`.
</ResponseField>

<ResponseField name="account_id" type="integer" required>
  Account the line item is posted to. There is no `/v1/` accounts endpoint yet — join
  against the unversioned `Accounting.accounts` for account metadata.
</ResponseField>

<ResponseField name="contra_account_id" type="integer">
  Contra account for the posting.
</ResponseField>

<ResponseField name="contra_account_name" type="string">
  Name of the contra account. Not derivable by joining `contra_account_id` against
  `accounts` — the two don't correspond.
</ResponseField>

<ResponseField name="creditor_id" type="integer">
  Creditor linked to the posting. References `Stakeholder.creditor`.
</ResponseField>

<ResponseField name="person_id" type="integer">
  Tenant or contact person linked to the posting.
</ResponseField>

<ResponseField name="property_id_person_id" type="integer">
  Composite key identifying the tenant this posting applies to. It resembles a
  concatenation of `property_id` and `person_id`, but isn't always exactly that — use the
  field as given rather than deriving it yourself.
</ResponseField>

<ResponseField name="period" type="object">
  Booking period — `{start, end}` (date strings).
</ResponseField>

<ResponseField name="amount" type="object">
  Posting amount — `{net, tax, gross}`.
</ResponseField>

<ResponseField name="amount_per_sqm" type="object">
  Posting amount normalised per square metre — `{net, tax, gross}`.
</ResponseField>

<ResponseField name="account_group" type="string">
  Account group assignment.
</ResponseField>

<ResponseField name="booking_date" type="date">
  Date of the posting.
</ResponseField>

<ResponseField name="booking_nr" type="integer">
  Booking number.
</ResponseField>

<ResponseField name="booking_Lfd_nr" type="integer">
  Sequential line number within the booking.
</ResponseField>

<ResponseField name="booking_type" type="integer">
  Booking type code.
</ResponseField>

<ResponseField name="booking_position_text" type="string">
  Free-text description of the line item.
</ResponseField>

<ResponseField name="sh" type="string">
  Debit/credit indicator (`S`/`H`). Don't infer it from the sign of `amount.net` — about
  3.55% of rows (reversal/correction postings) have a sign that contradicts this indicator.
</ResponseField>

<ResponseField name="HNDL" type="number">
  Meaning not yet confirmed with the source system. About 99.2% of rows are `0.0`; where
  non-zero, the value is often close to `amount.net` and concentrated in specific booking
  types tied to recoverable operating costs — consistent with a correction field, but not
  confirmed. Don't rename or reinterpret it.
</ResponseField>

<ResponseField name="property_structure_account_id" type="string">
  Foreign key into `Property.property_structure`, matching `property_structure.account_id`
  — the same join key as on `booking_header`.
</ResponseField>

## budgets

`GET /v1/accounting/budgets` — budget amounts, one row per property, account, and month.

<ResponseField name="property_id" type="integer" required>
  Unique property identifier.
</ResponseField>

<ResponseField name="account_id" type="integer" required>
  Account the budget applies to. Renamed from the unversioned `account_hdr_id` — joins to
  the unversioned `Accounting.accounts.account_hdr_id` (there is no `/v1/` accounts endpoint
  yet).
</ResponseField>

<ResponseField name="account_number" type="integer">
  Account number. An integer here, where the unversioned equivalent (`accounts.account_id`)
  is a string.
</ResponseField>

<ResponseField name="date" type="date" required>
  Month the budget row applies to.
</ResponseField>

<ResponseField name="budget" type="number" required>
  Budget amount for the specific month and account.
</ResponseField>

<ResponseField name="property_id_account_number" type="integer">
  Sync-pipeline artifact, not yet resolved. The [response shape
  conventions](/v1/response-shape-conventions) call for dropping unverifiable artifacts like
  this one — don't build on it, it may be removed in a future revision.
</ResponseField>
