SDKs
There's no Sendibl SDK to install. Sendibl's sending API is shape-compatible with Resend's, so the official Resend SDKs work as-is — point them at api.sendibl.com and keep your code.
Point an SDK at Sendibl
Every official Resend SDK except Java supports a base-URL override. Set it to https://api.sendibl.com and use a Sendibl API key (sb_...) as the Resend key:
| Field | Type | Description |
|---|---|---|
| Node | resend | RESEND_BASE_URL env var, or new Resend(key, { baseUrl }). |
| Python | resend | RESEND_API_URL env var (note the different name). |
| PHP | resend/resend-php | RESEND_BASE_URL env var. |
| Go | resend-go | RESEND_BASE_URL env var, or set client.BaseURL after construction. |
| Ruby | resend | RESEND_BASE_URL env var (read at load time). |
| Rust | resend-rs | RESEND_BASE_URL env var, or the client builder's .base_url(). |
| Java | resend-java | The base URL is hardcoded — call the REST API directly with any HTTP client. |
Node
// env: RESEND_API_KEY=sb_... RESEND_BASE_URL=https://api.sendibl.com
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
// or explicitly, no env needed:
const resend2 = new Resend("sb_...", { baseUrl: "https://api.sendibl.com" });
await resend.emails.send({
from: "Acme <hello@acme.com>",
to: ["ada@example.com"],
subject: "Hello",
html: "<p>Sent through Sendibl.</p>",
});Python
# env: RESEND_API_KEY=sb_... RESEND_API_URL=https://api.sendibl.com
import resend
resend.api_key = os.environ["RESEND_API_KEY"]
resend.Emails.send({
"from": "Acme <hello@acme.com>",
"to": ["ada@example.com"],
"subject": "Hello",
"html": "<p>Sent through Sendibl.</p>",
})Go
// env: RESEND_BASE_URL=https://api.sendibl.com
client := resend.NewClient("sb_...")
sent, err := client.Emails.Send(&resend.SendEmailRequest{
From: "Acme <hello@acme.com>",
To: []string{"ada@example.com"},
Subject: "Hello",
Html: "<p>Sent through Sendibl.</p>",
})What works
The full sending surface — everything under the SDKs' emails and batch namespaces. Verified against the official resend npm package:
| Field | Type | Description |
|---|---|---|
| emails.send() | POST /emails | All fields: from, to, cc, bcc, reply_to, subject, html, text, headers, attachments, tags, scheduled_at. |
| emails.send(_, opts) | Idempotency-Key | The SDK's idempotencyKey option maps to the same header Sendibl reads — retries return the original email's id for 24h. |
| emails.get() | GET /emails/:id | Returns the email with status, engagement counts, and its full event history. |
| emails.update() | PATCH /emails/:id | Reschedule a scheduled email by setting a new scheduled_at. |
| emails.cancel() | POST /emails/:id/cancel | Cancel a scheduled email before it sends. |
| batch.send() | POST /emails/batch | Up to 100 emails per call. |
Test the wiring with zero setup: sends to simulator addresses (
delivered@test.sendibl.com and friends) work without a verified domain and never leave the platform.What's different
- Management namespaces are dashboard-only.
domains.*,audiences.*,contacts.*, andbroadcasts.*return401with an API key — manage those in the dashboard. API keys are deliberately scoped to sending. - Webhook verification is not Svix. Resend signs webhooks with Svix headers; Sendibl uses
sendibl-timestampandsendibl-signature(plain HMAC-SHA256). Swap your verification code per the Webhooks guide. Event names match Resend's (email.delivered,email.bounced,email.delivery_delayed, ...). scheduled_attakes ISO 8601 only — natural-language values like"in 1 hour"aren't parsed.- Templates are referenced differently. Sendibl sends accept
template_id+template_datainstead of Resend's React/JSXreactprop. - Simulator addresses live at
@test.sendibl.com, not@resend.dev.
Migrating an existing app?
The Migrate from Resend guide covers the full cutover: domain verification, DNS gotchas, key rotation, and cleanup.