TypeScript SDK
Sparrow provides generated TypeScript client stubs for Connect-RPC. This is the recommended approach for both browser and Node.js applications — no gRPC proxy required, just standard HTTP.
Installation
Section titled “Installation”npm install @bufbuild/protobuf @connectrpc/connect @connectrpc/connect-webpnpm add @bufbuild/protobuf @connectrpc/connect @connectrpc/connect-webyarn add @bufbuild/protobuf @connectrpc/connect @connectrpc/connect-webThen copy the generated stubs into your project:
cp -r client/js/connect/proto/ src/lib/sparrow/Quick Start
Section titled “Quick Start”-
Create a transport and client
import { createClient } from "@connectrpc/connect";import { createConnectTransport } from "@connectrpc/connect-web";import { WebhookService, EventService } from "./lib/sparrow/webhook_pb";const transport = createConnectTransport({baseUrl: "http://localhost:8080",});const webhookClient = createClient(WebhookService, transport);const eventClient = createClient(EventService, transport);import { createClient } from "@connectrpc/connect";import { createConnectTransport } from "@connectrpc/connect/node";import { WebhookService, EventService } from "./lib/sparrow/webhook_pb.js";const transport = createConnectTransport({baseUrl: "http://localhost:8080",httpVersion: "1.1",});const webhookClient = createClient(WebhookService, transport);const eventClient = createClient(EventService, transport);For Node.js, install the Node transport:
Terminal window npm install @connectrpc/connect-node -
Register a webhook and push an event
// Register a webhookconst webhookResp = await webhookClient.registerWebhook({namespace: "default",url: "https://example.com/webhook",events: ["order.created"],active: true,});console.log("Webhook ID:", webhookResp.webhookId);// Push an eventconst pushResp = await eventClient.pushEvent({namespace: "default",event: "order.created",payload: {order_id: "ord_456",total: 149.99,},ttlSeconds: 3600,});console.log("Event ID:", pushResp.eventId);
API Key Authentication
Section titled “API Key Authentication”If the Sparrow server has SPARROW_API_KEY set, add the key via a transport interceptor:
import type { Interceptor } from "@connectrpc/connect";
const apiKeyInterceptor: Interceptor = (next) => async (req) => { req.header.set("X-API-Key", "your-api-key"); return next(req);};
const transport = createConnectTransport({ baseUrl: "http://localhost:8080", interceptors: [apiKeyInterceptor],});Label Filters
Section titled “Label Filters”import { SubscriptionService } from "./lib/sparrow/webhook_pb";
const subscriptionClient = createClient(SubscriptionService, transport);
// Create a subscription that only receives premium eventsawait subscriptionClient.createSubscription({ webhookId: webhookResp.webhookId, eventName: "order.created", namespace: "default", active: true, labelFilters: { plan: "premium", },});
// Push an event with labelsawait eventClient.pushEvent({ namespace: "default", event: "order.created", payload: { order_id: "ord_789", total: 299.99 }, ttlSeconds: 3600, labels: { plan: "premium", region: "us-east-1", },});Checking Deliveries
Section titled “Checking Deliveries”import { DeliveryService } from "./lib/sparrow/webhook_pb";
const deliveryClient = createClient(DeliveryService, transport);
const deliveries = await deliveryClient.listDeliveries({ webhookId: webhookResp.webhookId, namespace: "default", limit: 10,});
for (const d of deliveries.deliveries) { console.log(`Delivery ${d.id}: status=${d.status} attempts=${d.attemptCount}`);}Checking Webhook Health
Section titled “Checking Webhook Health”import { HealthService } from "./lib/sparrow/webhook_pb";
const healthClient = createClient(HealthService, transport);
const health = await healthClient.getWebhookHealth({ webhookId: webhookResp.webhookId, namespace: "default",});console.log(`Health: ${health.healthStatus}, success_rate=${health.successRate}%`);Error Handling
Section titled “Error Handling”Connect-RPC uses standard HTTP error codes mapped to gRPC status codes:
import { ConnectError, Code } from "@connectrpc/connect";
try { await webhookClient.registerWebhook({ namespace: "default", url: "https://example.com/webhook", events: ["order.created"], active: true, });} catch (err) { if (err instanceof ConnectError) { switch (err.code) { case Code.NotFound: console.error("Resource not found"); break; case Code.AlreadyExists: console.error("Already exists"); break; case Code.InvalidArgument: console.error("Invalid input:", err.message); break; default: console.error("RPC error:", err.code, err.message); } }}Available Services
Section titled “Available Services”| Service Descriptor | Description |
|---|---|
WebhookService | Register, update, pause/resume webhooks |
EventService | Push events, register event types, re-push |
SubscriptionService | Manage webhook-event subscriptions |
DeliveryService | Query delivery history, retry deliveries |
HealthService | Webhook health metrics and summaries |
Next Steps
Section titled “Next Steps”- API Reference — full RPC documentation
- Template Functions — payload transformation
- Error Classification — delivery error handling