> ## Documentation Index
> Fetch the complete documentation index at: https://onextel-09023014.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Send a message

> Send one Truecaller message now: free text, an approved template, or either with an image, file and buttons.

Use this for one-off messages such as OTP follow-ups, order updates or a test of a template. For
many people at once, use a [campaign](https://onextel-09023014.mintlify.site/api-reference/truecaller/create-campaign.md) instead: it
applies opt-outs and promotional limits for you.

Give **either** `body` **or** `template_id`:

* **`template_id`** sends an approved template. Its media and buttons come with it. Fill its
  `{{variables}}` with `variables`; any you leave empty use the template's defaults.
* **`body`** sends free text. Add `media` and up to 3 `buttons` if you need them.

A `202` means Truecaller accepted the message (`status: "sent"`). Delivery and read come later:
subscribe to [webhooks](https://onextel-09023014.mintlify.site/api-reference/truecaller/webhooks.md) or [get the message](https://onextel-09023014.mintlify.site/api-reference/truecaller/get-message.md).

> [!NOTE]
>
> If the number is not on Truecaller, the send fails with `Truecaller NOT_FOUND`. That is the most
> common failure and is not worth retrying.


## OpenAPI

````yaml api-reference/truecaller/openapi.yaml POST /v1/messages
openapi: 3.1.0
info:
  title: OneXtel Truecaller Business Messaging API
  version: 1.0.0
  description: >
    Send verified business messages to Truecaller users: single messages,
    templates with

    personalisation, images, files and buttons, and campaigns to contact lists.


    Every request carries a workspace API key in the `x-api-key` header. Create
    one in the

    Truecaller campaigns portal under **Developers → API keys**.


    Errors are JSON with a single `error` string (and `details` for validation
    errors):


    ```json

    { "error": "invalid phone number" }

    ```
servers:
  - url: https://truecaller.udchowdhury.me
    description: Production
security:
  - apiKey: []
tags:
  - name: Messages
    description: Send one message and read its status.
  - name: Templates
    description: Reusable messages with variables, media and buttons.
  - name: Media
    description: Upload files to attach to templates.
  - name: Contact lists
    description: Audiences for campaigns.
  - name: Campaigns
    description: Send a template to a whole contact list, now or later.
  - name: Senders
    description: The verified business profiles your workspace sends from.
paths:
  /v1/messages:
    post:
      tags:
        - Messages
      summary: Send a message
      description: >
        Sends one message now. Give either `body` (free text, optionally with
        `media` and

        `buttons`) or `template_id` with its `variables`. A template brings its
        own media and

        buttons. Returns `202` once Truecaller has accepted the message;
        delivery and read

        arrive later through webhooks.
      operationId: sendMessage
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessageRequest'
            examples:
              template:
                summary: Approved template with variables
                value:
                  to: '919999999999'
                  template_id: 7f3c2a9e-1b2d-4c5e-8f90-123456789abc
                  variables:
                    name: Asha
                    order_id: OX1002
              text:
                summary: Free text
                value:
                  to: '919999999999'
                  body: Hi Asha, your order *OX1002* has shipped.
                  category: transactional
              rich:
                summary: Free text with an image and buttons
                value:
                  to: '919999999999'
                  body: Your festive offer is here.
                  category: promotional
                  media:
                    url: https://example.com/offer.jpg
                    mime_type: image/jpeg
                  buttons:
                    - type: link
                      text: Shop now
                      url: https://example.com/sale
                    - type: reply
                      text: Not interested
      responses:
        '202':
          description: Accepted by Truecaller.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  schemas:
    SendMessageRequest:
      type: object
      required:
        - to
      properties:
        to:
          type: string
          description: >-
            Recipient number with country code (+919999999999 or 919999999999).
            Bare 10-digit numbers are treated as Indian.
          example: '919999999999'
        sender_id:
          type: string
          description: >-
            One of the workspace's active senders. Defaults to the first active
            sender.
        body:
          type: string
          maxLength: 1000
          description: >-
            Free text. Supports *bold*, _italic_, ~strikethrough~, `monospace`
            and [label](https://…) links. Give this or template_id.
        category:
          type: string
          enum:
            - promotional
            - transactional
            - service
          default: transactional
          description: For free-text sends. A template uses its own category.
        template_id:
          type: string
          format: uuid
          description: An approved template. Give this or body.
        variables:
          type: object
          additionalProperties:
            type: string
          description: >-
            Values for the template's variables. Empty ones fall back to the
            template's defaults.
        media:
          $ref: '#/components/schemas/Media'
        buttons:
          type: array
          maxItems: 3
          items:
            $ref: '#/components/schemas/Button'
    Message:
      type: object
      properties:
        id:
          type: string
          format: uuid
        to:
          type: string
          example: '+919999999999'
        sender_id:
          type: string
        category:
          type: string
          enum:
            - promotional
            - transactional
            - service
        template_id:
          type:
            - string
            - 'null'
          format: uuid
        campaign_id:
          type:
            - string
            - 'null'
          format: uuid
        body:
          type: string
        extras:
          type:
            - object
            - 'null'
          description: Media and buttons sent with the message.
        status:
          $ref: '#/components/schemas/MessageStatus'
        error:
          type:
            - string
            - 'null'
          example: null
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        events:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
              created_at:
                type: string
                format: date-time
    Media:
      type: object
      required:
        - url
        - mime_type
      description: >-
        One attachment. Upload with [Upload
        media](/api-reference/truecaller/upload-media), or give any public https
        URL.
      properties:
        url:
          type: string
          description: Public https URL Truecaller downloads the file from at send time.
        mime_type:
          type: string
          enum:
            - image/jpeg
            - image/png
            - image/gif
            - video/mp4
            - video/quicktime
            - application/pdf
            - text/plain
        file_name:
          type: string
          maxLength: 100
          description: Shown to the recipient for PDFs and text files.
    Button:
      description: Up to 3 per message. Labels and URLs can use `{{variables}}`.
      oneOf:
        - type: object
          title: Link button
          required:
            - type
            - text
            - url
          properties:
            type:
              type: string
              const: link
            text:
              type: string
              maxLength: 40
              example: Track order
            url:
              type: string
              maxLength: 1000
              description: An https URL or an app deep link. Plain http is rejected.
              example: https://example.com/t/{{order_id}}
        - type: object
          title: Quick reply
          required:
            - type
            - text
          properties:
            type:
              type: string
              const: reply
            text:
              type: string
              maxLength: 100
              description: Sent back as the person's reply when tapped.
              example: Call me back
    MessageStatus:
      type: string
      enum:
        - queued
        - sent
        - delivered
        - read
        - failed
        - blocked
      description: >-
        `sent` means Truecaller accepted it, `blocked` means a limit or opt-out
        skipped it.
    Error:
      type: object
      properties:
        error:
          type: string
        details:
          type: array
          items:
            type: object
  responses:
    BadRequest:
      description: >-
        The request is invalid. `details` lists each problem for validation
        errors.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid body
            details:
              - path:
                  - to
                message: Required
    Unauthorized:
      description: Missing or invalid `x-api-key`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid x-api-key
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Workspace API key from **Developers → API keys**. It starts with
        `tc_live_`.

````

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