Skip to content

API Reference

Complete method reference for the TypeScript SDK. Endpoints, requests, streaming, matchers, and error handling with code examples.

Updated Mar 2026

Constructor

import { WebhooksCC } from "@webhooks-cc/sdk";
 
const client = new WebhooksCC({
  apiKey: string,        // Required. Your API key.
  baseUrl?: string,      // Optional. Override API base URL.
  webhookUrl?: string,   // Optional. Override webhook receiver URL.
  timeout?: number,      // Optional. Request timeout in ms (default: 30000).
  retry?: RetryOptions,  // Optional. Automatic retry configuration.
  hooks?: ClientHooks,   // Optional. Lifecycle hooks for observability.
});

Endpoints

POST/endpoints

client.endpoints.create

Create a new webhook endpoint. The slug is auto-generated.

create(options?: CreateEndpointOptions): Promise<Endpoint>
ParamTypeRequiredDescription
namestringnoDisplay name
ephemeralbooleannoAuto-delete after TTL
expiresInstringnoCustom expiry duration
mockResponseMockResponsenoMock response config
notificationUrlstringnoURL to POST a JSON summary on each request

MockResponse fields:

FieldTypeRequiredDescription
statusnumberyesHTTP status code (100-599)
bodystringnoResponse body
headersRecord<string, string>noResponse headers
delaynumbernoResponse delay in ms (0-30000)
GET/endpoints

client.endpoints.list

List all endpoints for your account.

list(): Promise<Endpoint[]>
GET/endpoints/:slug

client.endpoints.get

Get a single endpoint by slug.

get(slug: string): Promise<Endpoint>
PATCH/endpoints/:slug

client.endpoints.update

Update an endpoint's name or mock response configuration.

update(slug: string, options: UpdateEndpointOptions): Promise<Endpoint>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
namestringnoNew display name
mockResponseMockResponse | nullnoMock response config (see fields above), or null to clear
notificationUrlstring | nullnoNotification webhook URL, or null to clear
DELETE/endpoints/:slug

client.endpoints.delete

Delete an endpoint and all its captured requests.

delete(slug: string): Promise<void>
POST/w/:slug

client.endpoints.send

Send a test webhook to an endpoint. Sends directly to the receiver, does not go through the API.

send(slug: string, options?: SendOptions): Promise<Response>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
methodstringnoHTTP method (default: "POST")
headersRecord<string, string>noHTTP headers to include
bodyunknownnoRequest body (JSON-serialized)
POST/w/:slug

client.endpoints.sendTemplate

Send a provider template webhook with generated signature headers.

sendTemplate(slug: string, options: SendTemplateOptions): Promise<Response>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
providerTemplateProvideryesProvider template to generate
templatestringnoProvider-specific template preset
secretstringyesShared secret for signature generation
eventstringnoProvider event/topic override
methodstringnoHTTP method override (defaults to POST)
timestampnumbernoUnix timestamp override for signature generation
headersRecord<string, string>noAdditional headers
bodyunknownnoTemplate body override

Direct Delivery

POST(any URL)

client.sendTo

Send a webhook directly to any URL with optional provider signing. Use for local integration testing — send properly signed webhooks to localhost handlers without routing through webhooks.cc.

sendTo(url: string, options?: SendToOptions): Promise<Response>
ParamTypeRequiredDescription
urlstringyesTarget URL (http or https)
providerTemplateProvidernoProvider template for signing
secretstringnoSecret for signature generation (required when provider is set)
bodyunknownnoRequest body (JSON-serialized if not a string)
headersRecord<string, string>noAdditional headers
methodstringnoHTTP method (default: "POST")
eventstringnoEvent name
timestampnumbernoUnix timestamp override for deterministic signatures in tests
POST(build only)

client.buildRequest

Build a signed webhook request without sending it. Returns the computed URL, method, headers, and body.

buildRequest(url: string, options?: SendToOptions): Promise<{url, method, headers, body?}>

Requests

GET/endpoints/:slug/requests

client.requests.list

List captured requests for an endpoint.

list(endpointSlug: string, options?: ListRequestsOptions): Promise<Request[]>
ParamTypeRequiredDescription
endpointSlugstringyesEndpoint slug
limitnumbernoMax results (default: 50)
sincenumbernoOnly return requests after this timestamp (ms)
GET/endpoints/:slug/requests

client.requests.listPaginated

List captured requests with cursor-based pagination.

listPaginated(slug: string, options?: ListPaginatedRequestsOptions): Promise<PaginatedResult<Request>>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
limitnumbernoMax results per page
cursorstringnoCursor from previous page
GET/requests/:id

client.requests.get

Get a single captured request by ID.

get(requestId: string): Promise<Request>
GET/endpoints/:slug/requests

client.requests.waitFor

Poll for incoming requests until one matches or timeout expires. Accepts human-readable duration strings.

waitFor(endpointSlug: string, options?: WaitForOptions): Promise<Request>
ParamTypeRequiredDescription
endpointSlugstringyesEndpoint slug to monitor
timeoutnumber | stringnoMax wait time — ms or "30s", "5m", "1h" (default: 30000)
pollIntervalnumber | stringnoInterval between polls (default: 500)
match(request) => booleannoFilter function
GET/endpoints/:slug/requests

client.requests.waitForAll

Wait for multiple matching requests to arrive.

waitForAll(slug: string, options: WaitForAllOptions): Promise<Request[]>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
countnumberyesNumber of requests to collect
timeoutnumber | stringnoMax wait time
match(request) => booleannoFilter function
GET/api/stream/:slug

client.requests.subscribe

Stream incoming requests via SSE as an async iterator.

subscribe(slug: string, options?: SubscribeOptions): AsyncIterable<Request>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
signalAbortSignalnoSignal to cancel the subscription
timeoutnumber | stringnoMax stream duration
reconnectbooleannoAuto-reconnect on disconnect
maxReconnectAttemptsnumbernoMax reconnection attempts
POST/requests/:id/replay

client.requests.replay

Replay a captured request to a target URL. Sends the original method, headers, and body. Hop-by-hop headers are stripped.

replay(requestId: string, targetUrl: string): Promise<Response>
ParamTypeRequiredDescription
requestIdstringyesID of the captured request
targetUrlstringyesURL to send the replayed request to
GET/requests/search

client.requests.search

Search captured webhook requests across endpoints with full-text search.

search(filters?: SearchFilters): Promise<SearchResult[]>
ParamTypeRequiredDescription
slugstringnoFilter by endpoint slug
methodstringnoFilter by HTTP method
qstringnoFree-text search
fromstringnoStart time (duration or timestamp)
tostringnoEnd time (duration or timestamp)
limitnumbernoMax results (default: 50)
offsetnumbernoPagination offset
order"asc" | "desc"noSort order (default: "desc")
GET/requests/count

client.requests.count

Count captured webhook requests matching the given filters.

count(filters?: SearchFilters): Promise<number>
DELETE/endpoints/:slug/requests

client.requests.clear

Delete captured requests for an endpoint without deleting the endpoint itself.

clear(slug: string, options?: ClearRequestsOptions): Promise<void>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
beforestringnoDelete requests before this duration/timestamp
GET/endpoints/:slug/requests/export

client.requests.export

Export captured requests as HAR 1.2 or cURL commands.

export(slug: string, options: ExportRequestsOptions): Promise<RequestsExport>
ParamTypeRequiredDescription
slugstringyesEndpoint slug
format"har" | "curl"yesExport format
limitnumbernoMax requests to export
sincenumbernoOnly export requests after this timestamp

Templates

GET(local)

client.templates.listProviders

List all supported webhook provider templates. No API call made.

listProviders(): TemplateProvider[]
// Returns: ["stripe", "github", "shopify", "twilio", "slack", "paddle", "linear", "sendgrid", "clerk", "discord", "vercel", "gitlab", "standard-webhooks"]
GET(local)

client.templates.get

Get metadata for a specific provider template.

get(provider: TemplateProvider): TemplateProviderInfo

Usage

GET/usage

client.usage

Get current request quota and usage.

usage(): Promise<UsageInfo>
// Returns: { used, limit, remaining, plan, periodEnd }

Flow Builder

POST(chained)

client.flow

Create a fluent workflow builder for common webhook capture, verify, and replay workflows.

const result = await client
  .flow()
  .createEndpoint({ name: "test" })
  .send({ body: { event: "test" } })
  .waitForCapture({ timeout: "10s" })
  .verifySignature({ provider: "stripe", secret: "whsec_..." })
  .replayTo("http://localhost:3000/webhooks")
  .cleanup()
  .run();

Introspection

GET(local)

client.describe

Returns a static description of all SDK operations and their parameters. No API call is made. Useful for AI agents and tool discovery.

describe(): SDKDescription

Matchers

Composable functions that return (request) => boolean. Use with waitFor or filter logic.

import {
  matchMethod,
  matchHeader,
  matchPath,
  matchQueryParam,
  matchBodyPath,
  matchBodySubset,
  matchContentType,
  matchJsonField,
  matchAll,
  matchAny,
} from "@webhooks-cc/sdk";
 
matchMethod("POST"); // match by HTTP method
matchHeader("x-github-event"); // match header presence
matchHeader("x-github-event", "push"); // match header value
matchPath("/webhooks/**"); // match path with glob wildcards
matchQueryParam("token"); // match query param presence
matchQueryParam("token", "abc"); // match query param value
matchBodyPath("data.object.id", "obj_123"); // match nested JSON path
matchBodySubset({ type: "checkout" }); // match deep partial subset
matchContentType("application/json"); // match content-type ignoring charset
matchJsonField("type", "checkout"); // match top-level JSON field
matchAll(matchMethod("POST"), matchHeader("stripe-signature"));
matchAny(matchMethod("GET"), matchMethod("POST"));

Provider Detection

Each helper checks for a provider-specific header (case-insensitive).

import {
  isStripeWebhook, // stripe-signature
  isGitHubWebhook, // x-github-event
  isShopifyWebhook, // x-shopify-hmac-sha256
  isSlackWebhook, // x-slack-signature
  isTwilioWebhook, // x-twilio-signature
  isPaddleWebhook, // paddle-signature
  isLinearWebhook, // linear-signature
  isSendGridWebhook, // user-agent: SendGrid + JSON array body
  isClerkWebhook, // webhook-id + webhook-timestamp + svix-id
  isDiscordWebhook, // x-signature-ed25519 + x-signature-timestamp
  isVercelWebhook, // x-vercel-signature
  isGitLabWebhook, // x-gitlab-event or x-gitlab-token
  isStandardWebhook, // webhook-id + webhook-timestamp + webhook-signature
} from "@webhooks-cc/sdk";

Body Parsing

import { parseJsonBody, parseFormBody, parseBody, extractJsonField } from "@webhooks-cc/sdk";
 
// Parse JSON body safely (returns undefined on failure)
const json = parseJsonBody(request);
 
// Parse form-encoded body
const form = parseFormBody(request);
 
// Auto-detect and parse by content-type
const parsed = parseBody(request);
 
// Extract nested JSON field by dot notation
const email = extractJsonField<string>(request, "data.customer.email");

Request Diffing

import { diffRequests } from "@webhooks-cc/sdk";
 
const diff = diffRequests(requestA, requestB);
console.log(diff.matches); // boolean
console.log(diff.differences); // { method?, path?, headers?, body? }

Signature Verification

import {
  verifySignature,
  verifyStripeSignature,
  verifyGitHubSignature,
  verifyShopifySignature,
  verifySlackSignature,
  verifyTwilioSignature,
  verifyPaddleSignature,
  verifyLinearSignature,
  verifyClerkSignature,
  verifyDiscordSignature,
  verifyVercelSignature,
  verifyGitLabSignature,
  verifyStandardWebhookSignature,
} from "@webhooks-cc/sdk";
 
// Universal verifier (dispatches by provider)
const result = await verifySignature(request, {
  provider: "stripe",
  secret: "whsec_...",
});
console.log(result.valid); // boolean
 
// Provider-specific verifiers
const valid = await verifyStripeSignature(body, signatureHeader, secret);
const valid = await verifyGitHubSignature(body, signatureHeader, secret);

Duration Strings

timeout and pollInterval accept human-readable strings alongside milliseconds.

"500ms"  →    500
"30s"    →  30000
"5m"     → 300000
"1h"     → 3600000
500      →    500    // numbers passed through

Types

interface Endpoint {
  id: string;
  slug: string;
  name?: string;
  url?: string;
  isEphemeral?: boolean;
  expiresAt?: number;
  createdAt: number;
}
 
interface Request {
  id: string;
  endpointId: string;
  method: string;
  path: string;
  headers: Record<string, string>;
  body?: string;
  queryParams: Record<string, string>;
  contentType?: string;
  ip: string;
  size: number;
  receivedAt: number;
}
 
interface MockResponse {
  status: number; // 100-599
  body: string;
  headers: Record<string, string>;
  delay?: number; // Response delay in ms (0-30000)
}
 
interface UsageInfo {
  used: number;
  limit: number;
  remaining: number;
  plan: "free" | "pro";
  periodEnd: number | null;
}
 
interface PaginatedResult<T> {
  items: T[];
  cursor?: string;
  hasMore: boolean;
}
 
type TemplateProvider =
  | "stripe"
  | "github"
  | "shopify"
  | "twilio"
  | "slack"
  | "paddle"
  | "linear"
  | "sendgrid"
  | "clerk"
  | "discord"
  | "vercel"
  | "gitlab"
  | "standard-webhooks";
 
type VerifyProvider = TemplateProvider;

Error Classes

Errors include actionable recovery hints when the server message is generic.

import {
  WebhooksCCError, // Base error (has statusCode)
  UnauthorizedError, // 401 — includes link to get API key
  NotFoundError, // 404 — suggests using endpoints.list()
  RateLimitError, // 429 — includes retryAfter seconds
  TimeoutError, // Request timeout
} from "@webhooks-cc/sdk";