> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendora.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Jobs

> Track background operations like bulk enrichment via the jobs API.

## Overview

Some Sendora operations are async, they kick off a background job instead of returning immediately. The **Jobs API** lets you poll for the status of these operations.

Operations that create jobs:

* `POST /lead-lists/{list_id}/enrich`: bulk enrich every lead in a list
* Large campaign launches (10,000+ leads)

## Checking job status

```bash theme={"dark"}
GET /api/v1/public/jobs/{job_id}
```

```json theme={"dark"}
{
  "id": "job_abc123",
  "kind": "bulk_enrich",
  "status": "running",
  "started_at": "2026-06-22T10:00:00Z",
  "finished_at": null,
  "summary": {
    "total": 500,
    "processed": 143,
    "enriched": 89,
    "skipped": 54
  },
  "error": null
}
```

Possible `status` values:

| Status | Meaning |
| - | - |
| `pending` | Queued, not started yet |
| `running` | Currently in progress |
| `completed` | Finished successfully |
| `failed` | Finished with an error, see `error` field |
| `cancelled` | Cancelled by user or system |

## Listing all jobs

```bash theme={"dark"}
GET /api/v1/public/jobs?status=running
```

Filter by `status` and `kind`. Results are newest-first.

## Polling pattern

```python theme={"dark"}
import time, httpx

def wait_for_job(client, job_id, timeout=300):
    start = time.time()
    while time.time() - start < timeout:
        job = client.get(f"/api/v1/public/jobs/{job_id}").json()
        if job["status"] in ("completed", "failed", "cancelled"):
            return job
        time.sleep(5)
    raise TimeoutError(f"Job {job_id} did not finish in {timeout}s")

result = wait_for_job(client, "job_abc123")
print(result["summary"])
```

## Webhook alternative

Instead of polling, subscribe to the `job.completed` webhook event and get pushed the result the moment it finishes:

```json theme={"dark"}
{ "events": ["job.completed"] }
```

The webhook payload includes the `job_id`, `status`, and `summary` so you can skip the polling loop entirely.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.