Ingestion API
Trigger Batch
Fan out up to 20 event-type payloads in a single request
Trigger multiple event types in one request — 1 to 20 items per call. Each item fans out to every endpoint subscribed to its event type, independently of the other items.
POST /api/ingest/event/batch
Request
curl -X POST https://us.api.nahook.com/api/ingest/event/batch \
-H "Authorization: Bearer nhk_us_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "eventType": "order.paid", "payload": { "orderId": "ord_1" } },
{ "eventType": "user.created", "payload": { "userId": "usr_2" }, "metadata": { "source": "signup" } }
]
}'const result = await nahook.triggerBatch([
{ eventType: "order.paid", payload: { orderId: "ord_1" } },
{ eventType: "user.created", payload: { userId: "usr_2" }, metadata: { source: "signup" } },
]);result = client.trigger_batch([
{"eventType": "order.paid", "payload": {"orderId": "ord_1"}},
{"eventType": "user.created", "payload": {"userId": "usr_2"}, "metadata": {"source": "signup"}},
])result, err := c.TriggerBatch(ctx, []nahook.TriggerBatchItem{
{EventType: "order.paid", Payload: map[string]any{"orderId": "ord_1"}},
{EventType: "user.created", Payload: map[string]any{"userId": "usr_2"}, Metadata: map[string]string{"source": "signup"}},
})import com.nahook.types.TriggerBatchItem;
import java.util.List;
import java.util.Map;
BatchResult result = client.triggerBatch(List.of(
new TriggerBatchItem("order.paid", Map.of("orderId", "ord_1")),
new TriggerBatchItem("user.created", Map.of("userId", "usr_2"), Map.of("source", "signup"))
));var result = await client.TriggerBatchAsync(new[] {
new TriggerBatchItem {
EventType = "order.paid",
Payload = new Dictionary<string, object> { ["orderId"] = "ord_1" }
},
new TriggerBatchItem {
EventType = "user.created",
Payload = new Dictionary<string, object> { ["userId"] = "usr_2" },
Metadata = new Dictionary<string, string> { ["source"] = "signup" }
}
});$result = $client->triggerBatch([
["eventType" => "order.paid", "payload" => ["orderId" => "ord_1"]],
["eventType" => "user.created", "payload" => ["userId" => "usr_2"], "metadata" => ["source" => "signup"]],
]);result = client.trigger_batch([
{ event_type: "order.paid", payload: { order_id: "ord_1" } },
{ event_type: "user.created", payload: { user_id: "usr_2" }, metadata: { "source" => "signup" } }
])use nahook::types::TriggerBatchItem;
use std::collections::HashMap;
let result = client.trigger_batch(vec![
TriggerBatchItem {
event_type: "order.paid".into(),
payload: serde_json::json!({"orderId": "ord_1"}),
metadata: None,
},
TriggerBatchItem {
event_type: "user.created".into(),
payload: serde_json::json!({"userId": "usr_2"}),
metadata: Some(HashMap::from([("source".into(), "signup".into())])),
},
]).await?;Body
| Field | Type | Required | Notes |
|---|---|---|---|
items | array | yes | 1 to 20 items. Each item fans out independently. |
items[].eventType | string | yes | Event type name (e.g. order.paid). |
items[].payload | object | yes | Arbitrary JSON, delivered to every subscribed endpoint. |
items[].metadata | object<string, string> | no | Up to 5 keys, string values. Attached to every fanned-out delivery for this item. |
items[].idempotencyKey | string | no | Accepted for input-shape parity with Send Batch, but the value is ignored today — no-op. |
The API key must be workspace-scoped — same rule as the single Trigger. Each item's payload is capped by your plan's per-payload limit; a batch can hold up to 20 items.
Response
202 Accepted (all items queued) or 207 Multi-Status (at least one item failed).
{
"items": [
{
"index": 0,
"eventTypeId": "evt_order_paid",
"deliveryIds": ["del_a1", "del_b2"],
"status": "accepted",
"failures": []
},
{
"index": 1,
"status": "accepted",
"error": { "code": "not_found", "message": "Event type not found" }
}
]
}| Field | Type | Notes |
|---|---|---|
items[].index | integer | Position in the request items array — use it to correlate. |
items[].eventTypeId | string | Present on successful items only. |
items[].deliveryIds | string[] | One entry per endpoint that was queued. May be empty if no endpoints are subscribed. |
items[].status | string | "accepted" for processed items. |
items[].failures | array | Per-endpoint enqueue failures within a single fan-out item — same shape as the single Trigger endpoint's failures field. |
items[].error | object | Present when the entire item failed (e.g. unknown event type). Mutually exclusive with the other success fields. |
Like Send Batch:
202— every item was processed.207— at least one item failed. Successful items are still queued.
Errors
Batch-level errors (the whole request fails before any item is processed):
| Status | Code | When |
|---|---|---|
400 | invalid_request | Missing items, empty list, or more than 20 items. |
400 | invalid_api_key | Used a key that isn't workspace-scoped. |
401 | unauthorized | Missing, malformed, or revoked API key. |
429 | rate_limited | Workspace or per-API-key rate limit hit. |
504 | ingest_timeout | Server-side ingest exceeded 5 s. Safe to retry. |
Per-item errors live in items[].error. Common ones: not_found (unknown event type), payload_too_large, internal_error.