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

# Overview

> Event-driven automations that run a workflow over a data model as its rows change. Define them with definePlay.

A **play** runs a [workflow](/workflows/overview) over a [data model](/models/overview), emitting a run for each row that changes. Where a tool is triggered on demand, a play continuously watches its model and fires when matching changes occur. You define one with `definePlay`.

## Define a play

```ts plays/onboarding.ts theme={null}
import { definePlay, defineWorkflow } from "@cargo-ai/cdk";
import { z } from "zod";
import { contacts } from "../models/contacts";
import { enrich } from "../tools/enrich";

const onboardRow = defineWorkflow(
  "onboard-contact",
  {
    input: z.object({ email: z.string() }),
    output: z.object({ welcomed: z.boolean(), message: z.string() }),
    uses: { enrich },
  },
  ({ input, uses, ai }) => {
    const enriched = uses.enrich({ email: input.email });
    const message = ai(
      `Draft a one-line welcome for ${input.email} at ${enriched.company}.`,
    );
    return { welcomed: true, message };
  },
);

export const onboarding = definePlay("onboarding", {
  model: contacts,                    // the model whose rows drive it
  workflow: onboardRow,               // per-row automation, deployed as the release
  changeKinds: ["added", "updated"],  // which row changes fire a run
  runCreationRule: "always",
  schedule: { type: "realtime" },     // fire as rows change; see below for other types
});
```

The per-row `workflow` is deployed as the play's release. `changeKinds` and `schedule` control when runs are created. `schedule` accepts one of:

| `type`       | Fires…                                                                 |
| ------------ | ---------------------------------------------------------------------- |
| `realtime`   | as the model's rows change (the reactive default for row-driven plays) |
| `cron`       | on a cron expression — `{ type: "cron", cron: "0 * * * *" }`           |
| `dbt`        | after a dbt job completes                                              |
| `dependency` | after another play finishes — `{ type: "dependency", play: upstream }` |
| `watch`      | on a watched external schedule                                         |

<Note>
  `realtime` and `watch` are distinct: `realtime` reacts to row changes in the
  model, while `watch` follows an externally managed schedule.
</Note>

## Deploy and trigger

```bash theme={null}
cargo-ai cdk deploy
cargo-ai orchestration play list                 # → workflowUuid, segmentUuid
cargo-ai orchestration batch create \
  --workflow-uuid <uuid> \
  --data '{"kind":"segment","segmentUuid":"<uuid>"}' \
  --wait-until-finished
```

<Warning>
  Plays always use `batch create`, never `run create` — `run create` on a play's
  workflow returns a `playNotCompatible` error.
</Warning>

## Fallbacks and health

Add fallback paths so a failed step doesn't fail the whole run (notify, try an alternative provider, write defaults, or skip and continue). Watch success rate and set batch-health alerts. See [Triggering](/plays/triggering) for schedules and enrolment, and [Monitoring](/tools/monitoring) for records and metrics.

## Using the UI

See [Using the UI](/plays/using-ui) for the visual play editor — publishing, manual enrolment, re-running failed runs, and fallback configuration.
