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

# Schedule a routine

> A routine gives one agent a saved prompt on a cron schedule and posts each run's reply to a direct message.

A **routine** is a saved prompt that Pinework gives to one agent on a schedule. Each scheduled tick starts an agent run, unless the last one is still going. The dashboard lists routines on the **Automations** page. The CLI calls them `automation`.

## Before you start

* You have an agent in your workspace. See [Create an agent](/guides/create-an-agent).
* For the CLI tab, you have signed in with `pinework login`.
* You know when the routine should run, as a time of day or a 5-field cron expression.

## Create the routine

<Steps>
  <Step title="Write the routine">
    <Tabs>
      <Tab title="Dashboard">
        1. Open **Automations** in the sidebar.
        2. In the **Routines** section, click **New routine**.
        3. Enter a **Name**.
        4. Under **Runs**, keep **Schedule** selected.
        5. Pick how often: **Every hour**, **Every day**, **Weekdays**, **Every week** or **Every month**.
        6. Set the time of day, except for **Every hour**. Set the timezone. It starts as your browser's timezone.
        7. In **What to do**, write the prompt the agent gets on each run.
        8. Pick the **Agent**.
        9. Optional: set **Runs on** to **Cloud** or **Device**, and pick a **Model**. Both default to the agent's own setting.
        10. Click **Create routine**.

        To type a cron expression, click **Use cron instead**. The field takes 5 fields and no seconds, such as `30 8 * * 1-5`.
      </Tab>

      <Tab title="CLI">
        Find the agent's id:

        ```bash theme={null}
        pinework agent list
        ```

        Create the routine:

        ```bash theme={null}
        pinework automation create \
          --name "Morning inbox triage" \
          --cron '30 8 * * 1-5' \
          --tz America/New_York \
          --agent agt_… \
          --prompt "Read the shared inbox. List what needs me today, shortest first."
        ```

        `--agent` also takes an @handle. `--tz` takes an IANA timezone and defaults to `UTC`. Put a long prompt in a file and pass `--prompt-file <path>` instead of `--prompt`. Add `--env cloud` or `--env device` to choose where each run happens. Add `--model <model-id>` to override the agent's model.
      </Tab>
    </Tabs>

    When it works, the dashboard shows a "Routine created" toast. The routine appears under **Routines** with its schedule in words and "Never ran". The CLI prints the routine as JSON. Its `id` starts with `aut_` and its `status` is `active`.
  </Step>

  <Step title="Run it once now">
    Test the prompt without waiting for the schedule.

    <Tabs>
      <Tab title="Dashboard">
        Open the routine's **More actions** menu and click **Run now**. The routine's own page also has a **Run now** button.
      </Tab>

      <Tab title="CLI">
        ```bash theme={null}
        pinework automation run aut_…
        ```
      </Tab>
    </Tabs>

    When it works, the dashboard shows a toast that the run started, with an **Open run** link. The CLI prints `"kind": "triggered"` and the new `runId`.
  </Step>

  <Step title="Read the result">
    When the run ends, the agent's final reply appears as a message in a direct message with the agent. The direct message belongs to the person who created the routine. If an agent created the routine, the reply goes to the company owner. A run that ends with an empty reply posts nothing.

    Open the routine from **Automations** to see its **Run history**. Each row shows the run, its status, what started it and when. The cards at the top count successful, failed and total runs over 7 days.
  </Step>
</Steps>

## Change, pause or stop a routine

<Tabs>
  <Tab title="Dashboard">
    * To change it, open its **More actions** menu and click **Edit**. Changes apply from the next run.
    * To pause it, turn off its switch in the **Routines** list, or click **Pause** on its page. Turn the switch on or click **Resume** to restart it.
    * To stop it for good, click **Archive**. Pinework archives routines and never deletes them. Click **Unarchive** to bring one back.
    * To copy it, click **Duplicate**.
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    pinework automation list --status active
    pinework automation update aut_… --cron '0 9 * * 1' --tz UTC
    pinework automation pause aut_…
    pinework automation resume aut_…
    pinework automation archive aut_…
    pinework automation unarchive aut_…
    ```

    `automation update` sends only the flags you pass. A new schedule replaces the old one whole, so pass `--cron` and `--tz` together.
  </Tab>
</Tabs>

## Start a routine from an event instead

A routine can also start on an event rather than a clock.

* On a GitHub pull request: pick **GitHub** under **Runs** in the dashboard, or pass `--event pr-merged` or `--event pr-checks-passed` with `--repo owner/name`. Your workspace needs GitHub connected first. See [Connect GitHub](/guides/connect-github).
* On an HTTP POST from your own system: see [Start a run from a webhook](/guides/send-webhooks).

## Fix a routine that does not start

<Accordion title="Run now says the run was skipped because one is in progress">
  A scheduled tick or **Run now** is skipped while the routine's last run is still queued or running. The skipped tick is not queued for later. Wait for the run to end, or cancel it with `pinework run cancel <run_id>`.
</Accordion>

<Accordion title="Run now says the automation is not active">
  A paused or archived routine does not start runs, from the schedule or by hand. Resume or unarchive it first.
</Accordion>

<Accordion title="The form says the cron must be a 5-field expression">
  Pinework takes standard cron with minute, hour, day of month, month and day of week. It has no seconds field. `0 9 * * 1-5` means 09:00 on weekdays.
</Accordion>

<Accordion title="The CLI says --agent me needs an agent id">
  `--agent me` works only when an agent runs the command. Pass the agent's `agt_` id or @handle instead.
</Accordion>

<CardGroup cols={2}>
  <Card title="Start a run from a webhook" href="/guides/send-webhooks">
    Start a routine's run with a POST from your own system.
  </Card>

  <Card title="Runs" href="/concepts/runs">
    What a run is and how to read its trace.
  </Card>

  <Card title="Cloud and device" href="/concepts/cloud-and-device">
    Choose where each routine run happens.
  </Card>

  <Card title="Run a workflow" href="/guides/run-a-workflow">
    Run several agent steps in order and watch each one.
  </Card>
</CardGroup>


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