For the complete documentation index, see llms.txt. This page is also available as Markdown.

RCS Send Template API

Base URL: https://app.quickreply.ai

Send an approved RCS template to a recipient. The request carries only the dynamic values for the template — the structure (which components exist, their {{n}} placeholders and paramLength) lives on the stored template and is resolved by templateId. POST https://app.quickreply.ai/api/v4/external/template-message/rcs/send


Authentication

External secret-key flow, via headers:

Header
Value
Description

x-client-id

Company id

Click the profile/account name in the bottom-left corner of the QuickReply dashboard. In the menu that opens, the Company ID is displayed directly below the company name.

x-secret-key

Company secret key

You can find client-id of your account in Settings > Developers > API credentials

Content-Type

application/json


Request body

Field
Type
Description

to*

string

Recipient phone number in E.164 format, e.g. +919800000000.

templateId*

string

You can find the template id by clicking on the 3 dots at the right of template block and clicking "Copy Template Id" The stored RCS template's _id. Must be an APPROVED template.

templateParams (Optional)

object

Dynamic values for the template. Send only the fields the template needs (see below).

customEngage (Optional)

object

Follow-up trigger fired on custom engagement.

buttonEngage (Optional)

object

Follow-up trigger fired on button click.

templateParams

Send only what the matched template requires. All fields are optional at the schema level; the template's structure determines what is actually needed.

Field
Shape
Notes

headerParam

{ type, value, filename?, size? }

typeIMAGE / VIDEO / DOCUMENT. value must be a valid URL (the media link). Required for media and carousel-card headers. filename applies to DOCUMENT (defaults to document.pdf).

bodyParams

[{ value }]

Count must equal the body's paramLength, in {{1}},{{2}},… order.

titleParams

[{ value }]

Count must equal the title's paramLength.

buttonParams

[{ value, index, key? }]

index = button position in the template. key is used for VIEW_LOCATION (lat / long) and CALENDAR (eventTitle / eventDescription / startDateTime / endDateTime).

suggestionParams

[{ value, index, key? }]

Same shape as buttonParams, for suggestion chips.

carouselParams

[{ cardIndex, headerParam, bodyParams?, titleParams?, buttonParams? }]

One entry per card; each card's headerParam is required.

Media is mandatory for interactive templates. Any template that defines buttons or suggestions must also carry a media header (IMAGE / VIDEO / DOCUMENT). Every send for such a template must include a headerParam with a valid media URL — this holds even for static buttons (QUICK_REPLY / SHARE_LOCATION) that otherwise take no value.

Params that need nothing sent (but still require the media header above):

  • Static text templates with no buttons/suggestions (paramLength: 0) — omit bodyParams or send []; no header needed.

  • QUICK_REPLY / SHARE_LOCATION buttons and suggestions — no buttonParams / suggestionParams value.

  • URL buttons — only need a buttonParam when the URL contains {{1}}. Dynamic URL buttons whose URL includes the template's shortLinkDomain are auto-shortened via swift-link.

customEngage / buttonEngage

Passed through and attached to the outgoing message (channel.custom_engage / channel.button_engage). For each object supply either playbook or event, not both.

Field
Type
Meaning

playbook

string

Playbook id to run on engagement.

event

string

Event name to fire on engagement.


Response

200 OK


Examples

The examples below cover every send-time scenario. Substitute <client-id>, <secret-key>, and <template-id>.

1. Text body with dynamic params

Body-only template "Hello {{1}}!", no buttons — so no media header. Static text templates work the same way with bodyParams: [].

2. Dynamic URL button (with mandatory media header)

For a URL button whose url is "<https://example.link/{{1}>}". Because the template has a button, a media headerParam is required.

3. Keyed buttons — VIEW_LOCATION and CALENDAR (with mandatory media header)

Dynamic fields on special button types are passed via key at the button's index. A VIEW_LOCATION button uses lat / long; a CALENDAR button uses the event keys shown here. The media headerParam is required because the template has buttons.

4. Media header — IMAGE / VIDEO / DOCUMENT

One shape for all three. Set type to IMAGE, VIDEO, or DOCUMENT; value must be a valid media URL. DOCUMENT may include filename.

For DOCUMENT: "headerParam": { "type": "DOCUMENT", "value": "<https://cdn.example.com/doc.pdf>", "filename": "invoice.pdf" }

One carouselParams entry per card; each card's headerParam is required.

6. With engagement follow-ups

customEngage / buttonEngage attach to any template. Use playbook or event per object. (If the template defines buttons, include the media headerParam as noted above.)


Errors (400 / 403)

Condition
Message

Unknown channel

Invalid channel. Supported: rcs

Missing to or templateId

to and templateId are required

to not a valid phone number

to must be a valid phone number

templateParams fails schema (e.g. headerParam.value not a URL)

Invalid templateParams

Body param count mismatch

Body parameter count mismatch: expected N, received M

Body requires params, none sent

Body requires N parameter(s), but none were provided

Media header param missing

Header component requires a parameter with media link...

Carousel card header missing

Carousel card at index N requires a header parameter with media link

Dynamic URL button without value

URL button "..." requires a variable parameter, but none was provided

Keyed dynamic field missing

... has dynamic '<field>' field but no variable with key '<field>' was provided

Template not approved

Template is not approved (status: ...)

Last updated