Viber transactional messaging — API reference

This guide is for developers building integrations on Routee. It describes the REST endpoints to create and manage Rakuten Viber Business Messages (BM) transactional templates and to send approved templates (including OTP).

For why templates are required, content and OTP rules, moderation timelines, and FAQs, see the customer guide.

You are looking for…Document
Business context and compliance (e.g. July 2026)Customer guide
Endpoint URLs, JSON fields, and responsesThis reference
Tracking GET and delivery callbackUrl payloadsTracking and delivery callbacks

Base URL and authentication

ItemValue
Production base URLhttps://connect.routee.net
AuthenticationOAuth 2.0 Bearer token in the Authorization header
FormatAuthorization: Bearer <access_token>

Your access token must belong to a Routee account that is allowed to use Viber. Routee resolves which account and which senders you may use from the token and from the parameters you pass (for example senderInfoTrackingId).


Permissions and errors

Your Routee API credentials (application / OAuth setup) must include:

  • Viber-related OAuth scopes — typically viber or all (as configured for your integration).
  • Rights to manage templates — create, read, and delete transactional templates for your Viber sender(s).
  • Rights to send — permission to send Viber messages for the same account.

If the token is missing, invalid, or not allowed to perform the operation, the API usually returns HTTP 403. If a resource (for example account or sender context) cannot be resolved, you may receive HTTP 404.


Quick start — typical flow

  1. Authenticate — Obtain a valid Bearer token with Viber access.
  2. Pick a sender — Use the Routee tracking id of your Viber sender (senderInfoTrackingId) when you create templates and when you send.
  3. Create a templatePOST /viber/transactional/templates?senderInfoTrackingId=… and wait until the template is approved in Routee (see the customer guide for moderation and optional notifications).
  4. Send — Call POST /viber/transactional/messages for every approved template (transactional or OTP category). There is no separate greenfield /viber/transactional/otp. Use templateId, templateLang, templateParams, and optional deliveryScope. OTP-category templates must include pin in templateParams.
  5. Optional webhooks — You may set a callbackUrl on the template for moderation status updates, and a callbackUrl on each send for delivery status. Those callbacks use different JSON payloads (see Moderation callback).
flowchart LR
  A[Create template] --> B[Wait until approved]
  B --> C[Send template message]
  C --> D[Optional delivery callback]

Request conventions

TopicGuidance
JSONUse Content-Type: application/json on all bodies.
Supported fields onlyFor POST /viber/transactional/messages, use only the fields described below. Extra or unknown top-level JSON properties may be rejected.
Device targetingUse deliveryScope: PRIMARY_DEVICE (default) or ALL_DEVICES. Invalid values may return HTTP 400.
NamingUse deliveryScope on these endpoints; do not send numeric transactionalSendTypeCode in the JSON — it is not part of this API.

Transactional templates

All paths below are relative to the base URL, for example:

https://connect.routee.net/viber/transactional/templates

List, read, create, update webhook, delete

MethodPathQuery parametersResponse (success)
GET/viber/transactional/templatesOptional: pageSize, lastServiceId, lastTemplateId, senderInfoTrackingId200 — list of templates
GET/viber/transactional/templates/{templateId}200 — one template
POST/viber/transactional/templatesRequired query: senderInfoTrackingId200 — created template
PATCH/viber/transactional/templates/{templateId}200 — updated template metadata
DELETE/viber/transactional/templates/{templateId}200 — confirmation payload

Create template — JSON body (POST)

FieldTypeRequiredDescription
categorystringYesOTP or Transactional. OTP templates must include {{pin}} in the text (see customer guide).
paramsarrayYesDeclares placeholders. May be an empty array for a fully static template. See Parameters below.
localesarrayYesAt least one language version of the text. See Locales below.
varExamplearrayYesExample values shown during moderation. Empty if params is empty. See Examples below.
callbackUrlstring (URL)NoHTTPS URL where Routee will POST JSON when the template’s moderation status changes (guide — lifecycle callback).
moderationNotifyEmailstringNoOptional email for Routee moderation status notifications when the template lifecycle changes (approved / rejected). If omitted, Routee may use account notification settings when available. See customer guide §8.2.

Parameters (params items)

FieldTypeRequiredDescription
namestringYesName of the variable (matches {{name}} in the template text).
typestringYesUse TEXT.

Locales (locales items)

FieldTypeRequiredDescription
langstringYesLanguage code (ISO 639-1, e.g. en). Must match the templateLang you send later.
templatestringYesMessage text including {{placeholders}}. Must comply with Viber / Routee rules.

Examples (varExample items)

FieldTypeRequiredDescription
namestringYesSame as in params.
examplestringYesSample value for reviewers.

Example body:

{
  "category": "Transactional",
  "params": [{ "name": "user_name", "type": "TEXT" }],
  "locales": [
    { "lang": "en", "template": "Hello {{user_name}}, your appointment is confirmed." }
  ],
  "varExample": [{ "name": "user_name", "example": "Alex" }]
}

Update moderation webhook only (PATCH)

This request only updates Routee settings for your template moderation webhook. It does not change the template text sent to Viber.

  • Send callbackUrl with an HTTPS URL, or "callbackUrl": null to remove the stored URL.
  • You may use the alternative property name lifecycleCallbackUrl instead of callbackUrl (same meaning).
  • The body must include callbackUrl or lifecycleCallbackUrl as a key. An empty body {} or omitting both keys returns HTTP 400 on greenfield paths (/viber/transactional/templates/...). Legacy /viber/bm/transactional-templates/... PATCH remains backward compatible (empty body may no-op).

Send transactional template messages

Paths are under:

https://connect.routee.net/viber/transactional/

MethodPathPurpose
POST/viber/transactional/messagesSend any approved BM transactional template (transactional or OTP category). No free-form marketing body; content comes from the template. OTP-category: templateParams must include pin.

There is no greenfield POST /viber/transactional/otp. Legacy POST /viber/otp on Routee Connect remains for older integrations.

POST /viber/transactional/messages — request body

FieldTypeRequiredDescription
senderInfoTrackingIdstringYesYour Viber sender (Routee tracking id).
tostringYesRecipient in E.164 format with leading +.
templateIdstringYesId of an approved template.
templateLangstringYesLanguage code matching the template (e.g. en).
templateParamsobjectNo*Map of placeholder name → value (TEXT, max 25 chars each, no URLs, no file-extension-like values such as test.pdf). For OTP templates, include pin. See Send-time validation. Omit or {} only when the template has no variables.
deliveryScopestringNoPRIMARY_DEVICE or ALL_DEVICES. Default: PRIMARY_DEVICE.
seqnumberNoOptional partner correlation id. If omitted, Routee assigns a value (millisecond timestamp) before the message is queued; the assigned or supplied value is returned in the HTTP 200 response and echoed on tracking GET / delivery callbacks as transactionalTemplate.seq.
ttlintegerNoTime-to-live / validity window where applicable.
inboundUrlstringNoHTTPS callback for inbound replies, where supported.
callbackUrlstringNoHTTPS URL for delivery status callbacks for this message.
labelstringNoOptional label for reporting.
multipleSinglesMessageIdstringNoOptional batch id for grouped reporting.
sessionMessagebooleanNoSession message flag where supported.

Example — non-OTP

POST https://connect.routee.net/viber/transactional/messages
Authorization: Bearer <access_token>
Content-Type: application/json
{
  "senderInfoTrackingId": "your-viber-sender-tracking-id",
  "to": "+972500000000",
  "templateId": "YOUR-APPROVED-TEMPLATE-ID",
  "templateLang": "en",
  "templateParams": {
    "user_name": "Alex",
    "order_id": "4829"
  },
  "deliveryScope": "PRIMARY_DEVICE"
}

Example — OTP-category template

{
  "senderInfoTrackingId": "your-viber-sender-tracking-id",
  "to": "+972500000000",
  "templateId": "YOUR-APPROVED-OTP-TEMPLATE-ID",
  "templateLang": "en",
  "templateParams": { "pin": "482910", "minutes": "5" },
  "deliveryScope": "PRIMARY_DEVICE",
  "ttl": 86400
}

POST /viber/transactional/messages — response (success)

HTTP 200 means the message was accepted for processing, not that the handset has received it yet.

The JSON includes fields such as:

FieldDescription
trackingIdRoutee tracking id for this send (use for support and status).
deliveryScopePRIMARY_DEVICE or ALL_DEVICES as applied.
seqCorrelation id (yours if supplied, otherwise assigned by Routee).
to, fromRecipient and sender identity as resolved by Routee.
statusInitial status object for the message.
priceCharged amount for this request where applicable.

Other fields (label, sessionMessage, callbackUrl, ttl, etc.) may appear depending on your request and product behaviour.


Delivery status: tracking GET and callbackUrl

Poll GET /viber/tracking/{trackingId} or receive delivery callbacks on the optional callbackUrl from the send request.

Full field reference, examples, and backward-compatibility notes:
Tracking and delivery callbacks (for public Routee / readme.io documentation).

messageKind and transactionalTemplate (summary)

Template-based sends add a discriminator and a nested metadata block. Values depend on the send path and stored record type — see the tracking guide for full examples.

FieldTypical valuesWhen present
messageKindtransactional_templateGreenfield POST /viber/transactional/messages and legacy template sends on POST /viber
otpLegacy POST /viber/otp; tracking GET when the stored record is flagged otp: true
transactionalTemplateObject with templateId, templateLang, deliveryScope, seqAny send that used an approved template id
transactionalTemplate.templateParamsPlaceholder map; pin masked as `*`**Tracking GET only — never in delivery callbacks

Shared transactional block

When the send used an approved BM template (POST /viber/transactional/messages, or legacy template fields on POST /viber / POST /viber/otp), responses include:

FieldTracking GETDelivery callbackNotes
messageKindtransactional_template or otp
transactionalTemplate.templateId
transactionalTemplate.templateLang
transactionalTemplate.deliveryScopePRIMARY_DEVICE or ALL_DEVICES
transactionalTemplate.seqAlways set for template sends (partner value or Routee-assigned)
transactionalTemplate.templateParamsGET only; pin is masked (***)
createdAtISO-8601 timestamp
templateId (top-level)Same as transactionalTemplate.templateId (portal compatibility)

Legacy rich single and campaign messages omit messageKind and transactionalTemplate. Existing fields (message, body.text, campaignTrackingId, etc.) are unchanged.

Callback status shape (unchanged): status.name, status.updatedDate. Tracking GET uses status.status, status.date.

Template sends on callback: empty body is omitted (no "body": {}). Legacy single/campaign callbacks still include body when present.

Example delivery callback:

{
  "trackingId": "304177c4-2478-4c49-bcea-3b6cede1b064",
  "to": "+306973359331",
  "status": {
    "name": "DELIVERED",
    "updatedDate": "2026-05-20T05:45:13.606Z"
  },
  "messageKind": "transactional_template",
  "transactionalTemplate": {
    "templateId": "2c017482-2f44-41d6-adad-2d6af725fdbe",
    "templateLang": "en",
    "deliveryScope": "PRIMARY_DEVICE",
    "seq": 1747719911946
  }
}

Send-time validation (before queue)

Routee validates templateLang and templateParams against the approved template before the message is queued. Invalid requests fail immediately with HTTP 400 instead of failing later at Viber with status 39.

Error response shape

FieldValue
HTTP status400
code400019029
developerMessageHuman-readable summary (single issue or joined list)
validationIssuesArray of { "code": "…", "message": "…" }

Example — file-extension-like parameter:

{
  "code": "400019029",
  "developerMessage": "Parameter document_name must not look like a file name or extension (e.g. test.pdf).",
  "validationIssues": [
    {
      "code": "PARAM_CONTAINS_FILE_EXTENSION",
      "message": "Parameter document_name must not look like a file name or extension (e.g. test.pdf)."
    }
  ]
}

Common validationIssues codes

CodeMeaning
TEMPLATE_LANG_REQUIREDtemplateLang missing
TEMPLATE_LANG_MISMATCHtemplateLang does not match template locale
MISSING_PARAMRequired placeholder missing or blank
UNKNOWN_PARAMExtra key not declared on template
PARAM_VALUE_TOO_LONGValue longer than 25 characters
PARAM_CONTAINS_URLURL-like content in a TEXT parameter
PARAM_CONTAINS_FILE_EXTENSIONFile-extension-like fragment (e.g. test.pdf)
OTP_PIN_REQUIREDOTP-category template without pin

These checks are in addition to auth (403), unknown template projection (404 / not approved), and Viber partner codes (7, 38, 39) after the send reaches the provider.


Moderation callback (callbackUrl on the template)

If you set callbackUrl when creating (or updating) a template, Routee will POST to that HTTPS URL when the template’s moderation status changes (for example pending → approved or rejected).

  • Content-Type: application/json
  • Payload — Routee sends a focused object, for example:
FieldAlways present?Meaning
templateIdYesTemplate id.
templateStatusYesRoutee status, e.g. PENDING_MODERATION, APPROVED, REJECTED.
templateBodySometimesTemplate text snapshot if available.
variablesSometimesOrdered list of placeholder names (not the values used at send time).
rejectionReasonSometimesReason when rejected.

Do not depend on extra fields such as serviceId, eventId, or vendor-specific raw codes unless Routee documents them for your integration.

Important: This payload is not the same as delivery callbacks you configure on POST /viber/transactional/messages. Use separate URLs unless you deliberately route both types through your own gateway and distinguish them there.

Moderation email (internal AMQP → Notifications)

Routee also sends moderation lifecycle emails when moderationNotifyEmail is set (or via Profile notification settings). The internal VIBER_BM_TRANSACTIONAL_TEMPLATE_LIFECYCLE AMQP payload (api → notifications) includes:

FieldWhen presentUsed in email
templateIdAlwaysTemplate ID row
templateNameWhen Routee can resolve display textTemplate Name row
statusNoteAlways for approve/pending; on reject when detail existsModeration Note row
rejectionReasonRejected eventsFallback for statusNote in Notifications when statusNote is absent
viberEventTypeAlwaysDrives status label (1000 / 1001 / 1002)

templateName is derived from the stored template body snapshot or the first locale returned by Viber Partners API. statusNote defaults to “Your template has been approved and is ready to send.” on approval when Viber sends no moderation text.


Common issues

SituationTypical result
Invalid OAuth or no Viber permission403
Unknown account / resource404
PATCH greenfield template without callbackUrl / lifecycleCallbackUrl400
Invalid templateLang or templateParams at send time400400019029 + validationIssues
Template or send rejected by Routee / Viber validation400 / 422 (depends on the case)
Send rejected with Viber partner codes (7, 38, 39, …)See guide §7.3

Partner error codes can change; treat tables as indicative and verify against the latest Viber / Routee documentation you receive.


Postman and samples

Routee provides a Postman collection with ready-made calls for transactional templates and sends (collection name along the lines of Routee Viber BM Transactional). Use the copy supplied in your Routee developer / onboarding materials, or ask your Routee contact for the latest export.