> This page is for CLI.

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

# Asynchronous jobs

> Follow bulk operations that the Deel API processes asynchronously

Bulk operations such as `adjustments create-bulk` return `202 Accepted` with a `job_id` instead of the final result. The API processes the items in the background; the CLI provides two ways to follow the job.

## Submit a job

```bash
deel adjustments create-bulk --invoice --input file://adjustments.json
```

```json
{
  "data": {
    "job_id": "7f3c9b1e-2d84-4a51-9c07-1b5e8a0f3d62",
    "items": [
      { "external_id": "bonus-2026-09-alice", "status": "PENDING" },
      { "external_id": "bonus-2026-09-bob", "status": "PENDING" }
    ]
  },
  "meta": { "request_id": "8b1c1a2e-3f96-4d05-a172-9e6b8c4d0f13" }
}
```

Each item echoes the `external_id` you supplied, so you can correlate results with your own records. Use `--quiet` to capture only the job id:

```bash
JOB_ID=$(deel adjustments create-bulk --invoice --input file://adjustments.json --quiet)
```

## Follow a job

Four commands follow a job, split between the `job` and `jobs` groups:

| Command                                   | Group  | Description                                      |
| ----------------------------------------- | ------ | ------------------------------------------------ |
| `deel job status <id>[,<id>]`             | `job`  | Fetch one or more jobs by id in a single command |
| `deel job list`                           | `job`  | List recent jobs                                 |
| `deel jobs status --job_id <id>`          | `jobs` | Retrieve one job by id                           |
| `deel jobs list [--limit n] [--cursor c]` | `jobs` | List jobs with pagination parameters             |

`job` (singular) accepts several comma-separated ids and returns an array when more than one is given. `jobs` (plural) adds pagination parameters for listing. Both read the same job data.

```bash
deel job status 7f3c9b1e-2d84-4a51-9c07-1b5e8a0f3d62
```

```json
{
  "data": {
    "job_id": "7f3c9b1e-2d84-4a51-9c07-1b5e8a0f3d62",
    "status": "SUCCEEDED",
    "items": [
      { "external_id": "bonus-2026-09-alice", "status": "SUCCEEDED" },
      { "external_id": "bonus-2026-09-bob", "status": "FAILED", "error": { "code": "http.422", "message": "amount: must be a positive number" } }
    ]
  }
}
```

## Job statuses

A job moves through four statuses:

| Status      | Meaning                                                                   |
| ----------- | ------------------------------------------------------------------------- |
| `PENDING`   | Accepted, not yet started                                                 |
| `RUNNING`   | Items are being processed                                                 |
| `SUCCEEDED` | Every item completed successfully                                         |
| `FAILED`    | At least one item failed; inspect `items[].error` from `deel jobs status` |

A job in `SUCCEEDED` or `FAILED` is terminal and does not change afterwards.

## Wait for completion in a script

Submitting a job returns immediately; the CLI does not wait for it to finish. Poll with `deel job status` until it reaches a terminal status:

```bash
JOB_ID=$(deel adjustments create-bulk --invoice --input file://adjustments.json --quiet)

while :; do
  STATUS=$(deel job status "$JOB_ID" --jq '.status' --raw)
  case "$STATUS" in
    SUCCEEDED|FAILED) break ;;
  esac
  sleep 5
done

deel jobs status --job_id="$JOB_ID" --jq '.items[] | select(.status == "FAILED")'
```

Poll every 5 seconds; the CLI automatically retries job lookups on `429` and `5xx` responses.

## Next steps

#### [Request input](/cli/usage/request-input#array-bodies)

Build the array body for a bulk operation

#### [jobs reference](/cli/reference/jobs)

Parameters and response fields of the jobs commands