Ingestion API

Send Batch

Send up to 20 payloads to specific endpoints in a single request

Send multiple payloads directly to specific endpoints in one request — 1 to 20 items per call. Each item is processed independently: a single bad endpoint won't reject the rest of the batch.

POST /api/ingest/batch

Request

curl -X POST https://us.api.nahook.com/api/ingest/batch \
  -H "Authorization: Bearer nhk_us_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "endpointId": "ep_abc", "payload": { "orderId": "ord_1" } },
      { "endpointId": "ep_def", "payload": { "orderId": "ord_2" }, "idempotencyKey": "key-2" }
    ]
  }'
const result = await nahook.sendBatch([
  { endpointId: "ep_abc", payload: { orderId: "ord_1" } },
  { endpointId: "ep_def", payload: { orderId: "ord_2" }, idempotencyKey: "key-2" },
]);
result = client.send_batch([
    {"endpointId": "ep_abc", "payload": {"orderId": "ord_1"}},
    {"endpointId": "ep_def", "payload": {"orderId": "ord_2"}, "idempotencyKey": "key-2"},
])
result, err := c.SendBatch(ctx, []nahook.SendBatchItem{
    {EndpointID: "ep_abc", Payload: map[string]any{"orderId": "ord_1"}},
    {EndpointID: "ep_def", Payload: map[string]any{"orderId": "ord_2"}, IdempotencyKey: "key-2"},
})
import com.nahook.types.SendBatchItem;
import java.util.List;
import java.util.Map;

BatchResult result = client.sendBatch(List.of(
    new SendBatchItem("ep_abc", Map.of("orderId", "ord_1")),
    new SendBatchItem("ep_def", Map.of("orderId", "ord_2"), "key-2")
));
var result = await client.SendBatchAsync(new[] {
    new SendBatchItem {
        EndpointId = "ep_abc",
        Payload = new Dictionary<string, object> { ["orderId"] = "ord_1" }
    },
    new SendBatchItem {
        EndpointId = "ep_def",
        Payload = new Dictionary<string, object> { ["orderId"] = "ord_2" },
        IdempotencyKey = "key-2"
    }
});
$result = $client->sendBatch([
    ["endpointId" => "ep_abc", "payload" => ["orderId" => "ord_1"]],
    ["endpointId" => "ep_def", "payload" => ["orderId" => "ord_2"], "idempotencyKey" => "key-2"],
]);
result = client.send_batch([
  { endpoint_id: "ep_abc", payload: { order_id: "ord_1" } },
  { endpoint_id: "ep_def", payload: { order_id: "ord_2" }, idempotency_key: "key-2" }
])
use nahook::types::SendBatchItem;

let result = client.send_batch(vec![
    SendBatchItem {
        endpoint_id: "ep_abc".into(),
        payload: serde_json::json!({"orderId": "ord_1"}),
        idempotency_key: None,
    },
    SendBatchItem {
        endpoint_id: "ep_def".into(),
        payload: serde_json::json!({"orderId": "ord_2"}),
        idempotency_key: Some("key-2".into()),
    },
]).await?;

Body

FieldTypeRequiredNotes
itemsarrayyes1 to 20 items. Each item is processed independently.
items[].endpointIdstringyesEndpoint public ID (e.g. ep_abc123).
items[].payloadobjectyesArbitrary JSON.
items[].idempotencyKeystringnoPer-item dedup. Same 15-minute window as the single Send.

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,
      "deliveryId": "del_a1",
      "idempotencyKey": "abc-uuid-...",
      "status": "accepted"
    },
    {
      "index": 1,
      "status": "accepted",
      "error": { "code": "not_found", "message": "Endpoint not found" }
    }
  ]
}
FieldTypeNotes
items[].indexintegerPosition in the request items array — use it to correlate.
items[].deliveryIdstringPresent on successful items only.
items[].idempotencyKeystringEchoes the supplied key or a Nahook-generated UUID. Present on successful items only.
items[].statusstring"accepted" for queued items.
items[].errorobjectPresent on failed items only. Same { code, message } shape as top-level errors.

The HTTP status code summarises the batch:

  • 202 — every item was queued. No error field on any item.
  • 207 — at least one item failed. Inspect items[].error per index. Successful items are still queued — don't replay the whole batch on 207.

Errors

Batch-level errors (the whole request fails before any item is processed):

StatusCodeWhen
400invalid_requestMissing items, empty list, or more than 20 items.
401unauthorizedMissing, malformed, or revoked API key.
429rate_limitedWorkspace or per-API-key rate limit hit.
504ingest_timeoutServer-side ingest exceeded 5 s. Safe to retry.

Per-item errors (the batch succeeded but individual items failed) live in items[].error — see the response shape above. Common ones: not_found (bad endpointId), payload_too_large, internal_error.