Integration
Send emails from Go (net/http) with Postkit
Send transactional emails from Go services using net/http. Zero dependencies, idiomatic Go.
1. Set your API key
# shell export POSTKIT_API_KEY=pk_live_...
2. Send an email
go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func sendWelcome(w http.ResponseWriter, r *http.Request) {
payload, _ := json.Marshal(map[string]string{
"from": "hello@yourapp.eu",
"to": "user@example.com",
"subject": "Welcome aboard!",
"html": "<h1>Welcome!</h1>",
})
req, _ := http.NewRequest("POST",
"https://api.postkit.eu/v1/emails",
bytes.NewReader(payload),
)
req.Header.Set("Authorization", "Bearer "+os.Getenv("POSTKIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
defer resp.Body.Close()
w.Header().Set("Content-Type", "application/json")
io.Copy(w, resp.Body)
}
func main() {
http.HandleFunc("/send", sendWelcome)
fmt.Println("Listening on :8080")
http.ListenAndServe(":8080", nil)
}3. Handle webhooks
Postkit sends delivery events (sent, delivered, bounced, opened, clicked) via HMAC-SHA256 signed webhooks following the Standard Webhooks specification.
go
func postkitWebhook(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
msgID := r.Header.Get("webhook-id")
timestamp := r.Header.Get("webhook-timestamp")
signature := r.Header.Get("webhook-signature")
secretB64 := strings.TrimPrefix(os.Getenv("POSTKIT_WEBHOOK_SECRET"), "whsec_")
secret, _ := base64.StdEncoding.DecodeString(secretB64)
content := fmt.Sprintf("%s.%s.%s", msgID, timestamp, string(body))
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(content))
expected := base64.StdEncoding.EncodeToString(mac.Sum(nil))
valid := false
for _, sig := range strings.Split(signature, " ") {
val := strings.TrimPrefix(sig, "v1,")
if hmac.Equal([]byte(val), []byte(expected)) {
valid = true
break
}
}
if !valid {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
log.Printf("Postkit event received")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"received":true}`))
}