Skip to main content

SDKs

Orbit has two SDKs that are feature-complete in workspace source today (Node.js, Web). Six more, Go, .NET, Java, Python, PHP, and Ruby, each wrap the platform’s 8 core resources (messaging, voice, contacts, campaigns, verify, webhooks) but are not yet at parity with Node — 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. None of the eight has been published to a package registry yet. When they ship, every SDK will share 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).
Pre-launch — no SDK is currently published to a public registry. Until first publish, the Node + Web SDK source lives in the monorepo under packages/sdk-node/ and packages/sdk-web/. Install commands here describe the future registry shapes — not the current reach (every public registry probe today returns 404, Node and Web included). Go, .NET, Java, Python, PHP, and Ruby now wrap 8 core resources in workspace source (see below) but none is full parity. Build against the REST API directly until first publish — 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 those six 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).
Where a table below marks a language GA, that describes the API surface — the methods exist and are implemented in the workspace source. It does not mean the package is installable; see the registry table for publish status.

In active development (workspace source)

Node.js / TypeScript

Source: packages/sdk-node/ — future package name @devotel-orbit/node. Hand-written, fully typed. Node 18+. Status: feature-complete in workspace, NOT published.

Web (browser)

Source: packages/sdk-web/ — future package name @devotel-orbit/web. Embeddable chat widget + inbound APIs. Status: feature-complete in workspace, NOT published.

Core-scope quickstarts (pre-registry)

Python

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

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/ (the module imports as orbit_sdk; no PyPI package is live yet — the registry moves off the retired legacy name before publish) 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, 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, 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.

Future registry coordinates

No public registry entry exists for ANY language today — including Node and Web. Do not attempt to install; the package names below 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, unpublished): 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)

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. Pre-launch, the SDKs are committed source-only; first publish to each registry is an operator action.