Loading...
Loading...
Bi-weekly engineering deep dives on auth, notifications, and developer infrastructure. No spam.
Sign Up for UpdatesPublished by Zyphr
10 min read
Read more
4 min read
Read more
7 min read
Read more
An API is only as good as its SDK. You can have the most powerful platform in the world, but if the SDK is painful to use, developers will either avoid it or build their own wrapper around it. We've done both, and we didn't want anyone to have to do either with Zyphr.
Here's how we designed the Zyphr SDK and the principles we followed.
The worst SDKs are the ones that try to be smart. Methods that return different types depending on the input. Configuration objects with dozens of optional fields. Magic string parameters that change behavior in non-obvious ways.
We optimized for predictability. Every method in the Zyphr SDK follows the same pattern:
const { data } = await zyphr.resource.action(params);
The return type is always { data: T }. Errors always throw. No status codes to check, no nullable returns, no "check the success field." If the call returns, it worked. If it didn't, you get an error with a clear message and an error code.
try {
const { data } = await zyphr.emails.send({ ... });
} catch (error) {
// error.status — HTTP status code
// error.code — Machine-readable error code ('INVALID_TEMPLATE', 'RATE_LIMITED')
// error.message — Human-readable description
}
No surprises.
If you can see it in the dashboard, you can access it through the SDK. The resource hierarchy matches what you see in the UI:
| Dashboard Section | SDK Namespace |
|---|---|
| Emails | zyphr.emails |
| SMS | zyphr.sms |
| Push | zyphr.push |
| In-App | zyphr.inApp |
| Subscribers | zyphr.subscribers |
| Templates | zyphr.templates |
| Topics | zyphr.topics |
| Webhooks | zyphr.webhooks |
| Auth | zyphr.auth |
You shouldn't need to read docs to guess the method name. If you want to send an email, it's zyphr.emails.send(). If you want to list subscribers, it's zyphr.subscribers.list(). If you want to create a template, it's zyphr.templates.create().
Too many SDKs are written in JavaScript and then have types bolted on as an afterthought. The types are loose, the generics are wrong, and your IDE can't help you.
The Zyphr SDK is written in TypeScript from the ground up. Every parameter, every return type, and every error is fully typed. Your editor knows exactly what fields are required, what types they expect, and what you'll get back.
// Your editor autocompletes every field
const { data } = await zyphr.emails.send({
to: 'user@example.com', // string (required)
template: 'welcome', // string (optional — or use subject + html)
variables: { // Record<string, string> (optional)
name: 'Jane',
},
});
// data is fully typed: { message_id: string; status: string }
This extends to error types too. When you catch an error, TypeScript knows the shape of the error object.
The SDK should work with one line of setup:
import Zyphr from '@zyphr-dev/node-sdk';
const zyphr = new Zyphr('your-api-key');
That's it. No region configuration, no environment selection, no feature flags. For the 90% case — a single workspace, production environment — you pass your API key and start making calls.
Advanced configuration exists for teams that need it (custom base URLs, request timeouts, retry policies), but it's opt-in. The defaults are sensible and tested.
We ship SDKs for seven languages:
@zyphr-dev/node-sdkzyphr-pythonzyphr-gozyphr-rubyzyphr/sdkZyphr.Sdkcom.zyphr.sdkEvery SDK follows the same resource hierarchy, the same naming conventions, and the same error handling patterns, adapted to the idioms of each language:
# Python — same structure, Pythonic style
from zyphr import Zyphr
zyphr = Zyphr("your-api-key")
result = zyphr.emails.send(
to="user@example.com",
template="welcome",
variables={"name": "Jane"},
)
// Go — same structure, Go idioms
client := zyphr.New("your-api-key")
result, err := client.Emails.Send(&zyphr.SendEmailParams{
To: "user@example.com",
Template: "welcome",
Variables: map[string]string{"name": "Jane"},
})
If you know one Zyphr SDK, you know all of them.
A good error message doesn't just tell you what went wrong — it tells you how to fix it. Every Zyphr error includes:
ZyphrError: Template 'welcome-v2' not found (TEMPLATE_NOT_FOUND) The template ID you specified does not exist in this workspace. Available templates: welcome, password-reset, verification Docs: https://zyphr.dev/docs/api/send-email#templates
No more Googling cryptic error codes or reading source code to understand what went wrong.
The SDK is good. It's not done. Here's what's on the roadmap:
useInbox(), useUnreadCount(), and other hooks for the in-app inboxWe ship SDK updates weekly and maintain backward compatibility. If you find something that doesn't feel right, tell us.