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

# Webhooks

> Receive a real-time payload for every recipient after an SMS send is processed.

<Info>
  Webhooks apply to the **V2 OAuth API** only. They are separate from [Delivery Receipts (DLRs)](/guides/delivery-receipts) and [Inbound Messages](/guides/inbound-messages).
</Info>

When you send an SMS via the V2 API, Vodafone Bulk Text sends an HTTP POST to your webhook URL for **each recipient** in the request. If you send to 5 numbers in one API call, you receive 5 webhook payloads — one per mobile number.

This gives you an immediate, per-recipient status report on how the message was processed — including any errors.

## Setup

Provide your webhook URL to [bulktext.ie@vodafone.com](mailto:bulktext.ie@vodafone.com) and we will configure it against your account. The endpoint must:

* Accept `HTTP POST` requests
* Respond with a `200 OK`

## Payload

Each payload is a JSON object sent in the POST body.

<CodeGroup>
  ```json title="Success payload" icon="circle-check" highlight={2,5} wrap theme={"system"}
  {
    "Status": "MESSAGE_SUCCESS",
    "FinishedAt": "2026-04-09T14:39:40.69257Z",
    "Message": "Your message has been queued.",
    "NotifyId": "order-001"
  }
  ```

  ```json title="Message error payload" icon="circle-xmark" highlight={2,5} wrap theme={"system"}
  {
    "Status": "MESSAGE_ERROR",
    "FinishedAt": "2025-06-06T17:50:57.675187Z",
    "Message": "Error trying to add a new message. No credits available",
    "NotifyId": "order-001"
  }
  ```

  ```json title="Campaign error payload" icon="triangle-exclamation" highlight={2,4} wrap theme={"system"}
  {
    "Status": "CAMPAIGN_ERROR",
    "FinishedAt": "2025-06-06T17:55:48.6689654Z",
    "Message": "Sender is not valid"
  }
  ```
</CodeGroup>

### Fields

| Field        | Type   | Description                                                                          |
| ------------ | ------ | ------------------------------------------------------------------------------------ |
| `Status`     | string | Processing outcome — see [Status values](#status-values) below                       |
| `FinishedAt` | string | ISO 8601 timestamp (UTC) of when processing completed                                |
| `Message`    | string | Human-readable description of the outcome                                            |
| `NotifyId`   | string | The `notifyId` you assigned to this recipient when sending — empty string if not set |

## Status values

| Status            | Scope         | Meaning                                                                                 |
| ----------------- | ------------- | --------------------------------------------------------------------------------------- |
| `MESSAGE_SUCCESS` | Per recipient | Message accepted and queued for delivery                                                |
| `MESSAGE_ERROR`   | Per recipient | Message could not be processed for this recipient                                       |
| `CAMPAIGN_ERROR`  | Per recipient | The send was rejected before any messages were queued — one payload fires per recipient |

`CAMPAIGN_ERROR` payloads do not include a `NotifyId` field. The error is campaign-level (e.g. an invalid sender ID), but a payload is still sent for each recipient in the request.

### Common `Message` values

| Message                                                    | Status            | What it means                                                |
| ---------------------------------------------------------- | ----------------- | ------------------------------------------------------------ |
| `Your message has been queued.`                            | `MESSAGE_SUCCESS` | Recipient accepted, message in queue                         |
| `Sender is not valid`                                      | `CAMPAIGN_ERROR`  | The `from` value is not a valid or approved sender ID        |
| `Error trying to add a new message. No credits available`  | `MESSAGE_ERROR`   | Account has insufficient SMS credits                         |
| `null/empty MSISDN`                                        | `MESSAGE_ERROR`   | The recipient number was blank or missing                    |
| `Error trying to add a new message to SMSBroadcastMessage` | `MESSAGE_ERROR`   | Internal processing error — contact support if this persists |

## One payload per recipient

Webhooks fire once for each recipient mobile number in the send request, not once per API call.

| Recipients in request | Webhook payloads received |
| --------------------- | ------------------------- |
| 1                     | 1                         |
| 5                     | 5                         |
| 100                   | 100                       |

## Tracking recipients with notifyId

Set a `notifyId` per recipient when sending and it will be echoed back in the `NotifyId` field of every webhook payload for that recipient. The same value also appears in DLRs and can be used to correlate inbound replies — making it the single identifier that spans your entire send-to-reply flow.

If no `notifyId` is set, the `NotifyId` field will be an empty string.

See [notifyId](/guides/notify-id) for full details, use cases, and end-to-end flow examples.

## Relation to DLRs

Webhooks and DLRs serve different purposes:

```mermaid title="Webhook and DLR timing" theme={"system"}
sequenceDiagram
  participant App as Developer app
  participant API as Vodafone Bulk Text API
  participant Gateway as Vodafone Bulk Text gateway
  participant Network as Mobile network
  participant Endpoint as Your endpoint

  App->>API: Send campaign
  API->>Gateway: Process recipient
  Gateway->>Endpoint: Webhook after processing
  Gateway->>Network: Submit SMS
  Network-->>Gateway: Delivery result
  Gateway->>Endpoint: DLR after network confirmation
```

|             | Webhook                                                      | DLR                              |
| ----------- | ------------------------------------------------------------ | -------------------------------- |
| **Trigger** | API message processing complete                              | Network delivery confirmed       |
| **Timing**  | Immediate, after the API call                                | Minutes to hours after sending   |
| **Scope**   | V2 OAuth API only                                            | All send methods                 |
| **Purpose** | Confirms message was accepted/rejected by Vodafone Bulk Text | Confirms delivery to the handset |

Use webhooks to confirm your API call was processed correctly. Use DLRs to confirm the message reached the recipient's device.
