Skip to main content

Double-Entry Ledger & Journal Entry API

MOCK DATA

Double-entry journal entries where every entry balances to zero, per-account running balances are exact, and the trial balance always sums to zero.

Generated test data for fixtures and development

Base URL
/api/ledger-entries
Capabilities
3 routes Seedable
Last updated
July 29, 2026

GET /api/ledger-entries

Each record is one journal entry with its postings. debitTotal always equals creditTotal, and summing every posting debit-positive across the response gives exactly zero.

Live requestRuns against the public API
No key required
GET/api/ledger-entries?seed=42

Request parameters

Active ISO 4217 code (3 letters, case-insensitive) every amount is denominated in. Amounts are integer minor units of this currency and no conversion is performed. XDR is rejected because ISO defines no minor unit for it.

Constrain generation to entries with at least one posting on an account of this type (asset, liability, equity, revenue or expense).

Exact number of postings in every entry (2–6). One side gets ⌈n/2⌉ legs and the other ⌊n/2⌋; both sides always sum to the same total.

Only generate this entry type. Omitted, you get an even mix of the six business types, and about 15% of entries (never the first) reverse one of the five entries before them.

Smallest amount of any single posting, in integer minor units (1 = one cent for USD, one yen for JPY). Bounds every posting, not the entry total.

Largest amount of any single posting, in integer minor units. Must be ≥ minAmount.

Start of the posting window, inclusive (YYYY-MM-DD = midnight UTC, or a full ISO 8601 timestamp). Defaults to 30 days before 'to'.

End of the posting window, inclusive. Defaults to today at UTC midnight, so a pinned seed returns identical entries all day. Must be ≥ from.

Advanced response options7 options

Limit the number of returned records (1–100). Defaults to 10.

Deterministic output: the same seed always returns the same records. Omit for random (the used seed is echoed in meta.seed).

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Response format: json envelope, ndjson (one record per line) or csv.

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/ledger-entries?seed=42"
const res = await fetch("https://randomapi.dev/api/ledger-entries?seed=42");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/ledger-entries?seed=42").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/ledger-entries?seed=42"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 8
currency string

Active ISO 4217 code (3 letters, case-insensitive) every amount is denominated in. Amounts are integer minor units of this currency and no conversion is performed. XDR is rejected because ISO defines no minor unit for it.

default: USD
allowed: 3 – 3
example: currency=EUR
accountType enum

Constrain generation to entries with at least one posting on an account of this type (asset, liability, equity, revenue or expense).

allowed: asset | liability | equity | revenue | expense
example: accountType=asset
postingsPerEntry int

Exact number of postings in every entry (2–6). One side gets ⌈n/2⌉ legs and the other ⌊n/2⌋; both sides always sum to the same total.

default: 2
allowed: 2 – 6
example: postingsPerEntry=4
entryType enum

Only generate this entry type. Omitted, you get an even mix of the six business types, and about 15% of entries (never the first) reverse one of the five entries before them.

allowed: payment | payout | refund | fee | transfer | accrual | reversal
example: entryType=payment
minAmount int

Smallest amount of any single posting, in integer minor units (1 = one cent for USD, one yen for JPY). Bounds every posting, not the entry total.

default: 100
allowed: 1 – 1000000000
example: minAmount=500
maxAmount int

Largest amount of any single posting, in integer minor units. Must be ≥ minAmount.

default: 250000
allowed: 1 – 1000000000
example: maxAmount=100000
from date

Start of the posting window, inclusive (YYYY-MM-DD = midnight UTC, or a full ISO 8601 timestamp). Defaults to 30 days before 'to'.

example: from=2026-01-01
to date

End of the posting window, inclusive. Defaults to today at UTC midnight, so a pinned seed returns identical entries all day. Must be ≥ from.

example: to=2026-03-31
Universal parameters Shared response and formatting options 7
count int

Limit the number of returned records (1–100). Defaults to 10.

default: 10
allowed: 1 – 100
example: count=3
seed int

Deterministic output: the same seed always returns the same records. Omit for random (the used seed is echoed in meta.seed).

example: seed=42
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=entryId,date
exclude list

Return all fields except these (comma-separated).

example: exclude=creditTotal
format enum

Response format: json envelope, ndjson (one record per line) or csv.

default: json
allowed: json | ndjson | csv
example: format=csv
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 10
entryId string

Journal entry id ('je_' + 8 hex characters), unique within a response.

example: je_3f9a2c01

date string (ISO 8601)

Posting date in UTC, inside the from..to window, and shared by every posting of the entry. Entries come out oldest first — strictly increasing while the window is at least 100 ms wide, otherwise non-decreasing because date slots collapse (a warning says so).

example: 2026-03-14T09:26:53.512Z

type string

payment | payout | refund | fee | transfer | accrual | reversal.

example: payment

currency string

ISO 4217 code every posting amount is denominated in (integer minor units).

example: USD

description string

Human memo for the entry; reversals name the entry they reverse.

example: Customer payment applied to an open invoice

reference string

External reference: a type prefix (PAY, PYT, REF, FEE, TRF, ACR, REV) plus 8 hex characters.

example: PAY-9F3A2C81

reversesEntryId string nullable

For a reversal, the entryId of the earlier entry in this response whose postings it mirrors; null for every other entry (and for the first record when entryType=reversal).

example: null

postings object[]

The entry's legs, debits first: lineNumber, accountId, account, accountType, normalBalance, side, amount (positive minor units) and signedAmount (debit-positive, so the legs sum to 0).

example: [{"lineNumber":1,"accountId":"cash","account":"Cash","accountType":"asset","normalBalance":"debit","side":"debit","amount":128450,"signedAmount":128450},{"lineNumber":2,"accountId":"accounts-receivable","account":"Accounts Receivable","accountType":"asset","normalBalance":"debit","side":"credit","amount":128450,"signedAmount":-128450}]

debitTotal integer

Sum of the debit legs in minor units — always equal to creditTotal.

example: 128450

creditTotal integer

Sum of the credit legs in minor units — always equal to debitTotal.

example: 128450

Documented examples

Build-generated requests and complete responses
5
Ten balanced journal entries
GET /api/ledger-entries?seed=42
{
  "data": [
    {
      "entryId": "je_7a4fe700",
      "date": "2026-06-29T06:22:39.185Z",
      "type": "fee",
      "currency": "USD",
      "description": "Monthly gateway fee",
      "reference": "FEE-FB6A5C85",
      "reversesEntryId": null,
      "postings": [
        {
          "lineNumber": 1,
          "accountId": "processing-fees",
          "account": "Processing Fees",
          "accountType": "expense",
          "normalBalance": "debit",
          "side": "debit",
          "amount": 9700,
          "signedAmount": 9700
        },
        {
          "lineNumber": 2,
          "accountId": "accounts-payable",
          "account": "Accounts Payable",
          "accountType": "liability",
          "normalBalance": "credit",
          "side": "credit",
          "amount": 9700,
          "signedAmount": -9700
        }
      ],
      "debitTotal": 9700,
      "creditTotal": 9700
    },
    {
      "entryId": "je_cfa45a01",
      "date": "2026-06-29T13:19:04.194Z",
      "type": "fee",
      "currency": "USD",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Compound entries with four postings each
GET /api/ledger-entries?postingsPerEntry=4&count=5&seed=7
{
  "data": [
    {
      "entryId": "je_ad8cd600",
      "date": "2026-06-29T04:43:12.670Z",
      "type": "fee",
      "currency": "USD",
      "description": "Platform fee for the settlement batch",
      "reference": "FEE-F61BCDE1",
      "reversesEntryId": null,
      "postings": [
        {
          "lineNumber": 1,
          "accountId": "processing-fees",
          "account": "Processing Fees",
          "accountType": "expense",
          "normalBalance": "debit",
          "side": "debit",
          "amount": 214666,
          "signedAmount": 214666
        },
        {
          "lineNumber": 2,
          "accountId": "processing-fees",
          "account": "Processing Fees",
          "accountType": "expense",
          "normalBalance": "debit",
          "side": "debit",
          "amount": 21601,
          "signedAmount": 21601
        },
        {
          "lineNumber": 3,
          "accountId": "clearing",
          "account": "Clearing Account",
          "accountType": "asset",
          "normalBalance": "debit",
          "side": "credit",
          "amount": 61963,
          "signedAmount": -61963"generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Euro fee entries in Q1 2026
GET /api/ledger-entries?currency=EUR&entryType=fee&from=2026-01-01&to=2026-03-31&count=20&seed=3
{
  "data": [
    {
      "entryId": "je_5bc7d600",
      "date": "2026-01-01T17:36:20.061Z",
      "type": "fee",
      "currency": "EUR",
      "description": "Platform fee for the settlement batch",
      "reference": "FEE-97DB2587",
      "reversesEntryId": null,
      "postings": [
        {
          "lineNumber": 1,
          "accountId": "processing-fees",
          "account": "Processing Fees",
          "accountType": "expense",
          "normalBalance": "debit",
          "side": "debit",
          "amount": 177349,
          "signedAmount": 177349
        },
        {
          "lineNumber": 2,
          "accountId": "clearing",
          "account": "Clearing Account",
          "accountType": "asset",
          "normalBalance": "debit",
          "side": "credit",
          "amount": 177349,
          "signedAmount": -177349
        }
      ],
      "debitTotal": 177349,
      "creditTotal": 177349
    },
    {
      "entryId": "je_a571d201",
      "date": "2026-01-02T02:44:57.841Z",
      "type": "fee",
      "currency": "EUR",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Entries that touch a revenue account
GET /api/ledger-entries?accountType=revenue&count=8&seed=11
{
  "data": [
    {
      "entryId": "je_16a9bb00",
      "date": "2026-06-29T05:46:53.234Z",
      "type": "accrual",
      "currency": "USD",
      "description": "Accrued revenue posted",
      "reference": "ACR-D2C76F32",
      "reversesEntryId": null,
      "postings": [
        {
          "lineNumber": 1,
          "accountId": "deferred-revenue",
          "account": "Deferred Revenue",
          "accountType": "liability",
          "normalBalance": "credit",
          "side": "debit",
          "amount": 104490,
          "signedAmount": 104490
        },
        {
          "lineNumber": 2,
          "accountId": "revenue",
          "account": "Revenue",
          "accountType": "revenue",
          "normalBalance": "credit",
          "side": "credit",
          "amount": 104490,
          "signedAmount": -104490
        }
      ],
      "debitTotal": 104490,
      "creditTotal": 104490
    },
    {
      "entryId": "je_181e8401",
      "date": "2026-06-29T09:46:10.959Z",
      "type": "refund",
      "currency": "USD",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Large whole-yen entries
GET /api/ledger-entries?currency=JPY&minAmount=100000&maxAmount=900000&count=5&seed=5
{
  "data": [
    {
      "entryId": "je_74ba2700",
      "date": "2026-06-29T03:38:30.692Z",
      "type": "transfer",
      "currency": "JPY",
      "description": "Sweep between internal balances",
      "reference": "TRF-70A88477",
      "reversesEntryId": null,
      "postings": [
        {
          "lineNumber": 1,
          "accountId": "clearing",
          "account": "Clearing Account",
          "accountType": "asset",
          "normalBalance": "debit",
          "side": "debit",
          "amount": 333028,
          "signedAmount": 333028
        },
        {
          "lineNumber": 2,
          "accountId": "cash",
          "account": "Cash",
          "accountType": "asset",
          "normalBalance": "debit",
          "side": "credit",
          "amount": 333028,
          "signedAmount": -333028
        }
      ],
      "debitTotal": 333028,
      "creditTotal": 333028
    },
    {
      "entryId": "je_5acc1701",
      "date": "2026-06-29T13:04:34.331Z",
      "type": "payout",
      "currency": "JPY",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

GET /api/ledger-entries/postings

Ledger rows from the same entry set (two postings per entry), oldest first, capped at 100 rows — so an unfiltered response covers the first ⌈count/2⌉ entries, not all of them. balanceAfter is the exact running total of that account over the rows above it.

Live requestRuns against the public API
No key required
GET/api/ledger-entries/postings?seed=42

Request parameters

Active ISO 4217 code (3 letters, case-insensitive) every amount is denominated in. Amounts are integer minor units of this currency and no conversion is performed. XDR is rejected because ISO defines no minor unit for it.

Constrain generation to entries with at least one posting on an account of this type (asset, liability, equity, revenue or expense).

Smallest amount of any single posting, in integer minor units (1 = one cent for USD, one yen for JPY). Bounds every posting, not the entry total.

Largest amount of any single posting, in integer minor units. Must be ≥ minAmount.

Start of the posting window, inclusive (YYYY-MM-DD = midnight UTC, or a full ISO 8601 timestamp). Defaults to 30 days before 'to'.

End of the posting window, inclusive. Defaults to today at UTC midnight, so a pinned seed returns identical entries all day. Must be ≥ from.

Advanced response options7 options

Limit the number of returned records (1–100). Defaults to 10.

Deterministic output: the same seed always returns the same records. Omit for random (the used seed is echoed in meta.seed).

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Response format: json envelope, ndjson (one record per line) or csv.

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/ledger-entries/postings?seed=42"
const res = await fetch("https://randomapi.dev/api/ledger-entries/postings?seed=42");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/ledger-entries/postings?seed=42").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/ledger-entries/postings?seed=42"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 6
currency string

Active ISO 4217 code (3 letters, case-insensitive) every amount is denominated in. Amounts are integer minor units of this currency and no conversion is performed. XDR is rejected because ISO defines no minor unit for it.

default: USD
allowed: 3 – 3
example: currency=EUR
accountType enum

Constrain generation to entries with at least one posting on an account of this type (asset, liability, equity, revenue or expense).

allowed: asset | liability | equity | revenue | expense
example: accountType=asset
minAmount int

Smallest amount of any single posting, in integer minor units (1 = one cent for USD, one yen for JPY). Bounds every posting, not the entry total.

default: 100
allowed: 1 – 1000000000
example: minAmount=500
maxAmount int

Largest amount of any single posting, in integer minor units. Must be ≥ minAmount.

default: 250000
allowed: 1 – 1000000000
example: maxAmount=100000
from date

Start of the posting window, inclusive (YYYY-MM-DD = midnight UTC, or a full ISO 8601 timestamp). Defaults to 30 days before 'to'.

example: from=2026-01-01
to date

End of the posting window, inclusive. Defaults to today at UTC midnight, so a pinned seed returns identical entries all day. Must be ≥ from.

example: to=2026-03-31
Universal parameters Shared response and formatting options 7
count int

Limit the number of returned records (1–100). Defaults to 10.

default: 10
allowed: 1 – 100
example: count=3
seed int

Deterministic output: the same seed always returns the same records. Omit for random (the used seed is echoed in meta.seed).

example: seed=42
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=postingId,entryId
exclude list

Return all fields except these (comma-separated).

example: exclude=balanceAfter
format enum

Response format: json envelope, ndjson (one record per line) or csv.

default: json
allowed: json | ndjson | csv
example: format=csv
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 14
postingId string

Row id: the entryId plus the line number ('je_3f9a2c01-L1').

example: je_3f9a2c01-L1

entryId string

Journal entry this posting belongs to.

example: je_3f9a2c01

entryType string

Type of the parent entry: payment | payout | refund | fee | transfer | accrual | reversal.

example: payment

lineNumber integer

1-based line number inside the entry, debits first.

example: 1

date string (ISO 8601)

Date of the parent entry — every posting of an entry shares it.

example: 2026-03-14T09:26:53.512Z

currency string

ISO 4217 code of the amount (integer minor units).

example: USD

accountId string

Chart-of-accounts slug — an internal key, never a statutory account number.

example: cash

account string

Human account name as it would appear in a ledger table.

example: Cash

accountType string

asset | liability | equity | revenue | expense.

example: asset

normalBalance string

Side on which this account type increases: debit for assets and expenses, credit for liabilities, equity and revenue.

example: debit

side string

debit or credit.

example: debit

amount integer

Positive amount in minor units, inside minAmount..maxAmount.

example: 128450

signedAmount integer

Debit-positive amount (+ for debits, − for credits). Each entry's own legs still net to 0, but these rows are a flat slice of the ledger rather than whole entries, so the response nets to 0 only when `count` is even and no `accountType` filter is applied; an odd `count` ends on an orphaned debit leg and the sum equals that last row.

example: 128450

balanceAfter integer

Exact debit-positive running balance of this account across the rows returned above it (a credit-normal account therefore trends negative).

example: 128450

Documented examples

Build-generated requests and complete responses
4
Ten ledger rows with running balances
GET /api/ledger-entries/postings?seed=42
{
  "data": [
    {
      "postingId": "je_7a4fe700-L1",
      "entryId": "je_7a4fe700",
      "entryType": "fee",
      "lineNumber": 1,
      "date": "2026-06-29T06:22:39.185Z",
      "currency": "USD",
      "accountId": "processing-fees",
      "account": "Processing Fees",
      "accountType": "expense",
      "normalBalance": "debit",
      "side": "debit",
      "amount": 9700,
      "signedAmount": 9700,
      "balanceAfter": 9700
    },
    {
      "postingId": "je_7a4fe700-L2",
      "entryId": "je_7a4fe700",
      "entryType": "fee",
      "lineNumber": 2,
      "date": "2026-06-29T06:22:39.185Z",
      "currency": "USD",
      "accountId": "accounts-payable",
      "account": "Accounts Payable",
      "accountType": "liability",
      "normalBalance": "credit",
      "side": "credit",
      "amount": 9700,
      "signedAmount": -9700,
      "balanceAfter": -9700
    },
    {
      "postingId": "je_cfa45a01-L1",
      "entryId": "je_cfa45a01",
      "entryType": "fee",
      "lineNumber": 1,
      "date": "2026-06-29T13:19:04.194Z",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Asset account rows only
GET /api/ledger-entries/postings?accountType=asset&count=20&seed=9
{
  "data": [
    {
      "postingId": "je_52097000-L1",
      "entryId": "je_52097000",
      "entryType": "accrual",
      "lineNumber": 1,
      "date": "2026-06-29T04:24:57.815Z",
      "currency": "USD",
      "accountId": "accounts-receivable",
      "account": "Accounts Receivable",
      "accountType": "asset",
      "normalBalance": "debit",
      "side": "debit",
      "amount": 56123,
      "signedAmount": 56123,
      "balanceAfter": 56123
    },
    {
      "postingId": "je_6b56a201-L2",
      "entryId": "je_6b56a201",
      "entryType": "refund",
      "lineNumber": 2,
      "date": "2026-06-29T10:08:59.761Z",
      "currency": "USD",
      "accountId": "clearing",
      "account": "Clearing Account",
      "accountType": "asset",
      "normalBalance": "debit",
      "side": "credit",
      "amount": 54727,
      "signedAmount": -54727,
      "balanceAfter": -54727
    },
    {
      "postingId": "je_0cfb2202-L2",
      "entryId": "je_0cfb2202",
      "entryType": "refund",
      "lineNumber": 2,
      "date": "2026-06-29T15:36:58.331Z",
    …
    ]
  }
}
A full ledger page as CSV
GET /api/ledger-entries/postings?count=100&seed=4&format=csv
postingId,entryId,entryType,lineNumber,date,currency,accountId,account,accountType,normalBalance,side,amount,signedAmount,balanceAfter
je_6d7ff700-L1,je_6d7ff700,payout,1,2026-06-29T05:16:23.930Z,USD,accounts-payable,Accounts Payable,liability,credit,debit,233044,233044,233044
je_6d7ff700-L2,je_6d7ff700,payout,2,2026-06-29T05:16:23.930Z,USD,clearing,Clearing Account,asset,debit,credit,233044,-233044,-233044
je_378f4501-L1,je_378f4501,payout,1,2026-06-29T10:11:41.069Z,USD,accounts-payable,Accounts Payable,liability,credit,debit,176714,176714,409758
je_378f4501-L2,je_378f4501,payout,2,2026-06-29T10:11:41.069Z,USD,cash,Cash,asset,debit,credit,176714,-176714,-176714
je_b3b50202-L1,je_b3b50202,transfer,1,2026-06-29T18:06:37.299Z,USD,clearing,Clearing Account,asset,debit,debit,122220,122220,-110824
je_b3b50202-L2,je_b3b50202,transfer,2,2026-06-29T18:06:37.299Z,USD,cash,Cash,asset,debit,credit,122220,-122220,-298934
je_b1d5b903-L1,je_b1d5b903,payment,1,2026-06-30T00:19:01.469Z,USD,clearing,Clearing Account,asset,debit,debit,50991,50991,-59833
je_b1d5b903-L2,je_b1d5b903,payment,2,2026-06-30T00:19:01.469Z,USD,deferred-revenue,Deferred Revenue,liability,credit,credit,50991,-50991,-50991
je_c9920d04-L1,je_c9920d04,transfer,1,2026-06-30T07:50:58.688Z,USD,clearing,Clearing Account,asset,debit,debit,24938,24938,-34895
je_c9920d04-L2,je_c9920d04,transfer,2,2026-06-30T07:50:58.688Z,USD,cash,Cash,asset,debit,credit,24938,-24938,-323872
je_25a00c05-L1,je_25a00c05,reversal,1,2026-06-30T19:04:25.639Z,USD,cash,Cash,asset,debit,debit,24938,24938,-298934
je_25a00c05-L2,je_25a00c05,reversal,2,2026-06-30T19:04:25.639Z,USD,clearing,Clearing Account,asset,debit,credit,24938,-24938,-59833
je_9d84a406-L1,je_9d84a406,accrual,1,2026-06-30T22:17:58.854Z,USD,accounts-receivable,Accounts Receivable,asset,debit,debit,32169,32169,32169
je_9d84a406-L2,je_9d84a406,accrual,2,2026-06-30T22:17:58.854Z,USD,revenue,Revenue,revenue,credit,credit,32169,-32169,-32169
je_917e2e07-L1,je_917e2e07,payment,1,2026-07-01T05:24:38.932Z,USD,cash,Cash,asset,debit,debit,165812,165812,-133122
je_917e2e07-L2,je_917e2e07,payment,2,2026-07-01T05:24:38.932Z,USD,accounts-receivable,Accounts Receivable,asset,debit,credit,165812,-165812,-133643
je_b1500008-L1,je_b1500008,transfer,1,2026-07-01T16:40:39.106Z,USD,clearing,Clearing Account,asset,debit,debit,234331,234331,174498
je_b1500008-L2,je_b1500008,transfer,2,2026-07-01T16:40:39.106Z,USD,cash,Cash,asset,debit,credit,234331,-234331,-367453
je_4afc4709-L1,je_4afc4709,transfer,1,2026-07-01T22:01:53.255Z,USD,clearing,Clearing Account,asset,debit,debit,165297,165297,339795
je_4afc4709-L2,je_4afc4709,transfer,2,2026-07-01T22:01:53.255Z,USD,cash,Cash,asset,debit,credit,165297,-165297,-532750
je_f091820a-L1,je_f091820a,reversal,1,2026-07-02T02:15:19.562Z,USD,cash,Cash,asset,debit,debit,234331,234331,-298419
je_f091820a-L2,je_f091820a,reversal,2,2026-07-02T02:15:19.562Z,USD,clearing,Clearing Account,asset,debit,credit,234331,-234331,105464
je_8279060b-L1,je_8279060b,transfer,1,2026-07-02T08:06:28.870Z,USD,clearing,Clearing Account,asset,debit,debit,130969,130969,236433
je_8279060b-L2,je_8279060b,transfer,2,2026-07-02T08:06:28.870Z,USD,cash,Cash,asset,debit,credit,130969,-130969,-429388
je_4cda5e0c-L1,je_4cda5e0c,payout,1,2026-07-02T20:45:33.986Z,USD,retained-earnings,Retained Earnings,equity,credit,debit,201686,201686,201686
je_4cda5e0c-L2,je_4cda5e0c,payout,2,2026-07-02T20:45:33.986Z,USD,cash,Cash,asset,debit,credit,201686,-201686,-631074
je_e0cf2a0d-L1,je_e0cf2a0d,accrual,1,2026-07-03T03:06:01.490Z,USD,accounts-receivable,Accounts Receivable,asset,debit,debit,67171,67171,-66472
je_e0cf2a0d-L2,je_e0cf2a0d,accrual,2,2026-07-03T03:06:01.490Z,USD,revenue,Revenue,revenue,credit,credit,67171,-67171,-99340
je_3857030e-L1,je_3857030e,transfer,1,2026-07-03T10:02:38.141Z,USD,clearing,Clearing Account,asset,debit,debit,181123,181123,417556
je_3857030e-L2,je_3857030e,transfer,2,2026-07-03T10:02:38.141Z,USD,cash,Cash,asset,debit,credit,181123,-181123,-812197
je_9aeca70f-L1,je_9aeca70f,refund,1,2026-07-03T13:26:25.050Z,USD,deferred-revenue,Deferred Revenue,liability,credit,debit,133650,133650,82659
je_9aeca70f-L2,je_9aeca70f,refund,2,2026-07-03T13:26:25.050Z,USD,clearing,Clearing Account,asset,debit,credit,133650,-133650,283906
je_eb3bb210-L1,je_eb3bb210,transfer,1,2026-07-03T23:59:50.221Z,USD,clearing,Clearing Account,asset,debit,debit,222973,222973,506879
je_eb3bb210-L2,je_eb3bb210,transfer,2,2026-07-03T23:59:50.221Z,USD,cash,Cash,asset,debit,credit,222973,-222973,-1035170
je_bdbf9f11-L1,je_bdbf9f11,transfer,1,2026-07-04T05:49:06.357Z,USD,clearing,Clearing Account,asset,debit,debit,150329,150329,657208
je_bdbf9f11-L2,je_bdbf9f11,transfer,2,2026-07-04T05:49:06.357Z,USD,cash,Cash,asset,debit,credit,150329,-150329,-1185499
je_b41d3812-L1,je_b41d3812,reversal,1,2026-07-04T16:46:45.839Z,USD,cash,Cash,asset,debit,debit,181123,181123,-1004376
je_b41d3812-L2,je_b41d3812,reversal,2,2026-07-04T16:46:45.839Z,USD,clearing,Clearing Account,asset,debit,credit,181123,-181123,476085
je_ed80ff13-L1,je_ed80ff13,refund,1,2026-07-04T18:22:49.669Z,USD,deferred-revenue,Deferred Revenue,liability,credit,debit,64460,64460,147119
    …
je_4d252d31-L1,je_4d252d31,accrual,1,2026-07-13T21:56:53.384Z,USD,deferred-revenue,Deferred Revenue,liability,credit,debit,41302,41302,1066617
je_4d252d31-L2,je_4d252d31,accrual,2,2026-07-13T21:56:53.384Z,USD,revenue,Revenue,revenue,credit,credit,41302,-41302,-52187
Kroner postings for a fixed quarter
GET /api/ledger-entries/postings?currency=DKK&from=2026-01-01&to=2026-03-31&count=25&seed=6
{
  "data": [
    {
      "postingId": "je_7a408c00-L1",
      "entryId": "je_7a408c00",
      "entryType": "payment",
      "lineNumber": 1,
      "date": "2026-01-01T10:59:20.771Z",
      "currency": "DKK",
      "accountId": "cash",
      "account": "Cash",
      "accountType": "asset",
      "normalBalance": "debit",
      "side": "debit",
      "amount": 260,
      "signedAmount": 260,
      "balanceAfter": 260
    },
    {
      "postingId": "je_7a408c00-L2",
      "entryId": "je_7a408c00",
      "entryType": "payment",
      "lineNumber": 2,
      "date": "2026-01-01T10:59:20.771Z",
      "currency": "DKK",
      "accountId": "revenue",
      "account": "Revenue",
      "accountType": "revenue",
      "normalBalance": "credit",
      "side": "credit",
      "amount": 260,
      "signedAmount": -260,
      "balanceAfter": -260
    },
    {
      "postingId": "je_cc99a401-L1",
      "entryId": "je_cc99a401",
      "entryType": "reversal",
      "lineNumber": 1,
      "date": "2026-01-02T16:45:30.723Z",
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

GET /api/ledger-entries/trial-balance

Summarizes a documented entry set — the first entries entries / returns for the same seed and the same parameters — into per-account debit and credit totals. difference is always 0.

Live requestRuns against the public API
No key required
GET/api/ledger-entries/trial-balance?seed=42

Request parameters

Active ISO 4217 code (3 letters, case-insensitive) every amount is denominated in. Amounts are integer minor units of this currency and no conversion is performed. XDR is rejected because ISO defines no minor unit for it.

Number of entries from the deterministic set to summarize (1–100). They are exactly the first N entries the root route returns for the same seed — this route accepts the root route's full parameter set, so currency, window, postingsPerEntry, entryType, accountType and the amount bounds all have to match for the two to reconcile.

Constrain generation to entries with at least one posting on an account of this type (asset, liability, equity, revenue or expense).

Exact number of postings in every entry (2–6). One side gets ⌈n/2⌉ legs and the other ⌊n/2⌋; both sides always sum to the same total.

Only generate this entry type. Omitted, you get an even mix of the six business types, and about 15% of entries (never the first) reverse one of the five entries before them.

Smallest amount of any single posting, in integer minor units (1 = one cent for USD, one yen for JPY). Bounds every posting, not the entry total.

Largest amount of any single posting, in integer minor units. Must be ≥ minAmount.

Start of the posting window, inclusive (YYYY-MM-DD = midnight UTC, or a full ISO 8601 timestamp). Defaults to 30 days before 'to'.

End of the posting window, inclusive. Defaults to today at UTC midnight, so a pinned seed returns identical entries all day. Must be ≥ from.

Seed of the entry set to summarize. Any integer (reduced modulo 2³² like the platform's universal seed) — pass the `seed` echoed by the root route to reconcile exactly the entries you fetched.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/ledger-entries/trial-balance?seed=42"
const res = await fetch("https://randomapi.dev/api/ledger-entries/trial-balance?seed=42");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/ledger-entries/trial-balance?seed=42").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/ledger-entries/trial-balance?seed=42"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 10
currency string

Active ISO 4217 code (3 letters, case-insensitive) every amount is denominated in. Amounts are integer minor units of this currency and no conversion is performed. XDR is rejected because ISO defines no minor unit for it.

default: USD
allowed: 3 – 3
example: currency=EUR
entries int

Number of entries from the deterministic set to summarize (1–100). They are exactly the first N entries the root route returns for the same seed — this route accepts the root route's full parameter set, so currency, window, postingsPerEntry, entryType, accountType and the amount bounds all have to match for the two to reconcile.

default: 25
allowed: 1 – 100
example: entries=40
accountType enum

Constrain generation to entries with at least one posting on an account of this type (asset, liability, equity, revenue or expense).

allowed: asset | liability | equity | revenue | expense
example: accountType=asset
postingsPerEntry int

Exact number of postings in every entry (2–6). One side gets ⌈n/2⌉ legs and the other ⌊n/2⌋; both sides always sum to the same total.

default: 2
allowed: 2 – 6
example: postingsPerEntry=4
entryType enum

Only generate this entry type. Omitted, you get an even mix of the six business types, and about 15% of entries (never the first) reverse one of the five entries before them.

allowed: payment | payout | refund | fee | transfer | accrual | reversal
example: entryType=payment
minAmount int

Smallest amount of any single posting, in integer minor units (1 = one cent for USD, one yen for JPY). Bounds every posting, not the entry total.

default: 100
allowed: 1 – 1000000000
example: minAmount=500
maxAmount int

Largest amount of any single posting, in integer minor units. Must be ≥ minAmount.

default: 250000
allowed: 1 – 1000000000
example: maxAmount=100000
from date

Start of the posting window, inclusive (YYYY-MM-DD = midnight UTC, or a full ISO 8601 timestamp). Defaults to 30 days before 'to'.

example: from=2026-01-01
to date

End of the posting window, inclusive. Defaults to today at UTC midnight, so a pinned seed returns identical entries all day. Must be ≥ from.

example: to=2026-03-31
seed int

Seed of the entry set to summarize. Any integer (reduced modulo 2³² like the platform's universal seed) — pass the `seed` echoed by the root route to reconcile exactly the entries you fetched.

default: 1
example: seed=42
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=currency,decimalDigits
exclude list

Return all fields except these (comma-separated).

example: exclude=difference
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 10
currency string

ISO 4217 code all totals are denominated in.

example: USD

decimalDigits integer

ISO 4217 minor-unit exponent for the currency — divide the integer totals by 10^this to display them.

example: 2

from string (ISO 8601)

Start of the summarized window, inclusive.

example: 2026-06-10T00:00:00.000Z

to string (ISO 8601)

End of the summarized window, inclusive.

example: 2026-07-10T00:00:00.000Z

entries integer

Number of journal entries summarized.

example: 25

postings integer

Number of postings across those entries.

example: 50

accounts object[]

One row per account with activity, ordered by accountId: accountId, account, accountType, normalBalance, debits, credits, balance (debits − credits) and postings.

example: [{"accountId":"cash","account":"Cash","accountType":"asset","normalBalance":"debit","debits":1284500,"credits":902100,"balance":382400,"postings":17}]

totalDebits integer

Sum of every debit posting in minor units.

example: 3100000

totalCredits integer

Sum of every credit posting in minor units — always equal to totalDebits.

example: 3100000

difference integer

totalDebits − totalCredits. Always exactly 0 by construction; the field exists so a reconciliation view has something to render.

example: 0

Documented examples

Build-generated requests and complete responses
5
Trial balance for the default entry set
GET /api/ledger-entries/trial-balance?seed=42
{
  "data": {
    "currency": "USD",
    "decimalDigits": 2,
    "from": "2026-06-29T00:00:00.000Z",
    "to": "2026-07-29T00:00:00.000Z",
    "entries": 25,
    "postings": 50,
    "accounts": [
      {
        "accountId": "accounts-payable",
        "account": "Accounts Payable",
        "accountType": "liability",
        "normalBalance": "credit",
        "debits": 214521,
        "credits": 350090,
        "balance": -135569,
        "postings": 6
      },
      {
        "accountId": "accounts-receivable",
        "account": "Accounts Receivable",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 150349,
        "credits": 286668,
        "balance": -136319,
        "postings": 5
      },
      {
        "accountId": "cash",
        "account": "Cash",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 333451,
        "credits": 813707,
        "balance": -480256,
        "postings": 9
      },
      {
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Reconcile the ten entries the root route returns
GET /api/ledger-entries/trial-balance?seed=42&entries=10
{
  "data": {
    "currency": "USD",
    "decimalDigits": 2,
    "from": "2026-06-29T00:00:00.000Z",
    "to": "2026-07-29T00:00:00.000Z",
    "entries": 10,
    "postings": 20,
    "accounts": [
      {
        "accountId": "accounts-payable",
        "account": "Accounts Payable",
        "accountType": "liability",
        "normalBalance": "credit",
        "debits": 9700,
        "credits": 9700,
        "balance": 0,
        "postings": 2
      },
      {
        "accountId": "accounts-receivable",
        "account": "Accounts Receivable",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 70907,
        "credits": 70907,
        "balance": 0,
        "postings": 2
      },
      {
        "accountId": "cash",
        "account": "Cash",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 247081,
        "credits": 230483,
        "balance": 16598,
        "postings": 2
      },
      {
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Danish kroner over a fixed quarter
GET /api/ledger-entries/trial-balance?currency=DKK&entries=40&from=2026-01-01&to=2026-03-31&seed=8
{
  "data": {
    "currency": "DKK",
    "decimalDigits": 2,
    "from": "2026-01-01T00:00:00.000Z",
    "to": "2026-03-31T00:00:00.000Z",
    "entries": 40,
    "postings": 80,
    "accounts": [
      {
        "accountId": "accounts-payable",
        "account": "Accounts Payable",
        "accountType": "liability",
        "normalBalance": "credit",
        "debits": 188288,
        "credits": 334373,
        "balance": -146085,
        "postings": 6
      },
      {
        "accountId": "accounts-receivable",
        "account": "Accounts Receivable",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 731077,
        "credits": 727968,
        "balance": 3109,
        "postings": 8
      },
      {
        "accountId": "cash",
        "account": "Cash",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 976512,
        "credits": 936398,
        "balance": 40114,
        "postings": 13
      },
      {
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Reconcile a feed filtered to fee entries
GET /api/ledger-entries/trial-balance?entryType=fee&entries=20&seed=12
{
  "data": {
    "currency": "USD",
    "decimalDigits": 2,
    "from": "2026-06-29T00:00:00.000Z",
    "to": "2026-07-29T00:00:00.000Z",
    "entries": 20,
    "postings": 40,
    "accounts": [
      {
        "accountId": "accounts-payable",
        "account": "Accounts Payable",
        "accountType": "liability",
        "normalBalance": "credit",
        "debits": 0,
        "credits": 789473,
        "balance": -789473,
        "postings": 7
      },
      {
        "accountId": "cash",
        "account": "Cash",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 0,
        "credits": 1168283,
        "balance": -1168283,
        "postings": 7
      },
      {
        "accountId": "clearing",
        "account": "Clearing Account",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 0,
        "credits": 801090,
        "balance": -801090,
        "postings": 6
      },
      {
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Trial balance of four-legged compound entries
GET /api/ledger-entries/trial-balance?postingsPerEntry=4&minAmount=500&maxAmount=100000&entries=30&seed=5
{
  "data": {
    "currency": "USD",
    "decimalDigits": 2,
    "from": "2026-06-29T00:00:00.000Z",
    "to": "2026-07-29T00:00:00.000Z",
    "entries": 30,
    "postings": 120,
    "accounts": [
      {
        "accountId": "accounts-payable",
        "account": "Accounts Payable",
        "accountType": "liability",
        "normalBalance": "credit",
        "debits": 131048,
        "credits": 237637,
        "balance": -106589,
        "postings": 7
      },
      {
        "accountId": "accounts-receivable",
        "account": "Accounts Receivable",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 198855,
        "credits": 273665,
        "balance": -74810,
        "postings": 8
      },
      {
        "accountId": "cash",
        "account": "Cash",
        "accountType": "asset",
        "normalBalance": "debit",
        "debits": 759394,
        "credits": 1081127,
        "balance": -321733,
        "postings": 36
      },
      {
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

About this API

Coverage & behavior

Double-entry journal entries that actually balance. Every amount is an integer number of minor units (cents, øre, whole yen) and every total is exact integer arithmetic — no floats, no rounding step, no currency conversion anywhere.

Four invariants hold, and the test suite proves each of them:

  1. Each entry balances. debitTotal === creditTotal, exactly, in minor units — on every route, at every count.
  2. A whole entry set balances. Sum every posting of / debit-positive and you get exactly 0 at any count, which is why /trial-balance always reports difference: 0. /postings is the exception by design: it returns a flat slice of ledger rows rather than whole entries, so it nets to zero only when the slice contains whole entries — an even count with no accountType filter (see below).
  3. Normal balances are correct. Assets and expenses are debit-normal; liabilities, equity and revenue are credit-normal. Every posting carries its account's normalBalance, so you can flip the sign for display.
  4. A reversal mirrors a real entry. In an unfiltered feed about 15% of entries (never the first) reverse one of the five entries before them: reversesEntryId names that earlier entry in the same response, and the reversal repeats its accounts and amounts with debit and credit swapped, dated no earlier than its source (strictly later whenever the window is at least 100 ms wide — see Determinism). Nothing is ever reversed twice, and a reversal never reverses a reversal.

The three routes

  • / — journal entries with their postings. postingsPerEntry (exactly 2–6) builds compound entries: one side gets ⌈n/2⌉ legs and the other ⌊n/2⌋, every leg stays inside minAmountmaxAmount, and both sides still sum to the same total.
  • /postings — the entry set / returns for the same seed and the parameters this route accepts (it pins the default two postings per entry and takes no entryType filter), flattened into ledger rows and capped at 100 rows, so an unfiltered response covers the first ⌈count/2⌉ entries of that set rather than all of them. Each row adds balanceAfter: the exact running balance of that account across the rows above it in this response. Because rows are a flat slice, signedAmount sums to 0 across the response only for an even count with no accountType filter; an odd count ends on an orphaned debit leg and the sum is exactly that last row.
  • /trial-balance — a summary of a documented, reproducible entry set: the first entries entries / returns for the same seed. It accepts the root route's full parameter set — currency, from, to, postingsPerEntry, entryType, accountType, minAmount and maxAmount — so any feed you can fetch from / can be reconciled here by passing the same values. It is never "whatever you fetched last".

Determinism you can rely on

Every record is a function of the seed and its index alone, never of count. The first three rows of ?seed=42&count=3 are byte-identical to the first three of ?seed=42&count=100, and balanceAfter is a prefix sum over that fixed stream rather than an accumulator that depends on how much you asked for. Entry i is dated inside slot i of 100 equal slots across the inclusive [from, to] window, which is exactly what makes the timeline stable — so count=100 spans the whole window and a smaller count covers its earliest part.

A window narrower than 100 ms has fewer milliseconds than slots, so adjacent slots collapse onto the same instant. Dates are then non-decreasing instead of strictly increasing, and a reversal can carry exactly the timestamp of the entry it reverses. A warning says so whenever it applies — including the from === to case, where every entry is dated at that single instant.

Filters that genuinely constrain

  • entryType pins every entry to one type. Filtering to a non-reversal type removes reversals, so reversesEntryId is null throughout. entryType=reversal returns only the reversing side: each record reverses the record before it (a reversal of a reversal restores the original postings, so the chain alternates) and the first record has nothing to reverse — its reversesEntryId is null and a warning says so. Drop the filter for a realistic mixed feed.
  • accountType constrains generation so every entry has at least one posting on an account of that type. On /postings it also limits the rows to that type, which never drops a posting on those accounts — that is why balanceAfter stays exact.
  • Combinations no template can satisfy (for example entryType=transfer&accountType=revenue) return a 400 naming both values instead of quietly ignoring one.
  • minAmount/maxAmount bound every posting, not the entry total. A compound entry therefore needs ⌈n/2⌉ × minAmount ≤ ⌊n/2⌋ × maxAmount; when that is impossible the API says so with a 400 rather than silently emitting an out-of-range leg.

The chart of accounts

Eight generic accounts — Cash, Clearing Account, Accounts Receivable, Accounts Payable, Deferred Revenue, Retained Earnings, Revenue and Processing Fees. They deliberately carry no statutory numbering from any jurisdiction: accountId is a slug, not a legal account code, and nothing here is a compliant chart of accounts for anywhere.

Each entry type draws its debit and credit accounts from a fixed, role-homogeneous pool, so every combination is a sensible entry and no entry ever debits and credits the same account:

entryType debits one of credits one of
payment Cash, Clearing Account Accounts Receivable, Deferred Revenue, Revenue
payout Accounts Payable, Retained Earnings Cash, Clearing Account
refund Revenue, Deferred Revenue Cash, Clearing Account, Accounts Payable
fee Processing Fees Cash, Accounts Payable, Clearing Account
transfer Clearing Account Cash
accrual Accounts Receivable, Deferred Revenue Revenue
reversal the credits of the entry it reverses the debits of the entry it reverses

Compound entries keep rotating through the same pool, so an entry with more legs on one side than that pool has accounts posts more than one line to an account — a normal multi-line entry.

What this is not

Fixture data for building ledger UIs, reconciliation screens and trial-balance reports. No entry corresponds to a real transaction, no amount is anybody's money, and none of this is accounting, tax or audit advice. It models the mechanics of double-entry bookkeeping — debits, credits, normal balances, reversals — not the tax or regulatory treatment of anything.

The entry-type mix is uniform rather than modelled on a real business, and that produces a systematic, not occasional, artifact: accounts routinely close a window on the opposite side of their normal balance. Cash sits in the credit pool of four of the six entry types (payout, refund, fee, transfer) and the debit pool of one (payment), so over a few dozen entries it almost always ends with a credit balance — an impossible position for a real cash account. Retained Earnings appears only as a debit (in payout), so it is never credited except by a reversal. The trial balance still reconciles to difference: 0 and every entry is internally correct — the arithmetic is exact, the economics are not simulated. Use this to exercise ledger mechanics, not to demo plausible financials.

Use it for

  • Build a journal-entry or general-ledger table that shows both sides of every posting
  • Demo a reconciliation screen whose trial balance actually nets to zero
  • Test reversal handling and running-balance math in an accounting UI with a pinned seed

Frequently asked questions

Do the debits and credits in these journal entries actually balance?

Yes. Every entry's debitTotal equals its creditTotal exactly in integer minor units, and any whole set of entries nets to zero — so / at any count sums to 0 and /trial-balance always reports difference: 0. /postings returns individual ledger rows rather than whole entries, so a response there nets to zero only when count is even and no accountType filter is applied.

How is this different from the transactions endpoint?

/api/transactions is single-sided — one amount per row, which is what a bank-feed UI needs. Here every entry carries both sides, so a ledger table, an account balance and a trial balance all reconcile.

Is the running balance still correct when I change count?

Yes. balanceAfter on /postings is a prefix sum over a stream that depends only on the seed and the row index, so the first N rows of count=N are byte-identical to the first N rows of count=100.

Can I resolve reversesEntryId inside the same response?

Yes — a reversal always names an earlier entry from the same response and repeats its accounts and amounts with the sides swapped. The one exception is the first record when you filter with entryType=reversal: nothing precedes it, so its reversesEntryId is null and a warning explains why.

Can two journal entries end up with the same timestamp?

Only when the window is narrower than 100 ms. Entry i is dated inside slot i of 100 equal slots across [from, to], so any window of at least 100 ms gives every entry a strictly later date than the one before it. A shorter window has fewer milliseconds than slots, dates become non-decreasing and a reversal can share its source's instant — a warning tells you when that applies.

Is this a real chart of accounts I can use in production?

No. The eight accounts are generic and deliberately carry no statutory numbering from any jurisdiction, and every entry is fixture data — it is not accounting advice and no entry corresponds to a real transaction. The entry-type mix is also uniform rather than realistic, so Cash almost always ends a window with an (impossible) credit balance and Retained Earnings is only ever credited by a reversal.

Standards & references