Quickstart
This guide will walk you through sending your first notification with Zyphr in under 5 minutes.
Prerequisites
- A Zyphr account (Sign up free)
- An API key (created in the Dashboard)
Skip the SDK install and code snippets — drop the Zyphr MCP Server into Claude Code, Cursor, Cline, or any MCP-compatible client. Once it's connected, ask the AI "add Zyphr email to this project" and it will wire up the install, the client, the route, and even the webhook signature verification for you.
Step 1: Create an Account
- Go to app.zyphr.dev/signup
- Create your account with email/password or OAuth
- An account and a Default project are created automatically — you are ready to go
Your account is your organization — it owns billing, team members, and projects. A project is an isolated environment with its own API keys, domains, subscribers, and messages. You can create additional projects later (e.g., Production, Staging, Development). See Accounts & Projects for details.
Step 2: Get Your API Key
All resources — including API keys — are created within your current project. Make sure you are in the correct project before proceeding (use the project switcher in the header).
- Navigate to Settings > API Keys in the dashboard
- Click Create API Key
- Give it a name (e.g., "Development")
- Copy your API key — you will only see it once!
Use zy_test_* prefixed keys during development. Test mode messages are stored but never delivered to actual recipients.
Step 3: Send Your First Email
- cURL
- Node.js
- Python
- Go
- PHP
- Ruby
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_test_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "test@example.com",
"subject": "Hello from Zyphr!",
"html": "<h1>It works!</h1><p>You just sent your first email with Zyphr.</p>"
}'
import { Configuration, EmailsApi } from '@zyphr-dev/node-sdk';
const config = new Configuration({ apiKey: 'zy_test_your_api_key' });
const emails = new EmailsApi(config);
const result = await emails.sendEmail({
sendEmailRequest: {
to: 'test@example.com',
subject: 'Hello from Zyphr!',
html: '<h1>It works!</h1><p>You just sent your first email with Zyphr.</p>',
},
});
console.log(`Email sent: ${result.id}`);
import requests
response = requests.post(
"https://api.zyphr.dev/v1/emails",
headers={
"X-API-Key": "zy_test_your_api_key",
"Content-Type": "application/json",
},
json={
"to": "test@example.com",
"subject": "Hello from Zyphr!",
"html": "<h1>It works!</h1><p>You just sent your first email with Zyphr.</p>",
},
)
data = response.json()
print(f"Email sent: {data['data']['id']}")
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]string{
"to": "test@example.com",
"subject": "Hello from Zyphr!",
"html": "<h1>It works!</h1><p>You just sent your first email with Zyphr.</p>",
})
req, _ := http.NewRequest("POST", "https://api.zyphr.dev/v1/emails", bytes.NewBuffer(body))
req.Header.Set("X-API-Key", "zy_test_your_api_key")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Printf("Status: %d\n", resp.StatusCode)
}
<?php
$ch = curl_init('https://api.zyphr.dev/v1/emails');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: zy_test_your_api_key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'to' => 'test@example.com',
'subject' => 'Hello from Zyphr!',
'html' => '<h1>It works!</h1><p>You just sent your first email with Zyphr.</p>',
]),
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
echo "Email sent: " . $data['data']['id'] . "\n";
curl_close($ch);
require 'net/http'
require 'json'
require 'uri'
uri = URI('https://api.zyphr.dev/v1/emails')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'zy_test_your_api_key'
request['Content-Type'] = 'application/json'
request.body = {
to: 'test@example.com',
subject: 'Hello from Zyphr!',
html: '<h1>It works!</h1><p>You just sent your first email with Zyphr.</p>'
}.to_json
response = http.request(request)
data = JSON.parse(response.body)
puts "Email sent: #{data['data']['id']}"
Response:
{
"data": {
"id": "msg_abc123",
"to": "test@example.com",
"subject": "Hello from Zyphr!",
"status": "queued",
"is_test": true,
"created_at": "2024-01-15T10:30:00Z"
},
"meta": {
"request_id": "req_xyz789"
}
}
Step 4: Verify Domain (for Production)
Before sending production emails, you need to verify your domain:
- Go to Settings → Domains
- Click Add Domain
- Enter your domain (e.g.,
notifications.yourapp.com) - Add the DNS records shown to your DNS provider
- Click Verify once records are propagated
Step 5: Go Live
Once your domain is verified, swap your test key for a live key:
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "real-user@example.com",
"from": "hello@notifications.yourapp.com",
"subject": "Welcome!",
"html": "<h1>Welcome to our app!</h1>"
}'