GuidesAPI ReferenceChangelog
Changelog

πŸš€ Enhancement: External HR Time Off Synchronization

API Reference: POST /rest/v2/time_offs/global-payroll/sync

Request body changes

  • Added Work accident leave value to policy_type enum

πŸš€ Enhancement: Retrieve onboarding right-to-work case for a worker

API Reference: GET /rest/v2/immigration/workers/{worker_id}/onboarding-case

Response field changes

  • Added rejection_reason and rejection_note to process object
  • Renamed case_created_at to created_at
  • Renamed last_updated_at to updated_at
{  
    "data": {  
        ...  
        "process": {  
            ...  
            "rejection_reason": "Poor image quality", // available when process has been rejected  
            "rejection_note": "This is the reason why the case was rejected.", // available when process has been rejected  
            "created_at": "2025-07-21T18:04:55.771Z",  
            "updated_at": "2025-07-21T18:04:55.771Z"  
        }  
    }  
}

πŸš€ Enhancements and Endpoint renamed: Retrieve a required document for a case

API Reference: GET /rest/v2/immigration/workers/{worker_id}/cases/{case_id}/required-document

Deprecated API Reference: GET /rest/v2/immigration/workers/{worker_id}/required-documents

Response field changes

  • Added immigration_document_requirement_id
  • Renamed previous_document_request to previous_rejected_document
  • Renamed expiry_date to expiration_date
  • Added created_at and updated_at
{
    "data": {
        "id": "f1a44946-6418-4295-b231-f4ae240e7663",
        "immigration_document_requirement_id": "ed1f24a0-3d59-4668-9c93-417b677e3e84", // static id
        "name": "Proof of employment",
        "description": "A government-issued document that proves your right to work in India. \n",
        "document": {
            "status": "PENDING",
        },
        "previous_rejected_document": {
            "id": "4ec1006d-df21-469a-b6fc-55eba5840940",
            "status": "REJECTED",
            "rejection_reason": "Incomplete information",
            "rejection_note": "The submitted document is missing some necessary details."
        },
				"created_at": "2025-07-21T18:04:55.771Z",  
        "updated_at": "2025-07-21T18:04:55.771Z"
    }
}

πŸš€ Enhancements and Endpoint renamed: Upload a required immigration document

API Reference: POST /rest/v2/immigration/workers/{worker_id}/cases/{case_id}/required-document/{document_request_id}

Deprecated API Reference: POST /rest/v2/immigration/workers/documents

Response field changes

  • Removed rejection_reason and note
  • Added created_at and updated_at
{
    "data": {
        "id": "c19c6d4a-6119-4283-b33d-bf429a344399",
        "status": "IN_REVIEW",
        "created_at": "2025-07-21T18:06:34.315Z",
        "updated_at": "2025-07-21T18:06:34.315Z"
    }
}

πŸš€ Enhancement: Update EOR Contract

API Reference: PATCH /rest/v2/eor/contract/{contract_id}

Request body changes

  1. The scope field now accepts either a plain string (as previously supported) or an object containing one of the following optional identifiers:

    1. scope_template_id: UUID referencing a predefined scope template.
    2. scope_validation_id: UUID referencing a validated scope of work.
    // Option 1: String
    "scope": "Scope of work description."
    
    // Option 2: Object
    "scope": {
      "scope_template_id": "00000000-0000-0000-0000-000000000000"
    }
    
    // Option 3: Object
    "scope": {
      "scope_validation_id": "00000000-0000-0000-0000-000000000000"
    }
    
  2. Added scope_of_work which represents the content sent on scope field in request body.

These changes align the update endpoint with the EOR contract creation endpoint, which has supported this flexible scope of work format. It ensures consistency across contract flows and provides a unified experience for clients integrating with both endpoints.

πŸš€ Enhancement: Retrieve payment receipts

API Reference: GET /rest/v2/payments

Introduced a new query param for filtering payment receipts based on status(paid, processing)


πŸš€ Enhancement: Create shifts

API Reference: POST /rest/v2/time_tracking/shifts

Added support for corrections of shifts. Clients can now add corrections via the create shifts API for the already processed shifts.


πŸš€ Enhancement: Amend contract

API Reference: POST /rest/v2/contracts/:contract_id/amendments

Enhanced Response Schema

The response for contract amendments has been enhanced to include additional useful information alongside existing fields.

Before:

{
    "data": {
        "created": true
    }
}

After:

{
    "data": {
        "created": true,
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "worker_id": "550e8400-e29b-41d4-a716-446655440001",
        "status": "PENDING",
        "rate": 100,
        "scale": "HOURLY",
        "job_title": "Software Engineer",
        "created_at": "2023-12-01T10:30:00Z",
        "updated_at": "2023-12-01T15:45:00Z",
        "currency_code": "USD",
        "scope_of_work": "Full-stack development",
        "special_clause": "Remote work allowed",
        "termination_notice_days": 30
    }
}

New Response Fields:

  • id - The unique identifier of the created amendment
  • worker_id - The unique identifier of the worker
  • status - Status of the amended work statement (INITIAL, PENDING, ACTIVE, OUTDATED, APPROVED, DECLINED)
  • rate - Rate/amount for the amended work statement (sensitive field)
  • scale - Payment scale for the amended work statement (HOURLY, DAILY, WEEKLY, MONTHLY, BIWEEKLY, SEMIMONTHLY, CUSTOM)
  • job_title - Job title for the amended work statement
  • created_at - Timestamp when the work statement was created
  • updated_at - Timestamp when the work statement was last updated
  • currency_code - Currency code for the amended work statement
  • scope_of_work - Scope of work for the amended work statement
  • special_clause - Special clause for the amended work statement
  • termination_notice_days - Number of days notice required for termination

πŸš€ New Endpoint: Sign amendment

Allows workers to sign contract amendments with their signature.

API Reference: POST /rest/v2/workers/amendments/:amendment_id/sign

Request Body:

{
    "data": {
        "contractor_signature": "John Doe"
    }
}

Response:

{
    "data": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "is_signed": true
    }
}

Parameters:

  • contract_id (path, required) - The unique identifier of the contract
  • amendment_id (path, required) - The unique identifier of the amendment to sign

Token Scopes: worker:read, worker:write, benefits:read

Allowed Tokens: PAT:WORKER

Updated: GET /v2/eor/workers/compliance-documents/{document_id}/templates/download

Added updated_at parameter to response in order to show when document was last updated.

Endpoint:


Employee Agreement and Onboarding Tracking endpoints update

Improves Employee Agreement and Onboarding Tracking endpoints to allow for version validation during signature collection to avoid inconsistencies that could be caused by race condition.


Updated: POST /v2/eor/workers/contracts/:contract_id/signatures

  • Add an optional version property to the payload in order to allow the client to specify the version of the Employment Agreement to be signed. In case of a mismatch, the API will return a 409 Conflict error. If the version either matches the internal version or is not provided, the endpoint will behave as before.
  • Add a 409 Conflict error response to the response schema.

Endpoint: Sign a contract


Updated: GET /v2/eor/workers/contracts/:contract_id/employee-agreement/download

  • Add an optional version query param to the endpoint in order to allow the client to specify the version of the Employment Agreement to be downloaded. We don't keep multiple Employment Agreements saved, so this version is for checking if the client has the correct version of the EA. In case of a mismatch, the API will return a 409 Conflict error. If the version either matches the internal version or is not provided, the endpoint will behave as before.
  • Add a 409 Conflict error response to the response schema.

Endpoint: Download employee agreement PDF


Updated: GET /v2/onboarding/tracker/hris_profile/:hris_profile_id

  • Add a employee_agreement object to the response schema, with the following properties:
    • version_hash: Version of the Employment Agreement. Can be null if the EA has not yet been generated.
    • status: Status of the Employment Agreement. Can be null if the EA has not yet been generated.
  • The version_hash can be used to check if the client has the correct version of the EA when downloading or signing it as mentioned in the previous endpoints.

Endpoint: Get onboarding details by employee HRIS profile ID


Updated: GET /v2/onboarding/tracker/:tracker_id

  • Same changes as the previous onboarding endpoint.

Endpoint: Get onboarding details by onboarding tracker ID

List HR verification letters and documents

List all HR verification letters and documents available.

Endpoint: GET /rest/v2/eor/workers/contracts/:contract_id/hr-documents

Token scopes: worker:read

API Reference: List HR verification letters and documents

curl --request GET \
     --url 'https://api.letsdeel.com/rest/v2/eor/workers/contracts/:contract_id/hr-documents' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'


Cost centers endpoints changes

Updated: Cost centers are now retrieved by legal_entity_id parameter, and the request and response format has been adjusted to cost_center_number and cost_center_name instead of number and name.

API Reference:

Updated: POST /v2/contacts endpoint

Added optionalcontract_template_id parameter to body to allow specifying a contract template when creating a contract.

Endpoints:

Magic Link Authentication for Workers

Create Magic Link

Generate secure, time-limited magic links that enable password-free, seamless worker authentication for quick and safe access. Ideal for temporary sessions or low-friction login flows.

Prerequisites: Requires a worker session token created via the existing POST /rest/v2/workers/session endpoint using an organization token with admin:worker scope.

Endpoint: POST /rest/v2/magic-link

Token scopes: worker:read

API Reference: Create Magic Link

Request Example:

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/magic-link \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

List of ActionableJourneys

Provides a list of Actionable Journeys for Workers

Returns a paginated list of actionable journeys assigned to the authenticated worker. Actionable journeys are learning paths or training programs that require active participation from the worker, such as completing courses, assessments, or other learning activities. The response includes journey details, completion status, and pagination metadata to support efficient data retrieval.

These journeys are personalised for the specific worker based on their role, department, and organisational requirements

Endpoint: GET rest/v2/engage/learning/actionable-journeys

Token scopes: worker:read

API Reference: List of ActionableJourneys

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/engage/learning/actionable-journeys \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

EOR contract documents signature for quote flow

Fetch EOR contract documents

Returns a list of all documents that are available for the given EOR contract, expecting client signature. The response will contain the document types and additional signature details when available.
These documents are intended for the client to review and sign, but not the employee, and are available only for certain countries, such as Framework Agreement for Belgium.

Endpoint: GET /rest/v2/eor/contracts/:contract_id/documents

Token scopes: contracts:read

API Reference: Fetch EOR contract documents

Request Example:

curl --request GET \
     --url 'https://api.letsdeel.com/rest/v2/eor/contracts/abc123/documents' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

Fetch EOR contract document

Returns the document in PDF format for the given EOR contract and document type for download. This file can be shared with the client as a reference.

Endpoint: GET /rest/v2/eor/contracts/:contract_id/documents/:document_type

Token scopes: contracts:read

API Reference: Fetch EOR contract document

Request Example:

curl --request GET \
     --url 'https://api.letsdeel.com/rest/v2/eor/contracts/abc123/documents/FRAMEWORK_AGREEMENT' \
     --header 'accept: application/pdf' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

Sign EOR contract document

Signs a document with the provided signature and title. Can be used after the client has reviewed the document and is ready to sign. A document can only be signed once - otherwise the signature will be rejected and the endpoint will return an error.
After signature, the responses for both this endpoint and for fetching all documents will contain the signature details.

Endpoint: POST /rest/v2/eor/contracts/:contract_id/documents/:document_type/sign

Token scopes: contracts:write

API Reference: Sign EOR contract document

Request Example:

curl --request POST \
     --url 'https://api.letsdeel.com/rest/v2/eor/contracts/abc123/documents/FRAMEWORK_AGREEMENT/sign' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}' \
     --data '{
         "data": {
             "signature": "John Doe",
             "client_job_title": "Software Engineer"
         }
     }'

Improvements:

GET /v2/immigration/workers/:worker_id/onboarding-case

Change: The documents.status enum values have been updated.
Before:

{  
  "status": "IN_REVIEW"  // or "APPROVED" or "REJECTED"  
}

After:

{  
  "status": "EXPIRED"  // or "EXPIRING" or "ACTIVE" or "IN_REVIEW"  
}

GET /v2/immigration/workers/:worker_id/required-documents

Change: Complete restructure of the response document object.
Before:

{  
  "id": "550e8400-e29b-41d4-a716-446655440000",  
  "description": "Passport document required for verification",  
  "documents": [  
    {  
      "id": "550e8400-e29b-41d4-a716-446655440000",  
      "status": "IN_REVIEW",  
      "rejection_reason": "File / photo poor quality",  
      "note": "Please provide a clear scan"  
    }  
  ]  
}

After:

{  
  "id": "550e8400-e29b-41d4-a716-446655440000",  
  "name": "Passport Requirement",  
  "description": "Passport document required for verification",  
  "status": "COMPLETED", // 'PENDING', 'IN_REVIEW', 'REJECTED', 'COMPLETED', 'FAILED', 'PROCESSING'  
  "document": { // can be null if no document has been uploaded  
    "id": "550e8400-e29b-41d4-a716-446655440000",  
    "name": "Proof of employment document",  
    "status": "EXPIRING", // "EXPIRED" or "EXPIRING" or "ACTIVE" or "IN_REVIEW"  
    "expiry_date": "2025-09-31"  
  },  
  "previous_document_request": { // only available if the current document request does not have a document and the current uploaded document was rejected  
    "id": "550e8400-e29b-41d4-a716-446655440000",  
    "status": "REJECTED", // 'REJECTED' only  
    "rejection_reason": "File / photo poor quality",  
    "rejection_note": "Please provide a clear scan"  
  }  
}

POST /v2/immigration/workers/documents

Change: Request body requirements have been updated.
Before:

{  
  "worker_id": "550e8400-e29b-41d4-a716-446655440000",  // optional  
  "case_id": "550e8400-e29b-41d4-a716-446655440000",  
  "immigration_document_requirement_id": "550e8400-e29b-41d4-a716-446655440000",  
  "file": "file_data"  
}

After:

{  
  "worker_id": "550e8400-e29b-41d4-a716-446655440000",  // now required  
  "document_request_id": "550e8400-e29b-41d4-a716-446655440000", // now required  
  "case_id": "550e8400-e29b-41d4-a716-446655440000", // still required  
  "file": "file_data" // still required  
}

Added:

reject_reason on List of employee compliance documents

rejection_messageon Get onboarding details by onboarding hris profile oid

Cost Centers management for contracts and legal entities

Assign Cost Centers

Register the allocation of active cost centers of a legal entity to an employment contract of that entity. The new configuration requires an effective day to become valid and the allocation must add up exactly to 1 (100% allocated). The returned id represents an employment term where this information is registered.

Endpoint: POST /rest/v2/contracts/:contract_id/cost-centers

Token scopes: contracts:write

API Reference: Assign cost centers to an employment contract

Request Example:

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/contracts/contract_id/cost-centers \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

Get cost centers for legal entity

Fetches a list of all available cost centers for a legal entity, which does not includes archived cost centers. Does not include cost centers allocations by contract, even if the legal entity is a part on these contracts.

Endpoint: GET /rest/v2/legal-entities/:legal_entity_id/cost-centers

Token scopes: legal-entity:read

API Reference: Get cost centers by legal entity

Request Example:

curl --request GET \
     --url https://api.letsdeel.com/rest/v2/legal-entities/id/cost-centers \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

Synchronize cost centers for legal entity

Define the active cost center data for a legal entity. This will delete existing items that are not present on the payload, create new items, and finally update cost centers that maintain the same name. Please be aware that is not possible to delete cost centers that are currently allocated to one or more contracts.

Endpoint: POST /rest/v2/legal-entities/:legal_entity_id/cost-centers/synchronize

Token scopes: legal-entity:write

API Reference: Sync cost centers for legal entity

Request Example:

curl --request POST \
     --url https://api.letsdeel.com/rest/v2/legal-entities/id/cost-centers/synchronize \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer {{token}}'

Added group_id to the response of the GET /v2/payments/:payment_id/breakdown endpoint.
Check the API Reference

Response example:

{
    "data": [
      {
        "date": "2022-10-01T00:59:28.482Z",
        "work": "3000.00",
        "bonus": "500.00",
        "total": "3500.00",
        "others": "0.00",
        "currency": "USD",
        "expenses": "0.00",
        "group_id": "4fd2daf5-7d59-4990-ba17-5dfc5f1034d0",
        "overtime": "0.00",
        "pro_rata": "0.00",
        "approvers": "John Smith",
        "frequency": "monthly",
        "adjustment": "0.00",
        "deductions": "0.00",
        "commissions": "0.00",
        "approve_date": "2022-10-28T14:32:15.847Z",
        "payment_date": "2022-11-01T17:20:32.837Z",
        "contract_type": "ongoing_time_based",
        "processing_fee": "0.00",
        "contract_country": "US",
        "contractor_email": "[email protected]",
        "payment_currency": "USD",
        "contract_start_date": "2020-03-31T10:58:49.780Z",
        "general_ledger_account": "6000 - Office Expenses",
        "total_payment_currency": "1000.00",
        "contractor_employee_name": "Jane Doe",
        "contractor_unique_identifier": "550e8400-e29b-41d4-a716-446655440000"
      }
    ]
  }

Added: work_schedule object to the response of contract by ID

Reference: https://developer.deel.com/reference/getcontractbyid

Example:

"work_schedule": {
      "name": β€œGP” work schedule,
      "work_hours_per_week": 40,
      "country": "DE",
      "employment_type": "FULL_TIME",
      "worker_types": [
        "HOURLY_DIRECT_EMPLOYEE_PAYROLL",
        "SALARIED_DIRECT_EMPLOYEE_PAYROLL"
      ],
      "work_schedule_type": "Fixed work schedule",
      "days": [
        {
          "day": "MONDAY",
          "start": "09:00:00",
          "end": "17:00:00",
          "work_hours": 8
        },
        {
          "day": "TUESDAY",
          "start": "09:00:00",
          "end": "17:00:00",
          "work_hours": 8
        },
        {
          "day": "WEDNESDAY",
          "start": "09:00:00",
          "end": "17:00:00",
          "work_hours": 8
        },
        {
          "day": "THURSDAY",
          "start": "09:00:00",
          "end": "17:00:00",
          "work_hours": 8
        },
        {
          "day": "FRIDAY",
          "start": "09:00:00",
          "end": "17:00:00",
          "work_hours": 8
        }
      ]
    }