Create EOR Contract

Creating EOR Contracts

This guide shows you how to create Employer of Record (EOR) contracts through Deel’s API. With EOR, you can hire full-time employees in countries where you don’t have a legal entity - Deel acts as the legal employer while you maintain day-to-day management of the worker.

Overview

Creating an EOR contract involves four main steps:

  1. Get Contract Form - Retrieve country-specific requirements
  2. Validate Job Scope (Optional) - Validate custom job descriptions
  3. Get Benefits - Retrieve available benefits for the country
  4. Create Contract - Submit the contract creation request

Before creating contracts, you can estimate employment costs.

Step 1: Get EOR Contract Form

Retrieve country-specific requirements for creating an EOR contract. This endpoint returns all required fields, validation rules, and data sources needed for contract creation.

API Endpoint: GET /forms/eor/create-contract/{country_code}

Query Parameters:

  • country_code (required) - ISO country code (e.g., US, GB, DE)
  • state (required for US/CA/AU) - State or province code
  • start_date (required) - Proposed start date (YYYY-MM-DD)
  • work_hours_per_week (required) - Weekly hours (e.g., 40)
  • contract_duration_in_days (optional) - Duration for fixed-term contracts
$curl --request GET \
> --url 'https://api.letsdeel.com/rest/forms/eor/create-contract/US?state=WA&start_date=2025-06-25&work_hours_per_week=40&contract_duration_in_days=300' \
> --header 'Authorization: Bearer YOUR_API_KEY'

Response includes:

  • Required fields with validation rules (first_name, last_name, email, etc.)
  • Data source endpoints for dropdowns (job titles, currencies, seniorities)
  • Country-specific fields and dependencies

Common lookup endpoints from the response:

  • GET /legal-entities - Your organization’s legal entities
  • GET /lookups/job-titles - Standard job titles
  • GET /lookups/seniorities - Seniority levels
  • GET /lookups/currencies - Supported currencies
  • GET /eor/start-date - Valid start dates for the country

Step 2: Validate Job Scope (Optional)

If you’re using a custom job description, validate it before creating the contract to avoid delays. You can skip this step if using a pre-approved job scope template.

Three approaches for job scope:

  1. Use a template - Get templates via GET /eor/job-scopes and pass scope_template_id in the contract
  2. Validate first - Validate custom job description, then use quote_validation_log_public_id in the contract
  3. Validate inline - Include scope_of_work directly in contract (may require 24-hour review)

API Endpoint: POST /eor/job-scopes/validate

$curl --request POST \
> --url 'https://api.letsdeel.com/rest/eor/job-scopes/validate' \
> --header 'Authorization: Bearer YOUR_API_KEY' \
> --header 'Content-Type: application/json' \
> --data '{
> "country": "US",
> "job_title": "Senior Data Scientist",
> "scope_of_work": "Lead data science initiatives including ML model development, data pipeline architecture, and cross-functional collaboration with product and engineering teams."
> }'

When approved, use the quote_validation_log_public_id when creating the contract. If rejected, you’ll receive feedback within 24 hours.

Step 3: Get Benefits

Retrieve available benefits for the target country to include in the contract.

API Endpoint: GET /eor/benefits

$curl --request GET \
> --url 'https://api.letsdeel.com/rest/eor/benefits?country=US' \
> --header 'Authorization: Bearer YOUR_API_KEY'

Response includes:

  • Benefit ID (use this when creating the contract)
  • Name and type
  • Monthly cost (if applicable)
  • Whether it’s statutory (required by law) or optional

Step 4: Create the EOR Contract

Submit the contract creation request with all the information gathered from the previous steps.

API Endpoint: POST /eor

Required Fields:

  • Client (client.team.id); client.legal_entity.id is optional
  • Employee information (employee.first_name, employee.last_name, employee.nationality; employee.email is optional)
  • Job details (job_title, seniority.id, employment.scope_of_work as a description, template, or validation reference)
  • Compensation (compensation_details.salary, compensation_details.currency)
  • Location (employment.country, employment.state if applicable)
  • Contract details (employment.start_date, employment.work_visa_required)
$curl --request POST \
> --url 'https://api.letsdeel.com/rest/eor' \
> --header 'Authorization: Bearer YOUR_API_KEY' \
> --header 'Content-Type: application/json' \
> --data '{
> "data": {
> "client": {
> "team": {
> "id": "team_abc123"
> },
> "legal_entity": {
> "id": "le_12345"
> }
> },
> "employee": {
> "first_name": "Jane",
> "last_name": "Smith",
> "email": "jane.smith@example.com",
> "nationality": "US"
> },
> "job_title": "Software Engineer",
> "seniority": {
> "id": "seniority-123"
> },
> "employment": {
> "country": "US",
> "state": "WA",
> "start_date": "2025-07-01",
> "work_visa_required": false,
> "scope_of_work": {
> "scope_template_id": "tpl_12345"
> }
> },
> "compensation_details": {
> "salary": 120000,
> "currency": "USD"
> },
> "benefits": [
> {
> "plan_id": "00000000-0000-0000-0000-000000000000",
> "cover_all": true
> }
> ]
> }
> }'

The response also includes a costs.sections breakdown (a line-item cost table grouped by category) and costs.additional_data (country-specific notes about the totals). They’re omitted above for readability; see the Create EOR contract reference for the full response schema.

Key Response Fields:

  • id - Use for signing, amendments, and other operations
  • status - Initially under_review, then waiting_for_client_sign
  • costs.summary - Cost breakdown, including a formatted monthly total in totals_formatted; costs.sections has the full line-item detail

What Happens After Creation

Once you create the contract, it enters under_review status. Deel will review the contract details and:

  1. Validate the job scope (if custom)
  2. Verify country-specific compliance requirements
  3. Generate the employment agreement
  4. Move the contract to the next stage for signatures

Next Steps:

  • The contract will transition to waiting_for_client_sign status (usually within 24 hours)
  • You can then sign the contract using the signature endpoints
  • After all parties sign, the worker can begin onboarding

See the Accept quote guide for next steps.

Best Practices

  • Validate job scopes early - For custom job descriptions, validate 24+ hours before you need to create the contract
  • Cache lookup data - Job titles, currencies, and benefits don’t change often; cache them to reduce API calls
  • Handle country-specific requirements - Different countries require different fields; always use the form endpoint to discover requirements
  • Estimate costs upfront - Use the employment cost endpoint to show candidates total employment costs before contract creation
  • Store contract IDs - You’ll need the response’s id for signing, amendments, terminations, and other lifecycle operations

Next Steps