webhook.co has been wound down. The hosted service is shut down and this module is deprecated and archived. If you are interested in acquiring any of the assets, including the domain, contact [email protected].
The official Go SDK for the webhook.co API. A typed client with the hardening you'd otherwise hand-roll: bearer auth, bounded retries with jitter, cursor pagination, idempotency, and secret redaction. Zero dependencies — standard library only.
go get github.com/webhook-co/webhook-gopackage main
import (
"context"
"fmt"
"log"
"os"
webhook "github.com/webhook-co/webhook-go"
)
func main() {
client, err := webhook.NewClient(os.Getenv("WEBHOOK_API_KEY"))
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Create an endpoint. The ingest URL is a credential, but it is NOT one-time.
ep, err := client.Endpoints.Create(ctx, webhook.EndpointsCreateParams{Name: "orders-prod"})
if err != nil {
log.Fatal(err)
}
// Lost it? Read it back — the token is sealed at rest, so there is nothing to lose and no need to
// rotate (rotating would revoke the live URL and break every sender still posting to it).
revealed, err := client.Endpoints.RevealIngestURL(ctx, ep.ID)
if err != nil {
log.Fatal(err)
}
fmt.Println(ep.IngestURL, *revealed.IngestURL) // the same URL — it was never lost
// List events for that endpoint (auto-paginates). Omit EndpointID to list the whole org.
it := client.Events.List(&webhook.EventsListParams{EndpointID: &ep.ID})
for it.Next(ctx) {
e := it.Value()
fmt.Println(e.ID, e.Verified)
}
if err := it.Err(); err != nil {
log.Fatal(err)
}
}The API key is a whk_-prefixed token from your dashboard. Keep it server-side — this SDK never prints
it, but it's still a credential.
List methods return an *Iterator[T] (a Scanner-style iterator) that follows the cursor for you:
it := client.Deliveries.List(&webhook.DeliveriesListParams{Status: []string{"failed"}})
for it.Next(ctx) {
d := it.Value()
// ...
}
if err := it.Err(); err != nil { /* ... */ }
// Collect everything (careful with large result sets):
all, err := client.Endpoints.List(nil).All(ctx)
// One page at a time (e.g. to build your own UI):
items, nextCursor, err := client.Endpoints.ListPage(ctx, &webhook.EndpointsListParams{Limit: webhook.Ptr(50)})Every API failure is an *webhook.Error (extract it with errors.As, or use the Is* helpers):
_, err := client.Endpoints.Get(ctx, id)
switch {
case webhook.IsNotFound(err):
// 404 — no such endpoint
case webhook.IsRateLimited(err):
var e *webhook.Error
errors.As(err, &e)
fmt.Println("retry after", e.RetryAfter)
case webhook.IsUnauthorized(err):
// 401 — the key is invalid, expired, or revoked
case err != nil:
log.Fatal(err)
}*Error carries Code (a stable capability-error string, or "" for an unexpected response), Status,
RequestID, and RetryAfter. A transport failure is a *webhook.ConnectionError; bad options are a
*webhook.ConfigError.
The client retries idempotent requests on transient failures (429/502/503/504 and network errors) with
capped exponential backoff and jitter, honouring Retry-After. It never blind-retries a
non-idempotent write — creating an endpoint, rotating a secret, or an un-keyed replay won't be sent twice
by the SDK. Replays carry an idempotency key (auto-generated if you pass ""), so those are safe:
_, err := client.Events.Replay(ctx, eventID,
webhook.ReplayTarget{Kind: "destination", DestinationID: destID}, "")Options are passed to NewClient:
client, err := webhook.NewClient(apiKey,
webhook.WithBaseURL("https://api.webhook.co"), // must be https (loopback http allowed for dev)
webhook.WithMaxRetries(4), // default 2
webhook.WithTimeout(15*time.Second), // default 30s
webhook.WithHTTPClient(myClient), // custom transport/proxy (redirect-following is disabled)
webhook.WithRefreshAuth(refresh), // rotate the bearer on a 401 (OAuth flows)
webhook.WithDebug(logLine), // redacted, single-line diagnostics — never the raw key
)Every method takes a context.Context for cancellation/deadlines.
Endpoints (List · ListPage · Get · Create · Delete · Rotate · ProviderSecrets Add/List/Revoke) ·
Events (List · ListPage · Get · GetPayload · Tail · Replay) · Deliveries (List · ListPage · Get) ·
ReplayDestinations (Create · List · Delete · Enable · SetOrdered · RotateSigningSecret ·
ListSigningSecrets) · Subscriptions (Create · List · Delete) · Audit.Verify · Whoami.
Apache-2.0