Reimburse employee expenses

Step-by-step guide to processing expense reimbursements through payroll

Overview

This guide walks you through the complete process of reimbursing business expenses for payroll employees using the adjustments API. You will learn how to submit expense reimbursements with supporting documentation, track approval workflows, and ensure timely payment through the regular payroll cycle.

When to use this workflow

Use this workflow when you need to:

  • Reimburse employees for travel expenses (flights, accommodation, transportation)
  • Pay back equipment purchases (laptops, monitors, office supplies)
  • Compensate for client meals and entertainment expenses
  • Process mileage or vehicle allowances
  • Refund any business-related expenses paid by employees

Prerequisites

Before you begin, ensure you have:

  • A valid API token with adjustments:write scope
  • The contract_id of the employee receiving the reimbursement
  • Expense details (amount, category, date, description)
  • Supporting documents (receipts, invoices) uploaded to a file storage service

Expense reimbursements are processed through the regular payroll cycle. Submit reimbursements before the payroll cutoff date to ensure they appear on the next payslip.

Step-by-step workflow

This example demonstrates reimbursing an employee $345.67 for a business trip, including flight and accommodation costs.

1

Identify the employee contract

First, retrieve the contract ID for the employee receiving the reimbursement. You can list contracts and filter by employee email or employee number.

$curl --request GET 'https://api.letsdeel.com/rest/v2/contracts?status=active&type=global_payroll' \
>--header 'Authorization: Bearer {{token}}'

Response:

1{
2 "data": [
3 {
4 "id": "gp8x3k5m",
5 "title": "Senior Product Manager",
6 "type": "global_payroll",
7 "worker_first_name": "Maria",
8 "worker_last_name": "Garcia",
9 "status": "active",
10 "employee": {
11 "email": "maria.garcia@company.com",
12 "employee_number": "EMP-2024-0042",
13 "first_name": "Maria",
14 "last_name": "Garcia"
15 },
16 "compensation_details": {
17 "amount": 7500.00,
18 "currency_code": "USD",
19 "frequency": "monthly"
20 }
21 }
22 ]
23}

Save the id field - this is your contract_id.

2

Retrieve available expense categories

Before creating a reimbursement, check which expense categories are available for your organization.

$curl --request GET 'https://api.letsdeel.com/rest/v2/adjustments/categories' \
>--header 'Authorization: Bearer {{token}}'

Response:

1{
2 "data": [
3 {
4 "id": "c1a23456b78c90d1e2f3g4h5",
5 "name": "Travel Expenses",
6 "label": "Travel Expenses",
7 "unit_type": "currency"
8 },
9 {
10 "id": "c2b34567c89d01e3f4g5h6i7",
11 "name": "Equipment Purchase",
12 "label": "Equipment Purchase",
13 "unit_type": "currency"
14 },
15 {
16 "id": "c3c45678d90e12f4g5h6i7j8",
17 "name": "Meals & Entertainment",
18 "label": "Meals & Entertainment",
19 "unit_type": "currency"
20 }
21 ]
22}

Identify the category ID that matches your expense type. For this example, we will use the “Travel Expenses” category.

3

Create the expense reimbursement

Submit the reimbursement with detailed description and expense breakdown. Include file attachments for receipts and invoices.

$curl --request POST 'https://api.letsdeel.com/rest/v2/adjustments' \
>--header 'Authorization: Bearer {{token}}' \
>--header 'Content-Type: application/json' \
>--data-raw '{
> "contract_id": "gp8x3k5m",
> "title": "Business Trip Reimbursement - NYC Client Meeting",
> "amount": "345.67",
> "adjustment_category_id": "c1a23456b78c90d1e2f3g4h5",
> "date_of_adjustment": "2026-02-10",
> "description": "Client meeting travel expenses: Flight $245.00, Hotel $85.67, Ground transport $15.00",
> "move_next_cycle": false,
> "file": {
> "id": "file_abc123xyz789",
> "name": "travel_receipts_feb2026.pdf",
> "fileType": "pdf"
> }
>}'

Always provide a detailed description breaking down the expense. This helps with approval tracking, audit trails, and makes it clear to the employee what is being reimbursed.

Response:

1{
2 "data": {
3 "id": "adj_9f8e7d6c-5b4a-3210-98fe-dcba09876543",
4 "status": "OPEN",
5 "created": true,
6 "contract_id": "gp8x3k5m",
7 "title": "Business Trip Reimbursement - NYC Client Meeting",
8 "amount": "345.67",
9 "adjustment_category_id": "c1a23456b78c90d1e2f3g4h5",
10 "description": "Client meeting travel expenses: Flight $245.00, Hotel $85.67, Ground transport $15.00",
11 "date_of_adjustment": "2026-02-10",
12 "file": {
13 "id": "file_abc123xyz789",
14 "name": "travel_receipts_feb2026.pdf",
15 "fileType": "pdf"
16 },
17 "created_at": "2026-02-06T14:30:00.000Z",
18 "updated_at": "2026-02-06T14:30:00.000Z"
19 }
20}

The reimbursement is now created with OPEN status, ready for processing through the payroll cycle.

4

Verify the reimbursement details

Confirm that the reimbursement was created correctly by retrieving its details.

$curl --request GET 'https://api.letsdeel.com/rest/v2/adjustments/adj_9f8e7d6c-5b4a-3210-98fe-dcba09876543' \
>--header 'Authorization: Bearer {{token}}'

Response:

1{
2 "data": {
3 "id": "adj_9f8e7d6c-5b4a-3210-98fe-dcba09876543",
4 "status": "OPEN",
5 "title": "Business Trip Reimbursement - NYC Client Meeting",
6 "amount": "345.67",
7 "contract_id": "gp8x3k5m",
8 "adjustment_category_id": "c1a23456b78c90d1e2f3g4h5",
9 "description": "Client meeting travel expenses: Flight $245.00, Hotel $85.67, Ground transport $15.00",
10 "date_of_adjustment": "2026-02-10",
11 "move_next_cycle": false,
12 "cycle_reference": "2026-02",
13 "actual_start_cycle_date": "2026-02-01T00:00:00.000Z",
14 "actual_end_cycle_date": "2026-02-28T23:59:59.000Z",
15 "file": {
16 "id": "file_abc123xyz789",
17 "name": "travel_receipts_feb2026.pdf",
18 "fileType": "pdf"
19 },
20 "created_at": "2026-02-06T14:30:00.000Z",
21 "updated_at": "2026-02-06T14:30:00.000Z"
22 }
23}

The reimbursement is associated with the correct payroll cycle and includes the attached receipt file.

5

Track reimbursement status

As the reimbursement progresses through the payroll workflow, its status will change. Check the status periodically to track approval and payment.

$curl --request GET 'https://api.letsdeel.com/rest/v2/adjustments/adj_9f8e7d6c-5b4a-3210-98fe-dcba09876543' \
>--header 'Authorization: Bearer {{token}}'

Response after approval:

1{
2 "data": {
3 "id": "adj_9f8e7d6c-5b4a-3210-98fe-dcba09876543",
4 "status": "SUCCESS",
5 "title": "Business Trip Reimbursement - NYC Client Meeting",
6 "amount": "345.67",
7 "contract_id": "gp8x3k5m",
8 "cycle_reference": "2026-02",
9 "actual_start_cycle_date": "2026-02-01T00:00:00.000Z",
10 "actual_end_cycle_date": "2026-02-28T23:59:59.000Z"
11 }
12}

Once the status changes to SUCCESS, the reimbursement has been approved and will be included in the employee’s next payslip.

6

Retrieve all reimbursements for an employee

To view the complete reimbursement history for an employee, list all adjustments for their contract.

$curl --request GET 'https://api.letsdeel.com/rest/v2/contracts/gp8x3k5m/adjustments' \
>--header 'Authorization: Bearer {{token}}'

This returns all adjustments (bonuses, deductions, reimbursements) for the contract. Filter on the client side by category or description to identify expense reimbursements.

Alternative: Manual approval workflow

For organizations requiring explicit approval before reimbursements are processed, use a manual approval workflow.

Create reimbursement pending approval

Create the reimbursement in DRAFT status, requiring explicit approval before processing.

$curl --request POST 'https://api.letsdeel.com/rest/v2/adjustments' \
>--header 'Authorization: Bearer {{token}}' \
>--header 'Content-Type: application/json' \
>--data-raw '{
> "contract_id": "gp8x3k5m",
> "title": "Equipment Purchase - Monitor",
> "amount": "450.00",
> "adjustment_category_id": "c2b34567c89d01e3f4g5h6i7",
> "date_of_adjustment": "2026-02-10",
> "description": "Dell UltraSharp 27-inch monitor for home office setup",
> "file": {
> "id": "file_def456uvw012",
> "name": "monitor_receipt.pdf",
> "fileType": "pdf"
> }
>}'

Check with your payroll administrator about approval requirements. Some organizations require manager or finance approval for reimbursements above a certain threshold.

Response:

1{
2 "data": {
3 "id": "adj_8g7f6e5d-4c3b-2109-87ed-cbaf98765432",
4 "status": "DRAFT",
5 "created": true,
6 "title": "Equipment Purchase - Monitor",
7 "amount": "450.00"
8 }
9}

The reimbursement is created in DRAFT status and will not be processed until explicitly approved.

Reimbursements in DRAFT status will not be included in payroll processing. Ensure timely approval to avoid payment delays for employees.

Adding supporting documentation

For all expense reimbursements, attach receipts, invoices, or approval emails as supporting documentation.

Upload and attach receipt file

Before creating the adjustment, upload the receipt file to your file storage and obtain the file ID.

$# Example file upload (implementation depends on your file storage)
$# After upload, you receive a file ID to reference in the adjustment
$
$curl --request POST 'https://api.letsdeel.com/rest/v2/adjustments' \
>--header 'Authorization: Bearer {{token}}' \
>--header 'Content-Type: application/json' \
>--data-raw '{
> "contract_id": "gp8x3k5m",
> "title": "Client Dinner Reimbursement",
> "amount": "187.50",
> "adjustment_category_id": "c3c45678d90e12f4g5h6i7j8",
> "date_of_adjustment": "2026-02-08",
> "description": "Client dinner at Bistro - 4 attendees, closed deal discussion",
> "file": {
> "id": "file_ghi789rst345",
> "name": "dinner_receipt_feb8.jpg",
> "fileType": "jpg"
> }
>}'

The attached file will be available to approvers and linked to the adjustment for audit and compliance purposes.

Accepted file formats include PDF, JPG, PNG, and common document formats. Keep file sizes under 10MB for optimal processing.

Common scenarios

Scenario 1: Monthly mileage reimbursement

For employees who use personal vehicles for business, create monthly mileage reimbursements.

$# Calculate: 450 miles × $0.67/mile = $301.50
$curl --request POST 'https://api.letsdeel.com/rest/v2/adjustments' \
>--header 'Authorization: Bearer {{token}}' \
>--header 'Content-Type: application/json' \
>--data-raw '{
> "contract_id": "gp8x3k5m",
> "title": "Mileage Reimbursement - January 2026",
> "amount": "301.50",
> "adjustment_category_id": "c1a23456b78c90d1e2f3g4h5",
> "date_of_adjustment": "2026-01-31",
> "description": "Business mileage for January 2026: 450 miles at $0.67/mile. Client visits and office meetings.",
> "file": {
> "id": "file_mileage_jan2026",
> "name": "mileage_log_january_2026.xlsx",
> "fileType": "xlsx"
> }
>}'

For recurring monthly mileage reimbursements, standardize the title format and always attach a detailed mileage log showing dates, destinations, and business purposes.

Scenario 2: Batch expense reimbursements

If you need to reimburse multiple employees for the same event (team offsite, conference), create separate adjustments for each employee.

1// Example: Batch processing conference expenses
2const conferenceExpenses = [
3 { contract_id: "gp8x3k5m", amount: "450.00", employee: "Maria Garcia" },
4 { contract_id: "gp9y4l6n", amount: "450.00", employee: "James Chen" },
5 { contract_id: "gp0z5m7o", amount: "475.00", employee: "Sarah Johnson" }
6];
7
8async function processBatchReimbursements(expenses) {
9 const results = [];
10
11 for (const expense of expenses) {
12 const response = await fetch('https://api.letsdeel.com/rest/v2/adjustments', {
13 method: 'POST',
14 headers: {
15 'Authorization': `Bearer ${process.env.DEEL_API_TOKEN}`,
16 'Content-Type': 'application/json'
17 },
18 body: JSON.stringify({
19 contract_id: expense.contract_id,
20 title: "Tech Conference 2026 - Travel & Accommodation",
21 amount: expense.amount.toString(),
22 adjustment_category_id: "c1a23456b78c90d1e2f3g4h5",
23 date_of_adjustment: "2026-02-15",
24 description: "Annual tech conference attendance: Flight, hotel, meals"
25 })
26 });
27
28 const data = await response.json();
29 results.push({
30 employee: expense.employee,
31 adjustment_id: data.data.id,
32 status: data.data.status
33 });
34 }
35
36 return results;
37}
38
39// Process all reimbursements
40processBatchReimbursements(conferenceExpenses)
41 .then(results => console.log('Reimbursements created:', results))
42 .catch(error => console.error('Error processing batch:', error));

Scenario 3: Correcting reimbursement amounts

If you need to correct a reimbursement amount before it is processed, you can update the adjustment while it is still in OPEN or DRAFT status.

$curl --request PATCH 'https://api.letsdeel.com/rest/v2/adjustments/adj_9f8e7d6c-5b4a-3210-98fe-dcba09876543' \
>--header 'Authorization: Bearer {{token}}' \
>--header 'Content-Type: application/json' \
>--data-raw '{
> "amount": "365.67",
> "description": "Client meeting travel expenses: Flight $245.00, Hotel $85.67, Ground transport $15.00, Parking $20.00 (updated)"
>}'

You can only update adjustments in OPEN or DRAFT status. Once processed (SUCCESS status), you cannot modify the adjustment. If you need to correct a processed reimbursement, create a new adjustment with the difference amount.

Scenario 4: Equipment purchase with multiple receipts

For large purchases with multiple receipts, combine all documentation into a single PDF before attaching.

$curl --request POST 'https://api.letsdeel.com/rest/v2/adjustments' \
>--header 'Authorization: Bearer {{token}}' \
>--header 'Content-Type: application/json' \
>--data-raw '{
> "contract_id": "gp8x3k5m",
> "title": "Home Office Setup - Complete Equipment",
> "amount": "1250.00",
> "adjustment_category_id": "c2b34567c89d01e3f4g5h6i7",
> "date_of_adjustment": "2026-02-05",
> "description": "Home office equipment: Standing desk $450, Ergonomic chair $350, Monitor $280, Keyboard & mouse $90, Desk lamp $80",
> "file": {
> "id": "file_equipment_bundle_2026",
> "name": "home_office_receipts_combined.pdf",
> "fileType": "pdf"
> }
>}'

Tracking expense reimbursements

List reimbursements by date range

Track all reimbursements processed within a specific period for reporting and reconciliation.

$curl --request GET 'https://api.letsdeel.com/rest/v2/adjustments?start_date=2026-02-01&end_date=2026-02-28' \
>--header 'Authorization: Bearer {{token}}'

Filter the response on the client side to identify expense reimbursements based on category or title patterns.

List reimbursements by employee

Retrieve all adjustments for a specific contract to see the employee’s complete reimbursement history.

$curl --request GET 'https://api.letsdeel.com/rest/v2/contracts/gp8x3k5m/adjustments' \
>--header 'Authorization: Bearer {{token}}'

Monitor pending reimbursements

Check which reimbursements are waiting for processing or approval.

$curl --request GET 'https://api.letsdeel.com/rest/v2/adjustments' \
>--header 'Authorization: Bearer {{token}}'

Filter the response for adjustments with OPEN, DRAFT, or PENDING_APPROVAL status.

Best practices

Clear and detailed descriptions

Always include:

  • The specific purpose of the expense (client meeting, equipment, travel)
  • Itemized breakdown of costs when applicable
  • Date or period the expense relates to
  • Any relevant project, client, or event names

Good examples:

  • “Client meeting travel - NYC: Flight 245,Hotel245, Hotel 85.67, Ground transport $15”
  • “Q1 2026 Monthly mileage: 450 miles at $0.67/mile for client site visits”
  • “Home office equipment: Standing desk 450,ergonomicchair450, ergonomic chair 350”

Bad examples:

  • “Travel expenses”
  • “Reimbursement”
  • “Equipment”

Receipt documentation

  • Always attach receipts: Include PDF or image files for all reimbursements
  • Combine multiple receipts: For purchases with multiple items, combine into one PDF
  • Name files clearly: Use descriptive filenames like travel_receipts_feb2026.pdf
  • Keep originals: Store original receipts according to your organization’s retention policy

Timing and payroll cycles

  • Submit before cutoff: Create reimbursements early in the payroll cycle
  • Check cycle dates: Verify actual_start_cycle_date and actual_end_cycle_date
  • Allow processing time: Submit at least 3-5 days before payroll cutoff
  • Track status: Monitor status changes to ensure timely processing

Expense categories

  • Use correct categories: Match expense type to the appropriate category
  • Retrieve categories first: Always call /adjustments/categories to get current options
  • Be consistent: Use the same categories for similar expense types
  • Document mappings: Keep an internal mapping of your expense types to Deel categories

Approval workflows

  • Define thresholds: Set clear approval thresholds (e.g., over $500 requires manager approval)
  • Document policies: Maintain clear expense reimbursement policies
  • Track approvers: Know who is responsible for approving different expense types
  • Set deadlines: Define approval turnaround times to avoid payment delays

Compliance and audit

  • Maintain records: Keep detailed records of all reimbursements
  • Include business purpose: Always document why the expense was incurred
  • Attach approvals: Include manager approval emails when applicable
  • Follow tax rules: Be aware of taxable vs non-taxable reimbursements in your jurisdiction

Troubleshooting

Check that the reimbursement status is SUCCESS and that it was submitted before the payroll cutoff date. If the payroll cycle has already closed, the reimbursement will appear on the next payslip. Verify the cycle_reference matches the expected payroll period.

Reimbursements can only be updated while in OPEN or DRAFT status. Once processed (SUCCESS status), they cannot be modified. If you need to correct a processed reimbursement, create a new adjustment for the difference amount with a clear description explaining the correction.

Ensure the file ID is valid and the file was successfully uploaded to your file storage before creating the adjustment. Check that file size is under 10MB and the file format is supported (PDF, JPG, PNG, XLSX, DOCX). If the file field is optional for your use case, you can submit the reimbursement without an attachment and add it later.

If you used the wrong category and the reimbursement is still in OPEN or DRAFT status, update the adjustment with the correct adjustment_category_id. If already processed, contact your payroll administrator for assistance with reclassification.

Check the adjustment status for error details. Common causes include invalid contract_id, payroll cycle already closed, insufficient information in description, or missing required documentation. Review the error message and resubmit with corrections. Status FAILED indicates a processing error; create a new adjustment with corrected information.

Notifications are typically sent when payroll is processed, not when the adjustment is created. Check that the adjustment status is SUCCESS and the payroll cycle has been processed. If the employee questions the reimbursement, provide the adjustment ID and confirm it appears on their payslip.

Next steps