---
title: "Subscribe to every received message"
method: POST
path: "/webhooks"
tags: ["Webhooks"]
---

# Subscribe to every received message

`POST /webhooks`

## Request

- Base URL: `https://api.automessage.app/v1`
- URL: `https://api.automessage.app/v1/webhooks`
- Auth: API key in header `X-API-KEY`

Registers a public HTTPS URL that receives a signed POST for EVERY
inbound iMessage / SMS on the account (a draft's `responseWebhook`
only covers that one thread). The response carries `data.secret`
(`whsec_…`) exactly once — store it. Re-subscribing the same `url`
rotates the secret and re-enables a disabled subscription (200);
a new URL is 201. At most 5 per account (409 `webhook_limit`).
Private, loopback and link-local targets are rejected (400), and
the target is re-checked at every delivery; redirects are never
followed. After 25 consecutive failed deliveries the subscription is
switched off (`disabled: true`) until it is re-subscribed.

Deliveries: `POST` JSON `{ event: "message.received", conversationId,
messageId, message: { body, from, sentDate, hasAttachments } }` with
`X-AutoMessage-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of
"<t>.<raw body>" keyed with the secret>`. Verify in constant time and
reject timestamps older than a few minutes.

## Request body

- object
  - `url` string, uri, required: Public HTTPS endpoint (max 2048 chars)
  - `events` string[]: Defaults to all supported events.

## Response `200`

Existing URL re-subscribed — secret rotated, subscription re-enabled.

- WebhookCreated
  - `data` object, required
    - `id` string, required
    - `url` string, uri, required
    - `events` string[], required
    - `createdAt` string, date-time, nullable, required
    - `lastDeliveryAt` string, date-time, nullable
    - `lastOutcome` 'delivered' | 'failed' | 'rejected', nullable: Outcome of the most recent delivery attempt.
    - `consecutiveFailures` integer, required: Reset to 0 by a successful delivery; 25 in a row switches the subscription off.
    - `disabled` boolean, required
    - `secret` string, required: whsec_… — shown only in this response.
  - `meta` object, required
    - `signature` string: How X-AutoMessage-Signature is computed.
    - `note` string

## Other responses

- `201`: Created. `data.secret` is shown only here.
- `400`: The request was malformed.
- `403`: Read-only key (`read_only_key`).
- `409`: Limit of 5 reached (`webhook_limit`). Delete one first.

---

[API](https://skmtc.dev/automessage/apis/automessage-rest-api.md) · [All operations](https://skmtc.dev/automessage/apis/automessage-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/automessage/apis/automessage-rest-api/revisions/129f369dee8b?raw)
