GuidesAPI ReferenceChangelog
Changelog

EOR: Retrieve Contract Details, Create EOR Contract updates

New: Retrieve EOR Contract Details

Description: Endpoint used to fetch basic information for an EOR contract, along with employment costs associated to it

Endpoint: GET /v2/eor/contracts/:contract_id/details

API Reference Retrieve EOR Contract Details

Example:

curl --request GET \
     --url https://api.letsdeel.com/v2/eor/contracts/{{contract_id}}/details \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}'

Updated: Create an EOR contract

Description: Extended scope_of_work input field to be passed as an object containing scope_template_id and scope_validation_id. New fields were added to response: costs, employment, compensation_details, client, employee, health_plan, job_title, seniority,created_at

Endpoint: POST /v2/eor

API Reference: Create an EOR contract

EOR: Job Scope Templates, Job Scope Validation, EOR Additional Costs, Get and Update Organization structure

New: List of job scope templates for EOR contracts

Description: Endpoint used to fetch all pre-populated job scopes from the Deel collection. Using those job scopes will automatically approve the job scope without the need for AI or human interaction.

Endpoint: GET /v2/eor/job-scopes

API Reference List of Job Scope Templates

Example:

curl --request GET \
     --url https://api.letsdeel.com/v2/eor/job-scopes \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}'

You can filter templates by team by adding the optional team query parameter:

curl --request GET \
     --url https://api.letsdeel.com/v2/eor/job-scopes?team={TEAM_ID} \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}'

New: Request job scope validation

Description: The endpoint is in charge of validating that a job scope is valid given a job title and employee name. After the job scope passes validation, the contract should be able to be processed and return the employment costs results automatically. If job scope validation passes, it goes to manual approval. If the client uses a provided job scope template using the Fetch job scope templates endpoint, there is no need to run job scope validation.

Endpoint: POST /v2/eor/job-scopes/validate

Required fields:

  • employment_country
  • team_id
  • job_scope
  • job_title
  • employee_name
  • client_legal_entity_id

API Reference Request Job Scope Validation

Example:

curl --request POST \
     --url https://api.letsdeel.com/v2/eor/job-scopes/validate \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}' \
     --header 'content-type: application/json' \
     --data '{
       "data": {
         "employment_country": "US",
         "team_id": "123e4567-e89b-12d3-a456-426614174000",
         "job_scope": "Software development and maintenance.",
         "job_title": "Software Engineer",
         "employee_name": "John Doe",
         "client_legal_entity_id": "123e4567-e89b-12d3-a456-426614174002"
       }
     }'

New: Get EOR Additional Costs

Description: Used to gather information from the created contract together with the employment costs of the employee. This employment costs is used to display to the end-customer in order to get an accurate calculation of the amount to be paid per month;

Endpoint: GET /v2/eor/additional-costs/{country}

Parameters:

  • country: The two-letter ISO code of the country for which to retrieve the EOR additional costs (required)

API Reference: Get EOR Additional Costs

Example:

curl --request GET \
     --url https://api.letsdeel.com/v2/eor/additional-costs/US \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}'

The response includes information about allowances and non-statutory costs associated with the specified country.

New: Get Organization Structure

Description: Retrieves detailed information about the organization's hierarchical structure, including departments and teams.

Endpoint GET /v2/hris/organization_structures

API Reference: Get Organization Structure

Example:

curl --request GET \
     --url https://api.letsdeel.com/v2/hris/organization_structures \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}'

Rename: Update department to Update organization structure

Endpoint: PUT /rest/v2/people/{id}/department

API Reference: Update organization structure

Notes:

  • As part of last releases, we have conducted various underlying bug fixes on Deel API.
  • Rename Update department endpoint to Update organization structure

Updated APIs: List contracts, Retrieve contract and EOR Benefits by country

Updated: List of contracts and Retrieve a single contract APIs

Introduced new query parameter expand as optional
A new field has been introduced to both of these APIs to include cost centers associated with a contract in the response.

Endpoints: GET /rest/v2/contracts and GET /rest/v2/contracts/{contract_id}

API references: List of contracts and Retrieve a single contract

Details

By Default, cost_centers object is optional in contracts payload. To include it, make sure to set expand query parameter to cost_centers value.

Example [List of contracts]

curl --location 'https://api.letsdeel.com/rest/v2/contracts?expand=cost_centers' \
--header 'Authorization: Bearer {API_TOKEN}'

Example [Retrieve a single contract]

curl --location 'https://api.letsdeel.com/rest/v2/contracts/{{contract_id}}?expand=cost_centers' \
--header 'Authorization: Bearer {API_TOKEN}'

Updated: Get list of benefits per country API

Introduced new response field is_discriminatory and updated existing is_mandatory field
A new is_discriminatory field has been introduced to response payload, which specifies if a benefit is discriminatory. Existing is_mandatory field no longer considers benefit discriminatory data.

  • is_discriminatory: Represents if benefit is discriminatory
  • is_mandatory: Represents if benefit is mandatory

Endpoint: GET /v2/eor/benefits

API Reference: Get list of benefits per country

Updated: Create global payroll contract API

New Optional Parameter: invite_employee_to_app
A new field has been introduced to allow automatic onboarding invitations for employees.

Endpoint: POST /rest/v2/contracts/gp

API reference: Create a contract

Details
When invite_employee_to_app is set to true, and if the employee app is enabled for the account, the invited employee will receive an email invitation to join the platform.
This feature streamlines the onboarding process by ensuring employees are proactively included in the Deel ecosystem.

Example

curl --request POST \
    --url \
    https://api.letsdeel.com/v2/rest/contracts/gp --header 'accept: application/json' \
    --header 'authorization: Bearer {API_TOKEN}' \
    --header 'content-type: application/json' \
    --data '
        {
            "data": {
                "client": {
                    "legal_entity": {
                        "id": "00000000-0000-0000-0000-000000000000"
                    },
                    "team": {
                        "id": "00000000-0000-0000-0000-000000000000"
                    }
                },
                "employee": {
                    "first_name": "Jane",
                    "last_name": "Doe",
                    "email": "[email protected]",
                    "address": {
                        "street": "Deel Street 500",
                        "city": "Denver",
                        "zip": "44000",
                        "country": "US"
                    },
                    "work_email": "[email protected]",
                    "nationality": "US",
                    "employee_number": "100"
                },
                "job_title": "Designer",
                "employment": {
                    "type": "Full-time",
                    "start_date": "2023-01-01",
                    "holidays": {
                        "allowance": 25,
                        "start_date": "2023-01-01"
                    }
                },
                "compensation_details": {
                    "scale": "YEAR",
                    "salary": 50000,
                    "currency": "GBP"
                },
                "invite_employee_to_app": true
            }
        }
    '

ReEnabled Candidates Endpoint

Endpoint: POST /rest/v2/candidates

API Reference: Create a Candidate

Notes:

  • As part of last releases, we have conducted various underlying bug fixes on Deel API.
  • Major change is re-enablement of /candidatesendpoint.

EOR: Create Worker

A new endpoint has been implemented to create an Employee of Record (EOR) worker with minimal required data. This EOR worker is automatically linked to the provided contract.

Use Case: Implement this endpoint to create an EOR worker and prepare them for the onboarding process in Deel. This is typically used when you already have a contract created and the worker's email address.

Endpoint: POST /rest/v2/eor/worker

API Reference: Create EOR Worker

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/eor/worker \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_ORG_TOKEN}' \
     --data '{
  "data": {
    "email": "[email protected]",
    "contract_id": "mp4y66j"
  }
}'

Forms: EOR Additional Fields & Benefits List

GET Worker Additional Fields for EOR by Country

A new endpoint has been implemented to retrieve the list of additional fields required when onboarding an Employee of Record (EOR) worker. This endpoint returns country-specific fields that must be completed during the worker profile creation process.

Use Case: Implement this endpoint to dynamically generate forms for collecting required worker information during the EOR onboarding process.

Note: The previously used endpoint /forms/eor/worker-sign-fields/ has been deprecated and should no longer be used in the creation flow.

Endpoint: GET /rest/v2/forms/eor/worker-additional-fields/{country_code}

API Reference: Get worker additional fields for EOR

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/forms/eor/worker-additional-fields/GB \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_TOKEN}'

GET List of Benefits by Country

A new endpoint has been implemented to retrieve available benefits for Employee of Record contracts. This endpoint returns both mandatory and optional benefits with their associated plans and providers, filtered by several parameters including country code, work visa status, working hours, employment type, team, and entity identification.

Use Case: Implement this endpoint to display appropriate benefit options during EOR contract creation.

Endpoint: GET /v2/eor/benefits

Query Parameters:

  • country_code - ISO country code
  • work_visa - Boolean indicating visa status
  • work_hours_per_week - Numeric value of weekly work hours
  • employment_type - Type of employment (e.g., "Full-time")
  • team_id - UUID of the team
  • legal_entity_id - UUID of the legal entity

API Reference: Get list of benefits per country

curl --request GET \
     --url 'https://api.letsdeel.com/rest/v2/eor/benefits?country_code=US&work_visa=true&work_hours_per_week=40&employment_type=Full-time&team_id=123e4567-e89b-12d3-a456-426614174000&legal_entity_id=123e4567-e89b-12d3-a456-426614174000' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_TOKEN}'

API Idempotency & EOR Contract Forms

Idempotent Requests

We’re introducing idempotency keys to make the Deel API safer and more reliable — especially for sensitive operations like contract creation and payments.

Why it matters
Third-party systems often retry failed requests. Without idempotency, this can lead to duplicate operations. Idempotency keys solve this by ensuring the same request won’t be processed twice.

How it works

  • Send an idempotency-key header with your API request.
  • If the same key is used within 24 hours, the API returns the original response.
  • No duplicate processing, no unintended side effects.

➡️ Learn more about idempotency

Forms

Get EOR Contract Form

Dynamically generate the correct contract form for any country without hardcoding the logic in your frontend. EOR contract requirements vary by country—fields, defaults, legal constraints—so this endpoint ensures your app always reflects the latest, compliant structure for that country. It decouples logic from your codebase and lets Deel handle country-specific rules centrally.

Method: GET

Endpoint: /rest/v2/forms/eor/create-contract/{country_code}

Docs: View on Developer Portal

Example Request

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/forms/eor/create-contract/{country_code}/gb \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_TOKEN}'
  1. Create an immigration case

Immigration

New endpoint for adding an immigration case.

Create an immigration case

Create an immigration case

Endpoint: [POST /rest/v2/immigration/client/cases]

https://developer.deel.com/reference/createcase

curl --location 'https://api.letsdeel.com/rest/v2/immigration/client/cases' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{token}}' \
--data '{
    "data":{
        "case_type":"EOR_VISA",
        "country_code":"US",
        "contract_id":"3pp5xvj"
    }
}'

Time Tracking

New endpoint for adding and managing time tracking shifts and shift rates.

Shifts

Create Shifts

Create multiple shifts for a particular contract.

Endpoint: [POST /rest/v2/time_tracking/shifts]

https://developer.deel.com/reference/createtimetrackingshift

curl --location --request POST 'https://api.letsdeel.com/rest/v2/time_tracking/shifts' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data '{
    "data": {
        "contract_id": "123456",
        "shifts": [
            {
                "external_id": "shift_123456",
                "description": "This is a sample shift description.",
                "date_of_work": "2023-10-01",
                "meta": {
                    "start": {
                        "date": "2023-10-01",
                        "time": "08:00",
                        "is_rest_day": false,
                        "is_public_holiday": false
                    },
                    "end": {
                        "date": "2023-10-01",
                        "time": "17:00",
                        "is_rest_day": false,
                        "is_public_holiday": false
                    },
                    "breaks": [
                        {
                            "start": {
                                "date": "2023-10-01",
                                "time": "12:00"
                            },
                            "end": {
                                "date": "2023-10-01",
                                "time": "12:30"
                            },
                            "is_paid": true
                        }
                    ],
                    "approval_date": "2023-10-02"
                },
                "summary": {
                    "shift_rate_external_id": "rate1234",
                    "shift_duration_hours": 8,
                    "total_break_hours": 1,
                    "payable_break_hours": 0.5,
                    "total_payable_hours": 7.5
                }
            }
        ]
    }
}'

Get shifts

List shifts for the particular organization

Endpoint: [GET /rest/v2/time_tracking/shifts]

https://developer.deel.com/reference/gettimetrackingshifts

curl --location --request GET 
'https://api.letsdeel.com/rest/v2/time_tracking/shifts?limit=10&offset=20' \
--header 'Authorization: Bearer {{token}}

Get Shift

Get single shift using shift external id

Endpoint: [GET /rest/v2/time_tracking/shifts/{{external_id}}]

https://developer.deel.com/reference/gettimetrackingshiftbyexternalid

curl --location --request GET 'https://api.letsdeel.com/rest/v2/time_tracking/shifts/{{external_id}}' \
--header 'Authorization: Bearer {{token}}'

Update shift

Update single shift

Endpoint: [PATCH /rest/v2/time_tracking/shifts/{{external_id}}]

https://developer.deel.com/reference/updatetimetrackingshift

curl --location --request PATCH 'https://api.letsdeel.com/rest/v2/time_tracking/shifts/{{external_id}}' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data '{
    "data": {
        "description": "This is a sample shift description.",
        "date_of_work": "2023-10-01",
        "meta": {
            "start": {
                "date": "2023-10-01",
                "time": "08:00",
                "is_rest_day": false,
                "is_public_holiday": false
            },
            "end": {
                "date": "2023-10-01",
                "time": "17:00",
                "is_rest_day": false,
                "is_public_holiday": false
            },
            "breaks": [
                {
                    "start": {
                        "date": "2023-10-01",
                        "time": "12:00"
                    },
                    "end": {
                        "date": "2023-10-01",
                        "time": "13:00"
                    },
                    "is_paid": false
                }
            ],
            "approval_date": "2023-10-01"
        },
        "summary": {
            "shift_duration_hours": 8,
            "total_break_hours": 1,
            "payable_break_hours": 0.5,
            "total_payable_hours": 7.5
        }
    }
}'

Delete shift

Delete single shift

Endpoint: [DELETE /rest/v2/time_tracking/shifts/{{external_id}}]

https://developer.deel.com/reference/deletetimetrackingshift

curl --location --request DELETE 'https://api.letsdeel.com/rest/v2/time_tracking/shifts/{{external_id}}' \
--header 'Authorization: Bearer {{token}}'

Rate

Create shift rate

Create single shift rate for your organization

Endpoint: [POST /rest/v2/time_tracking/shift_rates]

https://developer.deel.com/reference/createtimetrackingshiftrate

curl --location --request POST 'https://api.letsdeel.com/rest/v2/time_tracking/shift_rates' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data '{
    "data": {
        "external_id": "regular_rate_1",
        "name": "Regular Shift rate 1",
        "type": "PER_HOUR_FLAT_RATE",
        "value": 150
    }
}'

Get shift rates

List shift rates for a particular org

Endpoint: [GET /rest/v2/time_tracking/shift_rates]

https://developer.deel.com/reference/gettimetrackingshiftrates

curl --location --request GET 'https://api.letsdeel.com/rest/v2/time_tracking/shift_rates?limit=10&offset=5' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json'

Get shift rate

Retrieve single shift rate

Endpoint: [GET /rest/v2/time_tracking/shift_rates/{{external_id}}]

https://developer.deel.com/reference/gettimetrackingshiftratebyexternalid

curl --location --request GET 'https://api.letsdeel.com/rest/v2/time_tracking/shift_rates/{{external_id}}' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json'

Update shift rate

Update single shift rate

Endpoint: [PATCH /rest/v2/time_tracking/shift_rates/{{external_id}}]

https://developer.deel.com/reference/updatetimetrackingshiftrate

curl --location --request PATCH 'https://api.letsdeel.com/rest/v2/time_tracking/shift_rates/{{external_id}}' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data '{
    "data": {
         "name": "On-call shift rate",
        "type": "PER_HOUR_FLAT_RATE",
        "value": 150
    }
}'

Delete shift rate

Delete single shift rate

Endpoint: [DELETE /rest/v2/time_tracking/shift_rates/{{external_id}}]

https://developer.deel.com/reference/deletetimetrackingshiftrate

curl --location --request DELETE 'https://api.letsdeel.com/rest/v2/time_tracking/shift_rates/{{external_id}}' \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json'