VRPlatformVRPlatform
Integrate & Migrate Data

Opening Trial Balance

Seed OPEX opening balances from a mapped trial balance

Use opening trial balance when an OPEX team — one that runs operating-expense accounting alongside trust accounting (see trust, operating, and combined ledgers) — needs correct account balances on the day before its GL start date. This endpoint stores only the Operating opening values that are not already owned by VRPlatform Trust and bank workflows. Trust is read-only, and Combined is always calculated as Operating + Trust.

The public endpoints are:

  1. Get the opening trial balance — load bank and ledger rows, calculated Trust values, Operating values, import eligibility, and lock state.
  2. Replace the opening trial balance — replace the manual Operating values for editable ledger rows.

Concepts

Combined, Trust, And Operating

Each row exposes three cent totals:

FieldMeaning
operatingCentTotalOperating opening value; editable for non-bank ledger rows.
trustCentTotalTrust activity before GL start, across all party attribution.
combinedCentTotalCalculated as operatingCentTotal + trustCentTotal.

Only operatingCentTotal is submitted. Trust is calculated by the API. Operating values are projected into transaction-linked journal entries.

The row flags have different purposes:

  • editable means a user can manually change the Operating value.
  • importable means an importer can populate the Operating value.
  • A Trust-backed non-bank ledger row is editable=true and importable=false.
  • Every bank row is editable=false and importable=false.

Internal Transaction

The API stores the source values on one internal opening-balance transaction:

type = journalBatch
uniqueRef = openingTrialBalanceOperating

This is intentionally not exposed through the public transaction create/update APIs. Use the General Ledger opening trial balance endpoints instead.

Assignment Row

The response includes an assignment row. It is calculated by the API so each column balances to zero. Clients must not submit the assignment account in rows[].

Workflow

  1. Export a trial balance from the source system as of GL start date - 1.
  2. Map source accounts to active VRPlatform Asset, Liability, and Equity rows returned by GET /general-ledger/opening-trial-balance.
  3. Skip rows where importable=false.
  4. Submit the source Operating cent total for the remaining ledger rows.
  5. Re-read the endpoint and review Operating, Trust, and Combined.
  6. Add a manual Operating adjustment only when a skipped Trust-backed ledger row genuinely has an additional book-only Operating balance.
  7. Inspect opening-balance journal entries if needed.

This is an onboarding patch for opening balances, separate from detailed pre-go-live activity. Use Historical Journal Entries for detailed source journals.

What To Enter And What To Skip

The import follows the source-of-truth boundary:

Source rowImport behavior
Bank accountsSkip. VRPlatform bank workflows own their balances.
Advance deposits, A/R, and deferred revenue already in TrustSkip.
Taxes and A/P already in TrustSkip.
Any mapped non-bank account with a non-zero Trust balanceSkip automatically.
Undeposited fundsEnter its Operating balance.
Credit cardsEnter only when returned as an importable ledger row.
Accruals, deferrals, and prepaidsEnter their Operating balances.
Other book-only assets, liabilities, and equityEnter their Operating balances.
Revenue and expense accountsDo not enter; the assignment row absorbs net P&L.

Skipping import does not prohibit a manual adjustment. A Trust-backed non-bank ledger row remains editable so a user can add a separate Operating amount when the books require one.

Load Editable Rows

GET /general-ledger/opening-trial-balance

Example response shape:

{
  "glStartAt": "2025-01-01",
  "openingDate": "2024-12-31",
  "source": {
    "mode": "manual",
    "editable": true,
    "lastUpdatedAt": "2026-06-29"
  },
  "locked": false,
  "lockReasons": [],
  "rows": [
    {
      "accountId": "guest-deposits-account-uuid",
      "accountName": "Guest Deposits",
      "classification": "liability",
      "type": "ledger",
      "combinedCentTotal": -1585578,
      "trustCentTotal": -1585578,
      "operatingCentTotal": 0,
      "editable": true,
      "importable": false
    },
    {
      "accountId": "trust-bank-account-uuid",
      "accountName": "Trust Bank",
      "classification": "asset",
      "type": "bank",
      "combinedCentTotal": 3205585,
      "trustCentTotal": 3205585,
      "operatingCentTotal": 0,
      "editable": false,
      "importable": false
    }
  ],
  "assignment": {
    "accountId": "opening-balance-assignment-account-uuid",
    "accountName": "Opening Balance Equity",
    "combinedCentTotal": -1620007,
    "trustCentTotal": -1620007,
    "operatingCentTotal": 0
  }
}

For teams without saved manual values, source.mode is none and source.lastUpdatedAt is null. After saving manual values, source.mode becomes manual.

Replace Balances

PUT /general-ledger/opening-trial-balance
{
  "rows": [
    {
      "accountId": "undeposited-funds-account-uuid",
      "operatingCentTotal": 250000
    },
    {
      "accountId": "accounts-payable-account-uuid",
      "operatingCentTotal": -40000
    }
  ]
}

The request is a full replacement. Editable accounts omitted from rows[] are saved as zero. Bank accounts and the calculated assignment account are rejected.

Verify Journal Entries

Saving refreshes opening_trial_balance journal entries dated GL start date - 1. Use the journal entries report with openingBalanceType=openingTrialBalance to inspect them:

GET /reports/journal-entries?openingBalanceType=openingTrialBalance

Projected journal entries use:

  • type = opening_trial_balance
  • ledger = operating
  • party = manager
  • transactionId pointing at the internal journalBatch transaction

Zero Operating rows are skipped.

Guardrails

  • Updates are blocked when the opening date is books-closed, and when existing projected entries are attached to an owner statement.
  • Revenue accounts and non-equity Expense accounts are not editable in this endpoint.
  • Bank accounts remain visible for reconciliation but cannot be imported or edited.
  • Inactive, reference, and calculated assignment accounts are not input rows.
  • Historical GL detail, CSV parsing, and external accounting sync are out of scope for this endpoint.

API Reference

  • GET /general-ledger/opening-trial-balanceContract
  • PUT /general-ledger/opening-trial-balanceContract
  • GET /reports/trial-balanceContract
  • GET /reports/journal-entriesContract

On this page