Skip to Content
HelvetlyDocs
API referenceExpenses

Preview an expense without saving

Needs a token with the write:expenses scope. Authentication

Try in Playground sends a real request to app.helvetly.com with a token you paste. It stays in this browser tab only (session storage) and goes to no one else.

POST
/api/v1/expenses/preview

Runs the create rules and the computation on an ExpenseInput and answers with the expense it would produce (id empty, nothing written, no number used). Use it to check totals and VAT before create_expense. Same errors as create_expense.

Authorization

bearerAuth
headerAuthorizationBearer <token>

A personal API token, hvt_…, with scopes such as read:* or write:invoices

Request Body

application/json
  1. body

Fields of an expense you may set. Every field is optional on create (a draft needs nothing) and on update; an absent key is left alone and null clears a nullable field. Totals, VAT breakdown and base-currency amounts are computed by Helvetly and never accepted. A booked expense takes only payment_status, paid_on, payment_method, paid_by_member_id, reimbursed_on and note (409 expense_locked for anything else); a void one only note.

supplier_name?|

Up to 200 characters; required to book.

supplier_vat_number?|

Swiss UID (checksum verified) or EU VAT number; up to 30 characters.

supplier_country?string

ISO 3166 alpha-2, default CH. Anything but CH/LI defaults input_tax to none (foreign VAT is no Swiss input tax).

reference?|

The supplier's invoice or receipt number, up to 100 characters.

description?|

What was bought, up to 500 characters.

category_id?|

An active category of the workspace (see list_expense_categories); required to book.

document_date?|

The receipt's date, not in the future when booking; required to book.

Formatdate
due_date?|

Not before document_date.

Formatdate
currency?string

ISO 4217 with two minor units; default the workspace currency.

amount_mode?string

Whether line amounts include VAT (gross, default) or not (net).

Value in"gross""net"
lines?array<>

1 to 20 lines, one per VAT rate or cost item; on update the array replaces all lines.

Itemsitems <= 20
input_tax?string

Input tax (Vorsteuer) claim; default full when the workspace is VAT-registered, else none.

Value in"full""partial""none"
deductible_percent?string

Share of VAT reclaimable: 100 with full, 0 with none, above 0 and below 100 with partial.

Match^-?\d+(\.\d{1,2})?$
exchange_rate?string

Foreign currency to workspace currency; needed with exchange_rate_date and exchange_rate_source to book a foreign-currency expense.

Match^\d+(\.\d{1,6})?$
exchange_rate_date?|
Formatdate
exchange_rate_source?|
Value in"estv_monthly""estv_daily""bank""manual"null
payment_status?string

Setting unpaid clears paid_on, payment_method, paid_by_member_id and reimbursed_on; paid without paid_on uses the document date (or today).

Value in"unpaid""paid"
paid_on?|

Not in the future.

Formatdate
payment_method?|
Value in"bank_transfer""cash""card""twint""other"null
paid_by_member_id?|

A member of the workspace who paid out of pocket (makes it reimbursable and sets payment_status paid).

reimbursed_on?|

When the member was paid back; needs paid_by_member_id; not in the future.

Formatdate
note?|

Internal note, up to 1000 characters. Editable on booked expenses.

receipt_missing_reason?|

Substitute-receipt reason (Ersatzbeleg), up to 500 characters; stands in for a receipt when booking.

reverse_charge?boolean

Acquisition tax on a service from a supplier abroad; needs a supplier_country other than CH/LI.

input_tax_box?|

VAT return box for the input tax.

Value in"400""405"null

Response Body

OK

application/json
  1. response
data*
Example Request
curl -X POST 'https://app.helvetly.com/api/v1/expenses/preview' \  -H 'Content-Type: application/json' \  -d '{  "supplier_name": "Swisscom (Schweiz) AG",  "supplier_country": "CH",  "reference": "INV-2026-0412",  "category_id": "exc_01JABCDEF",  "document_date": "2026-10-31",  "currency": "CHF",  "amount_mode": "gross",  "lines": [    {      "description": "Mobile subscription October",      "amount": "89.90",      "vat_rate": "8.1"    }  ],  "payment_status": "paid",  "payment_method": "card"}'
Example Response
{  "data": {    "id": "string",    "number": 0,    "status": "draft",    "source": "string",    "supplier_name": "string",    "supplier_vat_number": "string",    "supplier_country": "string",    "reference": "string",    "duplicate_of": {      "id": "string",      "number": 0,      "date": "2019-08-24"    },    "description": "string",    "category": {      "id": "string",      "name": "string",      "account_code": "string"    },    "document_date": "2019-08-24",    "due_date": "2019-08-24",    "currency": "string",    "amount_mode": "string",    "lines": [      {        "id": "string",        "position": 0,        "description": "string",        "amount": "1234.50",        "vat_rate": "string"      }    ],    "net_total": "1234.50",    "vat_total": "1234.50",    "total": "1234.50",    "vat_breakdown": [      {        "rate": "string",        "taxable_amount": "1234.50",        "vat_amount": "1234.50",        "deductible_amount": "1234.50"      }    ],    "input_tax": "string",    "reverse_charge": true,    "input_tax_box": "string",    "deductible_percent": "string",    "deductible_vat": "1234.50",    "exchange_rate": "string",    "exchange_rate_date": "2019-08-24",    "exchange_rate_source": "string",    "base": {      "currency": "string",      "net_total": "1234.50",      "vat_total": "1234.50",      "total": "1234.50",      "deductible_vat": "1234.50"    },    "payment_status": "string",    "paid_on": "2019-08-24",    "payment_method": "string",    "paid_by_member": {      "id": "string",      "name": "string"    },    "reimbursed_on": "2019-08-24",    "is_overdue": true,    "note": "string",    "receipt_missing_reason": "string",    "receipts_count": 0,    "is_complete": true,    "missing_fields": [      "string"    ],    "created_by": {      "id": "string",      "name": "string"    },    "booked_at": "2019-08-24T14:15:22Z",    "booked_by": {      "id": "string",      "name": "string"    },    "voided_at": "2019-08-24T14:15:22Z",    "voided_by": {      "id": "string",      "name": "string"    },    "void_reason": "string",    "created_at": "2019-08-24T14:15:22Z",    "updated_at": "2019-08-24T14:15:22Z"  }}