A REST API that does not lie about its semantics.
Every SabNode object — contact, conversation, flow, broadcast, order, file — is reachable through a typed REST surface. OpenAPI 3.1, real HTTP status codes, idempotency keys on every POST, cursor pagination and zero-downtime versioning. SDKs for JavaScript, Python and Go are generated from the same spec.
- OpenAPI 3.1 spec, always current
- Idempotency-Key header on every POST
- Cursor pagination, opaque tokens
- SDKs for JS, Python, Go
Most CRM APIs are toys in production
You have integrated five CRMs by now. One returned 200 for failed writes. Another paginated by integer offset and silently dropped rows when a contact was added mid-scan. A third had a "create or update" endpoint that swallowed validation errors. By the time you hit production scale, you have built a wrapper library, a retry queue and a deduplication layer just to make the official SDK usable.
The second pain is versioning. You shipped against v2, the vendor pushed v3 with a breaking change, and v2 is in a year-long sunset that nobody bothers to honor. Your integration breaks during a Black Friday window because someone at the vendor decided to "improve" the response shape.
The third pain is observability. You sent 12,000 webhook deliveries last night, the partner is complaining that "events are missing", and the vendor dashboard shows you nothing useful — no per-delivery status, no replay tool, no signing secret rotation. SabNode's REST API and webhook system were designed by engineers who lived inside those failure modes.
REST API, in depth.
The SabNode REST API is documented by a single OpenAPI 3.1 spec that drives every SDK, the in-app reference and our internal validation. Every endpoint uses real HTTP semantics: 200 for success, 201 for created, 204 for empty success, 400 for input errors, 401 for missing auth, 403 for scope errors, 404 for not found, 409 for idempotency conflicts, 422 for business-rule failures and 429 for rate limiting. There are no 200-with-error-in-body responses anywhere in the surface.
POST requests accept an Idempotency-Key header (UUID v4). A repeated call with the same key replays the original response — even hours later — so a retried network call from your worker never accidentally creates a second contact or a duplicate broadcast. List endpoints use opaque cursor pagination: the cursor encodes the sort key and the position, so adding or deleting rows mid-scan never drops or duplicates results.
SDKs for JavaScript (TypeScript-first), Python (mypy-typed) and Go are generated from the same OpenAPI spec on every release. The generated clients ship retry logic with exponential backoff, jitter, and Retry-After honoring, plus a structured error type per status. You install the SDK with one command, paste your scoped token, and call typed methods with full IDE autocomplete.
Versioning follows a date-header model: every request carries an Api-Version header. Adding fields is non-breaking, removing or renaming requires a new version that is supported for at least 24 months. Sunset announcements are written into the response headers so your dashboards can alert you long before the cutoff.
Everything you get with REST API.
OpenAPI 3.1 spec
A machine-readable OpenAPI 3.1 spec drives the docs, the SDKs and our request validator. Import it into Postman or generate your own client if your stack is not in our official trio.
Idempotency keys
Every POST accepts Idempotency-Key. A 24-hour cache replays the original response on retry. Conflicting payloads under the same key return 409 with a structured diff explaining what changed.
Cursor pagination
List endpoints return an opaque next_cursor in the response and accept it as a query parameter. Cursors encode the sort key, the position and a tenant-id check, so they are stable under writes.
Predictable rate limits
Limits are per-token and per-endpoint family. Every response includes X-RateLimit-Remaining and X-RateLimit-Reset. 429 responses include Retry-After in seconds, and the SDKs honor it automatically.
Typed SDKs
JavaScript / TypeScript, Python and Go clients are generated from the spec. They expose typed methods, structured error classes per status, automatic retries and an SSE helper for streaming endpoints.
Versioning by header
Api-Version header pins your integration to a release. Additive changes are silent, breaking changes ship a new version supported 24+ months. Sunset notices land in response headers months in advance.
Bulk endpoints
Contacts, messages and tag operations have bulk variants accepting up to 1,000 items per call. Bulk endpoints return per-item status so partial failures are observable, not silent.
Built for the way teams actually work.
Sync from data warehouse
A B2B SaaS pushes daily contact updates from Snowflake into SabNode via the bulk upsert endpoint. Idempotency keys derived from a hash of (warehouse_row_id, day) make the job rerunnable without dedup logic.
Custom mobile app
A D2C brand's mobile app uses the REST API to fetch the user's order timeline, fire support tickets and trigger WhatsApp opt-in confirmations — without re-implementing any of the SabNode primitives.
Outbound enrichment
A fintech enriches new leads with PAN and address verification through their own internal API, then writes the verified fields back to the SabNode contact via PATCH. Webhook on update fires the next flow.
BI dashboard pipeline
A merchant pipes orders, messages and broadcast events from SabNode into BigQuery via a Cloud Run job that uses the cursor-paginated list endpoints. The job is rerunnable thanks to stable cursors.
Ops automation script
A logistics team runs a nightly Python script that finds contacts with a stuck shipment and patches a tag for the broadcast team. The script uses the typed Python SDK and runs in under 30 seconds for 50k contacts.
From signup to first send in minutes.
REST API is included on every SabNode workspace. No separate billing, no extra setup — flip it on from your workspace settings.
- 01
Mint a token
Create a scoped API key in Settings → Developer. Choose scopes (contacts:read, messages:write, etc) and an optional IP allowlist.
- 02
Install the SDK
npm i @sabnode/sdk, pip install sabnode, or go get github.com/sabnode/sabnode-go. All three are generated from the same spec.
- 03
Make a typed call
Instantiate the client with your token and Api-Version. Call sdk.contacts.create({ phone, name }) and get a typed Contact back.
- 04
Handle errors
Catch typed errors per status: ValidationError, RateLimitError, ConflictError. The SDK auto-retries on 429 and 5xx with backoff.
- 05
Listen on webhooks
Subscribe to events. Verify the HMAC signature, ack within 5 seconds, and the rest of your worker is yours to write.
Works with the tools you already ship on.
Connect directly with your existing stack, or use the platform APIs and webhooks to extend it natively.
- OpenAPI 3.1
- Postman
- Vercel
- AWS Lambda
- GitHub Actions
- Snowflake
- BigQuery
- Cloud Run
Platform core tools
Enhance this feature with deep integrations into our core infrastructure. Connect via API, use webhooks, or embed directly with our SDKs.
Unified dashboard apps
Manage every setting inside one workspace UI.
Developer APIs and webhooks
Extend functionality with custom automated workflows.
How do I retry safely without creating duplicates?
How are rate limits structured?
Will my integration break if you ship v3?
Can I use the API from the browser?
How is pagination stable?
What about webhooks vs polling?
Is the API GDPR and DPDP compliant?
Stronger when stacked.
Ship rest api into production this week.
No credit card. No sales call required. Spin up a workspace, plug in a number, and your team is live in under an hour.