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