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-orbit — npm 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 anX-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 throwsOrbitWebhookSignatureError 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)
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.- Node.js
- Python
- Go
Error hierarchy
Every SDK exposes the same error tree:OrbitApiError(base) → catch this to handle any non-2xx API response. Carriescode,statusCode(aliased asstatus),details,docsUrl, andrequestId, plusisRateLimited/isClientError/isServerErrorgetters.OrbitAuthError— 401/403 (bad API key or missing scope).OrbitNotFoundError— 404 (resource doesn’t exist or isn’t visible).OrbitRateLimitError— 429. Check theRetry-Afterheader (also surfaced indetails) 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 acodeof'bad_signature' | 'expired' | 'malformed'. ExtendsError, notOrbitApiError, so a broadcatch (OrbitApiError)block can’t accidentally swallow + retry forgeries.
Operator: publishing checklist
Seetools/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.