# Webhook endpoints

> Register the URLs PostWire calls when a post publishes or fails.

Source: https://postwire.io/docs/webhooks-api/ · Base URL: https://postwire.io · OpenAPI: https://postwire.io/openapi.json

This page lists the endpoints. The events, the signature and how to verify it in Node.js and Python are in the [webhooks guide](/docs/webhooks/). Up to 5 endpoints, on every plan.

- [`GET /api/webhooks`](#get-api-webhooks): List your webhook endpoints (the signing secret is never returned)
- [`POST /api/webhooks`](#post-api-webhooks): Add a webhook endpoint; the response carries its signing secret, once
- [`DELETE /api/webhooks/{id}`](#delete-api-webhooks-id): Delete a webhook endpoint (its pending deliveries are dropped)
- [`POST /api/webhooks/{id}/test`](#post-api-webhooks-id-test): Send a signed webhook.test event to this endpoint now and report what it answered
- [`GET /api/webhooks/{id}/deliveries`](#get-api-webhooks-id-deliveries): The delivery log of an endpoint: the last 50 deliveries with status, attempts, the endpoint's answer and the payload

## List your webhook endpoints (the signing secret is never returned)

`GET /api/webhooks`

PostWire calls your endpoints when a post goes out or fails on a network, and when a connection must be signed in again. Every plan; up to 5 endpoints. Events and signature: https://postwire.io/docs/webhooks/ (payload schema: components.schemas.WebhookEvent).

Needs an API key: `Authorization: Bearer pw_live_…`.

**Responses**

| Status | Means |
|---|---|
| `200` | { webhooks: [Webhook], events: [string], max: 5 } |
| `503` | code webhooks_unavailable: webhooks are not switched on on this server yet |

```bash
curl "https://postwire.io/api/webhooks" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
```

```js
const res = await fetch("https://postwire.io/api/webhooks", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
```

```python
import os, requests

r = requests.get(
    "https://postwire.io/api/webhooks",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())
```

## Add a webhook endpoint; the response carries its signing secret, once

`POST /api/webhooks`

Needs an API key: `Authorization: Bearer pw_live_…`.

**Body (JSON)**

| Field | Type | Description |
|---|---|---|
| `url` (required) | string (uri) | A public https URL. Redirects are not followed. |
| `events` | array of string | Default: all three. One of: post.published, post.failed, connection.reauth_required. |
| `description` | string | Up to 200 characters. |

**Responses**

| Status | Means |
|---|---|
| `201` | { webhook: Webhook, secret: "whsec_…" } — keep the secret: it is not shown again |
| `400` | code bad_url (not https, not public, malformed), bad_request (unknown event) or too_many (5 endpoints already) |
| `503` | code webhooks_unavailable |

```bash
curl -X POST "https://postwire.io/api/webhooks" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/hooks/postwire",
  "events": [
    "post.published",
    "post.failed"
  ]
}'
```

```js
const res = await fetch("https://postwire.io/api/webhooks", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "url": "https://example.com/hooks/postwire",
    "events": [
      "post.published",
      "post.failed"
    ]
  }),
});
console.log(res.status, await res.json());
```

```python
import os, requests

r = requests.post(
    "https://postwire.io/api/webhooks",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
    json={
        "url": "https://example.com/hooks/postwire",
        "events": ["post.published", "post.failed"],
    },
)
print(r.status_code, r.json())
```

## Delete a webhook endpoint (its pending deliveries are dropped)

`DELETE /api/webhooks/{id}`

Needs an API key: `Authorization: Bearer pw_live_…`.

**Parameters**

| Field | Type | Description |
|---|---|---|
| `id` (required) | path, string (uuid) |  |

**Responses**

| Status | Means |
|---|---|
| `200` | deleted |
| `404` | code not_found |

```bash
curl -X DELETE "https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
```

```js
const res = await fetch("https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
```

```python
import os, requests

r = requests.delete(
    "https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())
```

## Send a signed webhook.test event to this endpoint now and report what it answered

`POST /api/webhooks/{id}/test`

Needs an API key: `Authorization: Bearer pw_live_…`.

**Parameters**

| Field | Type | Description |
|---|---|---|
| `id` (required) | path, string (uuid) |  |

**Responses**

| Status | Means |
|---|---|
| `200` | { delivered: boolean, status: HTTP status or null, error?, delivery_id, event } |
| `404` | code not_found |

```bash
curl -X POST "https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f/test" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
```

```js
const res = await fetch("https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f/test", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
```

```python
import os, requests

r = requests.post(
    "https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f/test",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())
```

## The delivery log of an endpoint: the last 50 deliveries with status, attempts, the endpoint's answer and the payload

`GET /api/webhooks/{id}/deliveries`

Needs an API key: `Authorization: Bearer pw_live_…`.

**Parameters**

| Field | Type | Description |
|---|---|---|
| `id` (required) | path, string (uuid) |  |
| `limit` | query, integer |  |

**Responses**

| Status | Means |
|---|---|
| `200` | { webhook, deliveries: [{ id, event, status: pending\|delivered\|failed, attempts, last_status, last_error, next_attempt_at, created_at, delivered_at, payload }] } |

```bash
curl "https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f/deliveries?limit=20" \
  -H "Authorization: Bearer $POSTWIRE_API_KEY"
```

```js
const res = await fetch("https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f/deliveries?limit=20", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.POSTWIRE_API_KEY}` },
});
console.log(res.status, await res.json());
```

```python
import os, requests

r = requests.get(
    "https://postwire.io/api/webhooks/7c2a6f0e-5b1d-4c8a-9e3f-2d4b6a8c0e1f/deliveries?limit=20",
    headers={"Authorization": f"Bearer {os.environ['POSTWIRE_API_KEY']}"},
)
print(r.status_code, r.json())
```
