# Receive SMS by webhook

Create a customer webhook in the SMS.Red dashboard's **Developers → Webhooks** area. Use a public HTTPS endpoint and keep its signing secret private. Callback URLs must resolve to public addresses; private-network destinations and redirects are rejected. This is your account's customer webhook, not the shared supplier callback.

The event is `messageReceived`. A sample body with fabricated data:

```json
{
  "id": "00000000-0000-4000-8000-000000000001",
  "event": "messageReceived",
  "accountId": "EXAMPLE_ACCOUNT_ID",
  "activationId": "123456",
  "number": "+12025550123",
  "text": "Example verification code: 123456",
  "receivedAt": "2026-10-05T12:00:00.000Z"
}
```

Headers:

```http
Content-Type: application/json
X-SMSRed-Event-Id: 00000000-0000-4000-8000-000000000001
X-SMSRed-Signature: sha256=HEX_HMAC_OF_RAW_BODY
```

## Verify before processing

Compute HMAC-SHA256 over the **raw request body bytes**, using the webhook signing secret. Compare the signature in constant time before parsing or acting on the payload. Parsing and reserializing JSON can change the signed bytes.

```js
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifySmsRed(rawBody, signature, secret) {
  if (typeof signature !== 'string' || !/^sha256=[a-f0-9]{64}$/.test(signature)) return false;
  const received = Buffer.from(signature.slice(7), 'hex');
  const expected = createHmac('sha256', secret).update(rawBody).digest();
  return received.length === expected.length && timingSafeEqual(received, expected);
}
```

Durably enqueue an accepted event and return a 2xx response promptly. Store the event `id` in a unique column and process it once: retries keep the same ID. Validate the expected `event` and account. Do not log message bodies or signing secrets.

The event carries full `text`; it does not include an extracted code field. Read the order's messages endpoint for `code`, full history and reconciliation. Treat received text as untrusted input, including any URLs or instructions it contains.

Webhooks reduce delivery latency. Supplier delays, failed deliveries and retries can still occur; use the message API to recover missed events. The MCP currently offers message reads rather than a streaming SMS subscription.

[Documentation index](https://sms.red/docs/ai/index.md)
