> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.deel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.deel.com/_mcp/server.

# Add external Id

PATCH https://api.letsdeel.com/rest/contracts/{contract_id}
Content-Type: application/json

Sets an external identifier. Link your internal reference IDs, such as employee numbers or ERP keys, to a Deel worker. The external ID must be unique and, once set, can be used as a filter when listing contracts to directly look up Deel records from an external system.

 **Token scopes**: `contracts:write`

Reference: https://developer.deel.com/api/embedded/ic-endpoints/contracts/update-ic-contract

## Authentication

- `Authorization` header (bearer token, required) — ## Authentication The Deel API uses bearer tokens to authenticate requests. All API calls must be made over HTTPS — calls over plain HTTP or without authentication will fail. ```curl curl -X GET 'https://api.letsdeel.com/rest/v2/contracts' \ -H 'Authorization: Bearer YOUR-TOKEN-HERE' ``` [Learn more about authentication](/api/authentication)
- `Authorization` header (bearer token, required) — Standard OAuth2 security scheme based on https://swagger.io/docs/specification/authentication/

## Servers

- `https://api.letsdeel.com/rest` (Production, default)
- `https://api-staging.letsdeel.com/rest` (Demo)

## Request

### Path parameters

- `contract_id` (string, required) — Deel contract id.

### Body (application/json)

This endpoint expects an object.

- `data` (ContractsContractIdPatchRequestBodyContentApplicationJsonSchemaData, required)

## Response

### 200

Successful operation.

- `id` (string, required) — Unique identifier for the contract.
- `type` (enum, required) — Type of a contract.
  - Allowed values: `ongoing_time_based`, `milestones`, `time_based`, `pay_as_you_go_time_based`, `commission`, `payg_milestones`, `payg_tasks`, `contractor_outside_deel`, `eor`, `unknown`, `employee`, `global_payroll`, `shield_msa`, `hris_direct_employee`, `peo`
- `title` (string, required) — Title of the contract.
- `client` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaClient, required, nullable) — Client details associated with the contract.
- `status` (enum, required) — Status of a contract in Deel workflow.
  - Allowed values: `new`, `under_review`, `waiting_for_employee_contract`, `waiting_for_client_sign`, `processing_payment`, `waiting_for_contractor_sign`, `waiting_for_eor_sign`, `waiting_for_employee_sign`, `awaiting_deposit_payment`, `in_progress`, `completed`, `cancelled`, `user_cancelled`, `rejected`, `waiting_for_client_payment`, `onboarding`, `waiting_for_approval`, `onboarded`
- `worker` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorker, required, nullable) — Worker details associated with the contract.
- `created_at` (string, required) — Date and time when the contract was created.
- `signatures` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaSignatures, required) — Signature information for the contract parties.
- `start_date` (string, required) — Date and time when the contract starts.
- `updated_at` (string, required) — Date and time when the contract was updated.
- `invitations` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaInvitations, required) — Invitation email addresses for signing the contract.
- `is_archived` (boolean, required, nullable) — Flag to indicate if the contract is archived.
- `special_clause` (string, required, nullable) — Special clause of the contract.
- `termination_date` (string, required, nullable) — Date and time when the contract ends.
- `quote` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaQuote, optional) — EOR quote approved by Deel.
- `job_title` (string, optional) — Job title associated with the contract.
- `seniority` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaSeniority, optional, nullable) — Seniority describes level of expertise at a job e.g. junior.
- `external_id` (string, optional, nullable) — External identifier of the contract.
- `who_reports` (string, optional) — Who reports the hours.
- `cost_centers` (list of ContractsContractIdPatchResponsesContentApplicationJsonSchemaCostCentersItems, optional) — List of cost centers associated with the contract.
- `custom_fields` (list of ContractsContractIdPatchResponsesContentApplicationJsonSchemaCustomFieldsItems, optional, nullable) — List of custom fields attached to the contract.
- `notice_period` (double, optional, nullable) — Notice period in days.
- `scope_of_work` (string, optional, nullable) — Scope of work of the contract.
- `work_schedule` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkSchedule, optional, nullable) — Defines a work schedule including working days, hours, and employment details
- `employment_type` (enum, optional, nullable) — Type of employment.
  - Allowed values: `FULL_TIME`, `PART_TIME`
- `contract_template` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaContractTemplate, optional, nullable) — Contract template details.
- `work_statement_id` (string, optional, nullable) — The unique identifier of the associated work statement.
- `employment_details` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaEmploymentDetails, optional) — Employment-related details for the contract.
- `compensation_details` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaCompensationDetails, optional) — Compensation and payment configuration for the contract.

## Errors

### 400 Bad Request Error

Operation failed.

- `request` (ApiErrorRequest, optional)
- `errors` (list of ApiError, optional)

### 401 Unauthorized Error

Operation failed.

- `request` (ApiErrorRequest, optional)
- `errors` (list of ApiError, optional)

### 403 Forbidden Error

Operation failed.

- `request` (ApiErrorRequest, optional)
- `errors` (list of ApiError, optional)

### 404 Not Found Error

Not found

- `errors` (list of ContractsContractIdPatchResponsesContentApplicationJsonSchemaErrorsItems, required) — Error messages
- `request` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaRequest, optional) — Error request details

### 500 Internal Server Error

Operation failed.

- `request` (ApiErrorRequest, optional)
- `errors` (list of ApiError, optional)

## Types

### ContractsContractIdPatchRequestBodyContentApplicationJsonSchemaData

- `external_id` (string, required, nullable) — A unique identifier for the object provided by an external system. Use or send null when you want to reset the external id.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaClient

Client details associated with the contract.

- `team` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaClientTeam, required) — Team information for the client organization.
- `id` (string, optional) — Unique identifier of this resource.
- `email` (string, optional, nullable) — User's email address. It can be an empty string when no email has been provided for the worker. This can happen for draft contracts or workers with incomplete onboarding.
- `full_name` (string, optional) — Full name of the client.
- `legal_entity` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaClientLegalEntity, optional, nullable) — Legal entity details of the client.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorker

Worker details associated with the contract.

- `id` (string, optional) — Unique identifier of this resource.
- `email` (string, optional, nullable) — User's email address.
- `country` (string, optional, nullable) — Country of the worker.
- `full_name` (string, optional) — Full name of the client.
- `last_name` (string, optional) — Last name of the worker.
- `first_name` (string, optional) — First name of the worker.
- `nationality` (string, optional, nullable) — Nationality of the worker.
- `date_of_birth` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkerDateOfBirth, optional) — Date of birth of the worker. Supports full date-time, date-only, or an empty string.
- `expected_email` (string, optional) — Expected email address of the worker (e.g., invitation target email).
- `alternate_email` (list of ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkerAlternateEmailItems, optional, nullable) — List of alternate email addresses.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaSignatures

Signature information for the contract parties.

- `signed_at` (string, optional, nullable) — Date and time when the contract was signed.
- `client_signature` (string, optional) — Client representative signature (typically a name).
- `client_signed_at` (string, optional, nullable) — Date and time when the client signed the contract.
- `worker_signature` (string, optional) — Worker signature (typically a name).
- `worker_signed_at` (string, optional, nullable) — Date and time when the worker signed the contract.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaInvitations

Invitation email addresses for signing the contract.

- `client_email` (string, optional, nullable) — User's email address.
- `worker_email` (string, optional, nullable) — User's email address.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaQuote

EOR quote approved by Deel.

- `benefits` (list of ContractsContractIdPatchResponsesContentApplicationJsonSchemaQuoteBenefitsItems, optional) — Array of benefits.
- `currency` (string, optional) — Currency used for the quote.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaSeniority

Seniority describes level of expertise at a job e.g. junior.

- `id` (double, optional, nullable) — Unique identifier of this resource.
- `name` (string, optional, nullable) — Name of seniority level e.g. Mid (Individual Contributor Level 2).
- `level` (double, optional, nullable) — Level of seniority level e.g. 2.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaCostCentersItems

- `name` (string, optional) — Cost center name.
- `number` (string, optional) — Cost center number.
- `allocation_percentage` (double, optional) — Percentage of the cost center allocation.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaCustomFieldsItems

Customized attributes on contracts (Employee ID, Project code, etc).

- `name` (string, optional) — Custom field property name.
- `value` (string, optional) — Custom field property value.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkSchedule

Defines a work schedule including working days, hours, and employment details

- `days` (list of ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkScheduleDaysItems, required) — Working days and hours configuration
- `name` (string, required) — Unique identifier or name for the work schedule
- `country` (string, required) — Country code where this work schedule applies (ISO 3166-1 alpha-2)
- `worker_types` (list of enum, required) — List of worker types that can use this schedule
  - Allowed values: `SALARIED_DIRECT_EMPLOYEE_PAYROLL`, `SALARIED_HRIS_DIRECT_EMPLOYEE`, `SALARIED_EOR_EMPLOYEE`, `HOURLY_EOR_EMPLOYEE`, `HOURLY_DIRECT_EMPLOYEE_PAYROLL`
- `work_schedule_type` (string, required) — Work schedule type
- `work_hours_per_week` (integer, required) — Total number of working hours per week
- `employment_type` (enum, optional, nullable) — Type of employment arrangement
  - Allowed values: `FULL_TIME`, `PART_TIME`, `CONTRACT`, `TEMPORARY`

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaContractTemplate

Contract template details.

- `id` (string, optional) — Unique identifier of a contract template.
- `title` (string, optional) — Title of a contract template

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaEmploymentDetails

Employment-related details for the contract.

- `type` (string, optional) — Type of employment.
- `days_per_week` (double, optional) — Number of days per week.
- `hours_per_day` (double, optional) — Number of hours per day.
- `probation_period` (double, optional, nullable) — Probation period in days.
- `paid_vacation_days` (double, optional) — Number of paid vacation days.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaCompensationDetails

Compensation and payment configuration for the contract.

- `scale` (string, optional, nullable) — Scale of the payment.
- `amount` (string, optional, nullable) — Amount to be paid. This field can be excluded when creating a Pay-as-you-go task-based or Milestone contracts.
- `cycle_end` (double, optional, nullable) — Day of the cycle end
- `frequency` (string, optional) — Scale of the invoice cycle.
- `currency_code` (string, optional, nullable) — Currency code.
- `first_payment` (string, optional, nullable) — First payment amount.
- `cycle_end_type` (enum, optional, nullable) — Cycle end type
  - Allowed values: `DAY_OF_WEEK`, `DAY_OF_LAST_WEEK`, `DAY_OF_MONTH`
- `first_payment_date` (string, optional, nullable) — First payment date.
- `gross_annual_salary` (string, optional, nullable) — Gross annual salary.
- `gross_signing_bonus` (string, optional, nullable) — Gross signing bonus.
- `gross_variable_bonus` (string, optional, nullable) — Gross variable bonus.

### ApiErrorRequest

- `method` (string, optional) — The HTTP method of the failed request
- `url` (string, optional) — The relative URL of the failed request
- `status` (double, optional) — The status code of the response
- `api_req_id` (string, optional) — The request ID of the failed request
- `docs` (string, optional) — A link to the official documentation for the requested endpoint resource
- `source` (string, optional) — The source handler which produced the returned error
- `code` (double, optional) — The code of the source handler which produced the returned error

### ApiError

- `message` (string, optional) — A description of the returned error
- `path` (string, optional) — The JSON path where input validation failed

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaErrorsItems

- `message` (string, required) — Error response

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaRequest

Error request details

- `method` (string, optional) — Method of the API
- `status` (double, optional) — Status of API response

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaClientTeam

Team information for the client organization.

- `id` (ContractsContractIdPatchResponsesContentApplicationJsonSchemaClientTeamId, required) — Unique identifier of this resource.
- `name` (string, required) — Name of a team.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaClientLegalEntity

Legal entity details of the client.

- `id` (string, optional) — Unique identifier of this resource.
- `name` (string, optional) — Name of a team.
- `type` (string, optional, nullable) — Type of the legal entity.
- `email` (string, optional, nullable) — Email address of the legal entity.
- `subtype` (string, optional, nullable) — Sub-type of the legal entity.
- `vat_number` (string, optional, nullable) — VAT number of the legal entity.
- `registration_number` (string, optional, nullable) — Registration number of the legal entity.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkerDateOfBirth

Date of birth of the worker. Supports full date-time, date-only, or an empty string.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkerAlternateEmailItems

- `email` (string, optional) — Email address of the worker.
- `isVerified` (boolean, optional) — Indicates whether this alternate email address has been verified.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaQuoteBenefitsItems

- `fee` (double, optional) — Fee in local currency.
- `name` (string, optional) — Benefit's name.
- `plan` (string, optional) — Benefit's plan.
- `price` (double, optional) — Price in local currency.
- `fee_usd` (double, optional) — Fee in USD.
- `currency` (string, optional) — Currency code.
- `price_usd` (double, optional) — Price in USD.

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaWorkScheduleDaysItems

Defines working hours for a specific day of the week

- `day` (enum, required) — Day of the week
  - Allowed values: `MONDAY`, `TUESDAY`, `WEDNESDAY`, `THURSDAY`, `FRIDAY`, `SATURDAY`, `SUNDAY`
- `end` (string, required, nullable) — End time for the work day (HH:MM:SS format)
- `start` (string, required) — Start time for the work day (HH:MM:SS format)
- `work_hours` (float, required) — Number of working hours for this day

### ContractsContractIdPatchResponsesContentApplicationJsonSchemaClientTeamId

Unique identifier of this resource.

## Examples

**Request**

```json
{
  "data": {
    "external_id": "5f0b87ae-58bf-4ca6-944a-ecbecf3025d6"
  }
}
```

**Response**

```json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "type": "ongoing_time_based",
  "title": "Software Development Contract",
  "client": {
    "team": {
      "id": "team-xyz789",
      "name": "Engineering Team"
    },
    "id": "team-abc123",
    "email": "string",
    "full_name": "Acme Corp",
    "legal_entity": {
      "id": "team-xyz789",
      "name": "Engineering Team",
      "type": "company",
      "email": "test@example.com",
      "subtype": "general-partnership",
      "vat_number": "123456789",
      "registration_number": "123456789"
    }
  },
  "status": "in_progress",
  "worker": {
    "id": "team-abc123",
    "email": "client@example.com",
    "country": "US",
    "full_name": "Acme Corp",
    "last_name": "Doe",
    "first_name": "John",
    "nationality": "US",
    "date_of_birth": "",
    "expected_email": "test@example.com",
    "alternate_email": [
      {
        "email": "test@example.com",
        "isVerified": true
      }
    ]
  },
  "created_at": "2022-01-01T00:00:00Z",
  "signatures": {
    "signed_at": "2022-01-01T00:00:00Z",
    "client_signature": "Jane Doe",
    "client_signed_at": "2022-01-01T00:00:00Z",
    "worker_signature": "Jane Doe",
    "worker_signed_at": "2022-01-01T00:00:00Z"
  },
  "start_date": "2022-01-01T00:00:00Z",
  "updated_at": "2022-05-02T00:00:00Z",
  "invitations": {
    "client_email": "client@example.com",
    "worker_email": "worker@example.com"
  },
  "is_archived": "false",
  "special_clause": "Special clause",
  "termination_date": "2022-01-01T00:00:00Z",
  "quote": {
    "benefits": [
      {
        "fee": 200.5,
        "name": "Health Insurance",
        "plan": "Premium",
        "price": 150.75,
        "fee_usd": 220,
        "currency": "USD",
        "price_usd": 170.5
      }
    ],
    "currency": "USD"
  },
  "job_title": "Backend Developer",
  "seniority": {
    "id": 1,
    "name": "Mid (Individual Contributor Level 2)",
    "level": 2
  },
  "external_id": "external_id",
  "who_reports": "client",
  "cost_centers": [
    {
      "name": "6P73USR022JKJ2KU1",
      "number": "553",
      "allocation_percentage": 100
    }
  ],
  "custom_fields": [
    {
      "name": "Employee ID",
      "value": "54234"
    }
  ],
  "notice_period": 30,
  "scope_of_work": "Scope of work",
  "work_schedule": {
    "days": [
      {
        "day": "MONDAY",
        "end": "17:00:00",
        "start": "09:00:00",
        "work_hours": 8
      }
    ],
    "name": "34ZNYKYL3G",
    "country": "IN",
    "worker_types": [
      "SALARIED_DIRECT_EMPLOYEE_PAYROLL"
    ],
    "work_schedule_type": "Fixed work schedule",
    "work_hours_per_week": 40,
    "employment_type": "FULL_TIME"
  },
  "employment_type": "FULL_TIME",
  "contract_template": {
    "id": "37nex2x",
    "title": "UK Employment Contract 2022."
  },
  "work_statement_id": "123e4567-e89b-12d3-a456-426614174000",
  "employment_details": {
    "type": "full_time",
    "days_per_week": 5,
    "hours_per_day": 8,
    "probation_period": 30,
    "paid_vacation_days": 20
  },
  "compensation_details": {
    "scale": "hourly",
    "amount": "100",
    "cycle_end": 31,
    "frequency": "monthly",
    "currency_code": "GBP",
    "first_payment": "500",
    "cycle_end_type": "DAY_OF_MONTH",
    "first_payment_date": "2024-08-30T20:59:59.999+00:00",
    "gross_annual_salary": "50000",
    "gross_signing_bonus": "5000",
    "gross_variable_bonus": "5000"
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.letsdeel.com/rest/contracts/37nex2x"

payload = { "data": { "external_id": "5f0b87ae-58bf-4ca6-944a-ecbecf3025d6" } }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.patch(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.letsdeel.com/rest/contracts/37nex2x';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"data":{"external_id":"5f0b87ae-58bf-4ca6-944a-ecbecf3025d6"}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.letsdeel.com/rest/contracts/37nex2x"

	payload := strings.NewReader("{\n  \"data\": {\n    \"external_id\": \"5f0b87ae-58bf-4ca6-944a-ecbecf3025d6\"\n  }\n}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.letsdeel.com/rest/contracts/37nex2x")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"data\": {\n    \"external_id\": \"5f0b87ae-58bf-4ca6-944a-ecbecf3025d6\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.letsdeel.com/rest/contracts/37nex2x")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"data\": {\n    \"external_id\": \"5f0b87ae-58bf-4ca6-944a-ecbecf3025d6\"\n  }\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.letsdeel.com/rest/contracts/37nex2x', [
  'body' => '{
  "data": {
    "external_id": "5f0b87ae-58bf-4ca6-944a-ecbecf3025d6"
  }
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.letsdeel.com/rest/contracts/37nex2x");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"data\": {\n    \"external_id\": \"5f0b87ae-58bf-4ca6-944a-ecbecf3025d6\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["data": ["external_id": "5f0b87ae-58bf-4ca6-944a-ecbecf3025d6"]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.letsdeel.com/rest/contracts/37nex2x")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```