> This page is for API, version 2026-01-01 (Stable) (default).
> For other versions, use one of these documentation indexes:
> - 2026-01-01 (Stable) (default): https://developer.deel.com/api/stable/llms.txt

> 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.

# Bulk contract and amendment signing

## Overview

This guide explains how to sign multiple contracts and contract amendments programmatically using the API. The Deel UI requires signing contracts or amendments one by one, but the API enables automation for bulk signing workflows.

## When to use this workflow

Use this workflow when you need to:

* Sign multiple contracts or contract amendments at once
* Automate contract signing for large teams
* Process contracts and amendments that have already been reviewed and approved
* Integrate contract signing into your existing workflow automation
* Handle seasonal or periodic bulk contract updates

## Prerequisites

Before you begin, ensure you have:

* A valid API token with `contracts:write` scope
* Contract IDs for the contracts or amendments you need to sign
* Authorization to sign on behalf of the client organization
* Confirmation that contracts and amendments have been reviewed and approved

> **Warning**
>
> Contract signatures are legally binding. Only use this workflow for contracts and amendments that have been properly reviewed and approved through your organization's internal processes.

## Step-by-step workflow

This example demonstrates signing multiple contract amendments after a company-wide compensation review.

### Identify contracts requiring signatures

First, retrieve the list of contracts to identify which ones need signatures.

```shell
curl --request GET 'https://api.letsdeel.com/rest/contracts' \
--header 'Authorization: Bearer {{token}}'
```

Response:

```json focus={4,8-9}
{
  "data": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "title": "Senior Backend Engineer",
      "type": "ongoing_time_based",
      "status": "active",
      "worker": {
        "id": "28da9a07-102c-4a69-9781-3182a514f669",
        "full_name": "Sarah Johnson",
        "email": "sarah@example.com"
      },
      "signatures": {
        "client_signature": "Jane Doe",
        "client_signed_at": "2026-01-15T10:00:00Z",
        "worker_signature": "Sarah Johnson",
        "worker_signed_at": "2026-01-15T11:00:00Z"
      },
      "created_at": "2026-01-10T09:00:00Z"
    },
    {
      "id": "456e7890-e89b-12d3-a456-426614174111",
      "title": "Frontend Engineer",
      "type": "ongoing_time_based",
      "status": "active",
      "worker": {
        "id": "38da9a07-102c-4a69-9781-3182a514f770",
        "full_name": "Michael Chen",
        "email": "michael@example.com"
      },
      "signatures": {
        "client_signature": "Jane Doe",
        "client_signed_at": "2026-01-16T10:00:00Z",
        "worker_signature": "Michael Chen",
        "worker_signed_at": "2026-01-16T11:00:00Z"
      },
      "created_at": "2026-01-12T09:00:00Z"
    }
  ],
  "page": {
    "size": 2,
    "number": 1
  }
}
```

To identify contracts with pending amendments, you will need to check each contract for amendments in the next step.

### Check for pending amendments

For each contract, retrieve the list of amendments to identify which ones require client signature.

```shell
curl --request GET 'https://api.letsdeel.com/rest/contracts/123e4567-e89b-12d3-a456-426614174000/amendments?sign_statuses=PENDING&sign_statuses=WAITING_FOR_APPROVAL' \
--header 'Authorization: Bearer {{token}}'
```

Response:

```json focus={5,7,9-11}
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "PENDING",
      "sign_status": "PENDING",
      "rate": 8800.00,
      "scale": "MONTHLY",
      "currency_code": "USD",
      "effective_date": "2026-03-01",
      "created_at": "2026-02-10T10:00:00Z",
      "updated_at": "2026-02-10T10:00:00Z",
      "contract_name": "Senior Backend Engineer",
      "contract_type": "ongoing_time_based"
    }
  ],
  "has_more": false,
  "total_count": 1,
  "cursor": null
}
```

Filter amendments where `sign_status` is `PENDING` or `WAITING_FOR_APPROVAL`. These amendments require client signature.

> **Note**
>
> Always verify amendment details before signing. Ensure the changes match your internal approval records and that the effective date is correct.

### Sign a contract or amendment

Sign the contract or amendment by providing the client signature name. This endpoint handles both initial contract signing and amendment signing.

```shell
curl --request POST \
  'https://api.letsdeel.com/rest/contracts/123e4567-e89b-12d3-a456-426614174000/signatures' \
  --header 'Authorization: Bearer {{token}}' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "data": {
      "client_signature": "Johnathan A. Doe"
    }
  }'
```

> **Tip**
>
> The signature name should be the full legal name of the authorized signatory on behalf of the
> client organization. Use a consistent signature format across all contracts.

Response:

```json focus={3}
{
  "data": {
    "created": true
  }
}
```

The contract or amendment is now signed and will proceed to the next step in the contract workflow.

### Automate bulk signing

To sign multiple contracts, iterate through your list and sign each one programmatically.

```javascript
const axios = require('axios');

// Configuration
const API_BASE_URL = 'https://api.letsdeel.com/rest';
const API_TOKEN = process.env.DEEL_API_TOKEN || process.env.API_TOKEN;
const CLIENT_SIGNATURE = 'Johnathan A. Doe';

// Headers for API requests
const headers = {
  'Authorization': `Bearer ${API_TOKEN}`,
  'Content-Type': 'application/json'
};

// List of contract IDs requiring signatures
const contractIds = [
  '123e4567-e89b-12d3-a456-426614174000',
  '456e7890-e89b-12d3-a456-426614174111',
  '789e0123-e89b-12d3-a456-426614174222'
];

// Track results
const signedContracts = [];
const failedContracts = [];

async function signContracts() {
  for (const contractId of contractIds) {
    const url = `${API_BASE_URL}/contracts/${contractId}/signatures`;
    const payload = {
      data: {
        client_signature: CLIENT_SIGNATURE
      }
    };

    try {
      const response = await axios.post(url, payload, { headers });
      const data = response.data.data || {};
      signedContracts.push({
        contract_id: contractId,
        signed: data.created === true,
      });

      console.log(`✓ Successfully signed contract ${contractId}`);
    } catch (error) {
      failedContracts.push({
        contract_id: contractId,
        error: error.response ? `${error.response.status} ${error.response.statusText}` : error.message
      });
      console.log(`✗ Failed to sign contract ${contractId}: ${
        error.response ? `${error.response.status} ${error.response.statusText}` : error.message
      }`);
    }
  }

  // Summary
  console.log('\nSummary:');
  console.log(`Successfully signed: ${signedContracts.length} contracts`);
  console.log(`Failed: ${failedContracts.length} contracts`);

  if (failedContracts.length > 0) {
    console.log('\nFailed contracts:');
    failedContracts.forEach(contract => {
      console.log(`  - ${contract.contract_id}: ${contract.error}`);
    });
  }
}

signContracts();
```

This script processes multiple contracts and provides a summary of successful and failed signatures.

### Verify signatures

After bulk signing, verify that contracts and amendments were signed successfully by checking the amendment status.

```shell
curl --request GET 'https://api.letsdeel.com/rest/contracts/123e4567-e89b-12d3-a456-426614174000/amendments' \
--header 'Authorization: Bearer {{token}}'
```

Response:

```json focus={5-6}
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "APPROVED",
      "sign_status": "APPROVED",
      "rate": 8800.00,
      "scale": "MONTHLY",
      "currency_code": "USD",
      "effective_date": "2026-03-01",
      "created_at": "2026-02-10T10:00:00Z",
      "updated_at": "2026-02-12T14:30:00Z",
      "contract_name": "Senior Backend Engineer",
      "contract_type": "ongoing_time_based"
    }
  ],
  "has_more": false,
  "total_count": 1,
  "cursor": null
}
```

Confirm that `sign_status` is `APPROVED` for successfully signed amendments.

### Monitor signing progress

For large batches, monitor progress in real-time by tracking signature status.

```javascript
const axios = require('axios');

const API_BASE_URL = process.env.API_BASE_URL;
const API_TOKEN = process.env.API_TOKEN;

const headers = {
  'Authorization': `Bearer ${API_TOKEN}`,
  'Content-Type': 'application/json',
};

async function checkAmendmentStatus(contractId) {
  const url = `${API_BASE_URL}/contracts/${contractId}/amendments?sign_statuses=PENDING&sign_statuses=WAITING_FOR_APPROVAL&sign_statuses=APPROVED`;
  const response = await axios.get(url, { headers });
  const data = response.data.data;

  if (data && data.length > 0) {
    // Get the most recent amendment
    const amendment = data[0];
    return {
      contract_id: contractId,
      amendment_id: amendment.id,
      signed: amendment.sign_status === 'APPROVED',
      status: amendment.sign_status,
      updated_at: amendment.updated_at,
    };
  }

  return { contract_id: contractId, signed: false, status: 'no_amendment' };
}

// Check status for multiple contracts
const contractIds = [
  '123e4567-e89b-12d3-a456-426614174000',
  '456e7890-e89b-12d3-a456-426614174111',
  '789e0123-e89b-12d3-a456-426614174222'
];

console.log('Checking amendment signature status...');
(async () => {
  for (const contractId of contractIds) {
    try {
      const status = await checkAmendmentStatus(contractId);
      if (status.signed) {
        console.log(`✓ ${contractId}: Signed (${status.status}) at ${status.updated_at}`);
      } else {
        console.log(`○ ${contractId}: Not signed (${status.status})`);
      }
    } catch (err) {
      console.error(`Error checking ${contractId}:`, err.response?.data || err.message);
    }
  }
})();
```

## Best practices

### Security and authorization

* Store API tokens securely using environment variables or secret management systems
* Restrict API token scope to only `contracts:write` permission
* Implement role-based access control to limit who can execute bulk signing
* Log all signature operations with timestamps and user identification
* Use audit trails to track when and by whom contracts were signed
* Never commit API tokens to version control systems

### Validation before signing

* Verify amendment type and ensure it matches expected changes
* Check effective dates are reasonable and align with organizational policies
* Validate compensation changes are within approved ranges
* Confirm amendments have been reviewed by appropriate stakeholders
* Check for data integrity issues or unexpected values
* Review batch sizes before executing to prevent accidental mass signatures

### Error handling

* Implement retry logic with exponential backoff for transient failures
* Log all errors with contract IDs and error messages
* Create a separate process to handle failed signatures
* Send notifications when signature failures exceed threshold
* Provide clear error messages for debugging
* Monitor API rate limits and adjust batch sizes accordingly

### Testing and staging

* Test bulk signing scripts in sandbox environment first
* Start with small batches (5-10 contracts) before scaling up
* Verify signatures in the UI after API operations
* Use dry-run mode to simulate operations without actual signing
* Create rollback procedures for incorrect batch signatures
* Document all testing results before production deployment

### Audit and compliance

* Maintain detailed logs of all bulk signature operations
* Store records of who initiated bulk signing and when
* Keep copies of amendment details at time of signature
* Generate regular audit reports for compliance review
* Implement approval workflows before bulk operations
* Document the business justification for each bulk signing operation

## Troubleshooting

#### 403 error when signing

Verify your API token is valid and has the `contracts:write` scope. Check that the token has
not expired and that you are using the correct authorization header format.

#### 404 Contract not found

Confirm the contract ID is correct and that the contract exists. Check that you are using the
correct API environment (production vs. sandbox). Verify you have access to this contract in
your Deel account.

#### Contract has no pending amendments

Verify the amendment has been created using the GET `/contracts/{contract_id}/amendments` endpoint. Check if the `sign_status` is `PENDING` or `WAITING_FOR_APPROVAL`. If the status is already `APPROVED`, the amendment has already been signed.

#### Signature name validation failed

Ensure the signature name matches your authorized signatory format. The name should be the
full legal name of the person authorized to sign on behalf of the organization. Check for
extra spaces or special characters.

#### Rate limit exceeded

Reduce your batch size or implement rate limiting in your script. Deel's API has rate limits
to prevent abuse. Wait for the rate limit window to reset before retrying. Consider
processing contracts in smaller batches over a longer time period.

#### Some contracts signed but others failed

Review the error messages for failed contracts. Common causes include amendments that require
additional approval, contracts in unexpected states, or temporary API issues. Retry failed
contracts individually after resolving the specific issues.

#### Signature completed but status not updating

Allow time for the system to process the signature (usually a few seconds). Refresh the
contract details to see updated status. Check webhooks or event logs to confirm the signature
was processed successfully.

## Next steps

#### [Contract signatures endpoint](/api/endpoints/contractor-hiring/create-contract-signature)

API specifications for signing contracts

#### [Create contract amendments](/api/endpoints/contractor-amendments/create-contract-amendment)

API specifications for contract amendments

#### [Set up webhooks](/api/webhooks/introduction)

Receive notifications when contracts require signatures

#### [Authentication best practices](/api/essentials/authentication)

Best practices for securing API access