← Blog·Jul 23, 2026productsdks
Introducing: Python and Go SDKs
Two new official SDKs for eusend — idiomatic, zero-dependency, and shaped so a migration from Resend is mostly a find-and-replace.

Until this week, using eusend from anything other than Node.js meant talking to the HTTP API directly. That's not a hardship — it's a handful of JSON endpoints and a bearer token — but "roll your own client" is friction we'd rather absorb ourselves. So today we're shipping two official SDKs:
- Python —
pip install eusend - Go —
go get github.com/eusend-dev/eusend-go
Both are out now, alongside the existing Node.js / TypeScript SDK.
The shape will feel familiar
A lot of teams reach for eusend because they already have a Resend integration and want the same ergonomics without their email data leaving the EU. So we deliberately mirrored the shape of Resend's own libraries: resend-python and resend-go.
In practice, migrating is mostly a resend → eusend rename. Here's a send in Python:
import eusend
eusend.api_key = 'eu_live_...' # or set EUSEND_API_KEY
email = eusend.Emails.send({
'from': '[email protected]',
'to': '[email protected]',
'subject': 'Your order is confirmed',
'html': '<p>Thanks for your order!</p>',
})
print(email['id']) # 9a8b7c6d-...
And the same thing in Go:
import eusend "github.com/eusend-dev/eusend-go"
client := eusend.NewClient("eu_live_...") // or NewClient("") to read EUSEND_API_KEY
sent, err := client.Emails.Send(&eusend.SendEmailRequest{
From: "[email protected]",
To: []string{"[email protected]"},
Subject: "Your order is confirmed",
Html: "<p>Thanks for your order!</p>",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(sent.Id) // 9a8b7c6d-...
Everything the API can do, the SDKs can do: batch sends, scheduled sends ("in 1 hour" works, parsed server-side), idempotency keys, domains, templates, audiences and contacts, broadcasts, and webhooks — including a helper pattern for verifying the HMAC-SHA256 signature on every delivery.
Zero dependencies, on purpose
Neither SDK pulls in a third-party HTTP stack. The Python client is built on the standard library and ships py.typed, so your type checker sees it (Python 3.8+). The Go client is standard-library-only, context.Context-aware, and safe for concurrent use (Go 1.21+).
That's a deliberate choice, and it's the same instinct behind the rest of eusend. We don't want to widen your dependency tree — or your supply-chain surface — just so you can send an email. Fewer moving parts is a security property, not only a convenience.
Every Go method has a WithContext variant for deadlines and cancellation:
sent, err := client.Emails.SendWithContext(ctx, params)
And errors are typed rather than stringly-guessed. In Python you branch on the exception:
from eusend import EusendError, RateLimitError
try:
eusend.Emails.send({...})
except RateLimitError as e:
print(e.code) # 'MONTHLY_LIMIT_EXCEEDED'
print(e.status_code) # 429
except EusendError as e:
print(e.code, e.message, e.status_code)
In Go, every call returns (result, error) and API failures come back as *eusend.Error with a Code, Message, StatusCode, and — on a 429 — the rate-limit headers already parsed out for you.
What this doesn't change
The SDKs are a nicer front door to the same house. Behind them, nothing about where your data lives has moved: the request still hits our API in Germany, a worker still renders and DKIM-signs the message, and our own MTA still delivers it from European hardware. No third-party relay sees the mail. A client library was never going to be the place we compromised on that — but it's worth saying out loud, because the point of a good SDK is that you stop thinking about the transport at all.
Get started
The full reference for each lives in the docs:
We're still in invite-only beta, onboarding from the waitlist. If you build in Python or Go and you'd rather your email stayed in Europe, these are for you — come say Hei.