Skip to main content

Troubleshooting: Viber inbound and routing failures

Viber ships as a first-class channel on Orbit with two non-overlapping tiers (see Viber channel overview):
  • Tier 1 — One-way Basic Messaging. Outbound-only wholesale SMPP termination flow: apps/api → Jasmin HTTP API → SMPP client smppc(viber) → upstream aggregator → Viber. Inbound replies can never arrive on this tier.
  • Tier 2 — Two-way Advanced Messaging. The Rakuten Viber Business HTTP API with your branded sender, per-tenant auth token, inbound replies, and rich media.
Both tiers share the same POST /api/v1/messages/viber endpoint, so a routing mistake is not visible from your client code — work this page to find out which tier you are on and which side of the flow is failing.

Symptom split — pick your section first

Match your observation to one of the three failure classes before you work a checklist:

Inbound check list (Tier 2 only)

Tier 1 is outbound-only by construction — no inbound replies and no inbound webhooks exist on the SMPP route. If you are on Tier 1 and expected replies, the fix is a tier upgrade, not a debug session. Work the following in order on Tier 2 — each step doubles as an escalation input.
  1. Confirm the sender is Tier 2. Check Settings → Channels → Viber for a stored Business account (sender name + auth token). Without the stored token, every send routes through Tier 1 SMPP and inbound is structurally impossible — see Tier 2 provisioning.
  2. Confirm chatbot capability on the sender. Viber only forwards P2A replies to senders registered with chatbot capabilities — a standard Business Message (A2P) sender never receives user replies. This is a Rakuten-side account property. If replies matter for your flow and your sender is A2P-only, ask your Devotel account manager to re-register with chatbot capability.
  3. Register the inbound webhook with Rakuten Viber. Tier 2 inbound arrives on the platform route POST /api/v1/webhooks/inbound/viber. Sender registration wires this automatically — you never point Rakuten at your own URL — but if the sender was registered before this platform route existed or was re-registered through a different path, the webhook target at Rakuten must be re-set. Open a ticket and ask Support to verify the inbound webhook registration on your sender.
  4. Check the bot token has not rotated. The inbound route verifies the event against the auth token stored on your organization’s settings.channels.viber.businessAccount. If Rakuten re-issued the token (a re-registration, a security rotation, or an account-manager-driven re-issue), inbound verification fails until the new token is attached to your tenant. Ask Support to confirm the stored token matches the current Rakuten-issued value.
  5. Verify inbound resolution attaches to your tenant. Each inbound event must resolve to the organization that owns the branded sender before it is relayed to your webhook — the same resolve-then-relay pattern the inbound SMS and APAC channels runbooks use. If the tenant-resolution step fails, the event is dropped before any delivery is attempted, so an empty delivery log is the expected symptom. This is a Support-verifiable step — include your organization id in the escalation so the resolution can be traced directly.
  6. Check your webhook subscription scope. If you expect message.received at your own endpoint, list endpoints with GET /api/v1/webhooks and verify one is subscribed to inbound message events, and check its recent deliveries with GET /api/v1/webhooks/{endpoint_id}/deliveries. An indexed event with a failed delivery row means your endpoint rejected it — see Inspecting deliveries.

Outbound check list

A stuck outbound is almost always identity, connectivity, or quota — in that order.
  1. Confirm the sender identity is in lifecycle-good standing.
    • Tier 1: the alphanumeric sender ID must be allow-listed by Devotel before first use. An ID sent before allow-listing is rejected by the aggregator and surfaces as a failed delivery status on your webhook — check Settings → Channels for your allow-listed IDs.
    • Tier 2: the branded sender must have passed Rakuten review and the token must be attached. A sender pending review keeps routing sends through Tier 1 if it is allow-listed there, or fails with CHANNEL_NOT_CONFIGURED (503) if not.
  2. Weigh the delivery-status value. queued means persisted and accepted, not delivered. An undelivered / failed outcome with reason not-registered (recipient not on Viber) or not-on-Viber is a recipient-side outcome, not a routing fault — route it into the configured cross-channel fallback chain (Viber → SMS) instead of retrying Viber. See Delivery & fallback.
  3. Check provider connectivity (Tier 1). Tier 1 rides the platform SMPP route apps/api → Jasmin HTTP API → smppc(viber) → aggregator → Viber. A route-side outage fails sends with CHANNEL_NOT_CONFIGURED (503) or parks them in queued. Check status.orbit.devotel.io before assuming identity trouble, and prefer the configured fallback chain for time-sensitive traffic during a provider incident.
  4. Check Rakuten quota (Tier 2). Tier 2 is bounded by the API quota on your Viber Business token, on top of the platform’s per-tenant /messages/viber rate-limit row (50 requests/minute by default). Saturated quota surfaces as terminal MESSAGE_SEND_FAILED (502) after the platform’s backoff retries — inspect details.viberStatus on the error envelope for the provider’s status code.
  5. Know the Tier 1 vs Tier 2 difference. Both tiers use the same POST /api/v1/messages/viber endpoint, so tier membership comes from your tenant configuration, not from your request. You cannot force a tier by changing the request — check Settings → Channels → Viber to see whether a Business account is attached.

Error sample

A synchronous routing rejection returns a structured envelope — this sample is a Tier 2 provider rejection, the most common routing-error shape. Paste the full envelope into any escalation.
502
The other codes in this family — CHANNEL_NOT_CONFIGURED (503, no route and no token), INVALID_RECIPIENT (422), and VALIDATION_ERROR (422) — are enumerated on the Viber channel page with their causes and fixes.

Decision checklist

Run down this list before you escalate:
  • Symptom class named — inbound never arrives, outbound stuck queued/undelivered, or a routing error code.
  • Tier membership confirmed from Settings → Channels → Viber — not inferred from the request body.
  • (Inbound) chatbot capability confirmed with your account manager.
  • (Inbound) webhook subscription scoped to message.received and the delivery log inspected.
  • (Outbound) sender identity verified — Tier 1 ID allow-listed, or Tier 2 sender approved with token attached.
  • (Outbound) details.viberStatus captured on any 502, or the delivery-status reason (not-registered vs route fault) read from the delivery webhook.
  • Organization id from GET /api/v1/me ready for the ticket.

What not to do

  • Do not debug inbound on Tier 1. The SMPP route is outbound-only; no checklist resolves a reply that the tier can never carry. Upgrade to Tier 2.
  • Do not retry a 503 CHANNEL_NOT_CONFIGURED blindly. Nothing is configured — retrying changes nothing. Attach the token or complete allow-listing first; honor Retry-After only on 429.
  • Do not pass a fallback field on the request. The fallback chain lives on the organization under Settings → Channels → Cross-Channel Fallback; a per-request field is ignored.
  • Do not treat not-registered as a provider outage. The recipient is simply not on Viber — fall back or drop the recipient.
  • Do not re-register the Rakuten webhook yourself. The inbound platform route is wired by sender registration; self-registering a custom URL at Rakuten breaks inbound resolution — escalate to Support instead.

Escalation

Open a support ticket when the decision checklist is exhausted. Include:
  • The symptom class (inbound / outbound / routing code) and your tier.
  • Your organization id (dashboard → Settings → Organization, or organizationId on GET /api/v1/me).
  • For inbound: the branded sender name, the time window (with timezone) of a missed reply, and the webhook endpoint id if you were expecting message.received.
  • For outbound: the message id (msg_viber_*), the full error envelope when the send was rejected, and the delivery-status reason from the webhook when it reached a terminal state.

See also