SDKs oficiais
Bibliotecas TypeScript e Python geradas a partir da mesma spec OpenAPI da API externa.
Em vez de montar as chamadas HTTP na mão, você pode usar os SDKs oficiais. Eles são gerados a partir da mesma spec OpenAPI que documenta esta referência — então nunca divergem do contrato — com uma camada ergonômica escrita à mão por cima.
TypeScript / Node
npm i @orbitsender/sdk — tipado, ESM, Node 18+.
Python
pip install orbitsender-sdk — type hints inclusos.
Precisa de uma chave
Os dois usam a mesma chave sk_live_... da API externa. Veja
Autenticação.
O que eles resolvem por você
Quatro coisas que dão trabalho de acertar na mão:
1. Erros tipados — em vez de checar res.error string por string, você trata por tipo
e recebe os campos já estruturados (retryAfter, current/max, requiredScope).
2. Saber quando a campanha terminou de verdade — webhook não é fonte da verdade (o
evento de progresso pode nem disparar). Os waiters fazem polling do agregado groups e
resolvem quando a campanha realmente chega a um estado final.
3. Retry seguro — GET/PUT/PATCH/DELETE re-tentam honrando o Retry-After.
POST de disparo nunca re-tenta: sem Idempotency-Key, um retry duplicaria a campanha.
4. Webhook verificado sem HMAC na mão — a verificação de assinatura e o anti-replay já vêm prontos.
TypeScript
npm i @orbitsender/sdkimport { createOrbitSender } from '@orbitsender/sdk';
const os = createOrbitSender({ apiKey: 'sk_live_...' });
const c = await os.campaigns.sendMessage({
body: { name: 'Promo de sexta', id_segment: 'segment_abc', message: 'Olá!' },
});
const done = await os.campaigns.waitUntilSent(c.id_campaign!, {
onProgress: (g) => console.log(`${g.sent}/${g.total}`),
});Erros tipados
import { RateLimitError, PlanLimitError, ForbiddenScopeError } from '@orbitsender/sdk';
try {
await os.campaigns.sendMessage({ body: { name, id_segment, message } });
} catch (e) {
if (e instanceof RateLimitError) await sleep(e.retryAfter * 1000);
if (e instanceof PlanLimitError) console.log(`Plano no limite: ${e.current}/${e.max}`);
if (e instanceof ForbiddenScopeError) console.log(`Falta o scope: ${e.requiredScope}`);
}Webhooks
import { constructEvent } from '@orbitsender/sdk';
// Express: use express.raw({ type: 'application/json' }) e passe o RAW body —
// o corpo já parseado quebra a assinatura.
const event = constructEvent(rawBody, req.headers, signingSecret);Há adaptadores prontos: expressWebhook e verifyWebRequest (para runtimes que usam a
API Request do padrão web).
Recursos disponíveis
channels · segments · campaigns · settings · webhooks · integrations · partner
Python
pip install orbitsender-sdkfrom orbitsender_sdk import create_orbit_sender, RateLimitError
os_ = create_orbit_sender(api_key="sk_live_...")
c = os_.campaigns.send_message(
{"name": "Promo de sexta", "id_segment": "segment_abc", "message": "Olá!"}
)
done = os_.campaigns.wait_until_sent(c.id_campaign)Os erros são os mesmos, em snake_case: RateLimitError (.retry_after),
PlanLimitError (.current / .max), ForbiddenScopeError, OAuthError.
from orbitsender_sdk.webhooks import construct_event
event = construct_event(raw_body, headers, signing_secret)Correlação de chamadas
Cada requisição leva um x-request-id próprio, que o backend ecoa na resposta e registra
no log — é o que o suporte pede para localizar a sua chamada. Guarde-o:
const os = createOrbitSender({ apiKey, onRequestId: (id) => log.debug({ id }) });os_ = create_orbit_sender(api_key="sk_live_...", on_request_id=meu_log.append)Nas exceções ele também vem pronto: e.requestId (TS) / e.request_id (Python).
Modo de teste
createOrbitSender({ apiKey, sandbox: true })Aponta para um mock local (Prism) em vez da API real — útil para desenvolver sem consumir
cota nem disparar mensagem de verdade. Chaves sk_test_ também são respondidas em modo
sandbox pela própria API.
Prefere sem SDK?
Nada aqui é obrigatório: a referência da API
documenta cada endpoint, e a spec OpenAPI fica em
/openapi.yaml — dá para gerar um cliente na
linguagem que você quiser.