GuidesAPI ReferenceChangelog
Changelog

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'

Time Off

New endpoints for viewing and managing time-off


Get Profile Entitlements

List time-off entitlements.

Endpoint: [GET /rest/v2/time_offs/profile/{hris_profile_id}/entitlements]

https://developer.deel.com/reference/get_time-offs-profile-hris-profile-id-entitlements

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/time_offs/profile/{hris_profile_id}/entitlements \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_TOKEN}'

List policies

List time-off policies.

Endpoint: [GET /rest/v2/time_offs/profile/{hris_profile_id}/policies]

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

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/time_offs/profile/{hris_profile_id}/policies \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_TOKEN}'

List time-off requests

List time-off requests.

Endpoint: [GET /rest/v2/time_offs/profile/{hris_profile_id}]

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

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/time_offs/profile/hris_profile_id \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {YOUR_TOKEN}'

Create time-off request

Create time-off request.

Endpoint: [POST /rest/v2/time_offs]

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

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/time_offs \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "is_paid": true,
    "recipient_profile_id": "8bcac37e-b127-4089-ad21-105a55d4f1cd",
    "other_type_description": "info",
    "reason": "Vacation",
    "start_date": "2024-09-19T07:55:19.848Z",
    "end_date": "2024-09-29T07:55:19.848Z",
    "time_off_type_id": "ea410e13-39b3-4f3b-8311-f22e440aaaca",
    "description": "New Vacation",
    "attachments": [
      {
        "filename": "iKekwntQ",
        "upload_id": "eLwoRgmQ",
        "id": "44c11232-fcc6-434c-814a-d14e0158c941"
      }
    ],
    "contract_oid": "34w57nn",
    "dates": [
      {
        "date": "2024-09-29T07:55:19.848Z",
        "day_type": "FULL_DAY",
        "amount": 10,
        "hours": 2
      }
    ],
    "time_off_percentage": 1
  }
}
'

Update time-off request

Update time-off request

Endpoint: [PATCH /rest/v2/time_offs/{time_off_id}]

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

curl --request PATCH \
     --url https://api.letsdeel.com/rest/v2/time_offs/{time_off_id} \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "is_paid": false,
    "recipient_profile_id": "c7854faa-d4e2-447d-bed8-0744fddf7977",
    "start_date": "2024-09-19T07:55:19.848Z",
    "end_date": "2024-09-23T07:55:19.848Z",
    "time_off_type_id": "3aca334e-4233-4573-9103-63b2be235e25"
  }
}
'

Delete time-off request

Delete time-off request

Endpoint: [DELETE /rest/v2/time_offs/{time_off_id}]

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

curl --request DELETE \
     --url https://api.letsdeel.com/rest/v2/time_offs/{time_off_id} \
     --header 'accept: application/json'

Added

Background checks

An endpoint to fetch background checks requested with status and results for a contract using the API. And a webhook which gets triggered when a background check is completed. For more info, visit the Help Center .

List background checks by contract

Retrieve the background checks initiated for a contract.

Endpoint: [GET /rest/v2/background-checks/{contract_id}](https://developer.deel.com/reference/getbackgroundchecksbycontractid)

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/background-checks/contract_id \
     --header 'accept: application/json'
     --header 'authorization: Bearer {}'

Webhook: Get notified when a background check is completed

Triggered when a background check is completed.

Event type: bgcheck.result.available

{
  "data": {
    "meta": {
      "event_type": "bgcheck.result.available",
      "event_type_id": "af7ce5be-d404-4788-aed5-9a5fce1b66c8",
      "organization_id": "987deccd-cef2-4c0f-a068-7cb07971bcfe",
      "organization_name": "Deel",
      "serviceVersion": "2.0.1",
      "tracking_id": "q8tVRj_Je00wJLY2GriqT10nUjBZ"
    },
    "resource": {
      "candidate_email": "[email protected]",
      "completed_at": "2024-09-05T08:32:51. 658Z",
      "contract_id": "3072cm7",
      "created_at": "2024-09-05T08:28:24.394Z",
      "id": "d1f5e39c-fcfd-4f08-b5fa-66ce7112ffef",
      "is_complete": true,
      "name": "Softcheck",
      "package": null,
      "status": "COMPLETE",
      "third party_name": "request softcheck"
    }
  },
  "timestamp": "2024-09-05T08:32:52. 119Z"
}

Added

Background checks

A set of endpoints to request background checks on workers using the API. For more info, visit the Help Center .

List background checks

Retrieve the available background checks. Use country flag to fetch available background checks and packages for a given country.

Endpoint: [GET /rest/v2/background-checks/options](https://developer.deel.com/reference/getbackgroundchecksoptions)

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/background-checks/options \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {}'

Create background check

Request background checks on a worker or an employee contract. You can pass multiple individual checks or a package, available in a given country.

Please note that this EP supports a single contract ID as of now. Support for multiple contract IDs will be added in near future. Please keep an eye on change log for this update.

Endpoint: [POST /rest/v2/background-checks/regular](https://developer.deel.com/reference/createbackgroundcheckforcontracts)

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/background-checks/regular \
     --header 'accept: application/json' \
     --header 'authorization: Bearer {}' \
     --header 'content-type: application/json' \
     --data '{
              "data": {
                  "contract_ids": [
                      "39gz85g"
                  ],
                  "individual_check_ids": [
                      "5699a28e-bf06-4159-b7e3-288e95966321"
                  ],
                  "package_id": "5699a28e-bf06-4159-b7e3-288e95966321"
              }
          }'`

Custom contract upload

Endpoint: [POST /rest/v2/contracts](https://developer.deel.com/reference/createcontract)

Upload a custom contract file as part of the contract creation process. Use a custom contract instead of the standard Deel contract.

Please note that this endpoint requires using a multipart/form-data header and including a custom_contract_file parameter.

If you prefer the standard Deel contract, you can continue using the standard contract creation flow, which requires JSON-formatted data with the application/json header.

curl --location 'https://api.letsdeel.com/rest/v2/contracts' \
--header 'Authorization: Bearer {}' \
--form 'country_code="NO"' \
--form 'scope_of_work="scope_of_work"' \
--form 'client[legal_entity][id]="b27489e0-9f13-4814-ad53-67f5fd258ac9"' \
--form 'client[team][id]="6243f9f8-fd23-49d8-8816-56378acc6b5c"' \
--form 'job_title[name]="Algorithm Engineer"' \
--form 'seniority[id]="6"' \
--form 'notice_period="15"' \
--form 'who_reports="both"' \
--form 'meta[documents_required]="false"' \
--form 'meta[is_main_income]="false"' \
--form 'title="Ms. Homer Stokes payg_tasks"' \
--form 'worker[expected_email]="[email protected]"' \
--form 'worker[first_name]="Josiah"' \
--form 'worker[last_name]="Veum Custom"' \
--form 'type="payg_tasks"' \
--form 'start_date="2024-08-19"' \
--form 'compensation_details[amount]="20000"' \
--form 'compensation_details[currency_code]="NOK"' \
--form 'compensation_details[frequency]="monthly"' \
--form 'compensation_details[cycle_end]="1"' \
--form 'compensation_details[cycle_end_type]="DAY_OF_MONTH"' \
--form 'compensation_details[payment_due_type]="REGULAR"' \
--form 'compensation_details[payment_due_days]="0"' \
--form 'compensation_details[pay_before_weekends]="true"' \
--form 'compensation_details[first_payment_date]="2024-10-01"' \
--form 'compensation_details[first_payment]="2000"' \
--form 'compensation_details[notice_period]="15"' \
--form 'compensation_details[scale]="weekly"' \
--form 'custom_contract_file=@"/Users/Downloads/contract.pdf"'

New Custom Fields endpoints for Deel HR

Added

List all custom fields

Fetch all custom fields associated with People records, offering additional personalized information.

Endpoint: GET /rest/v2/contracts/contract_id/adjustments

Sample Request

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/people/custom_fields \
     --header 'authorization: Token'

Retrieve a single custom field

Access details of a specific custom field by using the custom field ID to enrich individual personnel records.

Endpoint: GET /rest/v2/people/custom_fields/{field_id}

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/people/custom_fields/field_id \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

Retrieve custom fields for a worker

Obtain all custom field values associated with a specific worker, facilitating detailed data retrieval for administrative or operational purposes.

Endpoint: GET /rest/v2/people/{worker_id}/custom_fields

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/people/worker_id/custom_fields \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

Update custom field value

Add or update custom field values for a specific worker, ensuring their profile is up-to-date with the latest information.

Endpoint: PUT /rest/v2/people/{worker_id}/custom_fields

curl --request PUT \
     --url https://api.letsdeel.com/rest/v2/people/worker_id/custom_fields \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "value": "Test"
  },
  "id": "4e5c8303-6368-4eff-9a50-df21018450e7"
}
'

Remove a custom field value

Delete a specific custom field value from a worker's profile, removing outdated or unnecessary information.

Endpoint: DELETE /rest/v2/people/{worker_id}/custom_fields/{field_id}

curl --request DELETE \
     --url https://api.letsdeel.com/rest/v2/people/5d4d076e-283e-461f-b492-94d043c1d21a/custom_fields/ba5af1fa-e0c1-474f-8e13-af5d08a8c32c \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

List all custom fields

Fetch all custom fields associated with contracts, providing additional data necessary for contract management.

Endpoint: GET /rest/v2/contracts/custom_fields

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/contracts/custom_fields \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

Retrieve a specific custom

Access details of a specific custom field associated with a contract to manage contract-specific attributes effectively.

Endpoint: GET /rest/v2/contracts/custom_fields/{field_id}

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/contracts/custom_fields/field_id \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

Retrieve custom fields for a contract

Obtain all custom field values for a specific contract, enhancing contract management with detailed, custom-configured data.

Endpoint: GET /rest/v2/contracts/{contract_id}/custom_fields

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/contracts/ej3yko/custom_fields \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

Update custom field value

Add or update custom field values for a specific contract, ensuring all contract details are current and relevant.

Endpoint: PUT /rest/v2/contracts/{contract_id}/custom_fields

curl --request PUT \
     --url https://api.letsdeel.com/rest/v2/contracts/fke32a/custom_fields \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "value": "Test"
  },
  "id": "3634384c-dcbd-4d22-a53c-82b6b35b9221"
}
'

Remove a custom field value

Delete a specific custom field’s value from a contract, streamlining contract data management by removing redundant or outdated information.

Endpoint: DELETE /rest/v2/contracts/{contract_id}/custom_fields/{field_id}

curl --request DELETE \
     --url https://api.letsdeel.com/rest/v2/contracts/rk43an/custom_fields/581b0c3e-02d4-4d81-afe7-5bdce64632b1 \
     --header 'accept: application/json' \
     --header 'authorization: Bearer Token'

We add support for EOR Adjustments

Added

Retrieve adjustments

Get all adjustments (GP + EOR) for your organization.

Endpoint: POST /rest/v2/contracts/contract_id/adjustments

Sample request

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/contracts/contract_id/adjustments \
     --header 'accept: application/json' \
     --header 'authorization: Bearer token'

New employee_number field in GP endpoints

Added

Employee Number

Our customers can specify the employee_number when they create a new GP contract.

Endpoint: POST rest/v1/contracts/gp

Sample request

curl --request POST \
     --url https://api.letsdeel.com/rest/v1/contracts/gp \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "employee": {
      "first_name": "Jane",
      "last_name": "Doe",
      "email": "[email protected]",
      "work_email": "[email protected]",
      "nationality": "US",
      "employee_number": "100",
      "address": {
        "street": "Deel Street 500",
        "city": "Denver",
        "state": "CO",
        "zip": "44000",
        "country": "US"
      }
    },
    ...
}
'

Our customers can update the employee_number.

Endpoint: PATCH rest/v1/gp/workers/{worker_id}/employee-information

Sample request

curl --request PATCH \
     --url https://api.letsdeel.com/rest/v1/gp/workers/worker_id/employee-information \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "employee_number": "100"
  }
}
'

New GP endpoints

Added

List payroll events by legal entity

Get list of global payroll events by legal entities.

Endpoint: GET rest/v1/gp/legal-entities/{legal_entity_id}/reports

Sample request

curl --request GET \
     --url https://api.letsdeel.com/rest/v1/gp/legal-entities/legal_entity_id/reports \
     --header 'accept: application/json' \
     --header 'authorization: Bearer token'

List gross-to-net report

Get list of global payroll reports detailing gross-to-net calculations.

Endpoint: GET rest/v1/gp/reports/{gp_report_id}/gross_to_net

Sample request

curl --request GET \
     --url https://api.letsdeel.com/rest/v1/gp/reports/gp_report_id/gross_to_net \
     --header 'accept: application/json' \
     --header 'authorization: Bearer token'

Download gross-to-net report

Download global payroll reports detailing gross-to-net calculations.

Endpoint: GET rest/v1/gp/reports/{gp_report_id}/gross_to_net/csv

Sample request

curl --request GET \
     --url https://api.letsdeel.com/rest/v1/gp/reports/gp_report_id/gross_to_net/csv \
     --header 'accept: text/csv' \
     --header 'authorization: Bearer token'

Request termination

Request a termination for a global payroll employee. A successful call starts the termination process and does not confirm termination.

Endpoint: POST rest/v1/gp/workers/{worker_id}/terminations

Sample request

curl --request POST \
     --url https://api.letsdeel.com/rest/v1/gp/workers/worker_id/terminations \
     --header 'accept: application/json' \
     --header 'authorization: Bearer token' \
     --header 'content-type: application/json' \
     --data '
{
  "data": {
    "desired_end_date": "2023-12-31T00:00:00.000Z",
    "last_date_of_work": "2023-12-31T00:00:00.000Z",
    "message": "Termination reason",
    "is_voluntary": true,
    "severance": {
      "amount": 100,
      "type": "TIME",
      "time_unit": "MONTHS",
      "currency": "GBP"
    }
  }
}
'