Webbu Docs

Step 2: Create a Buffer

Configure a buffer with a group key, flush conditions and a delivery destination.

A buffer defines how webhooks are grouped, when a group is flushed and where the batch is delivered.

Create via API

Minimal example

bufferId, projectId, name, groupKey and delivery.url are required. Everything else has defaults.

curl -X POST https://webbu.dev/api/v1/admin/buffers \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $WEBBU_API_KEY" \
  -d '{
    "bufferId": "b_orders",
    "projectId": "p_shop",
    "name": "Order events",
    "groupKey": { "mode": "jsonpath", "path": "$.customerId" },
    "delivery": { "url": "https://your-app.example.com/webhooks/batch" }
  }'
const res = await fetch('https://webbu.dev/api/v1/admin/buffers', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.WEBBU_API_KEY!,
  },
  body: JSON.stringify({
    bufferId: 'b_orders',
    projectId: 'p_shop',
    name: 'Order events',
    groupKey: { mode: 'jsonpath', path: '$.customerId' },
    delivery: { url: 'https://your-app.example.com/webhooks/batch' },
  }),
});
const buffer = await res.json();
resp = requests.post(
    "https://webbu.dev/api/v1/admin/buffers",
    headers={"X-API-Key": os.environ["WEBBU_API_KEY"]},
    json={
        "bufferId": "b_orders",
        "projectId": "p_shop",
        "name": "Order events",
        "groupKey": {"mode": "jsonpath", "path": "$.customerId"},
        "delivery": {"url": "https://your-app.example.com/webhooks/batch"},
    },
)
buffer = resp.json()

Complete example

All configurable fields, with their default values except where noted:

curl -X POST https://webbu.dev/api/v1/admin/buffers \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $WEBBU_API_KEY" \
  -d '{
    "bufferId": "b_orders",
    "projectId": "p_shop",
    "name": "Order events",
    "enabled": true,
    "groupKey": {
      "mode": "jsonpath",
      "path": "$.customerId",
      "fallbackHeader": "x-customer-id"
    },
    "batch": {
      "maxItems": 50,
      "maxBytes": 262144,
      "idleTimeoutMs": 5000,
      "maxWaitFromFirstMs": 15000
    },
    "overflow": {
      "maxGroupItems": 2000,
      "maxGroupBytes": 5242880
    },
    "delivery": {
      "url": "https://your-app.example.com/webhooks/batch",
      "method": "POST",
      "headers": { "Authorization": "Bearer your-destination-token" },
      "idempotencyHeader": "x-idempotency-key",
      "signing": { "type": "hmac-sha256", "secret": "your-signing-secret", "header": "x-webbu-signature" }
    },
    "throughput": {
      "maxAttempts": 3,
      "backoff": { "initialMs": 1000, "maxMs": 60000, "multiplier": 2 }
    },
    "dlqPauseThreshold": 3
  }'

fallbackHeader, delivery.headers and delivery.signing are optional and have no default.

Try it in the API reference

Response (201 Created) for the minimal example: the stored buffer, including every default:

{
  "bufferId": "b_orders",
  "customerId": "c_your_account",
  "projectId": "p_shop",
  "name": "Order events",
  "enabled": true,
  "groupKey": { "mode": "jsonpath", "path": "$.customerId" },
  "batch": { "maxItems": 50, "maxBytes": 262144, "idleTimeoutMs": 5000, "maxWaitFromFirstMs": 15000 },
  "overflow": { "maxGroupItems": 2000, "maxGroupBytes": 5242880, "policy": "flush_early_then_continue" },
  "delivery": { "url": "https://your-app.example.com/webhooks/batch", "method": "POST", "idempotencyHeader": "x-idempotency-key" },
  "throughput": { "maxAttempts": 3, "backoff": { "initialMs": 1000, "maxMs": 60000, "multiplier": 2 }, "minDelayBetweenFlushMs": 0, "maxConcurrencyPerGroup": 1 },
  "analytics": { "sampleDeliveryLogs": 0.05 },
  "dlqPauseThreshold": 3,
  "consecutiveDlqCount": 0,
  "createdAt": 1767225600000,
  "updatedAt": 1767225600000
}

Your ingest URL is https://webbu.dev/api/v1/ingest/p_shop/b_orders.

Common errors

StatusCauseFix
400bufferId, projectId, and name are requiredSend all three
400Project not foundCheck projectId (it must belong to your account)
400Invalid buffer configurationSee details in the response, e.g. missing groupKey or an invalid delivery.url
401Missing, invalid or revoked API keyCheck the X-API-Key header
403The key's role can't create buffersUse a member, admin or owner key
409A buffer with this bufferId already existsChoose another ID

Configuration explained

FieldDescription
groupKey.modejsonpath (read from the body, falling back to the header) or header (read from the header only)
groupKey.pathDot-notation path into the JSON body, e.g. $.customerId or $.data.object.customer
groupKey.fallbackHeaderRequest header used when the path is missing
batch.maxItemsFlush as soon as the group has this many items; also the maximum items per delivery
batch.maxBytesFlush when the group's payloads add up to this many bytes
batch.idleTimeoutMsFlush when no item has arrived for this long (minimum 100)
batch.maxWaitFromFirstMsFlush when the oldest item has waited this long (minimum 100)
overflow.maxGroupItems / maxGroupBytesPer-segment limits; see Segments & Overflow
delivery.methodPOST or PUT
delivery.headersExtra headers sent with every delivery (e.g. an auth token for your endpoint)
delivery.idempotencyHeaderHeader carrying the batch idempotency key
delivery.signingOptional HMAC-SHA256 signature of each delivery; see Security
throughput.maxAttemptsDelivery attempts, including the first, before the batch goes to the DLQ (1 to 5)
throughput.backoffDelay before retry n: initialMs × multiplier^(n-1), capped at maxMs
dlqPauseThresholdThe buffer is disabled after this many consecutive batches go to the DLQ (1 to 10)
sourceVerificationOptional signature check on incoming webhooks; see Security

Create via dashboard

  1. Go to Buffers in the sidebar
  2. Click New Buffer
  3. Pick the project, name the buffer, and fill in the group key, batch and delivery sections
  4. Save. The buffer list shows the ingest URL with a copy button

On this page