Reneva
IT EN Sign in

API

Keys for Reneva's REST API and the call log, on the Developers page.

Developers is a single page, with no tabs. At the top are keys for Reneva's REST API (/api/v1), shared across all companies; below them, the webhooks. API log and Webhook log are at the bottom.

API keys

With New key choose a name, read and write permissions for each section and an expiry (1, 3, 6, 12 months or "Never expires"). The sections are the same as in roles: Subscriptions, Client projects, Clients, Expenses and suppliers, Documents and registers, Price list and the others. Every key has a fixed cap of calls per minute.

With MCP connection the same key also serves AI assistants linked to the MCP endpoint in the AI tab: the assistant reads only the lists of the sections with Read ticked. On its own that permission does not open the routes below.

Copy the key as soon as you create it: Reneva does not show it again. The prefix visible in the table only helps you recognize it, it is not enough to authenticate.

Each key applies to all companies allowed for its creator and acts with that user’s current permissions: a scope can only narrow what the user can already do, never widen it. A key's status is one of Active, Off (from the toggle in the list), Revoked or Key expired — the last two cannot be turned back on.

With Edit you change name and permissions. With Revoke you close it immediately: a revoked key stops working and cannot be reactivated, it stays only in the table and the log as history.

Routes and scopes

Every request carries the key as a Bearer token: Authorization: Bearer <prefix>.<secret>.

Specify the company using the company parameter (ID or code), in the query or JSON body. If the user can access multiple companies and the parameter is missing, the request is rejected; with only one allowed company, that one is used. Switching companies in the panel does not change an API request. MCP tools using a key require an explicit company; data stays separate for each company.

A scope is the section plus the action: renewals:read to read subscriptions, renewals:write to write them. The section is the one of roles: spot_jobs for client projects, expenses for expenses and suppliers, documents for documents and registers. A key created before 15/10 with the Movements or Suppliers permissions must be opened with Edit and saved with the new ticks.

Reads

GET /api/v1/lists lists what the key can read. GET /api/v1/lists/{list} reads a list as you see it in the panel: same starting filters, same columns, same totals. Parameters, all optional: search, from and to (YYYY-MM-DD dates on the date of the list), filters[name]=value, tab, columns[], group_by, sort, sort_direction and limit (up to 50 rows).

The answer carries count, totals (the totals of the view, already computed), rows as CSV and truncated when there are more rows than the limit. The first call without filters also tells the filters, columns and tabs available.

Writes

Section Scope Path Methods
Clients clients:write /api/v1/clients POST, PATCH /{id}, POST /{id}/notes
Subscriptions renewals:write /api/v1/renewals POST, PATCH /{id}
Client projects spot_jobs:write /api/v1/jobs POST, PATCH /{id}
Expenses expenses:write /api/v1/expenses POST
Suppliers expenses:write /api/v1/suppliers POST, PATCH /{id}
Movements documents:write /api/v1/movements POST
Internal projects internal_projects:write /api/v1/internal_projects POST, PATCH /{id}

[!NOTE] Documents can only be read. The API does not issue, void or correct an invoice: those stay actions you take in the app.

In writes amounts are in cents and net of VAT. On a subscription or client project item the price is for one unit: the quantity makes the row total.

On an update items is the full list of items: send them all, even the ones that do not change. A row with its id updates that item and leaves everything else where it is — discount, VAT, price list, cost. A row without an id is a new item. Items you leave out are deleted.

Writes go through the same engines as the panel. When a rule of the app says no — items of a subscription already invoiced, details of a supplier that already has expenses — you get an error with the reason, not a silent write.

Examples

The list of clients:

curl -H "Authorization: Bearer <prefix>.<secret>" \
     -H "Accept: application/json" \
     "https://your-domain/api/v1/lists/clients?company=GMK"

A new subscription:

curl -X POST https://your-domain/api/v1/renewals?company=GMK \
     -H "Authorization: Bearer <prefix>.<secret>" \
     -H "Content-Type: application/json" \
     -d '{"client_id":12,"title":"Annual hosting","interval_months":12,"next_due_date":"2026-12-31","items":[{"description":"Hosting","amount_cents":12000,"category_id":3}]}'

A client project to update:

curl -X PATCH https://your-domain/api/v1/jobs/7?company=GMK \
     -H "Authorization: Bearer <prefix>.<secret>" \
     -H "Content-Type: application/json" \
     -d '{"title":"Website restyling 2026","due_date":"2026-11-30"}'

Limits

Each key can make 60 calls per minute, that is one per second. Before authentication a per-IP cap also applies: 300 calls per minute.

Past the cap the answer is 429. It carries the Retry-After header with the seconds to wait before trying again.

Every answer carries two headers: X-RateLimit-Limit is the cap, X-RateLimit-Remaining tells how many calls are left this minute.

Every call stays in the log below, successful or failed, with its status and — when it failed — the reason in one word.

API log

At the bottom of Developers, after keys and webhooks, the API log shows the latest requests across all companies, with the company, outcome and duration; a rejected call (too many calls, missing scope, expired key…) also shows the reason next to the code. The log never shows the key or the request body. Historical calls without a recorded company show a dash; no company is inferred.

See also