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

# Webhooks

> Trigger agents via HTTP using the serve API

Run agents on-demand via HTTP webhooks using `agentuse serve`. Integrate with external services, CI/CD pipelines, or any system that can make HTTP requests.

## Quick Start

1. Start the daemon:

```bash theme={"system"}
agentuse serve
```

2. Trigger an agent via HTTP:

```bash theme={"system"}
curl -X POST http://127.0.0.1:12233/api/run \
  -H "Content-Type: application/json" \
  -d '{"agent": "assistant.agentuse"}'
```

## Serving Multiple Projects

AgentUse runs one serve daemon at a time. Repeat `-C` on that daemon to serve multiple project roots:

```bash theme={"system"}
agentuse serve -C ./projA -C ./projB
```

Project ids default to directory basenames. Duplicate ids fail startup.

Select a project in the request body:

```bash theme={"system"}
curl -X POST http://127.0.0.1:12233/api/run \
  -H "Content-Type: application/json" \
  -d '{"project": "projA", "agent": "assistant.agentuse"}'
```

Without `project`, multi-project requests return `400 PROJECT_REQUIRED` unless a default is set:

```bash theme={"system"}
agentuse serve -C ./projA -C ./projB --default projA
```

Explicit `project` fields override the default.

### Global config

You can put serve defaults in `~/.agentuse/config.json`. See [Configuration Files](/reference/configuration-files#global-serve-config) for the schema and CLI override behavior.

### Environment isolation

Each project loads its own `.env` / `.env.local` in its worker process; env vars never mix across projects.

## API Reference

All JSON endpoints live under the `/api/*` prefix. The root paths (`/agents`,
`/sessions`, `/schedules`, `/stores`, `/approvals`) serve the HTML dashboard
pages instead. The per-session page `/sessions/:id` and its action subroutes
carry their own capability auth (session token / API key / local); see
[Approval Gates](/guides/approval-gates#auth-and-the-session-token).

<Note>
  `POST /run`, `POST /resume/:id`, and the `POST /approvals/:id/...` action
  endpoints are also still reachable at their original (un-prefixed) paths for
  backward compatibility. `GET /approvals/:id` now redirects to `/sessions/:id`.
  Prefer the `/api/*` and `/sessions` paths; the legacy aliases will be removed in
  a future release.
</Note>

### GET /api

Returns version, default project, and served projects. (`GET /` serves the HTML
dashboard built from the same data.)

```json theme={"system"}
{
  "version": "0.12.0",
  "default": "projA",
  "projects": [
    { "id": "projA", "path": "/abs/path/to/projA", "agentCount": 3, "scheduleCount": 1 },
    { "id": "projB", "path": "/abs/path/to/projB", "agentCount": 2, "scheduleCount": 0 }
  ]
}
```

### POST /api/run

Execute an agent and receive the result. (Legacy alias: `POST /run`.)

**Request:**

```json theme={"system"}
{
  "agent": "path/to/agent.agentuse",
  "project": "projA",
  "prompt": "Optional additional instructions",
  "model": "anthropic:claude-sonnet-5",
  "timeout": 300,
  "maxSteps": 100
}
```

| Field      | Type   | Required    | Description                                              |
| ---------- | ------ | ----------- | -------------------------------------------------------- |
| `agent`    | string | Yes         | Path to agent file (relative to that project's root)     |
| `project`  | string | Conditional | Required in multi-project mode unless `--default` is set |
| `prompt`   | string | No          | Additional prompt appended to agent instructions         |
| `model`    | string | No          | Override model in agent file                             |
| `timeout`  | number | No          | Max execution time in seconds (default: 300)             |
| `maxSteps` | number | No          | Max tool call steps                                      |

**Response:**

```json theme={"system"}
{
  "success": true,
  "result": {
    "text": "Agent response",
    "finishReason": "end-turn",
    "duration": 1234,
    "tokens": { "input": 500, "output": 200 },
    "toolCalls": 3
  }
}
```

**Error Response:**

```json theme={"system"}
{
  "success": false,
  "error": {
    "code": "AGENT_NOT_FOUND",
    "message": "Agent file not found: my-agent.agentuse"
  }
}
```

| Error Code          | HTTP Status | Description                                            |
| ------------------- | ----------- | ------------------------------------------------------ |
| `AGENT_NOT_FOUND`   | 404         | Agent file doesn't exist                               |
| `PROJECT_NOT_FOUND` | 404         | Unknown project id in multi-project mode               |
| `PROJECT_REQUIRED`  | 400         | Multi-project request without `project` or `--default` |
| `INVALID_PATH`      | 400         | Path outside project root                              |
| `INVALID_REQUEST`   | 400         | Invalid JSON body                                      |
| `MISSING_FIELD`     | 400         | Required field missing                                 |
| `TIMEOUT`           | 504         | Execution timed out                                    |
| `EXECUTION_ERROR`   | 500         | Runtime error                                          |

### GET /api/agents

Lists the agents the daemon loaded as JSON. `path` matches what `POST /api/run`
expects. (The browsable HTML page is at `/agents`.)

For one agent's capability summary and raw source, use
`GET /api/agents/detail?project=<id>&path=<agent-path>`. The path must match an
agent already loaded by that project; the browsable detail hub is at
`/agents/<project>/<agent-path>`.

```json theme={"system"}
{
  "success": true,
  "agents": [
    { "projectId": "projA", "path": "daily.agentuse", "name": "Daily Digest", "model": "anthropic:claude-sonnet-5", "schedule": "0 9 * * *" }
  ],
  "errors": []
}
```

### GET /api/schedules

Lists scheduled agents as JSON, soonest next run first. (The browsable HTML page
is at `/schedules`.)

```json theme={"system"}
{
  "success": true,
  "schedules": [
    { "projectId": "projA", "agentPath": "daily.agentuse", "expression": "0 9 * * *", "human": "Daily 9am", "enabled": true, "nextRun": "2026-06-03T16:00:00.000Z", "lastRun": null }
  ]
}
```

From the terminal, `agentuse serve agents` and `agentuse serve schedules` render these as tables. See [CLI Commands](/reference/cli-commands#serve-agents).

### GET /api/sessions

Lists every run (top-level sessions; subagent sessions are excluded) as JSON,
newest first. Filter with `?agent=<id>`, `?trigger=scheduled|manual|slack|api`,
and `?days=<n|all>` (default \~7 days). The browsable HTML page is at `/sessions`.

```bash theme={"system"}
curl "http://127.0.0.1:12233/api/sessions?trigger=scheduled" \
  -H "Authorization: Bearer $AGENTUSE_API_KEY"
```

```json theme={"system"}
{
  "success": true,
  "sessions": [
    {
      "project": "projA",
      "sessionId": "01JFN8K3M2P1",
      "agent": { "id": "daily", "name": "Daily Digest" },
      "status": "completed",
      "trigger": "scheduled",
      "createdAt": 1717430400000,
      "updatedAt": 1717430412000
    }
  ],
  "window": { "days": 7, "createdAfter": 1716825600000 },
  "errors": []
}
```

`trigger` records how the run started: `scheduled` (the built-in scheduler),
`api` (`POST /api/run`), `slack`, or `manual` (CLI runs and the default).

### GET /api/sessions/:id

Returns one session including its run-log entries. API-key gated.

```bash theme={"system"}
curl "http://127.0.0.1:12233/api/sessions/01JFN8K3M2P1" \
  -H "Authorization: Bearer $AGENTUSE_API_KEY"
```

For the human-facing view + approve page, the redirect target, and the session
token, see [Approval Gates](/guides/approval-gates#experimental-session--approval-api).

## Streaming Response

For real-time output, request NDJSON streaming:

```bash theme={"system"}
curl -N -X POST http://127.0.0.1:12233/api/run \
  -H "Content-Type: application/json" \
  -H "Accept: application/x-ndjson" \
  -d '{"agent": "analyzer.agentuse"}'
```

Each line is a JSON event:

```json theme={"system"}
{"type": "text", "text": "Analyzing..."}
{"type": "tool-call", "name": "read_file", "args": {"path": "data.txt"}}
{"type": "tool-result", "name": "read_file", "result": "..."}
{"type": "text", "text": "Complete!"}
{"type": "finish", "finishReason": "end-turn", "duration": 2345}
```

## Authentication

When exposing the server externally, authentication is required:

```bash theme={"system"}
# Set API key
export AGENTUSE_API_KEY="your-secret-key"

# Start on all interfaces
agentuse serve --host 0.0.0.0
```

Include the key in requests:

```bash theme={"system"}
curl -X POST http://server:12233/api/run \
  -H "Authorization: Bearer your-secret-key" \
  -H "Content-Type: application/json" \
  -d '{"agent": "assistant.agentuse"}'
```

<Warning>
  Use `--no-auth` to bypass authentication (dangerous for production).
</Warning>

## Exposing Your Local Server

<Tabs>
  <Tab title="Tailscale (Private)">
    Access from your devices or team only:

    ```bash theme={"system"}
    brew install tailscale
    tailscale up
    agentuse serve
    ```

    Connect via `http://<machine-name>:12233` from any device on your tailnet.
  </Tab>

  <Tab title="Cloudflare Tunnel (Public)">
    Expose to the internet for external webhooks:

    ```bash theme={"system"}
    brew install cloudflared
    agentuse serve
    cloudflared tunnel --url http://localhost:12233
    ```

    Prints a public `https://xxx.trycloudflare.com` URL with automatic HTTPS.
  </Tab>
</Tabs>

## Integration Examples

### GitHub Webhook

Create an agent to handle GitHub events:

```yaml theme={"system"}
---
model: anthropic:claude-sonnet-5
description: Process GitHub webhook events
tools:
  bash:
    commands:
      - "gh *"
      - "git *"
---

Process the incoming GitHub event and take appropriate action.
```

Configure a GitHub webhook to POST to your server:

```
URL: https://your-server.com/api/run
Content-Type: application/json
Body: {"agent": "github-handler.agentuse", "prompt": "<webhook payload>"}
```

### Slack Integration

Slack slash commands require a response within 3 seconds and signature verification. Use a workflow tool as middleware:

**With n8n or Make:**

1. Add Slack trigger node (receives slash commands)
2. Add HTTP Request node → POST to `http://server:12233/api/run`
3. Return agent response to Slack

**With Zapier:**

1. Trigger: Slack → New Slash Command
2. Action: Webhooks → POST to AgentUse `/run`
3. Action: Slack → Send Channel Message with result

<Note>
  Direct Slack integration requires handling the 3-second timeout, form-urlencoded parsing, and request signature verification. Workflow tools handle this automatically.
</Note>

### n8n / Make / Zapier

Use HTTP request nodes to trigger agents:

1. Set URL to `http://your-server:12233/api/run`
2. Method: POST
3. Headers: `Content-Type: application/json`
4. Body:

```json theme={"system"}
{
  "agent": "workflow-agent.agentuse",
  "prompt": "{{trigger.data}}"
}
```

### Cron Job (External)

Trigger from system cron instead of built-in scheduler:

```bash theme={"system"}
# /etc/cron.d/agent-tasks
0 * * * * curl -s -X POST http://127.0.0.1:12233/api/run \
  -H "Content-Type: application/json" \
  -d '{"agent": "hourly-task.agentuse"}'
```

## Server Configuration

See [CLI Commands - agentuse serve](/reference/cli-commands#agentuse-serve) for all server options including port, host, debug mode, and authentication configuration.

## Production Deployment

For deploying `agentuse serve` in production with reverse proxies (nginx), process management (PM2), and Docker, see [Self-Hosting](/guides/self-hosting#production-deployment).

## Next Steps

<CardGroup cols={2}>
  <Card title="Scheduled Agents" icon="clock" href="/guides/schedule">
    Run agents on a cron schedule
  </Card>

  <Card title="Self-Hosting" icon="server" href="/guides/self-hosting">
    Deploy in production
  </Card>
</CardGroup>
