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

# Webhook Inbox API Reference

> Create webhook inboxes that capture incoming HTTP requests, retrieve captured payloads, and stream new requests in real time over WebSocket.

Webhook inboxes give you a stable, publicly reachable URL that captures every incoming HTTP request — method, headers, body, and query string — without you running any server. You can inspect captured requests through the API or subscribe to a WebSocket channel to see them arrive in real time.

Each webhook inbox is reachable at:

```
https://<team_referenceId>-<project_slug>.swisstools.dev/api/webhook/<referenceId>
```

For example, if your team `referenceId` is `aB3cD4eF` and your project slug is `payments-api`, a webhook with `referenceId` `wbhkXyZ123abcABC` is reachable at:

```
https://aB3cD4eF-payments-api.swisstools.dev/api/webhook/wbhkXyZ123abcABC
```

Captured requests are stored for 12 hours, with a maximum of 50 per inbox. The inbox URL is public — no auth needed for external services to send requests to it.

All management endpoints require session authentication. See [Authentication](/api-reference/authentication) for details.

## List Webhooks

`GET /api/projects/:projectId/webhooks`

Returns all webhook inboxes for the specified project.

**Path Parameters**

<ParamField path="projectId" type="string" required>
  The UUID of the project.
</ParamField>

**Request**

```bash theme={null}
curl https://swisstools.dev/api/projects/018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b/webhooks \
  -b cookies.txt
```

**Response**

```json theme={null}
[
  {
    "id": "018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e",
    "referenceId": "wbhkXyZ123abcABC",
    "projectId": "018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b",
    "name": "Stripe Events",
    "description": "Capture Stripe payment events",
    "expiresAt": null,
    "createdAt": "2024-02-15T12:00:00.000Z",
    "updatedAt": "2024-02-15T12:00:00.000Z"
  }
]
```

## Create Webhook

`POST /api/projects/:projectId/webhooks`

Creates a new webhook inbox.

**Path Parameters**

<ParamField path="projectId" type="string" required>
  The UUID of the project.
</ParamField>

**Request Body**

<ParamField body="name" type="string" required>
  A human-readable name for the webhook inbox.
</ParamField>

<ParamField body="description" type="string">
  An optional description of what this inbox captures.
</ParamField>

**Request**

```bash theme={null}
curl -X POST https://swisstools.dev/api/projects/018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b/webhooks \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Stripe Events",
    "description": "Capture Stripe payment events"
  }'
```

**Response** — `201 Created`

```json theme={null}
{
  "id": "018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e",
  "referenceId": "wbhkXyZ123abcABC",
  "projectId": "018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b",
  "name": "Stripe Events",
  "description": "Capture Stripe payment events",
  "expiresAt": null,
  "createdAt": "2024-02-15T12:00:00.000Z",
  "updatedAt": "2024-02-15T12:00:00.000Z"
}
```

## Get Webhook

`GET /api/projects/:projectId/webhooks/:webhookId`

Returns a single webhook inbox by its ID.

**Path Parameters**

<ParamField path="projectId" type="string" required>
  The UUID of the project.
</ParamField>

<ParamField path="webhookId" type="string" required>
  The UUID of the webhook inbox.
</ParamField>

**Request**

```bash theme={null}
curl https://swisstools.dev/api/projects/018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b/webhooks/018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e \
  -b cookies.txt
```

**Response**

```json theme={null}
{
  "id": "018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e",
  "referenceId": "wbhkXyZ123abcABC",
  "projectId": "018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b",
  "name": "Stripe Events",
  "description": "Capture Stripe payment events",
  "expiresAt": null,
  "createdAt": "2024-02-15T12:00:00.000Z",
  "updatedAt": "2024-02-15T12:00:00.000Z"
}
```

## Update Webhook

`PUT /api/projects/:projectId/webhooks/:webhookId`

Updates the name or description of a webhook inbox.

**Path Parameters**

<ParamField path="projectId" type="string" required>
  The UUID of the project.
</ParamField>

<ParamField path="webhookId" type="string" required>
  The UUID of the webhook inbox to update.
</ParamField>

**Request Body**

<ParamField body="name" type="string">
  Updated display name.
</ParamField>

<ParamField body="description" type="string">
  Updated description.
</ParamField>

**Request**

```bash theme={null}
curl -X PUT https://swisstools.dev/api/projects/018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b/webhooks/018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"name": "Stripe Payment Events", "description": "Only payment.success and payment.failed events."}'
```

**Response**

```json theme={null}
{
  "id": "018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e",
  "referenceId": "wbhkXyZ123abcABC",
  "projectId": "018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b",
  "name": "Stripe Payment Events",
  "description": "Only payment.success and payment.failed events.",
  "expiresAt": null,
  "createdAt": "2024-02-15T12:00:00.000Z",
  "updatedAt": "2024-03-01T09:45:00.000Z"
}
```

## Delete Webhook

`DELETE /api/projects/:projectId/webhooks/:webhookId`

Permanently deletes the webhook inbox and all captured requests stored for it.

**Path Parameters**

<ParamField path="projectId" type="string" required>
  The UUID of the project.
</ParamField>

<ParamField path="webhookId" type="string" required>
  The UUID of the webhook inbox to delete.
</ParamField>

**Request**

```bash theme={null}
curl -X DELETE https://swisstools.dev/api/projects/018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b/webhooks/018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e \
  -b cookies.txt
```

**Response**

```json theme={null}
{"success": true}
```

## Get Captured Requests

`GET /api/projects/:projectId/webhooks/:webhookId/requests`

Returns the captured HTTP requests received by this webhook inbox, most recent first. Requests are stored for 12 hours with a maximum of 50 entries.

**Path Parameters**

<ParamField path="projectId" type="string" required>
  The UUID of the project.
</ParamField>

<ParamField path="webhookId" type="string" required>
  The UUID of the webhook inbox.
</ParamField>

**Request**

```bash theme={null}
curl https://swisstools.dev/api/projects/018e5a3b-2d4e-8c9f-a0b1-3c4d5e6f7a8b/webhooks/018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e/requests \
  -b cookies.txt
```

**Response**

```json theme={null}
[
  {
    "id": "req_a1b2c3d4e5f6",
    "webhookId": "018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e",
    "method": "POST",
    "headers": {
      "content-type": "application/json",
      "x-stripe-signature": "t=1706745600,v1=abc123..."
    },
    "body": "{\"event\": \"payment.success\", \"amount\": 4900}",
    "query": {},
    "receivedAt": "2024-02-15T13:00:00.000Z"
  }
]
```

## Real-Time WebSocket Stream

Connect to the WebSocket endpoint to receive captured requests the moment they arrive, without polling.

**WebSocket URL:**

```
wss://swisstools.dev/ws/webhook/:webhookId
```

Replace `:webhookId` with the UUID of the inbox.

**Connecting:**

```javascript theme={null}
const ws = new WebSocket(
  'wss://swisstools.dev/ws/webhook/018e7d5e-4f6a-0b1c-d2e3-5f6a7b8c9d0e'
);

ws.addEventListener('message', (event) => {
  const request = JSON.parse(event.data);
  console.log('Received:', request.method, request.body);
});
```

Each WebSocket message is a JSON string with the same shape as a captured request object (see above). Messages are broadcast to all connected clients subscribed to the same webhook channel.

## Webhook Object

<ResponseField name="id" type="string">
  UUID that uniquely identifies the webhook inbox.
</ResponseField>

<ResponseField name="referenceId" type="string">
  A 16-character alphanumeric identifier used in the public inbox URL path.
</ResponseField>

<ResponseField name="projectId" type="string">
  UUID of the project that owns this inbox.
</ResponseField>

<ResponseField name="name" type="string">
  Display name of the webhook inbox.
</ResponseField>

<ResponseField name="description" type="string">
  Optional description of what this inbox captures.
</ResponseField>

<ResponseField name="expiresAt" type="string">
  ISO 8601 timestamp at which the inbox will expire, or `null` if it has no expiry.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 timestamp of creation.
</ResponseField>

<ResponseField name="updatedAt" type="string">
  ISO 8601 timestamp of the last update.
</ResponseField>

## Captured Request Object

<ResponseField name="id" type="string">
  Unique identifier for the captured request.
</ResponseField>

<ResponseField name="webhookId" type="string">
  UUID of the webhook inbox that captured this request.
</ResponseField>

<ResponseField name="method" type="string">
  HTTP method of the incoming request (e.g., `POST`, `GET`).
</ResponseField>

<ResponseField name="headers" type="object">
  Key-value map of all HTTP headers sent with the incoming request.
</ResponseField>

<ResponseField name="body" type="string">
  The raw request body as a string.
</ResponseField>

<ResponseField name="query" type="object">
  Key-value map of URL query parameters from the incoming request.
</ResponseField>

<ResponseField name="receivedAt" type="string">
  ISO 8601 timestamp of when the request was captured.
</ResponseField>
