# Overview

What scheduled jobs are and how to run recurring agent prompts on a cron schedule.



A **scheduled job** is a cron-driven prompt that runs on a recurring schedule and posts its result to a Slack or Discord channel. Each job pairs a cron expression, a timezone, a prompt, and a target channel — Nairi handles dispatch, agent assignment, and posting the response.

## How it works [#how-it-works]

1. Discover the platform `channel_id` of your target Slack/Discord channel via [Channels](/api/channels/overview).
2. Create the job with `POST /scheduled-jobs`, passing the `schedule` (5-field cron), `timezone` (IANA name), `prompt`, `connected_channel_id`, and `job_type` (`slack` or `discord`).
3. At each scheduled tick, Nairi starts a conversation, assigns it to the default agent for the channel, and posts the result back. Set `is_threaded: true` to post each run inside a Slack thread.
4. Toggle `is_enabled` to pause or resume the job without deleting it.

See [Schedule rules](/api/scheduled-jobs/schedule-rules) for the cron format and minimum-granularity constraints.

## When to use it [#when-to-use-it]

* **Ship recurring content into Slack or Discord.** Daily PR digests, weekly summaries, customer-facing newsletters — straight to the channel on a cron.
* **Automate the periodic checks your team runs by hand.** Error-log scans, on-call rotations, status reports — once-an-hour or once-a-day.

## Tips [#tips]

* Minimum granularity is **5 minutes**. Anything more frequent (`* * * * *`) is rejected.
* `connected_channel_id` is the **platform** channel ID (Slack `Cxxx…`, Discord numeric snowflake), **not** the internal `cc_…` record ID.
* On create, `last_executed_at` is set to creation time even when the job is disabled — this prevents an immediate fire the moment you flip `is_enabled` to `true`.
