Use the core-scope SDK escape hatch
Six Orbit SDKs are core-scope: Python, Go, Ruby, PHP, Java, and .NET. Each wraps the platform’s core resources as typed helpers — messaging (SMS, WhatsApp, email), voice calls, contacts, campaigns, verify (OTP), numbers, and webhooks — and ships one low-levelrequest* method so every REST route stays reachable anyway. This page covers that escape hatch in all six languages: what the typed helpers cover versus what falls to the hatch, one worked call against the same route in each syntax, and where the Node SDK (full parity) becomes the better tool.
The escape method is a first-class client method, not a raw HTTP workaround. It inherits what the typed helpers inherit: the key you initialized with, retry on 429/5xx with exponential backoff, an auto-generated Idempotency-Key on every non-GET, and the shared OrbitError/OrbitApiError tree on failure. The shared contract lives on the SDKs index.
1. What is typed, and what falls to the hatch
Typed helpers cover the core loop. Deeper surfaces — conferences, IVR, recordings and transcripts, dialer, SIP trunks, analytics, audit-log export — fall to the hatch. Check the per-language page for the exact scope list:
A route no SDK page mentions stays reachable regardless — the hatch accepts any path under the
https://api.orbit.devotel.io/api/v1 base URL with any JSON body.
2. Six languages, one call — create a voice conference
POST /api/v1/voice/conferences with the same body (name, participants, from, record, maxParticipants) so you can diff syntax across languages. The route is out of typed scope in all six; the curl form is the reference. The hatch wants a leading-slash path; the conference id lands under data.
- Decoded envelope. Python, Ruby, PHP, and Java return the parsed JSON, so index
["data"]["id"](orconf.dig("data", "id"),$conf['data']['id'],conf.get("data")) holds the resource. Go unmarshalls into anoutstruct you declare; .NET returns aJsonElementwalked withGetProperty. - GET when you poll. Poll status with a plain GET through the same method:
client.request("GET", "/api/v1/voice/conferences/" + id). Non-GETs carry an auto idempotency key; GETs do not need one.
3. Guardrails, and when to upgrade to Node
- Prefer the typed helper when one exists. The hatch type-checks at runtime only; a bad field through the hatch fails at the API with a
422, on a typed call it fails in your test or IDE. Use the hatch only where the scope table says so. - Pin the body against the API reference, not a guess. The hatch is one hop from the raw REST call, so the field names you send are the contract in the API reference. Verify a new body in the sandbox before it touches live data.
- Keep the error shape the same. The hatch raises the same
OrbitErrorsubclasses the helpers do; handle it the same way and do not unwrap a transport exception around it. - Upgrade to Node SDK at the first whole surface. If a feature area lives entirely behind the hatch — conference participants, IVR with DTMF guards, dialer across queues — maintain that surface in Node instead of collecting six hatch snippets. Node is feature-complete and typed at compile time. Stay on the hatch when gaps are occasional one-offs, where a typed surface you do not need is just trade without incentive.
See also
- SDKs index — the scope-by-language table this guide shortens.
- SDK catalog walkthrough — picking a language and reading live status.
- Per-language recipes — the core loop past first send.
- API reference — every route the hatch can address.