POST /v1/transactions

Record a manual or Apple Pay transaction. Retrying with the same external_id, or the same Idempotency-Key, is safe.

Auth. Send the token in the X-Ledger-Token header.

Parameters

NameInTypeRequiredDescription
Idempotency-KeyheaderstringoptionalSend a unique key per logical create. A retry with the same key returns the first response and creates nothing new. Keys are kept for a day.

Request body

application/json: NewTransaction

FieldTypeRequiredDescription
sourcestring: one of manual, apple_payrequired
external_idstringoptionalClient-generated unique id, e.g. a UUID per entry
postedstring (date)required
amount_centsintegerrequiredNon-zero, magnitude up to 10000000
merchantstringrequired
categorystringoptionalMust be on the category list
account_idstringoptionalMust match an existing account
notestringoptional

Responses

StatusMeaningBody
201CreatedCreated
200A transaction with this external_id already existsCreated
400Request rejectedError
413Request rejectedError
415Request rejectedError
429Too many requests from this client address. Wait the number of seconds in Retry-After, then try again.Error

Example response

{
  "created": true
}

Code samples

Set KEY to your own token first.

curl

curl \
  -X POST \
  -H X-Ledger-Token:$KEY \
  -H "Content-Type: application/json" \
  -d '{"source": "manual", "external_id": "string", "posted": "2026-10-11", "amount_cents": 0, "merchant": "string", "category": "string", "account_id": "string", "note": "string"}' \
  "https://api.sasek.org/ledger/v1/transactions"

JavaScript

const res = await fetch("https://api.sasek.org/ledger/v1/transactions", {
  method: "POST",
  headers: { "X-Ledger-Token": KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "source": "manual",
    "external_id": "string",
    "posted": "2026-10-11",
    "amount_cents": 0,
    "merchant": "string",
    "category": "string",
    "account_id": "string",
    "note": "string"
  }),
});
const data = await res.json();

Python

import json
import os
import urllib.request

payload = {   'source': 'manual',
    'external_id': 'string',
    'posted': '2026-10-11',
    'amount_cents': 0,
    'merchant': 'string',
    'category': 'string',
    'account_id': 'string',
    'note': 'string'}

request = urllib.request.Request(
    "https://api.sasek.org/ledger/v1/transactions",
    method="POST",
    headers={
        "X-Ledger-Token": os.environ["KEY"],
        "Content-Type": "application/json",
    },
    data=json.dumps(payload).encode(),
)
with urllib.request.urlopen(request) as response:
    print(json.load(response))