Install the SDK, annotate a controller, ship.
The NestJS SDK (@nestarc/webhook-client) is the primary integration path. The REST API below is for non-NestJS stacks, cURL debugging, and custom automation.
Integration checklist
Everything needed before the first event is sent
Authorization
Authorization: Bearer whk_your_current_api_key
Message shape
event_type + payload, with endpoint_ids for targeting
Operations
Create endpoints, inspect deliveries, retry failed attempts
orders.controller.ts
import { Controller, Post } from '@nestjs/common';
import { WebhookEmit } from '@nestarc/webhook-client';
@Controller('orders')
export class OrdersController {
@Post()
@WebhookEmit('order.created', {
when: (response) => Boolean((response as { id?: string }).id),
await: true,
})
create() {
return { id: 'ord_123', total: 4900 };
}
}routing
Base path
/api/v1
auth
Authentication
Bearer API key from Settings.
lists
Pagination
limit defaults to 20 and is capped at 100.
post safety
Idempotency
Idempotency-Key is scoped per application and route.
Quick Start
From npm install to first delivery
Four steps. The SDK owns your application-side integration; the dashboard owns credentials and observability. Jump to the SDK section below for full module code.
1. Install the SDK
npm install @nestarc/webhook-client — works with NestJS 10 and 11. See the SDK section below for the full module import.
2. Sign in & grab your key
OAuth sign-in provisions your account and default application. Reveal or rotate the API key from Settings when needed.
3. Register endpoints
Add destination URLs in the dashboard and pick which event names each endpoint receives. Events can be '*' for everything.
4. Emit & monitor
Annotate a controller with @WebhookEmit or call webhookClient.send() — then watch deliveries, latency, and retries in the dashboard.
REST API
Current surface area
All routes below are scoped to the current application through the Bearer API key. Messages and deliveries support offset-based pagination, with limit defaulting to 20 and capped at 100.
POST /messages body
Required shape for publishing an event.
event_typestringLogical event name such as order.created or invoice.paid.
payloadobjectJSON payload delivered to subscribers.
endpoint_idsstring[]Optional. When provided, the message is sent only to those endpoint ids.
POST /endpoints body
Fields supported when creating an endpoint.
urlstringDestination URL. It must be a valid, publicly reachable webhook URL.
eventsstring[]Optional. Event names this endpoint subscribes to. Defaults to ['*'].
descriptionstringOptional human-readable label for the endpoint.
metadataobjectOptional JSON object for your own endpoint metadata.
PATCH /endpoints/:id body
Fields supported when updating an endpoint.
urlstringOptional replacement destination URL.
eventsstring[]Optional replacement event subscription list.
descriptionstringOptional replacement description.
metadataobjectOptional replacement metadata object.
activebooleanOptional flag for disabling or re-enabling an endpoint.
Data portability
Export webhook logs without scraping the dashboard
Create an asynchronous log export, poll for completion, and download a zip archive with stable JSONL files for events, deliveries, and attempts.
curl -X POST "$BASE_URL/api/v1/exports/logs" \
-H "Authorization: Bearer $WEBHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "2026-04-01T00:00:00.000Z",
"to": "2026-05-01T00:00:00.000Z",
"event_type": "order.created",
"status": "FAILED"
}'curl "$BASE_URL/api/v1/exports/export_uuid" \ -H "Authorization: Bearer $WEBHOOK_API_KEY" curl "$BASE_URL/api/v1/exports/export_uuid/download" \ -H "Authorization: Bearer $WEBHOOK_API_KEY" \ -o nestarc-webhook-logs.zip
Archive contents
Exports include manifest.json, events.jsonl, deliveries.jsonl, delivery_attempts.jsonl, and README.txt. Each JSONL line is a complete JSON object with snake_case fields.
Sensitive fields
Signing secrets and API keys are intentionally excluded. Delivery rows include endpoint_url_snapshot and public delivery metadata, not signing secret snapshots.
cURL examples
Minimal requests to get started
1. Export environment variables
export BASE_URL="https://your-webhook-platform.example.com" export WEBHOOK_API_KEY="whk_your_current_api_key"
2. Create an endpoint
curl -X POST "$BASE_URL/api/v1/endpoints" \
-H "Authorization: Bearer $WEBHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/orders",
"events": ["order.created", "order.cancelled"],
"description": "Orders service",
"metadata": { "env": "production" }
}'3. Publish a message
curl -X POST "$BASE_URL/api/v1/messages" \
-H "Authorization: Bearer $WEBHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_type": "order.created",
"payload": {
"id": "ord_123",
"customer_id": "cus_456",
"total": 4900
},
"endpoint_ids": ["endpoint_uuid_if_you_need_targeting"]
}'4. Inspect and retry deliveries
curl "$BASE_URL/api/v1/deliveries?status=FAILED&limit=20" \ -H "Authorization: Bearer $WEBHOOK_API_KEY" curl -X POST "$BASE_URL/api/v1/deliveries/delivery_uuid/retry" \ -H "Authorization: Bearer $WEBHOOK_API_KEY"
NestJS SDK
Use the published client package
The current package name is @nestarc/webhook-client and the version in this repo is 0.1.0. The client posts to /api/v1/messages with the same Bearer API key you use from cURL, ships a dedicated User-Agent header, and exposes structured error classes for timeout and API failures.
Install
Add the package to a NestJS service that needs to emit outbound events.
npm install @nestarc/[email protected]
The module supports both forRoot and forRootAsync. The send call accepts eventType, payload, optional endpointIds, and an optional idempotencyKey. When you omit idempotencyKey, the SDK automatically generates an Idempotency-Key header for each send. Register WebhookClientModule before using @WebhookEmit so the interceptor can resolve its client dependency.
Example module and service
import { Injectable, Module } from '@nestjs/common';
import {
WebhookClientModule,
WebhookClientService,
} from '@nestarc/webhook-client';
@Module({
imports: [
WebhookClientModule.forRoot({
baseUrl: process.env.WEBHOOK_BASE_URL!,
apiKey: process.env.WEBHOOK_API_KEY!,
}),
],
})
export class AppModule {}
@Injectable()
export class OrderEventsService {
constructor(private readonly webhookClient: WebhookClientService) {}
async emitOrderCreated(order: { id: string; total: number }) {
const result = await this.webhookClient.send({
eventType: 'order.created',
payload: order,
idempotencyKey: `order.created:${order.id}`,
});
return result.id;
}
}Decorator mode for controller responses
import { Controller, Post } from '@nestjs/common';
import { WebhookEmit } from '@nestarc/webhook-client';
@Controller('orders')
export class OrdersController {
@Post()
@WebhookEmit('order.created', {
when: (response) => Boolean((response as { id?: string }).id),
await: true,
})
create() {
return { id: 'ord_123', total: 4900 };
}
}Use await: true in serverless environments when you want the webhook send attempt to finish before the HTTP response returns. By default, null and undefined responses are skipped.
Open-source docs
Related nestarc package documentation
The managed platform docs on this site cover the hosted API and dashboard. For engine internals and broader package references, use the official nestarc open-source documentation.
nestarc package hub
Browse the wider nestarc package catalog and shared backend guides.
@nestarc/webhook package docs
Read the engine package overview, installation, delivery model, and endpoint management docs.
Webhook security guide
Review SSRF defense, signature handling, and security-specific engine guidance.
nestarc GitHub and npm
Inspect repositories, releases, and published packages behind the open-source modules.
Next step
Generate a key, register an endpoint, and send the first event.
The dashboard owns credential reveal and rotation. The API and SDK use the same application key once you have it.