Sandboxes
Testing a money integration is awkward for one reason: the thing you most need to rehearse is the thing you least want to get wrong. You want to post a full booking flow, watch balances move, and read the reports, without any of it landing in the books you will actually file.
A sandbox is a structural copy of a production ledger: the same chart of accounts, its own throwaway data. You reach it by swapping a live API key for a test key. Nothing else about your code changes.
What a sandbox is
A sandbox copies a production ledger's structure, meaning its categories, account templates, and control accounts, and keeps its own, separate transactions and balances. A fresh sandbox has production's exact chart of accounts with nothing posted to it, so you can replay real flows against a familiar shape.
| Copied from production (structure) | Not copied (data) |
|---|---|
| Categories | Transactions |
| Account templates | Balances |
| Control accounts | Template accounts (the per-object ones) |
Template accounts are not copied because they are data, not structure - a sandbox creates its own the first time a transaction references their slug, exactly as production does (see Accounts).
Structure stays in sync
You do not edit a sandbox's structure directly. You change the chart of accounts in the production ledger and Ledfra syncs the change down to every sandbox. Add a control account in production and it appears in the sandbox. Remove a category in production and it is removed there too. The sync is one-way, and production is always the source of truth.
Using a sandbox from the API
Sandboxes use the same endpoints as production - there is no separate base URL and no mode flag in the request. Which ledgers you can reach is decided entirely by your API key type:
- A live key (
lfk_live_…) reaches your production ledgers. - A test key (
lfk_test_…) reaches your sandbox ledgers.
A key can never cross that line, which is what makes the separation trustworthy: there is no request you can accidentally send with the wrong flag, because there is no flag. Point your integration at a test key and every call, GET /ledgers, posting transactions, reading balances, behaves identically.
# A test key (lfk_test_…) sees your sandbox ledgers — the same endpoint as production
curl 'https://ledfra.com/api/ledgers' \
-H 'Authorization: Bearer lfk_test_YOUR_TEST_KEY'For both key formats and how to send them, see Authentication in the API reference.
Creating and deleting sandboxes
Create a sandbox from its production ledger in the Ledfra app, on the ledger's Sandboxes tab, and name it something like Staging or Dev. You can keep more than one. Deleting a sandbox is permanent and removes all of its data. The production ledger is never affected.
Limitations
- A sandbox's structure is read-only. Change the chart of accounts in production and it syncs down - you cannot edit it in the sandbox.
- Sync is one-way (production → sandbox). Deleting a category or account in production removes its copy from the sandbox.
- A new sandbox starts empty, with no transactions, balances, or template accounts until you post to it.
- A test key only sees sandboxes and a live key only sees production, so reach for the key type that matches what you are doing.
- Deleting a sandbox is permanent.
Where to go next
- Quickstart - create a sandbox and post your first transaction into it.
- Accounts & templates - the structure a sandbox copies.
- Transactions - what you will be posting once you are in one.
- What is Ledfra? - where sandboxes sit in the model.