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

# Jobs and executions

> How triggers become jobs and executions, their status lifecycles, fan-out over records, and recurring schedules

When you trigger a [definition](/concepts/flow-definitions), GetDialed creates two kinds of records: one **job** for the triggering event, and one or more **executions** for the actual runs. You never create jobs or executions directly — they're always produced by a trigger.

## Jobs

A job represents one triggering event and groups every execution it produced. Key fields:

| Field                        | Description                                                                                                       |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `definition_id`              | The definition that was triggered                                                                                 |
| `source`                     | Trigger origin. Defaults to `api`; recurring schedules set `schedule`; you can pass your own (e.g., `csv_upload`) |
| `status`                     | See the lifecycle table below                                                                                     |
| `record_count`               | How many executions this job fans out to. `1` for a simple trigger, `N` when you trigger with records             |
| `input_data`                 | The input object for a single-record trigger                                                                      |
| `records`                    | The record array for a multi-record trigger                                                                       |
| `metadata`                   | Arbitrary metadata you attached at trigger time                                                                   |
| `scheduled_at`               | If set, the job waits until this time before running                                                              |
| `scheduled_job_id`           | Links back to the [scheduled job](#recurring-triggers-scheduled-jobs) that fired it, if any                       |
| `started_at`, `completed_at` | Lifecycle timestamps                                                                                              |

### Job status lifecycle

| Status             | Meaning                                |
| ------------------ | -------------------------------------- |
| `pending`          | Created, not yet started               |
| `scheduled`        | Waiting for its `scheduled_at` time    |
| `running`          | Executions are in flight               |
| `completed`        | Every execution succeeded              |
| `partially_failed` | Some executions succeeded, some failed |
| `failed`           | Executions failed                      |
| `cancelled`        | Cancelled before it ran                |

A job moves `pending → running → completed | partially_failed | failed`. Passing `scheduled_at` at trigger time inserts a `scheduled` stage before `running`. Only `pending` or `scheduled` jobs can be cancelled (`DELETE /jobs/{id}`) — anything already running returns `409`.

## Executions

An execution is one durable run processing one set of inputs. Each belongs to exactly one job:

| Field                        | Description                              |
| ---------------------------- | ---------------------------------------- |
| `job_id`                     | The parent job                           |
| `definition_id`              | The definition being run                 |
| `status`                     | See the lifecycle table below            |
| `input_data`                 | The inputs this specific run received    |
| `workflow_id`                | Identifier of the underlying durable run |
| `result`                     | The final output when the run completes  |
| `error`                      | The error message when the run fails     |
| `started_at`, `completed_at` | Lifecycle timestamps                     |

### Execution status lifecycle

| Status      | Meaning                                       |
| ----------- | --------------------------------------------- |
| `pending`   | Created, not yet picked up                    |
| `running`   | Steps are executing                           |
| `completed` | Finished successfully — `result` is populated |
| `failed`    | Finished with an error — `error` is populated |
| `cancelled` | Stopped before completion                     |

An execution moves `pending → running → completed | failed`. List a job's executions with `GET /jobs/{job_id}/executions` and fetch one with `GET /executions/{id}`.

## Single-record vs. multi-record triggers

A trigger creates executions in one of two shapes:

* **Single-record** — pass `input_data`. The job has `record_count: 1` and one execution that receives your `input_data`.
* **Multi-record (fan-out)** — pass a `records` array (up to 15,000,000 records). One execution is created **per record**, each receiving that record as its input. The job's `record_count` is the array length, and its final status aggregates all children: all succeed → `completed`, all fail → `failed`, a mix → `partially_failed`.

See [triggering with records](/guides/trigger-with-records) for a walkthrough.

## Recurring triggers: scheduled jobs

To run a definition on a repeating cadence, create a **scheduled job** with `POST /scheduled-jobs`. Each fire creates a normal job — visible under `GET /definitions/{id}/jobs` with `source: "schedule"` and a `scheduled_job_id` pointing back at the schedule — so the job and execution lifecycle above applies unchanged.

| Field                               | Description                                                            |
| ----------------------------------- | ---------------------------------------------------------------------- |
| `definition_id`                     | The definition to fire. Immutable after creation                       |
| `description`                       | Human-readable description (1–200 chars)                               |
| `cron_expression`                   | 5-field UTC cron, e.g. `*/15 * * * *`                                  |
| `enabled`                           | Default `true`. Set `false` to pause without losing fire history       |
| `input_data`                        | Input passed to each fired job                                         |
| `metadata`                          | Free-form metadata                                                     |
| `next_fire_at`                      | Computed from the cron expression at read time                         |
| `last_fired_at`, `last_fire_status` | The most recent fire and its state: `running`, `success`, or `failure` |

<Warning>
  Cron expressions are **UTC-only and 5-field syntax only**. Six-field expressions (with seconds), aliases like `@hourly`, and any `timezone` field are rejected with `422`.
</Warning>

Fire behavior is fixed: if a previous fire is still running when the next tick arrives, that tick is **skipped**, not queued. Missed fires during downtime are replayed only within a 60-second catch-up window.

Manage schedules with `PATCH /scheduled-jobs/{id}` (change the cron expression, pause/resume with `enabled`, update `input_data`) and `DELETE /scheduled-jobs/{id}` — deleting a schedule never affects jobs it already fired.
