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

# Hiring & contracts

> Step-by-step guide to setting up client companies and creating EOR contracts in Deel's Embedded model.

This guide covers EOR contract creation from initial company setup through employer signing. These phases are sequential: create the group before creating any contract for that client.

All endpoints require an admin-scoped API token. See [Getting started](/api/embedded/getting-started) for authentication and environment setup. For managing active employment after a contract is signed, see [Employment management](/api/embedded/eor-management).

### Create a group

Each client company is represented as a **group** in Deel. Create one group per client during their onboarding.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/groups`](/api/reference/endpoints/groups/create-group)
      </td>

      <td>
        Create a new group for a client company
      </td>
    </tr>

    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/groups/{id}/clone`](/api/reference/endpoints/groups/clone-group)
      </td>

      <td>
        Clone an existing group for a subsidiary
      </td>
    </tr>
  </tbody>
</table>

The response includes the group `id`. Store it; it maps to `client.team` in all EOR contract requests for this client. Use the `external_metadata` object to store your platform's internal identifiers on the group record, so you can reconcile records across systems without a separate mapping table.

For clients with multiple subsidiaries that share the same structural configuration, use the clone endpoint rather than repeating setup manually.

### Estimate employment costs

Surface a full cost breakdown before the employer confirms the hire. Showing the total cost upfront reduces the risk of abandonment at the contract submission step.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/eor/employment_cost`](/api/embedded/eor-endpoints/cost-calculator/get-employment-cost)
      </td>

      <td>
        Calculate total employment cost for a country and salary
      </td>
    </tr>

    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/eor/additional-costs/{country}`](/api/embedded/eor-endpoints/eor-hiring/get-additional-costs)
      </td>

      <td>
        Retrieve mandatory statutory fees beyond salary
      </td>
    </tr>
  </tbody>
</table>

Surface both the base cost and additional costs as a combined total before proceeding to contract creation.

### Fetch the contract form

Every country has different required fields, validation constraints, and data dependencies. Retrieve the field specification for the target country at the start of each contract creation flow.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/forms/eor/create-contract/{country_code}`](/api/embedded/eor-endpoints/eor-hiring/get-create-contract-form)
      </td>

      <td>
        Country-specific contract field specification
      </td>
    </tr>

    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/eor/start-date`](/api/embedded/eor-endpoints/eor-hiring/get-start-date)
      </td>

      <td>
        Earliest permissible employment start date
      </td>
    </tr>
  </tbody>
</table>

Pass `start_date` and `work_hours_per_week` as query parameters. The response `pages` array contains sections and questions. Each question includes the field name, type, validation constraints, and, where applicable, a `data_source` URL for dropdown values.

> **Tip**
>
> Field requirements and validation rules change as local regulations are updated. Do not cache form schemas across countries or sessions.

### Retrieve reference data

Before rendering the contract form, populate dropdown fields with reference data from the lookup endpoints.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/lookups/job-titles`](/api/reference/endpoints/lookups/get-job-titles)
      </td>

      <td>
        Available job titles
      </td>
    </tr>

    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/lookups/currencies`](/api/reference/endpoints/lookups/get-currencies)
      </td>

      <td>
        Supported salary currencies
      </td>
    </tr>

    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/eor/benefits`](/api/embedded/eor-endpoints/eor-hiring/get-benefits)
      </td>

      <td>
        Available benefits by country, including statutory and optional
      </td>
    </tr>

    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/eor/validations/{country_code}`](/api/embedded/eor-endpoints/eor-hiring/get-eor-hiring-guide-by-country)
      </td>

      <td>
        Country-specific hiring requirements and compliance constraints
      </td>
    </tr>
  </tbody>
</table>

Retrieve these in parallel to minimize form load time. The benefits endpoint distinguishes statutory (mandatory, employer-paid) from optional benefits; use this to control what you surface in the form.

### Validate the job scope

If using a custom job description, validate it before contract creation. An unvalidated custom scope triggers a 24-hour Deel review after submission, blocking the contract from progressing.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/eor/job-scopes/validate`](/api/reference/endpoints/eor-job-scopes/validate-job-scope)
      </td>

      <td>
        Validate a custom job description
      </td>
    </tr>

    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/eor/job-scopes`](/api/reference/endpoints/eor-job-scopes/get-job-scopes)
      </td>

      <td>
        Retrieve pre-approved job scope templates
      </td>
    </tr>
  </tbody>
</table>

If validation succeeds, pass the returned validation `id` in `employment.scope_of_work` when creating the contract. To avoid validation delay entirely, use a pre-approved template from `GET /eor/job-scopes` and pass the `scope_template_id` instead.

### Create the EOR contract

Submit the contract with the data collected from the previous steps.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/eor`](/api/reference/endpoints/eor-contract/create-eor-contract)
      </td>

      <td>
        Create an EOR contract
      </td>
    </tr>
  </tbody>
</table>

The request body requires four nested objects: `employee`, `employment`, `client` (containing `team` set to the group `id` from [step 1](#create-a-group)), and `compensation_details`. Store the returned `id` immediately; it is required for all subsequent operations on this contract.

The initial contract status is `under_review`. It transitions to `waiting_for_client_sign` after Deel completes its review.

### Handle compliance agreements

Some countries require side agreements to be fetched and signed before the main framework agreement. This step applies to Belgium, Germany, Spain, Italy, and Tunisia.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `GET`
      </td>

      <td>
        [`/eor/contracts/{contract_id}/documents`](/api/reference/endpoints/eor-contract-documents/get-eor-contract-documents)
      </td>

      <td>
        List documents available for the contract
      </td>
    </tr>

    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/eor/contracts/{contract_id}/documents/{type}/sign`](/api/embedded/eor-endpoints/eor-hiring/sign-contract-document)
      </td>

      <td>
        Sign a specific contract document
      </td>
    </tr>
  </tbody>
</table>

Retrieve the document list first and filter for documents with status `pending_signature`. Sign each before proceeding to the framework agreement.

> **Note**
>
> This step is only required for the countries listed above. For all other countries, proceed directly to framework agreement signing.

> **Warning**
>
> Fetching and signing side agreements requires a personal access token. Organization tokens are not supported for these endpoints.

### Sign the framework agreement

Once the contract reaches `waiting_for_client_sign` status, sign the framework agreement to complete the employer signing phase.

<table>
  <colgroup>
    <col />

    <col />

    <col />
  </colgroup>

  <thead>
    <tr>
      <th>
        Method
      </th>

      <th>
        Endpoint
      </th>

      <th>
        Purpose
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `POST`
      </td>

      <td>
        [`/eor/contracts/{contract_id}/documents/{type}/sign`](/api/embedded/eor-endpoints/eor-hiring/sign-contract-document)
      </td>

      <td>
        Sign the framework agreement (use 

        `FRAMEWORK_AGREEMENT`

         as 

        `{type}`

        )
      </td>
    </tr>
  </tbody>
</table>

After signing, the contract moves to the worker signing phase. The worker receives their invitation and completes onboarding. See [Worker onboarding](/api/embedded/eor-worker-onboarding).

## Key webhook events

| Event                     | Trigger                                                   |
| ------------------------- | --------------------------------------------------------- |
| `eor.quote.created`       | EOR contract quote created                                |
| `contract.created`        | Contract submitted and queued for Deel review             |
| `contract.status.updated` | Status changed (e.g. `waiting_for_client_sign`, `active`) |

See the [Webhooks guide](/api/webhooks/introduction) for event payload structure and signature verification.

## Next steps

#### [Employment management](/api/embedded/eor-management)

Track onboarding progress, manage employee data, and handle time off for active employees.

#### [Worker onboarding](/api/embedded/eor-worker-onboarding)

Worker-side contract signing, compliance documents, and bank setup.

#### [Amendments & offboarding](/api/embedded/eor-amendments)

Amend active contracts and process terminations.

#### [Getting started](/api/embedded/getting-started)

Authentication, environments, and webhook setup.