Skip to content

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.

Terminal window
go get github.com/sarathsp06/sparrow
go get connectrpc.com/connect
  1. Import the packages

    import (
    "connectrpc.com/connect"
    pb "github.com/sarathsp06/sparrow/proto"
    pbconnect "github.com/sarathsp06/sparrow/proto/protoconnect"
    )
  2. Create a client

    Connect-RPC uses standard net/http — no special transport, no HTTP/2 requirement, works through any proxy.

    httpClient := http.DefaultClient
    webhookClient := pbconnect.NewWebhookServiceClient(httpClient, "http://localhost:8080")
    eventClient := pbconnect.NewEventServiceClient(httpClient, "http://localhost:8080")
  3. Register a webhook and push an event

    ctx := context.Background()
    // Register a webhook
    resp, 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 event
    payload, _ := 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())

If the Sparrow server has SPARROW_API_KEY set, include the key in requests:

// Create an interceptor that adds the API key header
type 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 clients
interceptor := &apiKeyInterceptor{key: "your-api-key"}
client := pbconnect.NewWebhookServiceClient(
http.DefaultClient,
"http://localhost:8080",
connect.WithInterceptors(interceptor),
)

Subscriptions can use label filters to receive only matching events:

// Create a subscription that only receives premium plan events
subResp, 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 delivery
pushResp, 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",
},
}))

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")
Client ConstructorDescription
NewWebhookServiceClientRegister, update, pause/resume webhooks
NewEventServiceClientPush events, register event types, re-push
NewSubscriptionServiceClientManage webhook-event subscriptions
NewDeliveryServiceClientQuery delivery history, retry deliveries
NewHealthServiceClientWebhook health metrics and summaries

See the complete working example in the client README.