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

# Send a message

> Send transactional and marketing messages to your users with one simple endpoint, using Prelude Notify API.

<RequestExample>
  ```javascript Node.js theme={null}
  import Prelude from "@prelude.so/sdk";

  const client = new Prelude();

  async function main() {
    const response = await client.notify.send({
      template_id: "template_01k8ap1btqf5r9fq2c8ax5fhc9",
      to: "+30123456789",
      variables: { foo: "bar" },
    });

    console.log(response.id);
  }

  main();
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"fmt"

  	"github.com/prelude-so/go-sdk"
  	"github.com/prelude-so/go-sdk/option"
  )

  func main() {
  	client := prelude.NewClient()

  	response, err := client.Notify.Send(context.TODO(), prelude.NotifySendParams{
  		TemplateID: prelude.F("template_01k8ap1btqf5r9fq2c8ax5fhc9"),
  		To: prelude.F("+30123456789"),
  		Variables: prelude.F(map[string]string{
  			"foo": "bar",
  		}),
  	})
  	if err != nil {
  		panic(err.Error())
  	}

  	fmt.Printf("%+v\n", response.ID)
  }
  ```

  ```python Python theme={null}
  import os
  from prelude_python_sdk import Prelude

  client = Prelude()

  response = client.notify.send(
      template_id="template_01k8ap1btqf5r9fq2c8ax5fhc9",
      to="+30123456789",
      variables={
          "foo": "bar"
      },
  )

  print(response.id)
  ```
</RequestExample>

<Note>
  The `variables` object must contain **exactly** the variables defined in your template — no more, no less. Sending variables that don't belong to the template (for example, a `senderName` variable when the template only expects `smsShortLink`) will return an `invalid_template_variables` error. This strictness helps catch typos in variable names and prevents sending messages with unintended placeholders.
</Note>

## Common Use Cases

<AccordionGroup>
  <Accordion title="Send an immediate transactional message">
    ```javascript theme={null}
    const response = await client.notify.send({
      template_id: "template_01k8ap1btqf5r9fq2c8ax5fhc9",
      to: "+33612345678",
      variables: { 
        order_id: "12345",
        amount: "$49.99" 
      },
      callback_url: "https://your-app.com/webhooks/notify"
    });
    ```
  </Accordion>

  <Accordion title="Schedule a marketing campaign">
    ```javascript theme={null}
    const response = await client.notify.send({
      template_id: "template_01k8ap1btqf5r9fq2c8ax5fhc9",
      to: "+15551234567",
      schedule_at: "2025-12-25T10:00:00Z",
      variables: { 
        promotion: "Holiday Sale",
        discount: "20%" 
      }
    });

    // Check when it will actually be sent (may be adjusted for compliance)
    console.log(response.schedule_at); // "2025-12-25T08:00:00-05:00"
    ```
  </Accordion>

  <Accordion title="Send with custom sender ID">
    ```javascript theme={null}
    const response = await client.notify.send({
      template_id: "template_01k8ap1btqf5r9fq2c8ax5fhc9",
      to: "+4412345678",
      from: "YourBrand",
      variables: { name: "John" }
    });
    ```
  </Accordion>

  <Accordion title="Send via specific channel">
    ```javascript theme={null}
    const response = await client.notify.send({
      template_id: "template_01k8ap1btqf5r9fq2c8ax5fhc9",
      to: "+33612345678",
      preferred_channel: "whatsapp", // or "sms", "rcs"
      variables: { message: "Hello!" }
    });
    ```
  </Accordion>
</AccordionGroup>

## Error Handling

The Notify API returns specific error codes for different scenarios:

| Error Code                           | Description                                                                                       | Action                                                                          |
| ------------------------------------ | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| `category_forbidden`                 | Message category forbidden in country                                                             | Use a different template                                                        |
| `insufficient_balance`               | Account balance is too low                                                                        | Top up your account                                                             |
| `invalid_phone_number`               | Phone number format is invalid                                                                    | Validate phone number format                                                    |
| `invalid_template_id`                | Template ID is invalid or too long                                                                | Check the ID length and format                                                  |
| `invalid_template_variables`         | Template variables are invalid, missing, or include unknown variables not defined in the template | Provide a JSON object containing exactly the variables required by the template |
| `template_not_found`                 | Template ID doesn't exist                                                                         | Check template ID with your CSM                                                 |
| `template_not_registered_in_country` | Template is not registered for the target country                                                 | Register the template for this country or use a different template              |
| `template_not_validated`             | Marketing template not approved                                                                   | Contact your CSM                                                                |
| `unsubscribed`                       | Recipient has opted out of marketing messages                                                     | Update your records and don't retry                                             |

For a complete list of errors, see the [Error documentation](/introduction/errors).

## Related Documentation

* [WhatsApp 2-Way Messaging](/notify/v2/documentation/whatsapp) - Receive inbound messages and send replies
* [Webhooks](/notify/v2/documentation/webhook) - Receive delivery updates, inbound messages, and subscription events
* [Marketing Compliance](/notify/v2/documentation/marketing-compliance) - Understand compliance rules by country
* [Subscription Management](/notify/v2/documentation/subscription-management) - Handle opt-out/opt-in flows
* [Scheduling](/notify/v2/documentation/scheduling) - Advanced scheduling and timezone handling


## OpenAPI

````yaml post /v2/notify
openapi: 3.1.0
info:
  title: Prelude API
  version: 2.0.0
  description: The Prelude API allows you to send messages to your users.
  contact:
    email: support@prelude.so
servers:
  - url: https://api.prelude.dev
    description: Production server
security:
  - apiToken: []
tags:
  - name: Notify
    description: Send transactional and marketing messages with compliance enforcement.
  - name: Transactional
    description: Send transactional messages (deprecated - use Notify API instead).
  - name: Verify
    description: Verify phone numbers.
  - name: Watch
    description: Evaluate email addresses and phone numbers for trustworthiness.
  - name: Lookup
    description: >-
      Retrieve detailed information about a phone number including carrier data,
      line type, and portability status.
paths:
  /v2/notify:
    post:
      tags:
        - Notify
      summary: Send a message
      description: >-
        Send transactional and marketing messages to your users via SMS, RCS and
        WhatsApp with automatic compliance enforcement.
      operationId: sendNotify
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendNotifyRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendNotifyResponse'
        '400':
          description: KO
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      callbacks:
        webhook_event:
          '{$request.body#/callback_url}':
            post:
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/WebhookEvent'
              responses:
                '200':
                  description: Your server accepted the event and will process it.
                default:
                  description: >-
                    Your server did not accept the event and we will retry for
                    24 hours.
components:
  schemas:
    SendNotifyRequest:
      type: object
      properties:
        from:
          type: string
          description: The Sender ID. Must be approved for your account.
        to:
          type: string
          description: The recipient's phone number in E.164 format.
          examples:
            - '+33612345678'
        template_id:
          type: string
          description: The template identifier configured by your Customer Success team.
          examples:
            - template_01k8ap1btqf5r9fq2c8ax5fhc9
        locale:
          type: string
          description: >-
            A BCP-47 formatted locale string with the language the text message
            will be sent to. If there's no locale set, the language will be
            determined by the country code of the phone number. If the language
            specified doesn't exist, the default set on the template will be
            used.
          examples:
            - el-GR
            - fr-FR
        variables:
          type: object
          description: The variables to be replaced in the template.
          additionalProperties:
            type: string
          examples:
            - order_id: '12345'
              amount: $49.99
        expires_at:
          type: string
          format: date-time
          description: >-
            The message expiration date in RFC3339 format. The message will not
            be sent if this time is reached.
          examples:
            - '2025-12-25T18:00:00Z'
        schedule_at:
          type: string
          format: date-time
          description: >-
            Schedule the message for future delivery in RFC3339 format.
            Marketing messages can be scheduled up to 90 days in advance and
            will be automatically adjusted for compliance with local time window
            restrictions.
          examples:
            - '2025-12-25T10:00:00Z'
        callback_url:
          type: string
          description: The URL where webhooks will be sent for message delivery events.
          examples:
            - https://your-app.com/webhooks/notify
        correlation_id:
          type: string
          description: >-
            A user-defined identifier to correlate this message with your
            internal systems. It is returned in the response and any webhook
            events that refer to this message.
          maxLength: 80
          examples:
            - order-12345
        preferred_channel:
          type: string
          description: >-
            The preferred channel to be used in priority for message delivery.
            If the channel is unavailable, the system will fallback to other
            available channels.
          enum:
            - sms
            - rcs
            - whatsapp
          examples:
            - whatsapp
        document:
          type: object
          description: >
            A media attachment to include in the message header. Supported on

            WhatsApp templates registered with a `DOCUMENT`, `IMAGE`, or

            `VIDEO` header. The media type is determined by the template's

            registered header format; send the matching file type for each.


            - `DOCUMENT` headers accept PDF and other document formats;
            `filename` is required and displayed to the recipient.

            - `IMAGE` headers accept `.png`, `.jpg`, `.jpeg`, and `.webp` URLs;
            `filename` is ignored.

            - `VIDEO` headers accept `.mp4` and `.3gp` URLs; `filename` is
            ignored.
          properties:
            url:
              type: string
              description: >-
                HTTPS URL of the media file. The file extension must match the
                template's registered header format (PDF for DOCUMENT;
                PNG/JPG/JPEG/WEBP for IMAGE; MP4/3GP for VIDEO).
              examples:
                - https://example.com/invoice.pdf
                - https://example.com/promo.png
                - https://example.com/demo.mp4
            filename:
              type: string
              description: >-
                Filename displayed to the recipient. Required for templates with
                a `DOCUMENT` header; ignored for `IMAGE` and `VIDEO` headers.
              examples:
                - invoice.pdf
          required:
            - url
      required:
        - to
        - template_id
    SendNotifyResponse:
      type: object
      properties:
        id:
          type: string
          description: The message identifier.
          examples:
            - tx_01k8ap1btqf5r9fq2c8ax5fhc9
        from:
          type: string
          description: The Sender ID used for this message.
          examples:
            - YourBrand
        to:
          type: string
          description: The recipient's phone number in E.164 format.
          examples:
            - '+33612345678'
        template_id:
          type: string
          description: The template identifier.
          examples:
            - template_01k8ap1btqf5r9fq2c8ax5fhc9
        variables:
          type: object
          description: The variables to be replaced in the template.
          additionalProperties:
            type: string
          examples:
            - order_id: '12345'
              amount: $49.99
        callback_url:
          type: string
          description: The callback URL where webhooks will be sent.
          examples:
            - https://your-app.com/webhooks/notify
        correlation_id:
          type: string
          description: >-
            A user-defined identifier to correlate this message with your
            internal systems.
          maxLength: 80
          examples:
            - order-12345
        expires_at:
          type: string
          description: The message expiration date in RFC3339 format.
          format: date-time
          examples:
            - '2025-12-25T18:00:00Z'
        schedule_at:
          type: string
          format: date-time
          description: >-
            When the message will actually be sent in RFC3339 format with
            timezone offset. For marketing messages, this may differ from the
            requested schedule_at due to automatic compliance adjustments.
          examples:
            - '2025-12-25T08:00:00-05:00'
        created_at:
          type: string
          format: date-time
          description: The message creation date in RFC3339 format.
          examples:
            - '2025-10-24T12:00:00Z'
        estimated_segment_count:
          type: integer
          description: >-
            The estimated number of SMS segments for this message. This value is
            not contractual; the actual segment count will be determined after
            the SMS is sent by the provider. Only present for SMS messages.
          examples:
            - 1
        encoding:
          type: string
          enum:
            - GSM-7
            - UCS-2
          description: >-
            The SMS encoding type based on message content. GSM-7 supports
            standard characters (up to 160 chars per segment), while UCS-2
            supports Unicode including emoji (up to 70 chars per segment). Only
            present for SMS messages.
          examples:
            - GSM-7
      required:
        - id
        - to
        - template_id
        - variables
        - expires_at
        - created_at
    Error:
      type: object
      properties:
        code:
          type: string
          description: The error code.
          examples:
            - invalid_phone_number
        message:
          type: string
          examples:
            - >-
              The provided phone number is invalid. Provide a valid E.164 phone
              number.
          description: A human-readable message describing the error.
        type:
          type: string
          examples:
            - bad_request
          description: The error type.
        request_id:
          type: string
          examples:
            - 3d19215e-2991-4a05-a41a-527314e6ff6a
          description: >-
            A string that identifies this specific request. Report it back to us
            to help us diagnose your issues.
      required:
        - code
        - message
        - type
  securitySchemes:
    apiToken:
      type: http
      scheme: bearer

````