Fields - Food benefit expenses

Create and manage food benefit (kostförmån) expenses using the dynamic Fields system in the Expense API.

Create food benefit expenses (kostförmån) using the dynamic Fields system. This guide covers initializing fields, selecting meal types, handling dates, and saving food benefit records.

🇸🇪

Food benefits are currently only available for organizations in the Swedish market. The expense type will not appear in the organization's expense types list for non-Swedish organizations.

Overview

Food benefit expenses use the FoodBenefitsSpecification expense type. They allow employees to report meals provided by the employer as a taxable benefit (kostförmån) — a requirement under Swedish tax regulations. The employee records which meals were provided on which dates, and Findity calculates the benefit value for payroll reporting.

This is the simplest of the four expense types. It has a single hidden category (the user doesn't need to select one), and the form consists of a date, a description, and meal type toggles. No new control types are needed beyond what you've already built for receipt expenses.

Key concepts

ConceptDescription
Meal typesIndividual toggles for breakfast, lunch, and dinner. Each meal type has a fixed benefit value defined by Swedish tax rules.
Hidden categoryFood benefits have exactly one category, automatically selected. The categoryId field is present but hidden (visible: false).
Benefit valueThe taxable benefit amount is calculated server-side based on which meals are toggled on. Your client displays the result but doesn't compute it.
DateThe date the meal benefit was provided. One expense per date — if an employee receives benefits on multiple days, create one expense per day.

API endpoints

OperationMethodEndpoint
Initialize fieldsGET/v1/expense/me/organizations/{id}/expensetypes/FoodBenefitsSpecification/fields
Update fieldsPUT/v1/expense/me/organizations/{id}/expensetypes/FoodBenefitsSpecification/fields
Create expensePOST/v1/expense/expenses?format=fields&organizationId={id}&expenseType=FoodBenefitsSpecification
Update expensePUT/v1/expense/expenses/{expenseId}?format=fields
List expensesGET/v1/expense/expenses?organizationId={id}&processStatus={status}

Step 1: Initialize fields

Fetch the field structure for a new food benefit expense:

curl -X GET "https://stage-api.findity.com/api/v1/expense/me/organizations/{orgId}/expensetypes/FoodBenefitsSpecification/fields" \
  -H "Authorization: Bearer {access_token}"

To load an existing food benefit expense for editing:

curl -X GET "https://stage-api.findity.com/api/v1/expense/me/organizations/{orgId}/expensetypes/FoodBenefitsSpecification/fields?expenseRecordId={expenseId}" \
  -H "Authorization: Bearer {access_token}"

Field structure overview

The response is compact compared to other expense types:

Field propertycontrolTypeDescription
idTEXTExpense ID (hidden, system field)
categoryIdLISTCategory (hidden — auto-selected, visible: false)
verification.commentMULTI_LINE_TEXTDescription / comment
expenseReportIdLISTAssign to an expense report
verification.dateDATEDate the meal benefit was provided
verification.mealTypesFIELD_GROUPContainer for meal type toggles
Custom dimension fieldsLISTOrganization-specific dimensions (if configured)

Step 2: Handle meal types

The verification.mealTypes field group contains individual toggles for each meal:

Field propertycontrolTypeDescription
verification.breakfastSWITCHBreakfast provided — requiresUpdate: true
verification.lunchSWITCHLunch provided — requiresUpdate: true
verification.dinnerSWITCHDinner provided — requiresUpdate: true

Each toggle represents a meal provided by the employer on the specified date. The user switches on the meals that were provided.

Meal type behavior

  • Toggling a meal on marks it as a provided benefit for that date
  • At least one meal must be toggled on to save the expense
  • Each meal has a fixed benefit value determined by Swedish tax regulations — the server calculates the total
  • The meal toggles have requiresUpdate: true because changing them recalculates the benefit value

Example field group response

{
  "property": "verification.mealTypes",
  "controlType": "FIELD_GROUP",
  "visible": true,
  "fields": [
    {
      "property": "verification.breakfast",
      "name": "Breakfast",
      "controlType": "SWITCH",
      "value": false,
      "visible": true,
      "mandatory": false,
      "disabled": false,
      "requiresUpdate": true
    },
    {
      "property": "verification.lunch",
      "name": "Lunch",
      "controlType": "SWITCH",
      "value": true,
      "visible": true,
      "mandatory": false,
      "disabled": false,
      "requiresUpdate": true
    },
    {
      "property": "verification.dinner",
      "name": "Dinner",
      "controlType": "SWITCH",
      "value": false,
      "visible": true,
      "mandatory": false,
      "disabled": false,
      "requiresUpdate": true
    }
  ]
}

Step 3: The update cycle

Food benefits have a lightweight update cycle. The meal type toggles are the primary fields with requiresUpdate: true:

PUT /v1/expense/me/organizations/{id}/expensetypes/FoodBenefitsSpecification/fields

Fields that trigger updates

FieldWhat changes on update
verification.breakfastBenefit value recalculation
verification.lunchBenefit value recalculation
verification.dinnerBenefit value recalculation

Example update request

curl -X PUT "https://stage-api.findity.com/api/v1/expense/me/organizations/{orgId}/expensetypes/FoodBenefitsSpecification/fields" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": [
      { "property": "id", "value": null },
      { "property": "categoryId", "value": "auto-selected-category-id" },
      { "property": "verification.date", "value": "2024-03-15T00:00:00Z" },
      { "property": "verification.comment", "value": "Lunch provided at client site" },
      { "property": "verification.mealTypes", "fields": [
        { "property": "verification.breakfast", "value": false },
        { "property": "verification.lunch", "value": true },
        { "property": "verification.dinner", "value": false }
      ]}
    ]
  }'

After the update, the server returns recalculated benefit values in the response.

⚠️

Always send the complete fields array — including the hidden categoryId and any system fields. Even though the form is simple, the server expects the full state.

Step 4: Save the expense

Once the date and meal types are set, save the food benefit expense.

Using fields format (recommended)

Create:

POST /v1/expense/expenses?format=fields&organizationId={id}&expenseType=FoodBenefitsSpecification

Update:

PUT /v1/expense/expenses/{expenseId}?format=fields

Send the full fields payload as the request body.

Using standard JSON format

curl -X POST "https://stage-api.findity.com/api/v1/expense/expenses" \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "organizationId": "ff808181963979e20196397a2098004b",
    "categoryId": "auto-selected-category-id",
    "verification": {
      "type": "FoodBenefitsSpecification",
      "comment": "Lunch provided at client site",
      "date": "2024-03-15T00:00:00Z",
      "breakfast": false,
      "lunch": true,
      "dinner": false
    }
  }'

Example response

{
  "id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "organizationId": "ff808181963979e20196397a2098004b",
  "personId": "ff808181963979e20196397a119f002d",
  "status": "NORMAL",
  "processStatus": "DRAFT",
  "categoryId": "auto-selected-category-id",
  "reimbursementCurrency": "SEK",
  "reimbursementAmount": 0,
  "dateCreated": "2024-03-15T10:00:00Z",
  "lastUpdated": "2024-03-15T10:00:00Z",
  "verification": {
    "type": "FoodBenefitsSpecification",
    "comment": "Lunch provided at client site",
    "date": "2024-03-15T00:00:00Z",
    "breakfast": false,
    "lunch": true,
    "dinner": false
  },
  "meta": {
    "abbreviation": {
      "reimbursementDescription": "0.00 SEK",
      "dateDescription": "15 Mar 2024"
    },
    "capabilities": {
      "canBeEdited": true,
      "canBeDeleted": true,
      "canBeSentIn": true
    }
  }
}
📘

Food benefits typically have a reimbursementAmount of 0 — the employee is not reimbursed. Instead, the benefit value is reported as taxable income through payroll. The calculated benefit value appears in the voucher export via the Connect API.

Bulk creation for multiple dates

Employees often need to report food benefits for multiple days at once (e.g., a full work week). Since each food benefit expense represents a single date, create one expense per day:

const dates = ['2024-03-11', '2024-03-12', '2024-03-13', '2024-03-14', '2024-03-15'];

for (const date of dates) {
  // Initialize fields for each date
  const fields = await getFields(orgId, 'FoodBenefitsSpecification');

  // Set the date and meal types
  setFieldValue(fields, 'verification.date', `${date}T00:00:00Z`);
  setFieldValue(fields, 'verification.lunch', true);

  // Save each expense
  await createExpense(orgId, 'FoodBenefitsSpecification', fields);
}
💡

Consider building a "quick add" UI that lets users select a date range and meal types once, then creates all the individual expenses in the background.

Difference from per diem deductions

Food benefits and per diem meal deductions serve different purposes and should not be confused:

Food benefitsPer diem deductions
PurposeReport meals provided as a taxable benefitReduce per diem allowance for provided meals
Expense typeFoodBenefitsSpecificationSubsistenceAllowance
ResultAdds to taxable income (no reimbursement)Reduces the per diem reimbursement amount
When to useEmployer-provided meals at the office or regular workplaceMeals provided during business travel
MarketSwedish organizations onlyAll markets with per diem support

Common integration patterns

Calendar-based UI for food benefits

Since food benefits are date-based and typically recurring, a calendar view works well. Display each day of the month with indicators for which meals have been reported. Users can tap a day to toggle meals on/off, and your app creates or updates the corresponding expense. Fetch existing food benefit expenses for the month using the list endpoint with a date range filter.

Weekly batch creation

Many employees report food benefits at the end of each week. Build a weekly view that shows Monday–Friday with breakfast/lunch/dinner checkboxes for each day. On submit, create one expense per day for the selected meals. This reduces friction compared to creating one expense at a time.

Default meal type based on pattern

If an employee consistently reports the same meal type (e.g., lunch every weekday), pre-select that meal type when creating new food benefit expenses. Store the user's most common pattern client-side and apply it as a default — the user can always change it before saving.

Integration with payroll export

Food benefit values are included in the voucher export through the Connect API. When building a payroll integration, filter voucher lines for food benefit entries and map them to the correct payroll benefit code. The benefit value per meal is set by Swedish tax regulations and calculated by Findity — your integration just needs to pass the value through.

Error handling

Common errors when working with food benefit expenses:

Status codeError codeDescription
400INVALID_JSON_BODYFailed to parse the request body. Verify your JSON payload.
400INVALID_JSON_PROPERTY_VALUEMissing or invalid type on verification — ensure type is set to FoodBenefitsSpecification.
400DATE_REQUIREDThe benefit date is missing. Ensure verification.date has a value.
400NO_MEAL_TYPE_SELECTEDNo meal types are toggled on. At least one of breakfast, lunch, or dinner must be true.
400DUPLICATE_BENEFIT_DATEA food benefit already exists for this date. Edit the existing expense instead of creating a new one.
404EXPENSE_RECORD_NOT_FOUNDThe expense ID does not exist or is not accessible by the current user.
404ORGANIZATION_NOT_FOUNDThe organization does not exist or the user is not a member.
403EXPENSE_TYPE_NOT_AVAILABLEFoodBenefitsSpecification is not enabled for this organization. Food benefits are only available for Swedish organizations.

Next steps