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

# Webhooks

> Receive signed, real-time event deliveries per agent.

# Webhooks

Each agent can have **one webhook URL** that receives all of that agent's
events as signed JSON POSTs. For local agents without a public URL, prefer the
[persistent Agent Relay](/guides/relay).

## Configure a webhook

<CodeGroup>
  ```python theme={null}
  wh = client.webhooks.set(
      agent_id=agent.id,
      url="https://yourapp.com/agentline-webhook",
  )
  print(wh.secret)  # full secret shown ONCE — save it
  ```

  ```javascript theme={null}
  const wh = await client.webhooks.set({
      agentId: agent.id,
      url: "https://yourapp.com/agentline-webhook",
  });
  console.log(wh.secret); // full secret shown ONCE — save it
  ```
</CodeGroup>

The response returns the **full signing secret once**. On later reads it is
masked.

## Verify the signature

Each delivery includes an HMAC-SHA256 signature of the **raw request body** in
a header (default `X-Webhook-Signature`). Verify it before trusting the
payload:

<CodeGroup>
  ```python theme={null}
  import hmac, hashlib

  def verify(raw_body: bytes, signature: str, secret: str) -> bool:
      expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
      return hmac.compare_digest(expected, signature)
  ```

  ```javascript theme={null}
  import crypto from "node:crypto";

  function verify(rawBody, signature, secret) {
    const expected = crypto
      .createHmac("sha256", secret)
      .update(rawBody)
      .digest("hex");
    return crypto.timingSafeEqual(
      Buffer.from(expected),
      Buffer.from(signature),
    );
  }
  ```
</CodeGroup>

<Note>
  You can set a custom signature header (e.g. `X-Hub-Signature-256` for
  GitHub-style verification) via the `signature_header` field when configuring
  the webhook.
</Note>

## Manage & test

<CodeGroup>
  ```python theme={null}
  client.webhooks.list()
  client.webhooks.delete(agent_id=agent.id)
  client.webhooks.test(agent_id=agent.id)   # sends a signed webhook.test event
  ```

  ```javascript theme={null}
  await client.webhooks.list();
  await client.webhooks.delete({ agentId: agent.id });
  await client.webhooks.test({ agentId: agent.id });
  ```
</CodeGroup>

`test` fires a `webhook.test` event through the exact same pipeline as real
events — a successful delivery confirms the whole chain is wired correctly.
