Skip to main content

SDKs

Orbit publishes three SDKs today: Node.js and Web (feature-complete, on npm) and Python (core-scope, on PyPI). Six more, Go, .NET, Java, PHP, and Ruby, each wrap the platform’s 8 core resources (messaging, voice, contacts, campaigns, verify, webhooks) in workspace source but are not yet published — see Go: core-scope, not full parity, .NET: core-scope, not full parity, Java: core-scope, not full parity, Python: core-scope, not full parity, PHP: core-scope, not full parity, and Ruby: core-scope, not full parity below. Every SDK shares the same auth model (X-API-Key), retry policy (3 attempts on 429/5xx with exponential backoff), idempotency contract (auto-generated Idempotency-Key on every non-GET), and webhook verification format (t=<unix_ts>,v1=<hex_hmac> HMAC-SHA256, 5-minute replay window).
The npm scope is @devotel-orbitnpm install @devotel-orbit/node and npm install @devotel-orbit/web resolve today. Python is on PyPI: pip install devotel-orbit-sdk (import it as orbit_sdk). Go, .NET, Java, PHP, and Ruby now wrap 8 core resources in workspace source (see below) but none is full parity, and none is published to its package registry yet — build against the REST API directly for those languages, or vendor the SDK source. The REST API recipes cookbook walks the core send/verify/contacts/risk flows task by task, with the Node SDK as the second snippet on each. Anything the core-scope clients don’t wrap is still reachable: each of the unpublished SDKs ships an escape hatch (client.Request* / client.request) — every per-language page shows a worked example hitting a real uncovered route (Go, .NET, Java, Python, PHP, Ruby).

Published SDKs

Node.js / TypeScript

npm install @devotel-orbit/node — hand-written, fully typed. Node 18+. Status: feature-complete, published on npm.

Web (browser)

npm install @devotel-orbit/web — embeddable chat widget + inbound APIs. Status: feature-complete, published on npm.

Python

pip install devotel-orbit-sdk — messaging, voice, contacts, campaigns, verify. Status: core-scope, published on PyPI.

In workspace source (unpublished)

Go

Messaging, voice, contacts, campaigns, verify. Source-only, NOT published.

Ruby

Messaging, voice, contacts, campaigns, verify. Source-only, NOT published.

PHP

Messaging, voice, contacts, campaigns, verify. Source-only, NOT published.

Java

Messaging, voice, contacts, campaigns, verify. Source-only, NOT published.

.NET / C#

Messaging, voice, contacts, campaigns, verify. Source-only, NOT published.

Go: core-scope, not full parity

Source: packages/sdk-go/ (module github.com/devotel/orbit-go) now wraps 8 core resources with typed methods and its own test suite: messaging (SMS/WhatsApp/email via client.Messages()), voice (client.Voice()), contacts (client.Contacts()), campaigns (client.Campaigns()), verify/OTP (client.Verify()), and webhook signature verification (orbit.VerifyWebhook). This is no longer an empty placeholder. It is not feature-complete against the Node SDK, and it is unpublished / pre-GA like every non-Node/Web language today — do not advertise it to customers as install-ready. Sub-resources the Node SDK exposes are intentionally out of scope for now: voice conferences/IVR/dialer/recordings, contact lists/segments/scoring, and the verify voice-biometrics endpoints. For those, use the Node SDK or call the REST API directly (the Go client also exposes a low-level client.Request(ctx, method, path, ...) escape hatch). See packages/sdk-go/README.md’s Scope section for the authoritative, up-to-date list of what is and isn’t wrapped.

.NET: core-scope, not full parity

Source: packages/sdk-csharp/ (package Orbit.Sdk, targets .NET 8.0) also wraps the same 8 core resources with typed methods and its own test suite: messaging (SMS/WhatsApp/email via client.Messages), voice (client.Voice), contacts (client.Contacts), campaigns (client.Campaigns), verify/OTP (client.Verify), and webhook signature verification (Webhooks.Verify). Like Go, this is no longer an empty placeholder. It is not feature-complete against the Node SDK, and it is unpublished / pre-GA like every non-Node/Web language today — do not advertise it to customers as install-ready. Sub-resources the Node SDK exposes are intentionally out of scope for now: RCS, agents, conversations, billing, and voice recordings/transcripts/conferences/IVR/dialer. For those, use the Node SDK or call the REST API directly (the .NET client also exposes a low-level client.RequestAsync(method, path, ...) escape hatch). See packages/sdk-csharp/README.md’s Scope today section for the authoritative, up-to-date list of what is and isn’t wrapped.

Java: core-scope, not full parity

Source: packages/sdk-java/ (JDK 11+, no live Maven coordinates yet — the registry moves off the retired legacy name before publish) also wraps the same 8 core resources with typed methods and its own test suite: messaging (SMS/WhatsApp/email via client.messages), voice (client.voice), contacts (client.contacts), campaigns (client.campaigns), verify/OTP (client.verify), and webhook signature verification (Webhooks.verify). Like Go and .NET, this is no longer an empty placeholder. It is not feature-complete against the Node SDK, and it is unpublished / pre-GA like every non-Node/Web language today — do not advertise it to customers as install-ready. Sub-resources the Node SDK exposes are intentionally out of scope for now: WhatsApp templates, message streaming, contact segments/lists/opt-outs, campaign journeys/A-B tests, voice recordings/transcripts/conferences/IVR/dialer, verify voice-biometrics, plus RCS, agents, conversations, and billing. For those, use the Node SDK or call the REST API directly (the Java client also exposes a low-level client.request(method, path, ...) escape hatch). See packages/sdk-java/README.md’s Scope section for the authoritative, up-to-date list of what is and isn’t wrapped.

Python: core-scope, not full parity

Source: packages/sdk-python/ (published on PyPI — install with pip install devotel-orbit-sdk; the module imports as orbit_sdk) also wraps the same 8 core resources, fully hand-written against the Python standard library (urllib.request, zero runtime dependencies), with its own pytest suite: messaging (SMS/WhatsApp/ email via client.messages), voice (client.voice), numbers + HLR lookup (client.numbers, client.lookup), contacts (client.contacts), campaigns (client.campaigns), verify/OTP (client.verify), and webhook signature verification (verify_webhook). Like Go, .NET, and Java, this is no longer an empty placeholder. It is not feature-complete against the Node SDK — published on PyPI, but core-scope. Sub-resources the Node SDK exposes are intentionally out of scope for now: RCS, agents, conversations, billing, contact lists/segments/scoring, campaign journeys/A-B tests, and voice recordings/transcripts/conferences/IVR/dialer. For those, use the Node SDK or call the REST API directly (the Python client also exposes a low-level client.request(method, path, ...) escape hatch). See packages/sdk-python/README.md’s Scope section for the authoritative, up-to-date list of what is and isn’t wrapped.

PHP: core-scope, not full parity

Source: packages/sdk-php/ (PHP 8.1+, no Packagist package live yet — the registry moves off the retired legacy name before publish) also wraps the same 8 core resources with typed methods and its own PHPUnit suite: messaging (SMS/WhatsApp/email via $client->messages), voice ($client->voice), contacts ($client->contacts), campaigns ($client->campaigns), verify/OTP ($client->verify), and webhook signature verification (Webhooks::verify). Like Go, .NET, Java, and Python, this is no longer an empty placeholder. It is not feature-complete against the Node SDK, and it is unpublished / pre-GA like every non-Node/Web language today — do not advertise it to customers as install-ready. Sub-resources the Node SDK exposes are intentionally out of scope for now: voice conferences, IVR flows/intents, the outbound dialer, SIP trunks, voice clones, VAQI analytics, live transcript streaming, contact lists/segments, and voice-biometric caller authentication. For those, use the Node SDK or call the REST API directly (the PHP client also exposes a low-level OrbitClient::request(method: ..., path: ..., ...) escape hatch). See packages/sdk-php/README.md’s Scope section for the authoritative, up-to-date list of what is and isn’t wrapped.

Ruby: core-scope, not full parity

Source: packages/sdk-ruby/ (future gem name orbit_sdk, targets Ruby 2.7+) also wraps the same 8 core resources with typed methods and its own RSpec suite: messaging (SMS/WhatsApp/email via client.messages), voice (client.voice), contacts (client.contacts), campaigns (client.campaigns), verify/OTP (client.verify), and webhook signature verification (OrbitSdk::Webhooks.verify). Like Go, .NET, Java, Python, and PHP, this is no longer an empty placeholder. It is not feature-complete against the Node SDK, and it is unpublished / pre-GA like every non-Node/Web language today — do not advertise it to customers as install-ready. Sub-resources the Node SDK exposes are intentionally out of scope for now: RCS, agents, conversations, billing, voice recordings/transcripts/conferences/IVR/dialer, contact lists/segments/scoring, campaign journeys/A-B tests, and verify voice-biometrics. For those, use the Node SDK or call the REST API directly (the Ruby client also exposes a low-level client.request(method, path, **opts) escape hatch). See packages/sdk-ruby/README.md’s Scope section for the authoritative, up-to-date list of what is and isn’t wrapped.

Client / mobile SDKs (different scope, by design)

Besides the two server-capable SDKs above, the workspace also ships client-embed SDKs for native apps — each with its own quickstart page: Swift / iOS (source: packages/sdk-swift/, shipped as Swift Package Manager libraries), Android (Kotlin) (source: packages/sdk-android/, Gradle/Maven), Flutter (source: packages/sdk-flutter/, Dart), and React Native (source: packages/sdk-react-native/, npm). These are not thin ports of the Node SDK and are not meant to grow into one. Each is scoped to the same end-user-facing surfaces the Web SDK’s widget mode covers — conversations/inbox chat, owned in-app messages/content cards, video rooms, and (on Swift) VoIP push registration for inbound-call delivery — and authenticates only with a publishable key (dv_live_pk_…), because they ship inside a distributed app binary. They deliberately do not expose the backend/management resource clients (messaging, whatsapp, email, contacts, campaigns, verify, billing, etc.) — those require a secret key and must only ever be called from a backend, via the Node SDK or the REST API directly. If a client/mobile SDK’s file count looks small next to Node’s, that is this intentional split, not a gap to fill.

Client / mobile SDK sources

For the sensor-exemption contract each client/mobile SDK’s README must honor:
  • Source: packages/sdk-web/ — Web (browser, TypeScript, npm). README documents the deliberate scope as a “Scope — this is a client SDK, not a full API client” heading.
  • Source: packages/sdk-swift/ — iOS (Swift, SPM). README documents the deliberate scope as a “Scope — this is a client SDK, not a full API client” heading.
  • Source: packages/sdk-android/ — Android (Kotlin/Gradle). Same deliberate scope heading in its README.
  • Source: packages/sdk-flutter/ — Flutter (Dart, pub). Same deliberate scope heading in its README.
  • Source: packages/sdk-react-native/ — React Native (TypeScript). Same deliberate scope heading in its README.

Registry coordinates

Node, Web, and Python are published to their package registries today. The remaining languages have no public registry entry yet — the package names below for those describe the future coordinates and may change before first publish. The publishable npm scope is @devotel-orbit (the @devotel npm org is not ours), so the two npm SDKs ship as @devotel-orbit/node and @devotel-orbit/web. Non-npm coordinates are unaffected. Each SDK already has a quickstart page wired into the docs nav — the core-scope Python, Go, Ruby, PHP, Java, and .NET pages, the client/mobile Swift, Android, Flutter, and React Native pages, and the two feature-complete pages /sdks/node and /sdks/web. Each per-language page carries a first-send quickstart, an OTP verify round trip, and one paginated list example against a cursor-based endpoint — the pattern explained prose-side in the Pagination guide — plus a cross-link to the runnable repositories on Starter examples. Once each SDK lands on its registry, its page carries the production install command, a version pin, and the per-language quickstart. The codegen pipeline that drives this lives at tools/sdk-codegen/README.md.

Common patterns across languages

Authentication

Every SDK authenticates with an X-API-Key. The GA Node SDK exposes a single constructor — new Orbit({ apiKey }) (alias new Devotel({ apiKey })) — and you pass your own env var (e.g. process.env.ORBIT_API_KEY); the Web surfaces take a publicKey instead. There is no fromApiKey() static or from_env() helper on the GA SDKs today — those are roadmap-language for the codegen’d clients, so the From env column below is marked Roadmap on the still-roadmap languages that list one (core-scope languages that already implement it are marked with their own status instead). The GA Node and Web rows have no fromApiKey/env-reading helper — only the constructor shown in the Direct column.

Webhook verification

Webhook verification is server-side only — the Web SDK does not expose a verifier (browser surfaces never receive inbound webhooks). Each server-side SDK exposes a one-call verifier that returns the decoded event on success or throws OrbitWebhookSignatureError on any failure (malformed header, expired timestamp, signature mismatch, invalid JSON):
  • Node (GA): Orbit.webhooks.constructEvent(body, signature, secret)
  • Python (core-scope, published): verify_webhook(payload=..., signature=..., secret=...)
  • Go (core-scope, unpublished): orbit.VerifyWebhook(body, header, secret, 0, time.Time{})
  • PHP (core-scope, unpublished): Webhooks::verify(payload: ..., signature: ..., secret: ...)
  • Ruby (core-scope, unpublished): OrbitSdk::Webhooks.verify(payload:, signature:, secret:)
  • Java (core-scope, unpublished): Webhooks.verify(body, signature, secret)
  • C# (core-scope, unpublished): Webhooks.Verify(payload, signature, secret)
A complete framework handler per language — raw-body handling, header fallback, 401 on failure — lives at Verify webhook signatures with the SDK; a no-SDK stdlib variant for Python and Go is at Verify webhook signatures with no SDK.

Worked example

The same end-to-end flow — connect, send one SMS, verify an inbound webhook — in the exact constructor and method signatures above. Keep it under ten lines per step; per-language detail lives on each SDK’s own page.
For error handling, branch on the subclasses the error hierarchy names. In Node, distinguish a retryable rate limit from an unretryable validation failure:

Error hierarchy

Every SDK exposes the same error tree:
  • OrbitApiError (base) → catch this to handle any non-2xx API response. Carries code, statusCode (aliased as status), details, docsUrl, and requestId, plus isRateLimited / isClientError / isServerError getters.
  • OrbitAuthError — 401/403 (bad API key or missing scope).
  • OrbitNotFoundError — 404 (resource doesn’t exist or isn’t visible).
  • OrbitRateLimitError — 429. Check the Retry-After header (also surfaced in details) to decide when to retry.
  • OrbitValidationError — 400/422 (request body failed server-side validation).
  • OrbitServerError — 5xx after retries exhausted, or persistent network failure.
  • OrbitWebhookSignatureError — webhook verification failed. Carries a code of 'bad_signature' | 'expired' | 'malformed'. Extends Error, not OrbitApiError, so a broad catch (OrbitApiError) block can’t accidentally swallow + retry forgeries.

Operator: publishing checklist

See tools/sdk-codegen/README.md for the per-registry publish commands. The remaining unpublished SDKs (Go, Ruby, PHP, Java, .NET, and the client languages) are committed source-only; first publish to each registry is an operator action.