Skip to main content
Create and manage receipt-based expenses using the dynamic Fields system in the Expense API. Create receipt-based expenses using the dynamic Fields system. This guide covers uploading receipts with OCR, initializing fields, handling categories and tax, managing representation expenses, and saving.

Overview

Receipt expenses use the ReceiptVerification expense type. They represent standard purchases where a user submits a receipt for reimbursement — covering everything from office supplies and meals to travel costs and representation/entertainment. This is the most common expense type and has the most straightforward field structure, making it the recommended starting point for your Fields integration. The server handles tax calculations, VAT logic, and country-specific rules — your client renders the fields and lets the user fill them in.

Key concepts

API endpoints

Step 1: Upload the receipt

Upload the receipt image before initializing fields. Use action=scan to trigger OCR, which extracts data that can pre-fill the expense form.
bash

Example response

Scan result fields

Not all fields are guaranteed in a scan result — OCR accuracy depends on receipt quality. Always let the user review and correct pre-filled values.

Step 2: Initialize fields

Fetch the field structure for a new receipt expense:
bash
To apply scan results, first initialize the fields with GET, then apply the scan result via PUT:
bash
To load an existing expense for editing:
bash

Field structure overview

The response contains these key fields:

Step 3: Handle categories and tax

The category field (categoryId) has requiresUpdate: true. Changing the category triggers a server round-trip that can:
  • Show or hide tax fields based on the category’s tax rules
  • Reveal representation fields (guest list, purpose) for entertainment categories
  • Change which custom dimensions are visible
  • Update VAT calculation logic

Fetching categories

Example response

Categories may include a section property for grouping in the UI.

Category suggestions from scan

If you used OCR scanning in Step 1, pass the scanResultId when fetching categories to highlight 0–3 suggested categories in the picker:
Suggested categories are returned with a suggested: true flag. Display them prominently so the user can quickly confirm or change the pre-selected category.

Tax fields

Tax-related fields appear based on the selected category and country. Common tax fields include:
Tax fields are computed server-side. When the user changes totalAmount, currencyCode, or categoryId, send a PUT to get recalculated tax values. Never compute tax client-side — rules vary by country, category, and organization settings.

Step 4: Handle currency and exchange rates

When a user selects a foreign currency (different from the organization’s reimbursement currency), additional exchange rate fields appear: The currencyCode field has requiresUpdate: true — changing it triggers a server round-trip that fetches the current exchange rate. The reimbursement amount is calculated at the expense record level (not within the verification object) and returned as reimbursementAmount on the expense itself.

Fetching currencies

Returns the list of currencies available in the organization. The data property on the currencyCode field contains the currently selected currency.

Step 5: Handle representation expenses

When a category requires representation/entertainment details, additional fields appear dynamically after the category is selected:

Guest list format

The GUEST_LIST control type holds an array of guest objects:

Representation types

Fetch representation types for the selected category:
The verification.representation.type field has requiresUpdate: true — changing it may alter visibility of other representation fields based on the organization’s configuration.

Step 6: The update cycle

Receipt expenses have several fields with requiresUpdate: true. When the user changes any of these, send the full fields array back to the server:
Fields that trigger an update:

Example update request

bash
Always send the complete fields array — including hidden fields and fields you didn’t modify. The server uses the full state to compute the response.

Step 7: Save the expense

Once the user has filled in all required fields, save the receipt expense. Create:
Update:
Send the full fields payload as the request body in both cases.

Using standard JSON format

Alternatively, extract values from the fields and use the standard expense format:
bash

Receipt attachments

The verification.receiptAttachment field uses the CONTENT_HOLDER control type. It stores the content ID from the upload step.

Uploading additional attachments

Some expenses support multiple attachments. Upload each file separately and reference the IDs:
bash

Retrieving receipt images

Fetch receipt images at a specific size for display in your UI:
The API resizes the image to fit within the specified dimensions while preserving aspect ratio.

Supported file types

The maximum file size is controlled by the organization’s expenseReceiptMaxSize setting (in MB). Check this value from the organization’s settings object to validate file size client-side before uploading.

Card transaction expenses

When an organization has card integrations, card transactions can be automatically converted into receipt expenses. These appear as draft expenses with the card transaction data pre-filled. Card transaction expenses include:
  • Pre-filled amount, currency, and date from the transaction
  • A reference to the card transaction ID
  • meta.capabilities.canBeMerged: true if the expense can be merged with a manually created expense
The user reviews the pre-filled data, attaches a receipt, selects a category, and submits — the same fields flow as a regular receipt expense.

Common integration patterns

The recommended flow for receipt expenses is scan-first: upload the receipt with action=scan, then initialize fields with GET and apply the scan result via PUT. This pre-fills amount, tax, currency, date, and suggests categories — reducing manual entry to selecting the correct category and confirming values.
When the user selects a currency different from the organization’s reimbursement currency, the exchange rate and reimbursement amount fields appear automatically after the requiresUpdate round-trip. Display the reimbursement amount prominently so the user knows the final amount they’ll receive. The exchange rate is pre-filled from Findity’s rate service but can be manually overridden if the organization allows it.
Organizations can configure an expense email address (available in the organization’s settings.expenseEmail). Receipts forwarded to this email are automatically created as draft expenses with OCR scanning applied. These appear in the user’s draft list with the receipt already attached and data pre-filled.
Display the receipt image next to the expense form so users can reference it while filling in details. Fetch the image using the content ID from the verification.receiptAttachment field:
On mobile, show the receipt as a tappable thumbnail that opens a full-screen viewer.
When a receipt expense is rejected, load it with the fields endpoint using expenseRecordId. The response includes an INFORMATION field with informationType: error containing the approver’s rejection comment. Display this prominently at the top of the form so the user knows what to fix before resubmitting.

Error handling

Common errors when working with receipt expenses:

Next steps

Last modified on October 13, 2026