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:

FieldTypeDescription
NoderesendRESEND_BASE_URL env var, or new Resend(key, { baseUrl }).
PythonresendRESEND_API_URL env var (note the different name).
PHPresend/resend-phpRESEND_BASE_URL env var.
Goresend-goRESEND_BASE_URL env var, or set client.BaseURL after construction.
RubyresendRESEND_BASE_URL env var (read at load time).
Rustresend-rsRESEND_BASE_URL env var, or the client builder's .base_url().
Javaresend-javaThe 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:

FieldTypeDescription
emails.send()POST /emailsAll fields: from, to, cc, bcc, reply_to, subject, html, text, headers, attachments, tags, scheduled_at.
emails.send(_, opts)Idempotency-KeyThe SDK's idempotencyKey option maps to the same header Sendibl reads — retries return the original email's id for 24h.
emails.get()GET /emails/:idReturns the email with status, engagement counts, and its full event history.
emails.update()PATCH /emails/:idReschedule a scheduled email by setting a new scheduled_at.
emails.cancel()POST /emails/:id/cancelCancel a scheduled email before it sends.
batch.send()POST /emails/batchUp 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.*, and broadcasts.* return 401 with 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-timestamp and sendibl-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_at takes 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/JSX react prop.
  • 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.