Skip to content

Search documentation

Search documentation pages, sections, and topics.

On this page

Quickstart

This page takes you from a new account to a transaction posted through the API, in about fifteen minutes. You will build a ledger, design a small chart of accounts, post the same transaction twice — once by hand and once from code — and finish with a ledger that is already producing real reports.

The running example is a small rental marketplace. A guest pays $100 for a booking; you keep $10 as commission and owe the host $90. It is deliberately the smallest example that is still structurally correct, and it is the same shape as the full Marketplace example.

Before you start

Sign up from the Ledfra home page. You will enter your name, email, and password, then a six-digit code we email you. After that, one short screen asks for your workspace name and website.

A workspace is your organization, and everything below lives inside it. A new workspace has no ledger yet — that is the first thing you will create.

1. Create your ledger

From Ledgers, choose New ledger and give it a name, an optional description, and a currency.

A ledger is a self-contained book of accounts with its own structure and balances. Most companies need exactly one to start. Create a second only when you genuinely keep separate books — not to separate environments, which is what sandboxes are for.

Ledfra creates the five root categories every double-entry system is built on: Assets, Liabilities, Equity, Income, and Expenses. Everything you add hangs underneath one of them.

One currency per ledger
A ledger is denominated in a single currency, and each account holds one currency. Ledfra does not convert between currencies, and multi-currency ledgers are not supported yet. Pick the currency you keep your books in.

2. Add a sandbox to experiment in

Before you post anything real, open Sandboxes on your ledger and create one.

A sandbox is a structural copy of your ledger — the same chart of accounts, its own throwaway data. Structure flows one way, from production into the sandbox, so the two never drift apart. You reach a sandbox by swapping a live API key for a test key, and nothing you post there can touch your real balances.

Do the rest of this guide in the sandbox if you would rather not put practice transactions in your production ledger. Everything works identically. See Sandboxes for what does and does not sync.

3. Design your chart of accounts

Open the ledger editor. This is where you build structure: each of the five roots has a + menu offering a category, a control account, or an account template.

  • A category groups accounts. It holds no balance of its own.
  • A control account is a real account you name yourself — cash, commission, processing fees. There is a small, known set of them.
  • An account template is a pattern for per-object accounts — one payable per host, one wallet per user. You design it once and Ledfra creates each individual account the first time a transaction references its slug.

For this guide, create three control accounts:

UnderNameSlugWhat it holds
AssetsStripeassets:stripeMoney sitting in your Stripe balance
LiabilitiesHostsliabilities:payables-hostsWhat you owe hosts and have not paid yet
IncomeCommissionincome:commissionThe cut you actually keep
Only money you keep is income
The host's $90 is a liability, not income — you are holding money you owe someone else. Booking the full $100 as revenue is the single most common way a ledger balances perfectly and still reports the wrong number. That rule and the rest of the structural ones live in Chart of accounts design.

4. Draw the transaction before you post it

It is worth writing the entries down before touching a form or an API. Every transaction in Ledfra is a list of entries that must balance: total debits equal total credits, per currency.

AccountOperationAmount
assets:stripeDEBITUSD:100.00
income:commissionCREDITUSD:10.00
liabilities:payables-hostsCREDITUSD:90.00

$100 debited, $100 credited. One event, three entries, and the money is fully accounted for: cash arrived, $10 of it is yours, $90 of it is owed. Debit and credit are directions, not plus and minus — Transactions explains why a debit increases an asset and a credit increases a liability.

5. Post it from the app

Open Transactions → New transaction on your ledger, enter a description, and add the three entries above. The form will not let you save until the entries balance.

Posting once by hand is worth the two minutes: it shows you exactly what the API will do, and it proves your chart of accounts is usable before you write any code against it.

6. Issue an API key

Go to Developer and create a key. You choose:

  • Type — a live key (lfk_live_…) reaches your production ledgers; a test key (lfk_test_…) reaches sandboxes. A key can never cross that line, which is what makes the separation safe.
  • Scopesworkspace.ledgers.list, ledger.accounts.read, ledger.transactions.read, and ledger.transactions.create. Grant only what the integration needs.
The secret is shown once
Copy the key into your secrets store immediately. Ledfra stores a hash, not the token, so it cannot be shown again — if you lose it, issue a new key and revoke the old one.

Confirm the key works by listing the ledgers it can reach:

bash
curl 'https://ledfra.com/api/ledgers' \
  -H 'Authorization: Bearer YOUR_API_KEY'
json
[
  {
    "id": "9b7c1f2e-3d4a-4b5c-8e9f-1a2b3c4d5e6f",
    "name": "Firecnc",
    "description": "Production ledger"
  }
]

Take the id from that response — that is the {ledgerId} in every path below.

7. Post the same transaction from the API

Now post the transaction you already understand, this time over HTTP. Authenticate with Authorization: Bearer and send the entries as JSON.

bash
curl 'https://ledfra.com/api/ledgers/{ledgerId}/transactions' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: booking-1043' \
  -d '{
    "description": "Booking 1043 paid",
    "metadata": { "bookingId": "1043" },
    "entries": [
      { "account": "assets:stripe",             "operation": "DEBIT",  "amount": "USD:100.00" },
      { "account": "income:commission",         "operation": "CREDIT", "amount": "USD:10.00"  },
      { "account": "liabilities:payables-hosts", "operation": "CREDIT", "amount": "USD:90.00"  }
    ]
  }'

Three things in that request are worth noticing. Amounts are strings, never numbersUSD:100.00, so nothing is ever rounded through a float (see Money). metadata is where your own identifiers go, so an entry can always be traced back to the event that caused it. And Idempotency-Key makes the write retry-safe: resend the exact same request after a timeout and you get the original transaction back instead of a duplicate posting.

Unbalanced writes are rejected, not absorbed
Change one amount so the entries no longer balance and the request fails with a 400. Nothing partial is written. This is the guarantee the whole product is built on: you cannot ship a bug that silently loses money.

8. Read it back

A posted transaction is immutable. You never edit or delete one — to undo something you post its reverse, so the history stays intact and every figure remains explainable.

bash
curl 'https://ledfra.com/api/ledgers/{ledgerId}/transactions?limit=5' \
  -H 'Authorization: Bearer YOUR_API_KEY'

# And the balance of a single account
curl 'https://ledfra.com/api/ledgers/{ledgerId}/accounts/assets:stripe/balance' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Transactions come back most-recent first, with cursor pagination and optional since / till bounds. An account's balance is updated in the same write that posts the transaction, so the number the API returns is the number the app shows.

9. Next: let the reports fill up

One transaction is not a report. As your ledger collects real activity, four reports build themselves from the entries you have already posted — no export step, and no reporting pipeline for you to build:

Post a few days of real traffic before judging them. With the three accounts above, your balance sheet already shows $100 in assets against $90 of liabilities and $10 of equity earned — which is the whole point: it ties out on its own.

Where to go next

  1. Transactions — debits, credits, reversals, and holding funds before releasing them.
  2. Chart of accounts design — how to design structure that is still correct in three years.
  3. Marketplace example — the same story at full size, including payouts and processor fees.
  4. API reference — every endpoint, parameter, and error.

New to double-entry itself? What is Ledfra? explains the model and why it is enforced rather than assumed.