pgns

Webhook relay SDK and CLI integration for pgns

pgns — Webhook Relay SDK & CLI

You are helping a developer work with pgns, a webhook relay platform. pgns captures incoming webhooks ("pigeons"), routes them to destinations (URLs, Slack, Discord, email), and provides real-time streaming, replay, and delivery tracking.

Core Concepts

ConceptDescription
RoostA webhook endpoint that receives incoming HTTP requests. Each roost has a unique inbound URL (/r/{roost_id}) and an optional signing secret.
PigeonA captured webhook request — stores method, headers, body, query params, and delivery status.
DestinationA target for delivering pigeons. Types: url, slack, discord, email. Supports filter expressions, templates, and configurable retry (max attempts, delay, backoff multiplier).
Delivery AttemptA record of delivering a pigeon to a destination — tracks status, HTTP response, errors, and retry schedule.
API KeyServer-side authentication token (prefix pk_live_...). Use for backend integrations.
TemplateA transformation template applied to pigeon bodies before delivery. Supports preview with real pigeon data.

Authentication

pgns supports two auth modes:

  1. API Key (server-side) — Pass pk_live_... as a Bearer token. Best for backend services, CI/CD, scripts.
  2. JWT (browser/user sessions) — Access token with automatic refresh on 401. Best for frontend apps.

All SDKs accept both modes and handle token refresh transparently.

Quick Start by Language

JavaScript/TypeScript

import { PigeonsClient } from '@pgns/sdk';

const client = new PigeonsClient({
  baseUrl: 'https://api.pgns.io',
  apiKey: 'pk_live_...',
});

// List roosts
const roosts = await client.listRoosts();

// Create a destination
const dest = await client.createDestination(roost.id, {
  destination_type: 'url',
  config: { url: 'https://example.com/webhook' },
});

// Stream events in real-time
import { createEventSource } from '@pgns/sdk';

await createEventSource('https://api.pgns.io', {
  token: 'pk_live_...',
  roostId: roost.id,
  onEvent: (data) => console.log('Pigeon:', JSON.parse(data)),
  onError: (err) => console.error(err),
  signal: AbortSignal.timeout(60000),
});

For complete JS/TS API reference, see references/sdk-js.md.

Python

from pgns.sdk import PigeonsClient, event_stream

client = PigeonsClient("https://api.pgns.io", api_key="pk_live_...")

# List roosts
roosts = client.list_roosts()

# Create a destination
dest = client.create_destination(roost.id, CreateDestination(
    destination_type=DestinationType.url,
    config={"url": "https://example.com/webhook"},
))

# Stream events
for event in event_stream("https://api.pgns.io", token="pk_live_..."):
    print("Pigeon:", event)

For async support (AsyncPigeonsClient, async_event_stream) and complete API reference, see references/sdk-python.md.

Go

import sdk "github.com/pgns-io/sdk-go"

client := sdk.NewClient("https://api.pgns.io", sdk.WithAPIKey("pk_live_..."))

// List roosts
roosts, err := client.ListRoosts(ctx)

// Create a destination
dest, err := client.CreateDestination(ctx, roost.ID, sdk.CreateDestination{
    DestinationType: "url",
    Config:          map[string]any{"url": "https://example.com/webhook"},
})

// Stream events
err = client.ListenEvents(ctx, func(data string) {
    fmt.Println("Pigeon:", data)
}, sdk.WithRoostID(roost.ID))

For complete Go API reference, see references/sdk-go.md.

CLI

# Authenticate
pgns auth login

# List roosts
pgns roost list

# Forward webhooks to localhost
pgns listen my-roost --port 3000

# Watch incoming pigeons in real-time
pgns watch my-roost

# Replay a pigeon
pgns replay pgn_abc123

For complete CLI reference, see references/cli.md.

Common Patterns

Error Handling

All SDKs throw/return typed errors with HTTP status and machine-readable error codes:

  • JS: PigeonsError with .status and .code properties
  • Python: PigeonsError with .status and .code attributes, plus .is_not_found() / .is_unauthorized() helpers
  • Go: *PigeonsError with .StatusCode and .Code fields, plus sdk.IsNotFound(err) / sdk.IsUnauthorized(err) helpers

Pagination

List endpoints that return many items use cursor-based pagination:

{ data: [...], next_cursor: "...", has_more: true }

Pass cursor and limit to page through results. Applies to listPigeons and getPigeonDeliveries.

Webhook Delivery Flow

  1. HTTP request hits roost inbound URL → pigeon created
  2. Each active destination receives the pigeon
  3. Failed deliveries retry with exponential backoff (configurable per destination)
  4. Use replayPigeon to re-trigger delivery for debugging

Reference Navigation

When the user is working with a specific SDK or the CLI, load the appropriate reference file for detailed API docs:

ContextReference File
JavaScript / TypeScript / Node.jsreferences/sdk-js.md
Python / FastAPI / Django / Flaskreferences/sdk-python.md
Go / Golangreferences/sdk-go.md
CLI / terminal / command linereferences/cli.md