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

# Send Message

> Sends a WhatsApp template message to one or more recipients via a configured WhatsApp Business Account (WABA). Only approved template messages are supported.

<Note>
  Refer to [Authentication](/authentication) for information on how to obtain a bearer token.

  This endpoint requires the `message.whatsapp.send` API client authorization scope to send WhatsApp messages.

  You can configure scopes on the [API Clients](https://cloud.belio.co.ke/team-overview/api-access-keys) page.
</Note>

## Request Modes

The API supports two request modes:

* `TemplateSendToMany` - Sends the same template message with shared parameters to multiple recipients.
* `TemplateSendToEach` - Sends personalized template messages to individual recipients. Parameters can differ per recipient.

***

### Template Parameters

Templates support dynamic parameters that are substituted into the template body, header, buttons, OTP, offers, carousel cards, media, and location components when messages are sent.

#### Parameter Types

| Parameter Type              | Required Field | Description                                                            |
| --------------------------- | -------------- | ---------------------------------------------------------------------- |
| `BodyNamedParameter`        | `name`         | Substitutes a body placeholder referenced by name (e.g. `{{name}}`)    |
| `BodyPositionalParameter`   | `position`     | Substitutes a body placeholder referenced by position (e.g. `{{1}}`)   |
| `HeaderNamedParameter`      | `name`         | Substitutes a header placeholder referenced by name (e.g. `{{name}}`)  |
| `HeaderPositionalParameter` | `position`     | Substitutes a header placeholder referenced by position (e.g. `{{1}}`) |

### Example

```json theme={null}
{
  "params": [
    {
      "type": "BodyNamedParameter",
      "name": "name",
      "value": "Alice"
    },
    {
      "type": "BodyPositionalParameter",
      "position": 1,
      "value": "Alice"
    },
    {
      "type": "HeaderNamedParameter",
      "name": "business",
      "value": "Belio Limited"
    },
    {
      "type": "HeaderPositionalParameter",
      "position": 1,
      "value": "Belio Limited"
    }
  ]
}
```


## OpenAPI

````yaml POST /message/{serviceId}/whatsapp
openapi: 3.1.0
info:
  title: Belio API
  description: OpenAPI Specification for Belio's REST API
  contact:
    name: Belio API Support
    url: https://belio.co.ke
  version: 1.0.0
servers:
  - url: https://api.belio.co.ke
    description: API Server
security:
  - bearerAuth: []
paths:
  /message/{serviceId}/whatsapp:
    post:
      tags:
        - Whatsapp
      description: >-
        Sends a WhatsApp template message to one or more recipients via a
        configured WhatsApp Business Account (WABA). Only approved template
        messages are supported.
      operationId: sendWhatsAppMessage
      parameters:
        - name: serviceId
          in: path
          required: true
          schema:
            type: string
          description: Unique identifier of the WhatsApp service
      requestBody:
        description: WhatsApp template message send request
        content:
          application/json:
            schema:
              oneOf:
                - title: TemplateSendToMany
                  type: object
                  properties:
                    type:
                      type: string
                      enum:
                        - TemplateSendToMany
                      description: Must be "TemplateSendToMany"
                    phoneNumberId:
                      type: string
                      description: >-
                        Phone number ID of the WABA sender. Must match a number
                        registered on the service
                    templateId:
                      type: string
                      description: ID of the approved WhatsApp template to send
                    addresses:
                      type: array
                      maxItems: 10
                      items:
                        type: string
                      description: Recipient phone numbers. Maximum 10 per request
                    params:
                      type: array
                      items:
                        $ref: '#/components/schemas/TemplateParameter'
                    receiptRequest:
                      type: object
                      description: >-
                        Delivery receipt callback configuration. When provided,
                        both fields are required.
                      properties:
                        correlator:
                          type: string
                          minLength: 1
                          maxLength: 100
                        callbackUrl:
                          type: string
                          format: uri
                      required:
                        - correlator
                        - callbackUrl
                      additionalProperties: false
                  required:
                    - type
                    - phoneNumberId
                    - templateId
                    - addresses
                    - params
                  additionalProperties: false
                - title: TemplateSendToEach
                  type: object
                  properties:
                    type:
                      type: string
                      enum:
                        - TemplateSendToEach
                      description: Must be "TemplateSendToEach"
                    phoneNumberId:
                      type: string
                      description: >-
                        Phone number ID of the WABA sender. Must match a number
                        registered on the service
                    templateId:
                      type: string
                      description: ID of the approved WhatsApp template to send
                    messages:
                      type: array
                      maxItems: 10
                      items:
                        type: object
                        properties:
                          phone:
                            type: string
                            description: Recipient phone number
                          params:
                            type: array
                            items:
                              $ref: '#/components/schemas/TemplateParameter'
                        required:
                          - phone
                          - params
                        additionalProperties: false
                      description: Per-recipient message objects. Maximum 10 per request
                    receiptRequest:
                      type: object
                      description: >-
                        Delivery receipt callback configuration. When provided,
                        both fields are required.
                      properties:
                        correlator:
                          type: string
                          minLength: 1
                          maxLength: 100
                        callbackUrl:
                          type: string
                          format: uri
                      required:
                        - correlator
                        - callbackUrl
                      additionalProperties: false
                  required:
                    - type
                    - phoneNumberId
                    - templateId
                    - messages
                  additionalProperties: false
        required: true
      responses:
        '200':
          description: Successful send request accepted and queued
          content:
            application/json:
              schema:
                type: object
                properties:
                  result:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - WhatsAppResponse
                      requestId:
                        type: string
                        format: uuid
                      addresses:
                        type: integer
                      units:
                        type: object
                        description: >-
                          Credit units consumed per Pricing Category. Currently
                          always {}.
                    required:
                      - type
                      - requestId
                      - addresses
                      - units
                    additionalProperties: false
                required:
                  - result
                additionalProperties: false
        '400':
          description: >-
            Bad request - invalid input parameters or template parameter
            validation failure
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/APIError'
                  - $ref: '#/components/schemas/TemplateParameterValidationFailure'
        '401':
          description: Unauthenticated - invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
        '404':
          description: Not Found - service, phone number ID, or template not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIError'
components:
  schemas:
    TemplateParameter:
      description: >-
        Tagged template parameter used to fill body, header, button, OTP, offer,
        carousel, media, or location placeholders.
      oneOf:
        - $ref: '#/components/schemas/NamedTemplateParameter'
        - $ref: '#/components/schemas/PositionalTemplateParameter'
        - $ref: '#/components/schemas/MediaTemplateParameter'
        - $ref: '#/components/schemas/LocationTemplateParameter'
        - $ref: '#/components/schemas/CopyParameter'
        - $ref: '#/components/schemas/TimeToLiveParameter'
        - $ref: '#/components/schemas/VoiceCallPayloadParameter'
        - $ref: '#/components/schemas/OtpParameter'
        - $ref: '#/components/schemas/UrlNamedParameter'
        - $ref: '#/components/schemas/UrlPositionalParameter'
        - $ref: '#/components/schemas/CouponCodeParameter'
        - $ref: '#/components/schemas/QuickReplyPayloadParameter'
        - $ref: '#/components/schemas/LimitedTimeOfferParameter'
        - $ref: '#/components/schemas/CarouselCardParameter'
      discriminator:
        propertyName: type
    APIError:
      type: object
      properties:
        desc:
          type: string
        result:
          description: Optional structured error details.
    TemplateParameterValidationFailure:
      type: object
      properties:
        desc:
          type: string
          const: Template parameter validation failed
        result:
          oneOf:
            - $ref: '#/components/schemas/TemplateSendToManyValidationResult'
            - $ref: '#/components/schemas/TemplateSendToEachValidationResult'
      required:
        - desc
        - result
      additionalProperties: false
    NamedTemplateParameter:
      type: object
      required:
        - type
        - name
        - value
      properties:
        type:
          type: string
          enum:
            - BodyNamedParameter
            - HeaderNamedParameter
        name:
          type: string
          minLength: 1
        value:
          type: string
          minLength: 1
          maxLength: 1024
      additionalProperties: false
    PositionalTemplateParameter:
      type: object
      required:
        - type
        - position
        - value
      properties:
        type:
          type: string
          enum:
            - BodyPositionalParameter
            - HeaderPositionalParameter
        position:
          type: integer
          minimum: 1
        value:
          type: string
          minLength: 1
          maxLength: 1024
      additionalProperties: false
    MediaTemplateParameter:
      type: object
      required:
        - type
        - url
      properties:
        type:
          type: string
          const: MediaTemplateParameter
        url:
          type: string
          format: uri
          minLength: 1
          description: Public media URL for an image, video, or document header.
        filename:
          type: string
          description: Optional filename for document media.
      additionalProperties: false
    LocationTemplateParameter:
      type: object
      required:
        - type
        - latitude
        - longitude
      properties:
        type:
          type: string
          const: LocationTemplateParameter
        latitude:
          type: number
          minimum: -90
          maximum: 90
        longitude:
          type: number
          minimum: -180
          maximum: 180
        name:
          type: string
        address:
          type: string
      additionalProperties: false
    CopyParameter:
      type: object
      required:
        - type
        - value
      properties:
        type:
          type: string
          const: CopyParameter
        value:
          type: string
          minLength: 1
      additionalProperties: false
    TimeToLiveParameter:
      type: object
      required:
        - type
        - minutes
      properties:
        type:
          type: string
          const: TimeToLiveParameter
        minutes:
          type: integer
          minimum: 1
          description: >-
            Time-to-live duration in minutes. The accepted range depends on the
            template configuration.
      additionalProperties: false
    VoiceCallPayloadParameter:
      type: object
      required:
        - type
        - payload
      properties:
        type:
          type: string
          const: VoiceCallPayloadParameter
        payload:
          type: string
          minLength: 1
      additionalProperties: false
    OtpParameter:
      type: object
      required:
        - type
        - code
      properties:
        type:
          type: string
          const: OtpParameter
        code:
          type: string
          minLength: 1
      additionalProperties: false
    UrlNamedParameter:
      type: object
      required:
        - type
        - name
        - value
      properties:
        type:
          type: string
          const: UrlNamedParameter
        name:
          type: string
          minLength: 1
        value:
          type: string
          minLength: 1
      additionalProperties: false
    UrlPositionalParameter:
      type: object
      required:
        - type
        - position
        - value
      properties:
        type:
          type: string
          const: UrlPositionalParameter
        position:
          type: integer
          minimum: 1
        value:
          type: string
          minLength: 1
      additionalProperties: false
    CouponCodeParameter:
      type: object
      required:
        - type
        - code
      properties:
        type:
          type: string
          const: CouponCodeParameter
        code:
          type: string
          minLength: 1
      additionalProperties: false
    QuickReplyPayloadParameter:
      type: object
      required:
        - type
        - payload
      properties:
        type:
          type: string
          const: QuickReplyPayloadParameter
        payload:
          type: string
          minLength: 1
      additionalProperties: false
    LimitedTimeOfferParameter:
      type: object
      required:
        - type
        - expiresAt
      properties:
        type:
          type: string
          const: LimitedTimeOfferParameter
        expiresAt:
          type: string
          format: date-time
          description: Offer expiry timestamp. Must be in the future.
      additionalProperties: false
    CarouselCardParameter:
      type: object
      required:
        - type
        - cardIndex
        - params
      properties:
        type:
          type: string
          const: CarouselCardParameter
        cardIndex:
          type: integer
          minimum: 0
        params:
          type: array
          items:
            $ref: '#/components/schemas/TemplateParameter'
      additionalProperties: false
    TemplateSendToManyValidationResult:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/TemplateValidationError'
      required:
        - errors
      additionalProperties: false
    TemplateSendToEachValidationResult:
      type: object
      description: >-
        Validation errors keyed by recipient phone number. Only recipients with
        failures are included.
      not:
        required:
          - errors
      additionalProperties:
        type: array
        items:
          $ref: '#/components/schemas/TemplateValidationError'
    TemplateValidationError:
      oneOf:
        - $ref: '#/components/schemas/TemplateParameterError'
        - $ref: '#/components/schemas/TemplateComponentError'
      discriminator:
        propertyName: type
    TemplateParameterError:
      type: object
      properties:
        type:
          type: string
          const: ParameterError
        parameterType:
          type: string
        error:
          type: string
      required:
        - type
        - parameterType
        - error
      additionalProperties: false
    TemplateComponentError:
      type: object
      properties:
        type:
          type: string
          const: ComponentError
        componentType:
          type: string
        error:
          type: string
      required:
        - type
        - componentType
        - error
      additionalProperties: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````