Skip to main content

Go Integration

Zyphr doesn't have an official Go SDK yet, but the REST API is easy to use with Go's net/http package.

Setup

No external dependencies required — Go's standard library has everything you need.

package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)

const baseURL = "https://api.zyphr.dev/v1"

// Client wraps Zyphr API calls
type Client struct {
APIKey string
BaseURL string
HTTPClient *http.Client
}

func NewClient(apiKey string) *Client {
return &Client{
APIKey: apiKey,
BaseURL: baseURL,
HTTPClient: &http.Client{},
}
}

func (c *Client) do(method, path string, body any) ([]byte, error) {
var reqBody io.Reader
if body != nil {
data, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("marshal request: %w", err)
}
reqBody = bytes.NewReader(data)
}

req, err := http.NewRequest(method, c.BaseURL+path, reqBody)
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}

req.Header.Set("X-API-Key", c.APIKey)
req.Header.Set("Content-Type", "application/json")

resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, fmt.Errorf("send request: %w", err)
}
defer resp.Body.Close()

respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response: %w", err)
}

if resp.StatusCode >= 400 {
return nil, fmt.Errorf("API error (%d): %s", resp.StatusCode, string(respBody))
}

return respBody, nil
}

Send an Email

func main() {
client := NewClient(os.Getenv("ZYPHR_API_KEY"))

resp, err := client.do("POST", "/emails", map[string]any{
"to": "user@example.com",
"subject": "Welcome!",
"html": "<h1>Hello from Go!</h1>",
})
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}

var result map[string]any
json.Unmarshal(resp, &result)
fmt.Printf("Email sent: %v\n", result["data"])
}

Send with a Template

resp, err := client.do("POST", "/emails", map[string]any{
"to": "user@example.com",
"template_id": "welcome-email",
"template_data": map[string]any{
"name": "John",
"action_url": "https://yourapp.com/activate",
},
})

Send a Push Notification

resp, err := client.do("POST", "/push", map[string]any{
"user_id": "user_123",
"title": "New Message",
"body": "You have a new message",
"data": map[string]any{
"message_id": "msg_456",
},
})

Send an SMS

resp, err := client.do("POST", "/sms", map[string]any{
"to": "+14155551234",
"body": "Your verification code is 123456",
})

Send an In-App Notification

resp, err := client.do("POST", "/inbox", map[string]any{
"subscriber_id": "user_123",
"title": "New Comment",
"body": "John commented on your post",
"action_url": "/posts/123#comments",
"category": "comments",
})

Create a Subscriber

resp, err := client.do("POST", "/subscribers", map[string]any{
"external_id": "user_123",
"email": "user@example.com",
"phone": "+14155551234",
"name": "John Doe",
"metadata": map[string]any{
"plan": "pro",
},
})

List with Pagination

resp, err := client.do("GET", "/emails?page=1&per_page=25&status=delivered", nil)
if err != nil {
log.Fatal(err)
}

var result struct {
Data []map[string]any `json:"data"`
Meta struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
} `json:"meta"`
}
json.Unmarshal(resp, &result)

fmt.Printf("Page %d of %d (total: %d)\n", result.Meta.Page, result.Meta.TotalPages, result.Meta.Total)

Error Handling

resp, err := client.do("POST", "/emails", map[string]any{
"to": "invalid-email",
"subject": "Test",
"html": "<p>Hi</p>",
})
if err != nil {
// err contains the status code and response body
fmt.Fprintf(os.Stderr, "Failed: %v\n", err)
return
}

For more granular error handling, parse the error response:

type APIError struct {
Error struct {
Code string `json:"code"`
Message string `json:"message"`
Details any `json:"details"`
} `json:"error"`
}

// In your error handling:
var apiErr APIError
if err := json.Unmarshal([]byte(err.Error()), &apiErr); err == nil {
switch apiErr.Error.Code {
case "rate_limited":
// Back off and retry
case "validation_error":
// Fix request parameters
case "unauthorized":
// Check API key
}
}

Requirements

  • Go 1.21 or later