Endpoint
POST https://app.octopods.io/api/v1/vbm/templates/{template_id}/messages
{template_id}is the ID of the approved VBM template you want to send.Authentication:
X-Octopods-Auth: YOUR_CHANNEL_API_KEYfor the VBM channel you want to send from (see API Overview and Authentication).Content type:
application/json.
Finding a template ID
Templates must be approved before they can be sent.
Open Settings → Channels and select your VBM channel.
Click Manage Templates.
Click the template you want to send. Its ID appears in the URL and on the template’s detail page.
Request body
Field | Type | Required | Description |
| string | Yes | Recipient phone in E.164 format, e.g. |
| object or array | Conditional | Values for the template’s variables. Required when the template has any. See below for the shape. |
| string | Conditional | Public URL of the header image. Required only for a Promotional template with an image header — Transactional and OTP templates are always text-only. |
| boolean | No | Set to |
| string | No | The ID of the teammate the sent message should be attributed to. |
Message variable formats
A template built the classic way, with {{1}}, {{2}}-style placeholders, is fully supported and is still the most common format. Send a plain array of values in placeholder order — either as message_variables directly, or nested under a body key. Both are equivalent:
{
"destination_phone": "+14155552671",
"message_variables": ["Alex", "1234"]
}
{
"destination_phone": "+14155552671",
"message_variables": { "body": ["Alex", "1234"] }
}
Every Transactional and OTP template — and a Promotional template built with Named variables — uses variable names like {{first_name}} instead. Send an object with a body key mapping each name to its value:
{
"destination_phone": "+14155552671",
"message_variables": {
"body": {
"first_name": "Alex",
"order_id": "1234"
}
}
}
An OTP template’s variables must include pin.
If the template has no variables, omit message_variables entirely.
Image headers
For a Promotional template with an image header, provide a public URL in header_image_url. The URL must be reachable by Octopods’s servers.
{
"destination_phone": "+14155552671",
"header_image_url": "https://example.com/banner.jpg",
"message_variables": { "body": { "customer_name": "Alex" } }
}
Full example
curl -X POST "https://app.octopods.io/api/v1/vbm/templates/456/messages" \
-H "X-Octopods-Auth: YOUR_CHANNEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination_phone": "+14155552671",
"message_variables": { "body": { "first_name": "Alex", "order_id": "1234" } },
"open_intercom_conversation": true
}'
Successful response
On success, Octopods returns HTTP 201 Created with an empty body. The message has been accepted and handed to Viber. Final delivery status is tracked per-message in the Octopods UI.
Error codes
Errors return HTTP 400 Bad Request with:
{ "request_id": "…", "error_code": N, "error": "…" }
Code | Meaning | Fix |
1 | A required argument is missing (e.g. | Include the named field. |
2 |
| Send an object for a Named-variable template, or an array only for a template whose variables are all |
3 | Template does not exist, isn’t approved, or is inactive on this channel. | Re-check the template ID and confirm it’s Approved in the Octopods dashboard. |
5 |
| Use E.164 format (leading |
6 | Deprecated API key. | Copy the current key from the VBM channel settings screen. |
7 | Viber returned an error. | See the |
8 | Invalid header media URL. | Confirm the URL is public and points to a valid image. |
9 | An OTP template’s | Include a non-blank |
10 | One or more of the template’s declared variables is missing or blank. | Supply a non-blank value for every variable the template’s body references. |
11 | Template sending is temporarily disabled for this account. | Contact Octopods support. |
Note: Full details and recovery steps for provider errors are in Troubleshooting Failed Proactive Messages.
What’s next
