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

# Tasks and platform events

> Run a stack on a schedule with task, and react to Xano branch changes and error signatures with workspace and error triggers.

Endpoints run when a client calls them. The kinds on this page run on their own: on a schedule,
when a Xano branch changes, or when an error signature appears.

## A scheduled task

A `task` is a stack with a `schedule` and no input or response.

```ts theme={null}
// xano/tasks/cleanup.ts
import { task, s, c, col, expr, every } from "@xano/sdk";
import { posts } from "../tables.js";

export const nightlyCleanup = task({
  name: "nightly_cleanup",
  // freq is seconds; every() converts a duration at compile time.
  schedule: [{ startsOn: "2026-01-01T03:00:00Z", freq: every("1d") }],
  stack: [
    s.db.bulk.delete({ table: posts, where: expr(col("published"), "=", c.bool(false)) }),
  ],
});

export const launchAnnouncement = task({
  name: "launch_announcement",
  // No freq: the task runs once, at startsOn.
  schedule: [{ startsOn: "2026-11-01T16:00:00Z" }],
  stack: [s.debug.log({ value: c.text("launch day") })],
});
```

* `schedule` is a list. Each entry has a `startsOn` and, to repeat, a `freq` interval in seconds.
  `every("15m")`, `every("1d")` and `every("1w")` spell it readably. Omit `freq` and the task
  runs once at `startsOn`.
* `startsOn` (and an optional `endsOn`) is a timestamp string with a zone, never an epoch
  number.
* There is no cron syntax and no time zone, so a fixed `startsOn` drifts an hour at each daylight
  saving change. To run at a local time, run hourly and check the local hour in the stack.
* `active: false` deploys the task without running it.

Register it with `.registerTasks([nightlyCleanup, launchAnnouncement])`.

Work that a request starts but does not wait for is not a task. Call a function with a
background `runtime` from the endpoint instead; see
[APIs, functions and middleware](/build/apis-and-middleware).

## Platform triggers

A trigger runs a stack when something happens. Its inputs are fixed by its type, so it takes no
`input`. Instead, `stack` is a callback that receives a typed handle `t`, and reading a name the
type does not have is a compile error. Both triggers here are config-only: they take no
`response`. Register them with `.registerTriggers([...])`.

Triggers that belong to another object live with it: table triggers on
[Data and tables](/build/data-and-tables#react-to-row-changes-table-triggers), realtime triggers on
[Realtime](/build/realtime#control-who-connects-server-triggers), and MCP server and agent
triggers on [AI agents and MCP servers](/build/ai-agents-and-mcp-servers).

## React to Xano branch changes: workspace triggers

A `workspaceTrigger` fires when a Xano branch is created (`branch_new`), merged into another
(`branch_merge`), or made live (`branch_live`). Pick the actions in `actions`.

```ts theme={null}
// xano/tasks/platform.ts
import { workspaceTrigger, s } from "@xano/sdk";

export const onBranchLive = workspaceTrigger({
  name: "on_branch_live",
  actions: { branch_live: true, branch_merge: true },
  stack: (t) => [
    // t.action is branch_live or branch_merge; the branches are t.from_branch and t.to_branch.
    s.debug.log({ value: t.to_branch }),
  ],
});
```

`t` exposes `t.action`, `t.from_branch` and `t.to_branch`.

## React to errors: error triggers

An `errorTrigger` fires on an error signature, which groups repeats of the same error. It fires
when a signature is first seen (`t.event` is `new`), when one marked fixed happens again
(`regression`), and when one is marked fixed (`fixed`).

```ts theme={null}
// xano/tasks/platform.ts
import { errorTrigger, s } from "@xano/sdk";
import { incidents } from "../tables.js";

export const onError = errorTrigger({
  name: "on_error",
  stack: (t) => [
    s.db.add({
      table: incidents,
      row: { event: t.event, code: t.error("code"), message: t.error("message") },
    }),
  ],
});
```

Besides `t.event` and `t.error("code")` / `t.error("message")`, `t` exposes the signature
(`t.id`, `t.signature`), where it happened (`t.caller`, `t.statement`, `t.actor`), and its
counts and times (`t.count`, `t.first_seen`, `t.last_seen`, `t.fixed_at`).

Tasks and triggers fire on their own once deployed. To run one on demand while you develop, ask
your coding agent to run it through the Xano Engine's [MCP server](/run/engine-mcp).

## Next

* Every trigger type's actions and handle: [object kinds reference](/reference/object-kinds).
* Serve websocket channels and gate who connects: [Realtime](/build/realtime).
* Test what these objects do: [Tests](/build/tests).


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