---
title: "SDK workflow runs and schedules"
canonical: https://trickest.com/docs/developer-tools/sdk/runs-schedules
description: "client.runs and client.schedules; execute workflows, poll status, read outputs, and manage schedules."
---

# SDK workflow runs and schedules

Examples use a server-side `client` from
[Client setup](/docs/developer-tools/sdk/client-setup), and resource IDs supplied
by your application.

<Info>
  **CLI:** [Runs & Outputs](/docs/developer-tools/cli/runs),
  [Schedules](/docs/developer-tools/cli/schedules). **Concepts:** workflow
  execution in [Workflows](/docs/key-concepts/workflows).
</Info>

## `client.runs`

| Method                                                                  | Description                                |
| ----------------------------------------------------------------------- | ------------------------------------------ |
| `execute(workflowId, options?)`                                         | Start a run (full workflow or single node) |
| `waitFor(executionId, options?)`                                        | Poll until terminal status (or timeout)    |
| `get(executionId, options?)`                                            | Run status + per-node statuses             |
| `list(workflowId?, options?)`                                           | Auto-paginated runs                        |
| `listPage(workflowId?, options?)`                                       | One page of runs                           |
| `stop(executionId, options?)`                                           | Stop a running execution                   |
| `retry(executionId, options?)`                                          | Retry a failed run                         |
| `delete(executionId, options?)`                                         | Remove run record                          |
| `getOutputContent(outputId, maxBytes?, options?)`                       | Read output file bytes as string           |
| `getNodeOutputFiles(executionId, nodeName, options?)`                   | List artifacts for a node                  |
| `listSubjobs(executionId, options?)`                                    | Top-level subjob generator                 |
| `listSubjobsPage(executionId, options?)`                                | One top-level subjobs page                 |
| `listModuleJobs(executionId, subjobId, moduleId, hierarchy?, options?)` | Child jobs inside a module; array          |
| `getSubjobConsole(executionId, subjobId, stream?, mode?, options?)`     | stdout/stderr console                      |
| `findSubjobByNodeName(executionId, nodeName, options?)`                 | Lookup subjob by node                      |

### Execute options

```ts
const run = await client.runs.execute(workflowId, {
  fleet: "Managed fleet", // fleet name or id
  inputs: { domain: "example.com" }, // input overrides
  node: "httpx-1", // exact node name from the saved graph
  retry: false, // request options share this object
});
```

<Note>
  `execute` does not take `watch` or `dry_run`. Its `timeout` is an HTTP request
  timeout, not a run limit. Use `waitFor(id, {timeoutMs})` to bound polling and
  `stop(id)` to stop server-side work. A polling timeout does not stop the run.
</Note>

The run options do not include `maxMachines`. The client uses the
saved version's machine allocation, or resolves fleet capacity when no allocation
is saved. Check that allocation before running.

For advanced partial execution, `partialExecution` requires a `jobs` array;
`memoizeFrom` and `runDownstreamJobs` are optional. Usually the `node` option
is enough to resolve upstream dependencies. Inputs are scalar values only.

### Wait until complete

```ts
const run = await client.runs.execute(workflowId, {
  inputs: { target: "example.com" },
});

const finished = await client.runs.waitFor(run.id, {
  intervalMs: 5000,
  timeoutMs: 600_000,
});

if (finished.status !== "COMPLETED") {
  throw new Error(`Run ended with status ${finished.status}`);
}
const files = await client.runs.getNodeOutputFiles(finished.id, "httpx-1");
console.log(files);
```

`waitFor` returns failed terminal runs without throwing. A `COMPLETED` wrapper
can also contain failed nested or distributed jobs. Inspect their outcomes and
expected artifacts in the run view before declaring success. `listSubjobs()`
alone does not cover every depth or distributed task.

### Read output content

```ts
const content = await client.runs.getOutputContent(outputId, 1024 * 1024);
```

## `client.schedules`

| Method                   | Description     |
| ------------------------ | --------------- |
| `create(data, options?)` | Create schedule |
| `delete(id, options?)`   | Delete          |

The client also exposes `list`, `get`, `enable`, and `disable`. The current
platform routes forward these operations to the workflow backend, so backend
support and permissions determine whether they succeed. To inspect a workflow's
schedule, use `client.workflows.get(workflowId)` and read `schedule_info`.
Use the schedule ID, not the workflow ID, for `schedules.get` and `delete`.

`create` expects fields such as `workflow`, `fleet`, `date`, `repeat_period`, `parallelism`. Check the `CreateSchedule` type in your IDE or see package types.

```ts
const schedule = await client.schedules.create({
  workflow: workflowId,
  fleet: fleetId,
  date: new Date(Date.now() + 60 * 60 * 1000).toISOString(), // one hour from now
  repeat_period: 86400,
  parallelism: 1,
});
```

<Tip>
  Prefer `workflow get … schedule_info` (CLI) or `client.workflows.get` for
  reading a workflow's attached schedule when the backend does not support
  schedule listing.
</Tip>

## Related

<CardGroup cols={2}>
  <Card
    title="Database"
    icon="database"
    href="/docs/developer-tools/sdk/database"
  >
    Query Live Tables a run populated.
  </Card>
  <Card
    title="Sandbox"
    icon="terminal"
    href="/docs/developer-tools/sdk/sandbox"
  >
    Dev sessions for iterative workflow work.
  </Card>
</CardGroup>

---
_Markdown source of https://trickest.com/docs/developer-tools/sdk/runs-schedules._
