API & AI
REST API
Authentication, conventions and examples for the REST API of Annuva.
All business data is available under /api/v1. The API, the MCP tools and the forms of the app are generated from the same entity definitions, so the API can always do what the UI can do.
Authentication
Create a personal API token in Annuva under Profile → API tokens and send it as bearer token:
curl -H "Authorization: Bearer an_…" https://annuva.example.com/api/v1/customers- A token belongs to its user and has the same permissions as that user (admin endpoints need an admin).
- The scope is either
readorread_write. Read tokens can only callGETendpoints. - Tokens can expire. The token is only shown once – store it in your password manager.
- In the browser the session cookie works as well.
Conventions
- JSON in and out,
Content-Type: application/jsonfor request bodies. - Money in entity endpoints are decimals in the instance currency (
60.5); the dashboard returns integer cents. - Dates are
YYYY-MM-DD, timestamps ISO 8601. - IDs are UUIDs.
Lists
GET /api/v1/{entity} returns {items, total, limit, offset} and accepts:
| Parameter | Description |
|---|---|
q |
Full-text search |
sort, order |
Sort field and asc / desc |
limit, offset |
Paging (max. 1000) |
customerId |
Only records of one customer |
includeArchived |
Customers only: include archived ones |
filter[field] |
Equality filter, e.g. filter[status]=open |
Entities: customers, partners, resources, offers, recurring-charges, recurring-costs, expenses, tasks, tax-years, tax-adjustments, invoice-templates and invoices.
Errors
Errors use the HTTP status code and a JSON body:
{
"error": {
"code": "unauthorized",
"message": "Authentication required.",
"details": null
}
}For validation errors (400) details contains the affected fields.
Endpoints at a glance
| Endpoint | Description |
|---|---|
GET /api/v1/{entity} |
List |
POST /api/v1/{entity} |
Create |
GET/PATCH/DELETE /api/v1/{entity}/{id} |
Read, update, delete |
POST/DELETE /api/v1/customers/{id}/archive |
Archive or restore a customer |
POST /api/v1/invoices/{id}/{action} |
issue, pay, reopen, cancel, send, remind |
GET /api/v1/invoices/{id}/pdf |
Invoice PDF (preview for drafts) |
POST /api/v1/billing/run |
Billing run (dryRun for a preview) |
GET /api/v1/dashboard |
All dashboard figures (year, customer); amounts in cents |
POST /api/v1/files, GET /api/v1/files/{id} |
Upload and download files |
GET/PATCH /api/v1/settings |
Company settings (admins) |
GET /api/v1/openapi |
OpenAPI 3.1 description |
The complete list with all parameters is in the API reference.
Examples
Create a customer:
curl -X POST https://annuva.example.com/api/v1/customers \
-H "Authorization: Bearer an_…" \
-H "Content-Type: application/json" \
-d '{"name": "Bakery Huber", "channel": "direct", "status": "active", "language": "de"}'Preview the billing run until the end of the year:
curl -X POST https://annuva.example.com/api/v1/billing/run \
-H "Authorization: Bearer an_…" \
-H "Content-Type: application/json" \
-d '{"until": "2026-12-31", "dryRun": true}'Issue a draft and download the PDF:
curl -X POST https://annuva.example.com/api/v1/invoices/<id>/issue -H "Authorization: Bearer an_…"
curl -o invoice.pdf https://annuva.example.com/api/v1/invoices/<id>/pdf -H "Authorization: Bearer an_…"OpenAPI
Every instance describes its API at /api/v1/openapi (OpenAPI 3.1). Import it into Postman, Insomnia or Bruno, or generate a client from it.