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

# Adjustments

> Learn how to manage payroll adjustments for bonuses, deductions, and one-time payments

Adjustments allow you to add or subtract amounts from a worker's payroll outside of their regular compensation. Use adjustments to handle bonuses, deductions, allowances, reimbursements, or any one-time payment that affects net pay.

The **Adjustments API** provides endpoints to create, retrieve, and manage adjustments programmatically. Each adjustment is linked to a specific contract and payroll cycle, ensuring accurate processing and compliance with local tax rules.

## Key concepts

### Adjustment types

Adjustments are categorized by purpose. Each category determines how the adjustment is processed and reported.

Common adjustment categories include:

* **Bonuses**: Performance bonuses, sign-on bonuses, or retention payments
* **Deductions**: Loan repayments, garnishments, or advance deductions
* **Allowances**: Housing allowances, transportation stipends, or meal allowances
* **Reimbursements**: Expense reimbursements for business-related costs

Use the `GET /adjustments/categories` endpoint to retrieve all available categories for your organization.

### Adjustment status

Adjustments move through different statuses depending on the contract type and approval workflow.

**Global Payroll (GP) statuses:**

* `OPEN`: Adjustment created but not yet submitted
* `PENDING_APPROVAL`: Submitted and awaiting approval
* `SUCCESS`: Approved and processed in payroll
* `FAILED`: Processing failed due to validation errors
* `OVERWRITTEN`: Replaced by a newer adjustment
* `AI_CHECK_IN_PROGRESS`: Under automated review

**Employer of Record (EOR) statuses:**

* `DRAFT`: Adjustment created but not finalized
* `PENDING`: Submitted for processing
* `APPROVED`: Approved and ready for disbursement
* `DENIED`: Rejected by approver
* `DISBURSE_SCHEDULED`: Scheduled for payment
* `REIMBURSED`: Payment completed
* `UNDER_REVIEW`: Manual review in progress
* `ERRORS_FOUND`: Validation errors detected
* `PENDING_DEEL_REVIEW`: Awaiting internal Deel review

### Payroll cycles

Adjustments are tied to specific payroll cycles. Each adjustment has:

* `date_of_adjustment`: The date the adjustment should apply
* `cycle_reference`: The payroll cycle identifier
* `actual_start_cycle_date`: Start date of the payroll cycle
* `actual_end_cycle_date`: End date of the payroll cycle

If `move_next_cycle` is set to `true`, the adjustment can be moved to the next payroll cycle if it misses the current cutoff.

## Creating an adjustment

Use the `POST /adjustments` endpoint to create a new adjustment.

### Required fields

| Field                    | Type   | Description                                                             |
| ------------------------ | ------ | ----------------------------------------------------------------------- |
| `contract_id`            | string | The identifier of the contract this adjustment applies to               |
| `title`                  | string | A descriptive title for the adjustment                                  |
| `amount`                 | string | The adjustment amount (positive for additions, negative for deductions) |
| `adjustment_category_id` | string | The category ID from `/adjustments/categories`                          |
| `date_of_adjustment`     | string | The date the adjustment should apply (ISO 8601 date format)             |

### Optional fields

| Field             | Type    | Description                                                             |
| ----------------- | ------- | ----------------------------------------------------------------------- |
| `description`     | string  | Additional context or notes about the adjustment                        |
| `file`            | object  | Attachment supporting the adjustment (e.g., receipt, approval document) |
| `cycle_reference` | string  | Specific payroll cycle identifier                                       |
| `move_next_cycle` | boolean | Allow moving to next cycle if current cycle is closed                   |

### Example request

**`Python`**

```python Python
import requests
import os

url = "https://api.letsdeel.com/rest/adjustments"

headers = {
    "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}",
    "Content-Type": "application/json"
}

payload = {
    "contract_id": "m3jk2j",
    "title": "Q4 Performance Bonus",
    "amount": "2500.00",
    "adjustment_category_id": "c9cf4c2c0165f48f494415390c3b49",
    "date_of_adjustment": "2024-12-31",
    "description": "Year-end performance bonus",
    "move_next_cycle": False
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())
```

**`Node.js`**

```javascript Node.js
const axios = require('axios');

const url = 'https://api.letsdeel.com/rest/adjustments';

const headers = {
  'Authorization': `Bearer ${process.env.DEEL_API_TOKEN}`,
  'Content-Type': 'application/json'
};

const payload = {
  contract_id: 'm3jk2j',
  title: 'Q4 Performance Bonus',
  amount: '2500.00',
  adjustment_category_id: 'c9cf4c2c0165f48f494415390c3b49',
  date_of_adjustment: '2024-12-31',
  description: 'Year-end performance bonus',
  move_next_cycle: false
};

axios.post(url, payload, { headers })
  .then(response => console.log(response.data))
  .catch(error => console.error(error.response.data));
```

**`cURL`**

```bash cURL
curl -X POST 'https://api.letsdeel.com/rest/adjustments' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "contract_id": "m3jk2j",
    "title": "Q4 Performance Bonus",
    "amount": "2500.00",
    "adjustment_category_id": "c9cf4c2c0165f48f494415390c3b49",
    "date_of_adjustment": "2024-12-31",
    "description": "Year-end performance bonus",
    "move_next_cycle": false
  }'
```

### Response structure

A successful request returns a `201 Created` status with the adjustment details:

```json
{
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "contract_id": "m3jk2j",
    "title": "Q4 Performance Bonus",
    "amount": "2500.00",
    "status": "OPEN",
    "adjustment_category_id": "c9cf4c2c0165f48f494415390c3b49",
    "date_of_adjustment": "2024-12-31",
    "description": "Year-end performance bonus",
    "move_next_cycle": false,
    "cycle_reference": "2024-12",
    "actual_start_cycle_date": "2024-12-01T00:00:00.000Z",
    "actual_end_cycle_date": "2024-12-31T23:59:59.000Z",
    "file": null,
    "created_at": "2024-12-15T10:30:00.000Z",
    "updated_at": "2024-12-15T10:30:00.000Z"
  }
}
```

## Retrieving adjustments

### Retrieve a specific adjustment

Use `GET /adjustments/{id}` to fetch details of a single adjustment.

**`Python`**

```python Python
import requests
import os

adjustment_id = "123e4567-e89b-12d3-a456-426614174000"
url = f"https://api.letsdeel.com/rest/adjustments/{adjustment_id}"

headers = {
    "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}"
}

response = requests.get(url, headers=headers)
print(response.json())
```

**`Node.js`**

```javascript Node.js
const axios = require('axios');

const adjustmentId = '123e4567-e89b-12d3-a456-426614174000';
const url = `https://api.letsdeel.com/rest/adjustments/${adjustmentId}`;

const headers = {
  'Authorization': `Bearer ${process.env.DEEL_API_TOKEN}`
};

axios.get(url, { headers })
  .then(response => console.log(response.data))
  .catch(error => console.error(error.response.data));
```

**`cURL`**

```bash cURL
curl -X GET 'https://api.letsdeel.com/rest/adjustments/123e4567-e89b-12d3-a456-426614174000' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'
```

### List adjustments by contract

Use `GET /contracts/{contract_id}/adjustments` to retrieve all adjustments for a specific contract.

This endpoint returns all adjustments associated with a contract, allowing you to track the complete history of bonuses, deductions, and other modifications.

**`Python`**

```python Python
import requests
import os

contract_id = "m3jk2j"
url = f"https://api.letsdeel.com/rest/contracts/{contract_id}/adjustments"

headers = {
    "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}"
}

response = requests.get(url, headers=headers)
adjustments = response.json()

for adjustment in adjustments['data']:
    print(f"{adjustment['title']}: {adjustment['amount']} ({adjustment['status']})")
```

**`Node.js`**

```javascript Node.js
const axios = require('axios');

const contractId = 'm3jk2j';
const url = `https://api.letsdeel.com/rest/contracts/${contractId}/adjustments`;

const headers = {
  'Authorization': `Bearer ${process.env.DEEL_API_TOKEN}`
};

axios.get(url, { headers })
  .then(response => {
    response.data.data.forEach(adjustment => {
      console.log(`${adjustment.title}: ${adjustment.amount} (${adjustment.status})`);
    });
  })
  .catch(error => console.error(error.response.data));
```

**`cURL`**

```bash cURL
curl -X GET 'https://api.letsdeel.com/rest/contracts/m3jk2j/adjustments' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'
```

## Retrieving adjustment categories

Before creating an adjustment, retrieve the available categories for your organization using `GET /adjustments/categories`.

Each category has a unique identifier, name, and unit type that determines how the adjustment is processed.

**`Python`**

```python Python
import requests
import os

url = "https://api.letsdeel.com/rest/adjustments/categories"

headers = {
    "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}"
}

response = requests.get(url, headers=headers)
categories = response.json()

for category in categories['data']:
    print(f"{category['name']} (ID: {category['id']}, Type: {category['unit_type']})")
```

**`Node.js`**

```javascript Node.js
const axios = require('axios');

const url = 'https://api.letsdeel.com/rest/adjustments/categories';

const headers = {
  'Authorization': `Bearer ${process.env.DEEL_API_TOKEN}`
};

axios.get(url, { headers })
  .then(response => {
    response.data.data.forEach(category => {
      console.log(`${category.name} (ID: ${category.id}, Type: ${category.unit_type})`);
    });
  })
  .catch(error => console.error(error.response.data));
```

**`cURL`**

```bash cURL
curl -X GET 'https://api.letsdeel.com/rest/adjustments/categories' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'
```

### Response structure

```json
{
  "data": [
    {
      "id": "c0431543f64c448e5ba4b525a50291",
      "name": "Performance Bonus",
      "label": "Performance Bonus",
      "unit_type": "currency"
    },
    {
      "id": "d1542654g75d559f6cb5c636b61402",
      "name": "Loan Repayment",
      "label": "Loan Repayment",
      "unit_type": "currency"
    }
  ]
}
```

## Error handling

The API returns standard HTTP status codes and error messages to help you diagnose issues.

### Common errors

| Status Code | Error                 | Cause                                          | Solution                                                                    |
| ----------- | --------------------- | ---------------------------------------------- | --------------------------------------------------------------------------- |
| `400`       | Bad Request           | Missing required fields or invalid data format | Verify all required fields are present and correctly formatted              |
| `401`       | Unauthorized          | Invalid or missing API token                   | Check that your API token is valid and included in the Authorization header |
| `403`       | Forbidden             | Insufficient permissions                       | Ensure your token has the `adjustments:write` scope                         |
| `404`       | Not Found             | Adjustment or contract ID does not exist       | Verify the ID is correct and the resource exists                            |
| `500`       | Internal Server Error | Server-side issue                              | Retry the request or contact Deel support if the issue persists             |

### Example error response

```json
{
  "errors": [
    {
      "message": "contract_id is required"
    }
  ]
}
```

> **Warning**
>
> Always validate adjustment amounts before submission. Negative amounts represent deductions and must be prefixed with a minus sign (e.g., "-150.00").

## Authentication and scopes

All adjustment endpoints require authentication using either an API token or OAuth2.

**Required scopes:**

* `adjustments:read` - Read adjustment data
* `adjustments:write` - Create and modify adjustments

> **Info**
>
> For detailed information on authentication methods and token management, see the [Authentication guide](/api/authentication).

## Best practices

#### Timing and payroll cycles

* **Submit adjustments early**: Create adjustments well before the payroll cutoff to ensure processing
* **Monitor cycle dates**: Check `actual_start_cycle_date` and `actual_end_cycle_date` to confirm timing
* **Use move\_next\_cycle carefully**: Only enable this if the adjustment can be delayed to the next cycle
* **Validate cycle references**: Ensure the `cycle_reference` matches an active payroll cycle

#### Amount formatting

* **Use string format**: Always pass amounts as strings (e.g., "1234.56") to preserve precision
* **Include decimals**: Specify two decimal places for currency values
* **Negative for deductions**: Use negative amounts (e.g., "-500.00") for deductions
* **Validate before submission**: Check that amounts match your payroll records

#### Category selection

* **Retrieve categories first**: Always call `/adjustments/categories` before creating adjustments
* **Use correct category IDs**: Map your internal adjustment types to Deel's categories
* **Check unit\_type**: Ensure the category matches the adjustment purpose (currency vs. other units)
* **Cache category data**: Store category mappings to reduce API calls

#### Attachments and documentation

* **Include supporting documents**: Attach receipts, approvals, or invoices when applicable
* **Use descriptive titles**: Make adjustment titles clear and searchable
* **Add context in descriptions**: Provide additional details that explain the adjustment
* **Track adjustment IDs**: Store adjustment IDs in your system for reconciliation

#### Error handling and retries

* **Handle validation errors**: Check for 400 status codes and display helpful messages
* **Implement retry logic**: Retry failed requests with exponential backoff
* **Log adjustment attempts**: Keep audit trails of all adjustment creation attempts
* **Monitor status changes**: Poll adjustment status if approval workflows are involved

## Common use cases

### Scenario 1: Monthly performance bonuses

Submit performance bonuses at the end of each month for eligible employees.

```python
import requests
import os

def create_performance_bonus(contract_id, amount, month):
    url = "https://api.letsdeel.com/rest/adjustments"

    headers = {
        "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}",
        "Content-Type": "application/json"
    }

    payload = {
        "contract_id": contract_id,
        "title": f"Performance Bonus - {month}",
        "amount": str(amount),
        "adjustment_category_id": "c0431543f64c448e5ba4b525a50291",
        "date_of_adjustment": f"2024-{month}-31",
        "description": f"Monthly performance bonus for {month}/2024"
    }

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

    if response.status_code == 201:
        return response.json()
    else:
        raise Exception(f"Failed to create bonus: {response.json()}")

# Create bonus for December
bonus = create_performance_bonus("m3jk2j", 1500.00, "12")
print(f"Bonus created: {bonus['data']['id']}")
```

### Scenario 2: Expense reimbursements

Reimburse employees for business expenses like travel, meals, or equipment.

```python
import requests
import os

def create_expense_reimbursement(contract_id, amount, description, receipt_file=None):
    url = "https://api.letsdeel.com/rest/adjustments"

    headers = {
        "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}",
        "Content-Type": "application/json"
    }

    payload = {
        "contract_id": contract_id,
        "title": "Expense Reimbursement",
        "amount": str(amount),
        "adjustment_category_id": "d1542654g75d559f6cb5c636b61402",
        "date_of_adjustment": "2024-12-20",
        "description": description
    }

    # Attach receipt if provided
    if receipt_file:
        payload["file"] = receipt_file

    response = requests.post(url, json=payload, headers=headers)
    return response.json()

# Reimburse travel expenses
reimbursement = create_expense_reimbursement(
    contract_id="m3jk2j",
    amount=345.67,
    description="Client meeting travel - December 2024"
)
print(f"Reimbursement created: {reimbursement['data']['id']}")
```

### Scenario 3: Loan deductions

Process recurring loan deductions from employee paychecks.

```python
import requests
import os

def create_loan_deduction(contract_id, amount, loan_reference):
    url = "https://api.letsdeel.com/rest/adjustments"

    headers = {
        "Authorization": f"Bearer {os.getenv('DEEL_API_TOKEN')}",
        "Content-Type": "application/json"
    }

    payload = {
        "contract_id": contract_id,
        "title": f"Loan Repayment - {loan_reference}",
        "amount": f"-{amount}",  # Negative for deduction
        "adjustment_category_id": "e2653765h86e660g7dc6d747c72513",
        "date_of_adjustment": "2024-12-31",
        "description": f"Monthly loan repayment for {loan_reference}",
        "move_next_cycle": False
    }

    response = requests.post(url, json=payload, headers=headers)
    return response.json()

# Deduct monthly loan payment
deduction = create_loan_deduction(
    contract_id="m3jk2j",
    amount=250.00,
    loan_reference="LOAN-2024-001"
)
print(f"Deduction created: {deduction['data']['id']}")
```

## Next steps

#### [Time tracking](/api/global-payroll/time-tracking)

Learn how to submit shifts and hours for payroll calculation

#### [Expense reimbursements](/api/global-payroll/expense-reimbursements)

Learn how to reimburse employee expenses through payroll

#### [Authentication](/api/authentication)

Set up API tokens and OAuth2 for secure access

#### [Webhooks](/api/webhooks/introduction)

Set up webhooks to monitor adjustment status changes