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.
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
| Status | Cause | Fix |
|---|---|---|
400 | bufferId, projectId, and name are required | Send all three |
400 | Project not found | Check projectId (it must belong to your account) |
400 | Invalid buffer configuration | See details in the response, e.g. missing groupKey or an invalid delivery.url |
401 | Missing, invalid or revoked API key | Check the X-API-Key header |
403 | The key's role can't create buffers | Use a member, admin or owner key |
409 | A buffer with this bufferId already exists | Choose another ID |
Configuration explained
| Field | Description |
|---|---|
groupKey.mode | jsonpath (read from the body, falling back to the header) or header (read from the header only) |
groupKey.path | Dot-notation path into the JSON body, e.g. $.customerId or $.data.object.customer |
groupKey.fallbackHeader | Request header used when the path is missing |
batch.maxItems | Flush as soon as the group has this many items; also the maximum items per delivery |
batch.maxBytes | Flush when the group's payloads add up to this many bytes |
batch.idleTimeoutMs | Flush when no item has arrived for this long (minimum 100) |
batch.maxWaitFromFirstMs | Flush when the oldest item has waited this long (minimum 100) |
overflow.maxGroupItems / maxGroupBytes | Per-segment limits; see Segments & Overflow |
delivery.method | POST or PUT |
delivery.headers | Extra headers sent with every delivery (e.g. an auth token for your endpoint) |
delivery.idempotencyHeader | Header carrying the batch idempotency key |
delivery.signing | Optional HMAC-SHA256 signature of each delivery; see Security |
throughput.maxAttempts | Delivery attempts, including the first, before the batch goes to the DLQ (1 to 5) |
throughput.backoff | Delay before retry n: initialMs × multiplier^(n-1), capped at maxMs |
dlqPauseThreshold | The buffer is disabled after this many consecutive batches go to the DLQ (1 to 10) |
sourceVerification | Optional signature check on incoming webhooks; see Security |
Create via dashboard
- Go to Buffers in the sidebar
- Click New Buffer
- Pick the project, name the buffer, and fill in the group key, batch and delivery sections
- Save. The buffer list shows the ingest URL with a copy button