Manage jobs

Jobs are the core unit of the ATS pipeline. Each job represents an open or draft position and must have at least one team, one location, and one employment type before it can receive applications.

Before creating a job, complete the Getting started guide to retrieve the required reference IDs.

Job lifecycle

A job moves through the following statuses:

StatusDescription
DRAFTJob created but not yet published
WAITING_FOR_APPROVALPending approval before opening
APPROVEDApproved but not yet open
NOT_APPROVEDApproval rejected
OPENAccepting applications
CLOSEDNo longer accepting applications
ARCHIVEDRemoved from active listings

Jobs are opened and closed in the Deel application. The API supports creating jobs and reading their status.

Create a job

Use POST /ats/jobs to create a new job. Provide a title, at least one team_id, at least one location_id, and at least one employment_type_id.

$curl --request POST 'https://api.letsdeel.com/rest/v2/ats/jobs' \
> --header 'Authorization: Bearer YOUR-TOKEN-HERE' \
> --header 'Content-Type: application/json' \
> --data '{
> "data": {
> "title": "Senior Software Engineer",
> "team_ids": ["team_01hxyz123abc"],
> "location_ids": ["loc_01hxyz456def"],
> "employment_type_ids": ["et_01hxyz789ghi"],
> "department_ids": ["dept_01hxyzjklmno"],
> "richtext_description": "<p>We are looking for a Senior Software Engineer to join our platform team.</p>",
> "is_confidential": false
> }
> }'

Store the returned job.id. You will need it when creating applications.

The job_employment_types[].id field (the join record ID, e.g. jet_01hxyz333bcd) is different from the employment_type.id. When creating applications, use the job_employment_type_id (the join record ID), not the employment type ID directly.

List and filter jobs

Use GET /ats/jobs to retrieve jobs. You can filter by status, location, team, employment type, or department.

Request
$curl --request GET 'https://api.letsdeel.com/rest/v2/ats/jobs?status=OPEN&limit=20' \
> --header 'Authorization: Bearer YOUR-TOKEN-HERE'

Available filters:

ParameterTypeDescription
statusarrayFilter by job status (e.g. OPEN, DRAFT)
location_idsarrayFilter by location IDs
team_idsarrayFilter by team IDs
employment_type_idsarrayFilter by employment type IDs
department_idsarrayFilter by department IDs
searchstringFull-text search across job titles
updated_afterISO 8601 stringReturn jobs updated after this timestamp
cursorstringPagination cursor from previous response
limitintegerResults per page

Retrieve job postings

Job postings are the published representations of jobs on job boards. Retrieve them to sync listing data with an external system.

Request
$curl --request GET 'https://api.letsdeel.com/rest/v2/ats/job-postings?job_id=job_01hxyzpqrstu' \
> --header 'Authorization: Bearer YOUR-TOKEN-HERE'

You can also retrieve postings for a specific job board:

Request
$curl --request GET 'https://api.letsdeel.com/rest/v2/ats/job-boards/{job_board_id}/job-postings' \
> --header 'Authorization: Bearer YOUR-TOKEN-HERE'

Job posting sources include: INTERNAL_CAREER_PAGE, EXTERNAL_CAREER_PAGE, and LINKEDIN.

Job postings are read-only via the API. No endpoint exists to create, publish, or unpublish a posting, and Deel provides no embeddable widget. Use the Deel application to manage job board publications.

Best practices

  • Retrieve reference IDs fresh at startup: Location, employment type, and department IDs rarely change but should be fetched at integration startup rather than hardcoded.
  • Store job_employment_type_id alongside job_id: You need the join record ID (not the employment type ID) when creating applications. Retrieve it from GET /ats/jobs and store it with the job record.
  • Use updated_after for sync: When polling for job changes, use the updated_after filter with the timestamp of your last successful sync to retrieve only changed records.

Next steps