nenoDevelopers
⌘K
v1

Bills & Expenses

Upload an expense

POST/expenses

Documented alias of POST /bills. It requires bills:write and has the same form, responses and duplicate detection.

Headers

Idempotency-Keystring · max 255required

Client-generated key that identifies one write for 24 hours. Reuse it only when retrying the same method, path, query, and body.

Body · multipart/form-data

filestring · binaryrequired

PDF, JPEG, PNG, HEIC or HEIF file, up to 10 MB. HEIC and HEIF files are stored as JPEG.

notestring · max 1000

Responses

200
OK. A matching bill already exists. duplicate is true.
201
Created. Uploaded and queued for processing.
400
Bad request. Invalid multipart form.
401
Unauthorized. Missing, invalid, revoked, or expired API key.
403
Forbidden. The API key lacks a required scope or the creator lacks a required permission.
409
Conflict. A matching request with this Idempotency-Key is still in progress. Retry after one second.
413
Payload too large. File exceeds the 10 MB limit.
415
Unsupported media type. Unsupported file type or file bytes do not match the declared type.
422
Unprocessable content. This Idempotency-Key was already used for a different request.
429
Too many requests. Rate limit exceeded.
Request
curl -X POST https://api.neno.build/public/v1/expenses \
-H "Authorization: Bearer $NENO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "note=Receipt for client meeting travel."
201 Created · application/json
{
"id": "9b2f6c1e-4a7d-4f0e-8c3b-2d51e7a0f4c9",
"vendor": "Coolblue",
"supplierName": null,
"documentNumber": null,
"status": null,
"processingStatus": "PROCESSING",
"docType": "INVOICE",
"currencyCode": "EUR",
"netAmountMinor": null,
"taxTotalMinor": null,
"tipTotalMinor": null,
"totalMinor": null,
"documentDate": "2026-09-24",
"dueDate": "2026-10-24",
"paidAt": null,
"bookedAt": null,
"createdAt": "2026-09-24T09:30:00Z",
"updatedAt": "2026-09-24T09:30:00Z",
"duplicate": false
}