---
title: "template_send"
method: POST
path: "/template_send"
tags: ["Send"]
---

# template_send

`POST /template_send`

## Request

- Base URL: `https://api.commpeak.com/textpeak/streams`
- URL: `https://api.commpeak.com/textpeak/streams/template_send`
- Auth: API key in header `Authorization`

Send a templated message to one or more recipients. Provide the template once — inline in `message_template` with `[placeholder]` tokens, or as a saved template by its `event` key — then supply each recipient's values in `template_variables`.

- Set a default `sender` and `event` at the top level; override either per recipient.
- Up to 250 recipients per request.
- An unknown `event`, or neither `event` nor `message_template`, fails the whole request.

**Response.** HTTP `200` with a `task_id` and one entry per message. `status` is `false` when any message failed: failed entries come first and carry `error` (hex code) and `details`; accepted entries carry `message_uuid` (and `conversation_uuid` on two-way channels). Match entries by `internal_id`. Final delivery status is sent asynchronously to your configured webhook.

**Authentication:** stream token in the `Authorization` header (see **Authentication** in the API Overview).

## Request body

- TemplateSendRequest
  - `sender` string, nullable: Default sender for every recipient. An alphanumeric sender ID or a phone number registered on the stream. Omit it to use the stream's default sender.
  - `event` string, nullable: Default template: an `eventKey` from **Stream event templates**. An unknown key fails the whole request.
  - `message_template` string, nullable: Inline template text instead of `event`, with `[name]` or `{name}` placeholders. Used only when `event` is not set.
  - `recipients` TemplateRecipient[], required: The recipients, up to 250 per request.
    - `internal_id` string, nullable: Your identifier for the message. Echoed back in the response and in delivery webhooks (`internal_id`). Up to 36 characters are kept; longer values are cut. Not checked for uniqueness.
    - `sender` string, nullable: Sender for this recipient; overrides the top-level `sender`.
    - `event` string, nullable: Template for this recipient: an `eventKey` from **Stream event templates**. Overrides the top-level `event` / `message_template`.
    - `recipient_phone` string, nullable: Recipient phone number in international format, as a string. `+`, spaces, `-` and parentheses are removed before validation. Not needed when `conversation_uuid` or `contact.phone` identifies the recipient.
    - `template_variables` object, nullable: Values for the template placeholders, `{ "name": "value" }`. A placeholder with no value is sent empty; leaving `template_variables` out entirely sends the placeholders as written.
    - `contact` Contact
      - `display_name` string, nullable: Name shown in the inbox. Defaults to `first_name` + `last_name`.
      - `first_name` string, nullable: First name.
      - `last_name` string, nullable: Last name.
      - `phone` string, nullable: Phone number; used as the recipient when `recipient_phone` is not set.
      - `email` string, nullable: E-mail address.
      - `external_id` string, nullable: Your CRM identifier for the contact; stored as the conversation lead ID.
      - `additional` object, nullable: Extra contact attributes. `additional.lead_id` takes precedence over `external_id`.
    - `conversation_uuid` string, nullable: Continue an existing conversation: the sender and recipient are taken from it. Two-way channels only (WhatsApp, Telegram, two-way SMS); ignored on one-way SMS.
    - `conversation_info` object, nullable: Metadata stored on new conversations (inbox).
  - `conversation_info` object, nullable: Metadata stored on new conversations (inbox).
  - `senders_pool` string[], nullable: Candidate senders, used only when no sender is set on the message, the request or the stream: a sender allowed for the destination is picked at random. When none is allowed, the whole request fails with `0x61`.
  - `schedule_to` string, nullable: Send at this time instead of now (ISO 8601 date-time).

## Response `200`

Successful Response

- SendResponse
  - `status` boolean, required: `true` when every message was accepted; `false` when at least one failed. The HTTP status is `200` either way.
  - `task_id` string, required: Identifier of this request.
  - `messages` SendResultItem[], required: One entry per message. Failed messages are listed first, then accepted ones; match them by `internal_id`.
    - `internal_id` string, nullable: Your `internal_id`, echoed back (cut to 36 characters).
    - `message_uuid` string, nullable: Platform message identifier. Accepted messages only; use it with **Get message status**.
    - `conversation_uuid` string, nullable: The conversation the message belongs to. Two-way channels only.
    - `error` string, nullable: Failed messages only: the hex error code, for example `0x1` (invalid input), `0x19` (duplicate) or `0x31` (daily limit).
    - `details` string, nullable: Failed messages only: why it failed.

## Other responses

- `401`: Invalid token, or the token is not valid from this IP address.
- `402`: Payment required: the account balance is depleted (`0x41`).
- `403`: Missing token, blocked IP address, or the stream is not available (`0x11`, `0x16`, `0x21`, `0x22`).
- `422`: Validation Error
- `500`: The request was rejected as a whole (`0x0`): for example an unknown template or more than 250 items.

---

[API](https://skmtc.dev/commpeak/apis/commpeak-textpeak-streams-api.md) - [All operations](https://skmtc.dev/commpeak/apis/commpeak-textpeak-streams-api/llms.txt) - [OpenAPI document](https://skmtc.dev/commpeak/apis/commpeak-textpeak-streams-api/revisions/b9aaa8b4efa2?raw)
