Skip to main content
When an expense nature requires a receipt (i.e. the receipt is mandatory), you must follow a three-step process to attach it. You cannot pass a file upload ID directly in the expenseReceipts array — doing so will result in a 403 Forbidden error.

Step 1 — Upload the file

First, upload the receipt file (image, PDF, etc.) using the Files API:
POST /lucca-files/api/uploads HTTP/2
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Accept: application/json
Content-Type: multipart/form-data; boundary=----FormBoundary

------FormBoundary
Content-Disposition: form-data; name="form"; filename="receipt.pdf"
Content-Type: application/pdf

< ./receipt.pdf
------FormBoundary--
Save the returned id — this is your uploadId for the next step.

Step 2 — Create an ExpenseReceipt

Next, create an ExpenseReceipt resource by calling POST /api/v3/expenseReceipts. This step links the uploaded file to the Expenses module:
POST /api/v3/expenseReceipts HTTP/2
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Content-Type: application/json

{
  "ownerId": 123,
  "requiresOcr": false,
  "sourceId": "WebForm",
  "uploadId": "a24f4279-6bb4-4e1c-9b40-a80a5d44b36d"
}
PropertyTypeDescription
ownerIdintegerThe user ID of the expense owner. Must match the owner of the expense you will create at the next step.
requiresOcrbooleanSet to true if you want Lucca to run OCR (optical character recognition) on the receipt to automatically extract data.
sourceIdstringThe source of the receipt. Use "WebForm" when creating via API.
uploadIdstring (uuid)The id returned by /lucca-files/api/uploads in step 1.
Save the returned id (here f0d01fd0-...) — this is the ExpenseReceipt ID you will reference in the expense.

Step 3 — Create the expense with the receipt attached

Finally, create the expense via POST /api/v3/expenseTempItems, referencing the ExpenseReceipt by its id:
POST /api/v3/expenseTempItems HTTP/2
Host: example.ilucca.net
Authorization: lucca application={API_KEY}
Content-Type: application/json

{
  "expenseNatureId": 1,
  "purchasedOn": "2025-06-15",
  "paymentMethodId": 0,
  "quantity": 1,
  "originalTransaction": {
    "currencyId": "EUR",
    "grossAmount": 42.50
  },
  "processedAmounts": {
    "grossAmount": 42.50,
    "currencyId": "EUR"
  },
  "deviceId": "Web",
  "ownerId": 123,
  "merchant": "Restaurant ABC",
  "comment": "Business lunch",
  "expenseReceipts": [
    { "id": "f0d01fd0-5f27-4061-8dca-bee6318b0103" }
  ]
}
Do not pass the file upload ID (from step 1) directly in expenseReceipts. You must create an ExpenseReceipt resource first (step 2) and reference that ID. Passing the upload ID directly will result in a 403 Forbidden error with the message: “Property Id of type CleemyFile is not writable”.

Summary