Developers

A REST API over the ledger, not around it.

The API posts through the same code path as the screens, with the same balance check, the same permission model and the same audit event. There is no back door that skips the accounting rules — which is the whole reason to have one.

Authentication

One bearer key, scoped and optionally pinned

Keys are shown once, stored hashed, and carry a capability subset. A key can be pinned to a single company, so an integration built for one set of books cannot reach another.

Request
curl https://app.falcon.godengine.si/api/v1/reports/trial-balance \
  -H "Authorization: Bearer iak_…" \
  -G -d from=2026-04-01 -d to=2027-03-31

# 200 OK
# X-API-Version: v1
# X-RateLimit-Remaining: 119
{
  "data": {
    "balanced": true,
    "difference": "0.0000",
    "rows": [ … ]
  }
}

Surface

What is exposed today

Deliberately small. Every endpoint here is covered by tests that exercise it over HTTP with a real key, including the failure cases. A scope is a capability string in namespace:verb form — the same text you tick when you create a key, because a key holds capabilities rather than a separate set of API-only names.

Public API endpoints and their required scopes
MethodPathScopeNotes
GET/api/v1/companiescompany:viewCompanies the key may see.
GET/api/v1/accountsaccount:viewChart of accounts, with balances.
GET/api/v1/partiesparty:viewCustomers and suppliers.
GET/api/v1/vouchersvoucher:viewDay book, filtered and paged.
POST/api/v1/vouchersvoucher:postPost a balanced voucher. Needs an Idempotency-Key.
GET/api/v1/reports/trial-balanceaccounting:reportDerived, never cached.
GET/api/v1/openapi—The OpenAPI 3.1 document. No key required.

Details

The things that bite

What happens if I retry a POST?
Posting a voucher requires an Idempotency-Key header, and a request without one is refused. A retry with the same key returns the voucher the first request posted rather than posting a second. Financial writes are the one place where "just try again" has to be safe.
Can a key do more than the person who made it?
No. A key carries a subset of its creator’s capabilities and is validated against that subset on every request. Requesting a scope the creator lacks fails at creation time, not at use time.
How is the API versioned?
In the path. /api/v1 will keep its response shapes; anything that changes them becomes /api/v2. Every response carries an X-API-Version header (v1) so a client can assert what it is talking to.
What are the rate limits?
120 requests a minute per key. Every response carries the number of requests remaining in the current minute, and a request over the limit is refused with status 429.

Build against real books.

Create an account, generate a key with only the scopes you need, and post your first voucher over HTTP.

Developers · Falcon