What this does
The Expenses API lets you create and manage expense claims programmatically. Use it to push expenses from receipt-scanning tools, finance bots, or external procurement systems into Relentify. If your entity has expense approval enabled, newly created expenses enter a pending_approval state until approved via the UI or the approve endpoint.
When to use it
Use this endpoint when a bot, mobile app, or automation needs to log a business expense without the user opening the dashboard — for example, a receipt-scanning integration that creates an expense from a photographed receipt.
Authentication and scopes
Requests must include Authorization: Bearer rly_your_key_here. Each endpoint requires one of:
expenses:read— list and retrieve expensesexpenses:write— create, update, and delete expenses
Endpoints
List expenses
GET /api/v1/expenses
Returns a paginated list of expenses ordered newest-first. Supports ?page=1&limit=50 query parameters.
Create an expense
POST /api/v1/expenses
{
"description": "Train ticket — Manchester to London",
"date": "2026-04-25",
"grossAmount": 84.50,
"vatRate": 20,
"category": "Travel"
}
description, date, and grossAmount are required. grossAmount is the total including VAT. vatRate defaults to 0 if omitted. category is a free-text string mapped to the nearest nominal account.
Response (201 Created): the created expense object including id, status, and the net/VAT breakdown.
If expense approval is enabled for the entity, status is pending_approval. If approval is disabled, status is approved and the GL entry is posted immediately.
403 period_locked— the expense date falls in a locked accounting period
Get a single expense
GET /api/v1/expenses/:id
Returns the expense scoped to the calling key's user.
Update an expense
PATCH /api/v1/expenses/:id
Pass only the fields you want to change. Only expenses in pending_approval or draft status can be updated.
Delete an expense
DELETE /api/v1/expenses/:id
Removes the expense. Returns 404 not_found if the expense does not belong to the calling key's user. Deletion is rejected with 403 period_locked if the expense date falls in a locked period.
Test mode
Test-mode keys validate the request and return a stubbed response with "test": true in the envelope; no database writes are performed.