skip to content

everything you need to talk to your ledger

a clean REST API. bearer token auth, JSON in and out, consistent error envelopes. read on Free, write on Plus and above.

Authentication

every request needs an API key. pass it as a Bearer token or via the X-Api-Key header. create keys from Settings → API Keys once you have an account.

readlist and get transactions, wallets, and categories
read_writeeverything in read + create, update, and delete (Plus/Pro only)

free-tier keys are read-only. write attempts return 403.

Rate Limits

daily request limits reset at midnight UTC. every response includes these headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 997
X-RateLimit-Reset: 1750896000
Free100 requests / day
Plus1,000 requests / day
Pro10,000 requests / day

Transactions API

List transactions

GET/api/v1/transactions
curl "https://api.ledger-post.com/v1/transactions?wallet=checking&from=2026-06-01&to=2026-06-30&page=1&pageSize=25" \
  -H "Authorization: Bearer lp_live_YOUR_KEY"

filter by wallet (slug) or walletId (UUID), category or categoryId, from, to (dates). paginate with page and pageSize (max 100, default 50).

Response200
{
  "data": [ { ... }, { ... } ],
  "pagination": {
    "total": 42,
    "page": 1,
    "pageSize": 25
  }
}

Get a transaction

GET/api/v1/transactions/:id

Create a transaction

POST/api/v1/transactions
curl -X POST https://api.ledger-post.com/v1/transactions \
  -H "Authorization: Bearer lp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "wallet": "checking",
    "amount": "12.50",
    "type": "Expense",
    "note": "coffee",
    "category": "food",
    "occurredAt": "2026-06-23T10:00:00Z"
  }'

amount (decimal string, required), type (Income, Expense, or Transfer), and a wallet are required — pass wallet (slug) or walletId (UUID). category / categoryId, note, and occurredAt are optional.

Pass "category": "auto" — or leave category off entirely — and your auto-categorization rules pick one from the note. No rule matches, and the entry just lands uncategorized. auto is a reserved keyword here, not a category slug, and it's a Plus feature; on Free the entry stays uncategorized. It only applies when you first write the line — rules fill blanks, they don't second-guess a category you already set.

Response201
{
  "data": {
    "id": "a1b2c3d4-...",
    "walletId": "...",
    "walletName": "Checking",
    "walletSlug": "checking",
    "categoryId": "...",
    "categoryName": "Food",
    "categorySlug": "food",
    "amount": "12.50",
    "type": "expense",
    "note": "coffee",
    "occurredAt": "2026-06-23T10:00:00.0000000Z",
    "source": "api",
    "createdAt": "2026-06-23T10:00:01.0000000Z"
  }
}

Update a transaction

PATCH/api/v1/transactions/:id
curl -X PATCH https://api.ledger-post.com/v1/transactions/TXN_UUID \
  -H "Authorization: Bearer lp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "updated note", "amount": "15.00" }'

all fields optional. send only what you want to change.

Delete a transaction

DELETE/api/v1/transactions/:id
curl -X DELETE https://api.ledger-post.com/v1/transactions/TXN_UUID \
  -H "Authorization: Bearer lp_live_YOUR_KEY"

Error Handling

all errors return a consistent envelope with a machine-readable code and a human-readable message.

Errorenvelope
{
  "error": {
    "code": "validation_error",
    "message": "wallet not found."
  }
}
400validation_error — bad input (missing amount, unknown wallet, etc.)
401invalid or revoked api key
403insufficient_scope — free key trying to write
404not_found — transaction doesn't exist or isn't yours
429daily rate limit exceeded

Apple Shortcuts

use Get Contents of URL to POST to the API. add the X-Ledgerpost-Source: shortcut header and entries show up with a Shortcuts badge in your dashboard.

POSTwith shortcut source
curl -X POST https://api.ledger-post.com/v1/transactions \
  -H "Authorization: Bearer lp_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Ledgerpost-Source: shortcut" \
  -d '{
    "wallet": "checking",
    "amount": "12.50",
    "type": "Expense",
    "note": "coffee"
  }'
When I leave Officeautomation trigger
↓
Ask for Amountnumeric prompt
↓
Ask for Notetext prompt
↓
Post to LedgerpostPOST /api/v1/transactions

no signal where you post? if you've added ledgerpost to your home screen, point the shortcut at the app instead of the api — it queues the entry on your device and sends it once you're back online, same as posting from the app itself. no api key needed for this one.

OPEN URLno network required
https://app.ledger-post.com/queue#<base64url of>
{
  "amount": "12.50",
  "type": "Expense",
  "walletId": "your-wallet-id",
  "note": "coffee"
}

build the json dictionary, base64-encode it (the shortcuts "encode" action, url-safe), then use Open URLs with that link instead of Get Contents of URL. walletId andcategoryId are the ids from your account — copy them once when you set the shortcut up.

want to build on ledgerpost?

join the waitlist and you'll be the first to get an API key.

we'll email you once, when it's ready — nothing else. see privacy.