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

# Async Jobs

> Kick off long-running agent tasks in the background with optional webhooks

## When to use async jobs

Chat sessions wait for the agent to complete before returning. Async jobs are fire-and-forget — use them when:

* The task takes longer than 30 seconds (e.g. enriching 500 contacts)
* You want a callback when the result is ready
* You're triggering work from another system (n8n, Zapier, your own backend)

## Submitting a job

```bash theme={null}
curl -X POST https://ascend-agent-worker.ascendgtm.workers.dev/jobs \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_type": "crm_enricher",
    "message": "Enrich all HubSpot contacts created in the last 7 days with company size, LinkedIn URL, and annual revenue. Prioritize accounts in the Series A–C range.",
    "callback_url": "https://your-app.com/webhooks/hermes-job"
  }'
```

**Response (immediate):**

```json theme={null}
{
  "job_id": "job_01J...",
  "status": "queued",
  "agent_type": "crm_enricher",
  "created_at": "2026-05-05T15:00:00Z"
}
```

## Checking job status

```bash theme={null}
curl https://ascend-agent-worker.ascendgtm.workers.dev/jobs/job_01J... \
  -H "Authorization: Bearer <your-token>"
```

```json theme={null}
{
  "job_id": "job_01J...",
  "status": "complete",
  "agent_type": "crm_enricher",
  "created_at": "2026-05-05T15:00:00Z",
  "completed_at": "2026-05-05T15:03:42Z",
  "response": "Enriched 47 contacts. 12 matched Perplexity data. 35 used Discover...",
  "tool_calls": [...],
  "iterations": 8
}
```

## Webhook payload

When `callback_url` is set, Hermes POSTs the completed job result to your URL:

```json theme={null}
{
  "event": "job.complete",
  "job_id": "job_01J...",
  "agent_type": "crm_enricher",
  "status": "complete",
  "response": "...",
  "completed_at": "2026-05-05T15:03:42Z"
}
```

Failed jobs post `"status": "error"` with an `error` field. Implement idempotent webhook handlers — Hermes retries delivery up to 3 times with exponential backoff.

## Job parameters

| Parameter        | Type    | Required | Description                             |
| ---------------- | ------- | -------- | --------------------------------------- |
| `agent_type`     | string  | Yes      | Agent config to run                     |
| `message`        | string  | Yes      | Job instruction                         |
| `callback_url`   | string  | No       | Webhook URL for completion notification |
| `context`        | object  | No       | Additional context passed to the agent  |
| `max_iterations` | integer | No       | Override config default                 |

## Job statuses

| Status                   | Meaning                                              |
| ------------------------ | ---------------------------------------------------- |
| `queued`                 | Job accepted, not yet started                        |
| `running`                | Agent loop executing                                 |
| `complete`               | Finished successfully                                |
| `max_iterations_reached` | Stopped at iteration limit; partial result available |
| `error`                  | Unrecoverable error; check `error_code`              |

## Listing jobs

```bash theme={null}
curl "https://ascend-agent-worker.ascendgtm.workers.dev/jobs?limit=20&status=complete" \
  -H "Authorization: Bearer <your-token>"
```

Results are paginated with a `cursor` field. Jobs are retained for 30 days.

## Integration examples

### n8n webhook trigger

In n8n, add an HTTP Request node that POSTs to `/jobs`, captures `job_id`, then uses a Webhook node configured at `callback_url` to receive the result.

### Polling from your backend

If you can't receive webhooks, poll `/jobs/{job_id}` every 10–30 seconds until `status` is not `queued` or `running`. Most jobs complete within 2 minutes; set a polling timeout of 10 minutes.
