> ## 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.

# Start a run from a webhook

> Each new POST body to a webhook routine's secret URL starts an agent run, and you can replay a failed inbound delivery.

A **webhook routine** is a routine with a secret URL instead of a schedule. A POST with a new body starts an agent run. The request body becomes the run's input. Use it to hand events from your own system, such as an alert or a form submission, to an agent.

<Note>
  Pinework receives webhooks. It does not send its own events out to a URL you host.
</Note>

## 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`.
* Your system can send an HTTP POST.

## Send an event to an agent

<Steps>
  <Step title="Create a webhook routine">
    <Tabs>
      <Tab title="Dashboard">
        1. In the sidebar, click **Automations**. Under **Routines**, click **New routine**.
        2. Enter a **Name**. Under **Runs**, click **Webhook**.
        3. Under **What to do**, write the prompt. Pick an **Agent**.
        4. Click **Create routine**.

        When it works, the **Webhook URL** dialog opens. Click **Copy URL**, then **Done**. Pinework cannot show the URL again.

        The routine appears under **Routines**. Its trigger reads **Webhook**.
      </Tab>

      <Tab title="CLI">
        ```bash theme={null}
        pinework automation create \
          --name "Triage alerts" \
          --trigger webhook \
          --agent agt_… \
          --prompt "An alert fired. Find the likely cause and tell me the first thing to check."
        ```

        `--agent` also takes an @handle. Run `pinework agent list` to find the id.

        When it works, the CLI prints the routine as JSON. It includes a `webhookUrl` field. Copy it now. Pinework shows the URL once, and `automation get` does not print it again.
      </Tab>
    </Tabs>
  </Step>

  <Step title="POST an event to the URL">
    Send any body, such as JSON, to the URL. The URL works as a password, so no auth header is needed.

    ```bash theme={null}
    curl -X POST "<webhookUrl>" \
      -H "Content-Type: application/json" \
      -d '{"id": "evt_1042", "service": "checkout", "status": "down"}'
    ```

    When it works, Pinework answers `202` with the run it started:

    ```json theme={null}
    {
      "object": "automation_fire",
      "automationId": "aut_…",
      "kind": "triggered",
      "runId": "run_…"
    }
    ```
  </Step>

  <Step title="Read what the agent did">
    The agent gets the routine's prompt, then your body. Pinework marks the body as untrusted outside data. The agent is told to read it as data, never as instructions. The agent sees the first 32 KiB of the body.

    When the run ends, the agent's final reply appears in a direct message with the agent. The direct message belongs to the person who created the routine. Open the routine from **Automations** to see every run in its **Run history**.
  </Step>
</Steps>

## Know what each POST does

* **A new body starts a new run.** Webhook runs do not wait for each other. Two different bodies start two runs, even at the same time.
* **A repeated body starts nothing new.** Pinework answers with the run that the same body started before. Put a unique field, such as an event id, in each body.
* **A paused or archived routine starts nothing.** Pinework still answers `202`, with `"kind": "skipped"` and `"reason": "not_active"`.
* **A routine takes 60 POSTs per hour.** Past that, Pinework answers `429`.
* **A body over 1 MiB is refused** with `413`.
* **An unknown or old URL gets `404`.**

## Keep the URL secret

Anyone with the URL can start runs of your agent. Treat it like a password.

If the URL leaks or you lose it, mint a new one:

<Tabs>
  <Tab title="Dashboard">
    Open the routine from **Automations**. Next to **Trigger**, click **Rotate URL**. Confirm with **Rotate URL**. The **Webhook URL** dialog shows the new URL once.
  </Tab>

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

    The CLI prints the new `webhookUrl` once.
  </Tab>
</Tabs>

The old URL stops working at once. Switching the routine to a schedule or a GitHub event also turns its URL off.

## Replay a failed delivery from a connected service

Pinework records webhooks that connected services send it as **deliveries**. A delivery has a status: Received, Verified, Routed, Handled, Failed, Dead or Cancelled. You can replay one that did not get handled.

<Tabs>
  <Tab title="Dashboard">
    1. Open **Settings**. Under **Monitoring**, click **Activity**.
    2. Click the **Webhooks** tab, then **Deliveries**.
    3. Click the **Failed** filter and open a delivery. Its page shows the raw body, the parsed payload, the signature result and any error.
    4. Click **Replay**, then **Confirm replay**.

    When it works, a "Delivery replayed" toast appears. The new delivery's page opens.
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    pinework webhook list --status failed
    pinework webhook get <delivery-id>
    pinework webhook replay <delivery-id>
    ```

    When it works, the CLI prints the original delivery id and the new delivery id.
  </Tab>
</Tabs>

A replay copies the delivery into a new one with status Received. The original stays as it was.

Pinework refuses a replay in these cases:

* The delivery is already Handled.
* Pinework stored only part of the body, so the body shows as truncated.
* An agent asks for the replay. A person must replay a delivery.

To mark a failed delivery Dead without replaying it, click **Dead-letter** or run `pinework webhook dead-letter <delivery-id>`. To clear a dead one from the unresolved view, click **Acknowledge** or run `pinework webhook acknowledge-dead <delivery-id>`.

<CardGroup cols={2}>
  <Card title="Schedule a routine" href="/guides/schedule-a-routine">
    Start the same kind of run on a clock instead.
  </Card>

  <Card title="Add a connection" href="/guides/add-a-connection">
    Link an outside service to your workspace.
  </Card>

  <Card title="Runs" href="/concepts/runs">
    Read what the agent did on each run.
  </Card>
</CardGroup>


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