Using the REST API
The MoneyLights REST API lets your own systems read and maintain your organization’s data: transactions, vendors, clients, projects, categories and cashflow. You authenticate with an API key.
Calling the API
Section titled “Calling the API”Send your key in the X-API-Key header:
GET /api/transactions HTTP/1.1Host: api.moneylights.appX-API-Key: ml_sk_<key-id>_<secret>Authorization: ApiKey <key> also works. Authorization: Bearer <key> does
not — Bearer belongs to the browser session. Never put the key in the
URL: such requests are refused before they reach anything.
The machine-readable reference
Section titled “The machine-readable reference”The complete, always-current list of what your key can reach is the public OpenAPI document:
GET https://api.moneylights.app/api/public/openapi.jsonIt is generated from the running application and lists exactly the published
endpoints, each annotated with the scope it requires (x-required-scope). If
this guide and that document say different things, trust the document. You
can feed it to a client generator or import it into an API tool.
What is reachable — and what is not
Section titled “What is reachable — and what is not”Only endpoints that were explicitly published are part of the public API. The guiding rule is enrich and maintain, never destroy:
- You can list and filter transactions, assign them a category, vendor, client or project, split them across people (allocations), and create or update vendors, clients, projects and categories.
- You cannot delete a vendor, client, project or category through the API. Removing a record other records point at is a decision a script should not make unattended — those actions live in the app.
Bank connections, billing, team management and API-key management are never reachable with a key, whatever scopes it holds.
Rate limits
Section titled “Rate limits”Three limits apply, and a request must satisfy all of them:
| Plan | Reads/min per key | Writes/min per key | Requests/min per organization | Per day, per organization |
|---|---|---|---|---|
| Team | 120 | 30 | 120 | 10 000 |
| Enterprise | 600 | 150 | 600 | 100 000 |
The organization-wide per-minute limit is the one to design around. It is the same number as the per-key limit, so one key running flat out can consume the whole organization’s minute — adding keys does not buy throughput. If you have several integrations, spread their requests out over time.
Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. A
429 carries Retry-After in seconds — honour it; retrying immediately can
turn a short rate limit into an outage.
Errors
Section titled “Errors”Refusals carry a stable code that your integration can act on. The ones you
will actually meet:
| Code | Meaning |
|---|---|
api_key_invalid | The key is malformed or unknown, or its secret is wrong |
api_key_expired | Past its expiry date — create a new key |
api_key_revoked | The key was revoked, or the old secret was used after its rotation window closed |
api_key_scope_missing | The key lacks the scope this endpoint needs |
api_key_endpoint_not_published | The endpoint is not part of the public API |
api_key_rate_limited | Over a limit — honour Retry-After |
A request that sends no key gets a plain 401 with an empty body and no
error code. If you see that, the key header was not sent.
Date ranges
Section titled “Date ranges”GET /api/cashflow/overview takes an optional dateFrom and dateTo. If
omitted, dateFrom defaults to 1 January of the current year and dateTo to
today (both UTC). It returns 400, not an empty overview, when:
- a date cannot be parsed (for example
2026-13-01); dateFromis afterdateTo;- only
dateTois sent and it is earlier than the default start (1 January of the current UTC year) — send adateFromtoo; - only
dateFromis sent and it is later than today — send adateTotoo.
Good to know
Section titled “Good to know”- Your key reaches exactly one organization — the one it was issued for. It cannot be pointed anywhere else.
- Usage figures are approximate. Use “Last used” and the request count to check whether a key is still in use, not for billing.
- Prefer the API for data flows, and the MCP Server when an AI assistant makes the requests — same credential, same scopes.