Skip to main content

Migration from Sinch to Orbit

This guide walks you through migrating your SMS, multipurpose Conversation API, and Verification integration from Sinch to Orbit. Sinch’s account shape — a service_plan_id-scoped API token, a batch-only send surface, and (for omnichannel) the Conversation API “app” wrapping every channel — differs from Orbit’s model, and each of those concepts has a direct equivalent. The migration is incremental: every step below works alongside your live Sinch traffic until you cut over.

Concept Mapping


Prefer not to do it by hand?

The import tooling covers the configuration layer — numbers, messaging services, templates, and consent/contact data — before you touch any code:
  • Dashboard wizardSettings → Import walks you through connecting a read-only credential, a dry-run preview, and a one-click commit with rollback.
  • CLInpm install -g @devotel/cli, devotel auth login, then preview with devotel migrate and commit with --run.
The wizard imports your configuration only — it never moves live traffic, so the Sinch integration keeps running until you cut over. The rest of this guide covers the manual, code-level migration for teams who want full control over each step.

Step 1: Create Your Orbit Account

  1. Sign up at orbit.devotel.io/signup
  2. Generate an API key at Settings → API Keys
  3. Note your key prefix: dv_live_sk_xxxx
Replace every Authorization: Bearer <service_plan_id token> header with X-API-Key: dv_live_sk_xxxx — one header, one key, for SMS, Verify, Numbers, and webhooks alike.

Step 2: Port Your Numbers

Sinch supports LOA-based port-out, so you can move existing numbers to Orbit. The process takes 7–14 business days. A port request must carry a Letter of Authorization (LoA). Orbit only accepts an LoA URL it issued itself, so you upload the signed PDF to Orbit first and submit the returned URL.
Alternative: purchase new numbers and update your systems gradually. If the recipient is a US local number you’ll reuse for outbound (including 10DLC traffic), port it before you point sends at Orbit, then finish the 10DLC registration in the dashboard — the 10DLC walkthrough covers the ordering.

Step 3: Swap the SMS Send Path

Sinch’s SMS surface is the Batches resource — batch-shaped even for a single recipient — so “one endpoint to all your to[] values” has to be read as either a single send or a batch.

Sinch (Before)

Orbit (After)

Field-by-field mapping

If your Sinch send was a single-recipient call, leave it single in Orbit. If it genuinely fanned out over to[], move it to /batch; the per-recipient map mirrors what Sinch’s per-batch DLR would have told you.

Step 4: Migrate Delivery-Report Webhooks

Sinch pushes DLRs as HTTP callbacks into an envelope you registered on the batch. Orbit subscribers see the same signal as signed webhook events with a stable event id — you dedupe on it instead of building idempotency out of per-message state.

Envelope mapping

Sinch DLR callback (before)
Orbit webhook event (after)

Handler migration

  1. Subscribe once — POST /api/v1/webhooks with events: ["message.delivered", "message.failed", "message.received"] — instead of embedding delivery_report: "full" on every send.
  2. Read the raw body before parsing, and verify against X-Orbit-Signature (HMAC-SHA256 over timestamp.body). X-Devotel-Signature still exists for backward compatibility only.
  3. Dedupe on the envelope id — Orbit retries at-least-once for about 4–5 hours, so the id is the durable key for your seen_events table.
  4. Ack fast (2xx in milliseconds) and hand the work to a queue.
Full walkthrough with verified Node.js and Python receivers in the webhook consumer guide.

Step 5: Map the Conversation API

Sinch’s Conversation API wraps multiple channels inside one “app” that owns the sender and the inbound webhook. In Orbit the equivalent construct is a Messaging Service scoped to a channel, and sends name the channel explicitly. If your Sinch app handled WhatsApp — the most common Conversation-API case — the split looks exactly like the WhatsApp guides. If your Sinch app mixed SMS and WhatsApp traffic, split it into a SMS Messaging Service plus the WhatsApp WABA path — you’ll get a per-channel throughput cap and a cleaner opt-out list instead of one shared envelope.

Step 6: Migrate Verification

Sinch Verification is the same send/check OTP model as Orbit Verify — two backend calls, plus an optional webhook for asynchronous completion.

Sinch (Before)

Orbit (After)

If you don’t want a client library, plain HTTPS works end-to-end — POST /api/v1/verify/send then POST /api/v1/verify/check — see Verify without the SDK.

Migration Checklist

  • Create Orbit account and generate an API key
  • Port numbers (or purchase new ones) with an LoA
  • Install the Orbit SDK (npm install @devotel-orbit/node) or use plain HTTPS
  • Swap single sends to POST /api/v1/messages, batches to POST /api/v1/messages/batch
  • Rewire per-batch delivery_report flags to one webhook subscription
  • Update webhook handler to verify X-Orbit-Signature and dedupe on event id
  • Split any Conversation API app into a per-channel Messaging Service (+ WhatsApp WABA if applicable)
  • Migrate Verification to /verify/send + /verify/check
  • Update monitoring and alerting for the new event names
  • Run parallel sends against both providers
  • Decommission the Sinch service_plan_id credential only after cutover
  • Cancel the Sinch account once cutover is stable

Parallel Running Strategy

We recommend running Sinch and Orbit in parallel during migration:
  1. Phase 1 (Week 1–2): Send 10% of traffic through Orbit, 90% through Sinch
  2. Phase 2 (Week 3–4): Split 50/50 and compare delivery rates
  3. Phase 3 (Week 5): Route 100% through Orbit, keep Sinch as fallback
  4. Phase 4 (Week 6+): Decommission Sinch
Only decommission the service_plan_id credential after cutover is stable — a leftover token that still verifies forces you to treat signature failures as auth bugs.
Need help with your migration? Our solutions team offers free migration support for customers moving from Sinch. Contact migrate@devotel.io.