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

# Webhook Events

> Every event Contiguity can send to your webhook endpoint, grouped by product. Use the on-page navigation to jump straight to an event.

> [!NOTE]
>
> This reference covers the **v2** webhook format (users registered after November 1st, 2024). For the full payload envelope and best practices, see [Overview](https://docs.contiguity.com/api-reference/webhook/overview.md) and [Example Webhook Data - v2](https://docs.contiguity.com/api-reference/webhook/example-v2.md). For the legacy v1 format, see [Example Webhook Data - v1](https://docs.contiguity.com/api-reference/webhook/example.md).

Use the `type` field on every webhook payload to determine which event occurred.

## Text

### `text.incoming.sms`

***

An incoming SMS message was received.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "text.incoming.sms",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "body": "Hello world",
    "timestamp": 1726502400
  }
}
```

### `text.incoming.mms`

***

An incoming MMS message with attachments was received.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "text.incoming.mms",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "body": "Check out this image!",
    "timestamp": 1726502400,
    "attachments": [
      {
        "url": "https://api.contiguity.com/attachments/15551234567/15559876543/image.jpg",
        "mime": "image/jpeg",
        "filename": "image.jpg"
      }
    ]
  }
}
```

### `text.delivery.confirmed`

***

SMS/MMS delivery was confirmed by the carrier.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "text.delivery.confirmed",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "message_id": "msg_abc123",
    "timestamp": 1726502400
  }
}
```

### `text.delivery.failed`

***

SMS/MMS delivery failed or timed out.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "text.delivery.failed",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "message_id": "msg_abc123",
    "timestamp": 1726502400,
    "error": "Carrier never provided delivery confirmation. Your message may have delivered, but Contiguity has no idea if it did."
  }
}
```

### `text.cancelled`

***

Fired when you cancel a queued SMS/MMS send ([`POST /conversations/cancel/{msg_id}`](https://docs.contiguity.com/api-reference/product/text/cancel)). Does not mean the message was unsent — an in-flight send may still go out.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "text.cancelled",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "message_id": "text_abc123",
    "timestamp": 1726502400
  }
}
```

## iMessage

### `imessage.incoming`

***

An incoming iMessage was received.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "imessage.incoming",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "body": "Hello from iMessage",
    "timestamp": 1726502400,
    "attachments": []
  }
}
```

### `imessage.cancelled`

***

Fired when you cancel a queued iMessage send ([`POST /conversations/cancel/{msg_id}`](https://docs.contiguity.com/api-reference/product/text/cancel)). Does not mean the message was unsent — an in-flight send may still go out.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "imessage.cancelled",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "from": "+15551234567",
    "to": "+15559876543",
    "message_id": "imessage_abc123",
    "timestamp": 1726502400
  }
}
```

## Email

### `email.incoming`

***

An incoming email was received.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "email.incoming",
  "timestamp": 1726502400,
  "api_version": "v2025.12.7",
  "data": {
    "email_id": "in_email_xxx",
    "from": { "name": "Sender", "address": "sender@example.com", "complete": "Sender <sender@example.com>" },
    "to": { "name": null, "address": "user@example.com", "complete": "<user@example.com>" },
    "cc": [],
    "bcc": [],
    "reply_to": null,
    "subject": "Hello",
    "body": {
      "text": "Hello world",
      "html": "<p>Hello world</p>",
      "raw": "raw MIME email"
    },
    "timestamp": 1726502400,
    "headers": {
      "return-path": [
        { "address": "sender@example.com", "name": "" }
      ]
    },
    "in_reply_to": "<msg_prior@example.com>",
    "references": ["<msg_prior@example.com>"],
    "attachments": [
      {
        "id": "att_abc",
        "filename": "file.png",
        "content_type": "image/png",
        "size": 12345,
        "url": "https://api.contiguity.com/attachments/email/in_email_xxx/file.png"
      }
    ]
  }
}
```

## FaceTime

### `facetime.call.initiated`

***

An outbound FaceTime Audio dial created the call. `data.status` is `queued`. Posted to your `facetime` webhook URL, else catchall. `data` is the same call object as [Get a call](https://docs.contiguity.com/api-reference/product/facetime/get.md).

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "facetime.call.initiated",
  "timestamp": 1758998599994,
  "api_version": "v2026.9.27",
  "data": {
    "call_id": "call_ftaAbCdEfGhIjKlMnOp",
    "ft_audio_line": "+15551234567",
    "to": "+15559876543",
    "from": "+15551234567",
    "caller_id": "+1 (555) 123-4567",
    "direction": "outbound",
    "status": "queued",
    "cause": null,
    "link": null,
    "webrtc": {
      "url": "wss://rtc.contiguity.cloud",
      "room": "contiguity:facetime:call_ftaAbCdEfGhIjKlMnOp",
      "token": "eyJhbGciOi...",
      "join": "https://facetime.contiguity.com/call?j=example"
    },
    "participants": [],
    "created_at": "2026-09-27T19:23:19.994Z",
    "answered_at": null,
    "ended_at": null,
    "duration": null
  }
}
```

### `facetime.call.ringing`

***

The outbound call is ringing, or an inbound call arrived. `data.status` is `ringing`. Same envelope and call object as initiated: `link` is still `null`, `participants` is `[]`, `webrtc` is present, `duration` is `null`.

### `facetime.call.answered`

***

The call is connected. `data.status` is `in_progress`. `link` is now the FaceTime join URL. `participants` is the remote party.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "facetime.call.answered",
  "timestamp": 1758998615578,
  "api_version": "v2026.9.27",
  "data": {
    "call_id": "call_ftaAbCdEfGhIjKlMnOp",
    "ft_audio_line": "+15551234567",
    "to": "+15559876543",
    "from": "+15551234567",
    "caller_id": "+1 (555) 123-4567",
    "direction": "outbound",
    "status": "in_progress",
    "cause": null,
    "link": "https://facetime.apple.com/join#v=1&p=example&k=example",
    "webrtc": {
      "url": "wss://rtc.contiguity.cloud",
      "room": "contiguity:facetime:call_ftaAbCdEfGhIjKlMnOp",
      "token": "eyJhbGciOi...",
      "join": "https://facetime.contiguity.com/call?j=example"
    },
    "participants": ["+15559876543"],
    "created_at": "2026-09-27T19:23:19.994Z",
    "answered_at": "2026-09-27T19:23:35.578Z",
    "ended_at": null,
    "duration": null
  }
}
```

### `facetime.call.rejected`

***

You rejected an inbound ringing call via [`POST /{call_id}/reject`](https://docs.contiguity.com/api-reference/product/facetime/reject). Same call object; `status` reflects the rejected call.

### `facetime.call.failed`

***

Contiguity could not place the call. `data.status` is `failed`.

### `facetime.call.ended`

***

The call ended: you hung up, the recipient hung up, or FaceTime disconnected. `data.status` is `completed`. `webrtc` is `null`. `duration` is seconds of connected time.

`participants` at hangup is the remaining roster, not everyone who was on the call. If the recipient already left, this is often just your FaceTime Audio line.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "facetime.call.ended",
  "timestamp": 1758998689511,
  "api_version": "v2026.9.27",
  "data": {
    "call_id": "call_ftaAbCdEfGhIjKlMnOp",
    "ft_audio_line": "+15551234567",
    "to": "+15559876543",
    "from": "+15551234567",
    "caller_id": "+1 (555) 123-4567",
    "direction": "outbound",
    "status": "completed",
    "cause": null,
    "link": "https://facetime.apple.com/join#v=1&p=example&k=example",
    "webrtc": null,
    "participants": ["+15551234567"],
    "created_at": "2026-09-27T19:23:19.994Z",
    "answered_at": "2026-09-27T19:23:35.578Z",
    "ended_at": "2026-09-27T19:24:49.511Z",
    "duration": 74
  }
}
```

| Event | `participants` |
| - | - |
| initiated / ringing | `[]` |
| answered | Remote party, e.g. `["+15559876543", "your_number"]` |
| ended | Remaining handles after hangup. If the recipient already left, this is often just your FaceTime Audio line. |

## OTP

### `otp.reverse.verified`

***

A user has verified their phone number using a Reverse OTP.

```json theme={null}
{
  "id": "evt_dgUIkRo18",
  "type": "otp.reverse.verified",
  "timestamp": 1726502400,
  "api_version": "v2026.8.20",
  "data": {
    "otp_id": "r_otp_123456",
    "number": "+15551234567",
    "to": "+16465550123",
    "service": "sms",
    "factor": "ABC123",
    "status": "verified",
    "expires_at": "2026-08-20T19:30:00.000Z",
    "verified_at": "2026-08-20T19:15:00.000Z"
  }
}
```

## Numbers

### `numbers.substitution`

***

When the requested number is unavailable, a random number is used instead.

```json theme={null}
{
  "id": "evt_d61aCHRo18",
  "type": "numbers.substitution",
  "timestamp": 1726502400,
  "api_version": "v2025.9.7",
  "data": {
    "original_number": "+15551111111",
    "used_number": "+15552222222",
    "reason": "requested_unavailable_random_used",
    "message_id": "msg_abc123",
    "timestamp": 1726502400
  }
}
```

![](https://fake.img.com/nonexistent.jpg)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.