Go SDK
Sparrow provides generated Go client stubs for both Connect-RPC (recommended) and gRPC. The Go client is part of the main Sparrow module — no separate dependency needed.
Installation
Section titled “Installation”go get github.com/sarathsp06/sparrowgo get connectrpc.com/connectgo get github.com/sarathsp06/sparrowgo get google.golang.org/grpcQuick Start
Section titled “Quick Start”-
Import the packages
import ("connectrpc.com/connect"pb "github.com/sarathsp06/sparrow/proto"pbconnect "github.com/sarathsp06/sparrow/proto/protoconnect")import ("google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"pb "github.com/sarathsp06/sparrow/proto") -
Create a client
Connect-RPC uses standard
net/http— no special transport, no HTTP/2 requirement, works through any proxy.httpClient := http.DefaultClientwebhookClient := pbconnect.NewWebhookServiceClient(httpClient, "http://localhost:8080")eventClient := pbconnect.NewEventServiceClient(httpClient, "http://localhost:8080")conn, err := grpc.NewClient("localhost:50051",grpc.WithTransportCredentials(insecure.NewCredentials()),)if err != nil {log.Fatal(err)}defer conn.Close()webhookClient := pb.NewWebhookServiceClient(conn)eventClient := pb.NewEventServiceClient(conn) -
Register a webhook and push an event
ctx := context.Background()// Register a webhookresp, err := webhookClient.RegisterWebhook(ctx, connect.NewRequest(&pb.RegisterWebhookRequest{Namespace: "default",Url: "https://example.com/webhook",Events: []string{"order.created"},Active: true,}))if err != nil {log.Fatal(err)}log.Printf("Webhook ID: %s", resp.Msg.GetWebhookId())// Push an eventpayload, _ := structpb.NewStruct(map[string]any{"order_id": "ord_456","total": 149.99,})pushResp, err := eventClient.PushEvent(ctx, connect.NewRequest(&pb.PushEventRequest{Namespace: "default",Event: "order.created",Payload: payload,TtlSeconds: 3600,}))if err != nil {log.Fatal(err)}log.Printf("Event ID: %s", pushResp.Msg.GetEventId())ctx := context.Background()// Register a webhookresp, err := webhookClient.RegisterWebhook(ctx, &pb.RegisterWebhookRequest{Namespace: "default",Url: "https://example.com/webhook",Events: []string{"order.created"},Active: true,})if err != nil {log.Fatal(err)}log.Printf("Webhook ID: %s", resp.WebhookId)// Push an eventpayload, _ := structpb.NewStruct(map[string]any{"order_id": "ord_456","total": 149.99,})pushResp, err := eventClient.PushEvent(ctx, &pb.PushEventRequest{Namespace: "default",Event: "order.created",Payload: payload,TtlSeconds: 3600,})if err != nil {log.Fatal(err)}log.Printf("Event ID: %s", pushResp.EventId)
API Key Authentication
Section titled “API Key Authentication”If the Sparrow server has SPARROW_API_KEY set, include the key in requests:
// Create an interceptor that adds the API key headertype apiKeyInterceptor struct { key string}
func (i *apiKeyInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { req.Header().Set("X-API-Key", i.key) return next(ctx, req) }}
func (i *apiKeyInterceptor) WrapStreamingClient(next connect.StreamingClientFunc) connect.StreamingClientFunc { return next // not needed for Sparrow (no streaming RPCs)}
func (i *apiKeyInterceptor) WrapStreamingHandler(next connect.StreamingHandlerFunc) connect.StreamingHandlerFunc { return next}
// Use the interceptor when creating clientsinterceptor := &apiKeyInterceptor{key: "your-api-key"}client := pbconnect.NewWebhookServiceClient( http.DefaultClient, "http://localhost:8080", connect.WithInterceptors(interceptor),)// Per-RPC credentialstype apiKeyCredentials struct { key string}
func (c apiKeyCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { return map[string]string{"x-api-key": c.key}, nil}
func (c apiKeyCredentials) RequireTransportSecurity() bool { return false }
// Use when dialingconn, err := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(apiKeyCredentials{key: "your-api-key"}),)Label Filters
Section titled “Label Filters”Subscriptions can use label filters to receive only matching events:
// Create a subscription that only receives premium plan eventssubResp, err := subscriptionClient.CreateSubscription(ctx, connect.NewRequest(&pb.CreateSubscriptionRequest{ WebhookId: webhookID, EventName: "order.created", Namespace: "default", Active: true, LabelFilters: map[string]string{ "plan": "premium", },}))
// Push an event with labels -- only matching subscriptions trigger deliverypushResp, err := eventClient.PushEvent(ctx, connect.NewRequest(&pb.PushEventRequest{ Namespace: "default", Event: "order.created", Payload: payload, TtlSeconds: 3600, Labels: map[string]string{ "plan": "premium", "region": "us-east-1", },}))TLS Configuration
Section titled “TLS Configuration”Connect-RPC uses standard net/http, so TLS configuration is straightforward:
httpClient := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ // your TLS config }, }, Timeout: 30 * time.Second,}client := pbconnect.NewWebhookServiceClient(httpClient, "https://sparrow.example.com:8080")creds, err := credentials.NewClientTLSFromFile("ca-cert.pem", "")if err != nil { log.Fatal(err)}
conn, err := grpc.NewClient("sparrow.example.com:50051", grpc.WithTransportCredentials(creds),)Available Services
Section titled “Available Services”| Client Constructor | Description |
|---|---|
NewWebhookServiceClient | Register, update, pause/resume webhooks |
NewEventServiceClient | Push events, register event types, re-push |
NewSubscriptionServiceClient | Manage webhook-event subscriptions |
NewDeliveryServiceClient | Query delivery history, retry deliveries |
NewHealthServiceClient | Webhook health metrics and summaries |
Full Example
Section titled “Full Example”See the complete working example in the client README.
Next Steps
Section titled “Next Steps”- API Reference — full RPC documentation
- Template Functions — payload transformation
- Error Classification — delivery error handling