Skip to main content

How to read a worked sample

Every endpoint guide in these docs ships a worked sample — a request you can copy verbatim, and the exact response envelope the platform returns. This index shows you how to turn a sample into a running call, and where the rest of the worked examples live.

Reading an endpoint’s sample

A worked sample is a complete request: method, path, headers, and body. Nothing in it is a placeholder except your API key — so translating the curl block to your language is mechanical.
  1. Copy the request as written. Base URL is always https://api.orbit.devotel.io/api/v1; substitute a Test key (dv_test_sk_…) for X-API-Key and the sample runs against the sandbox.
  2. Translate it per language. The headers and JSON body carry over unchanged — only the HTTP client differs.
cURL
fetch
The Node SDK collapses the same call to one line — orbit.messages.send({ channel: "sms", to, body }) — and returns the same data the raw response carries. Pick whichever you read faster; the envelope below is identical either way.

Typed SDK tab, or raw fetch — one canonical pattern

Every endpoint page renders the same slice of languages: cURL, Node.js (TypeScript), and for the most-used operations Python, Go, Ruby, and PHP. Which client each tab shows is one decision, made once — here is the whole rule.

Why the non-published-language tabs use raw HTTP

The SDK coverage matrix tells you which SDKs are on a registry today. Only Node and Web (npm) and Python (PyPI) install from a package manager — Go, Ruby, PHP, Java, and .NET live in workspace source, unpublished. A tab for a language whose SDK has no published package renders the raw HTTP call (plain fetch, requests, net/http, curl_exec) against the documented path, so the sample compiles and runs the day you paste it. This is deliberate, not a gap: an import that 404s on a registry is a worse sample than no import at all.

When the Node tab switches to the typed SDK

The Node SDK is feature-complete and published, so the Node tab has a real choice. Use Typed SDK whenever a typed method for the route exists — which today means one of the six core resources: orbit.messages, orbit.contacts, orbit.campaigns, orbit.verify, orbit.voice, and orbit.webhooks (check the coverage matrix before writing). Fall back to raw fetch() only for a route no typed method covers — and when you do, keep the escape-hatch shape (import { Orbit } + constructor, then the raw call) so a reader can move the call inside a typed client later without restructuring auth.
Never mix. Every raw-HTTP block on an endpoint page sets its own X-API-Key header explicitly, and every typed block constructs new Orbit({ apiKey: process.env.ORBIT_API_KEY }). Pick one per block — do not construct the client and then hand-fetch next to it, and do not import the SDK for a raw HTTP call.

Migrating a sample from fetch to the typed SDK

The swap is verbatim — same body, same envelope; only the transport changes. Messaging send, before:
fetch (before)
Typed, after — the client handles the header, JSON body, retries, and the Idempotency-Key on every non-GET:
Node SDK (after)
Same { data, meta } envelope comes back — see the four envelope shapes for what you branch on either way.

The snippet template contributors follow

New samples and doc overlays copy this shape exactly — the readers’ tabs stay uniform:
Snippet template — escape-hatch signature
Two rules hold on every endpoint page: never a raw-HTTP block without an explicit X-API-Key, and never an SDK import on a block that only uses fetch. The SDK index is the source of truth for “is the language published and does the route have a typed method” — if the matrix says no, the tab says raw fetch.

The four envelope shapes

Every response the platform returns is one of four shapes. Recognize the shape at a glance and you know how to read the body:
  1. Success envelope — { data, meta }, HTTP 2xx. The resource (or a resource id) sits under data; meta carries the request correlation id:
  2. Success with pagination — the same { data, meta }, with meta.pagination telling you how to fetch the next page:
  3. 207 Multi-Status batch envelope — bulk endpoints answer 207 on partial success and give you one row per recipient; branch on status per row, never blanket-retry the batch:
    Canonical sample: Bulk sends (207 and all) and the Verify API.
  4. Error envelope — { error, meta } on any non-2xx status. Branch on the stable error.code, never on the human-readable error.message:
    Canonical sample: API error handling by example.

Branching on a 207 in code

Bulk sends — POST /messages/batch, POST /verify/bulk — answer with one result row per recipient. Treat the HTTP status as a summary and handle each row by its own status:
Idempotency on the batch call. POST endpoints that create resources accept an Idempotency-Key header; the SDK mints one per call, raw fetch must set it explicitly. A retry with the same key returns the original envelope — no duplicate sends, no second charge. The full contract lives in Idempotency and safe retries.
Node
Python
The full 207/400/503 response matrix with its handling table: Bulk sends (207 and all).

Where the worked examples live

Samples are spread across the docs deliberately — each sits next to the endpoint it exercises. This page is the index:
  • REST API recipes — sixteen task-by-task worked samples (messaging, voice, campaigns, CDP, webhook round trips), each pairing curl with Node or Python.
  • API recipes: operations endpoints — the operational surfaces as six runnable loops: the Verify second-officer approvals round trip, a cascade policy previewed through route-preview before smart-send arms it, the message-history q= search DSL over the API, the SMPP no-delivery receipt window on a termination rule, the brand-identity trust posture read, and a risk-score pre-send gate.
  • API recipes: contact lifecycle — opt-outs bulk export/re-opt-in round trip, AI segment autopilot through a materialized lookalike audience, per-contact frequency-cap rules behind the send decision, and a day of usage for metering guardrails.
  • Error handling by example — three worked failures with the fix in code.
  • Endpoint worked samples — each endpoint family page carries a curated sample block (messaging, campaigns, voice, and the rest).
  • Starter examples and the Quickstart — five runnable repos and the end-to-end first call, when a single request/response isn’t enough.

Pagination in one paragraph

List endpoints paginate one of two ways, and the response tells you which: most endpoints are cursor-based — read meta.pagination.cursor when has_more is true and pass it back as ?cursor=…; a smaller set of dashboard-oriented families is offset-based — the page metadata (items, total, limit, offset) lives inside the data envelope instead. The shape of the response you’re holding identifies the style.

The cursor loop in code

Node
Python
The full contract — both loops with both styles, per-endpoint caps, and which families are offset-based: Pagination.