> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reconifyhq.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Reconify's API reference is read-only for customer data. Do not invent endpoints or authentication behavior beyond the OpenAPI contract.
> The public OpenAPI document contains only the documented external /v2 contract.

# Send events with TypeScript

> Build event batches, handle every result, and retry delivery safely.

A production sender built on `@reconifyhq/sdk` batches events, reads every item result,
retries without duplicating evidence, and carries provider lookup data where a payment
integration exists. This page covers all four.

## Build an event batch

A batch carries between 1 and 500 events. Events from the same business operation share a
`reference`, and `entity_id` identifies the wallet, order, or other entity the flow
monitors.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import type { MonitoringBatchRequest } from "@reconifyhq/sdk";

const occurredAt = new Date().toISOString();

const batch: MonitoringBatchRequest = {
  events: [
    {
      id: "evt_01J3Y0M8VJQ5W1R3E4J4K7N8S2",
      flow: "payment_to_wallet",
      type: "payment.succeeded",
      occurred_at: occurredAt,
      amount: "150.00",
      currency: "USD",
      reference: "order-123",
      entity_id: "wallet_123",
    },
    {
      id: "evt_01J3Y0M8VJQ5W1R3E4J4K7N8T3",
      flow: "payment_to_wallet",
      type: "wallet.credited",
      occurred_at: occurredAt,
      amount: "150.00",
      currency: "USD",
      reference: "order-123",
      entity_id: "wallet_123",
    },
  ],
};
```

Replace the sample IDs, timestamps, and business identifiers with values from
your source system. `amount` is a decimal string, not a JavaScript number.

## Send the batch

One call submits the whole batch:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { ReconifyClient } from "@reconifyhq/sdk";

const client = new ReconifyClient({
  apiKey: process.env.RECONIFY_API_KEY,
});

const receipt = await client.ingestion.ingestMonitoringEvents({ body: batch });
```

## Handle every result

The response carries one result per input event, in the same order:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
for (const item of receipt.results) {
  if (item.status === "accepted" || item.status === "duplicate") {
    deliveryMetrics.increment(item.status);
    continue;
  }

  logger.error("Reconify rejected an event", {
    batchIndex: item.index,
    code: item.code,
    field: item.field,
  });
}
```

* `accepted`: Reconify stored the event.
* `duplicate`: Reconify already stored the same ID and payload. Treat it as
  delivered.
* `rejected`: Reconify did not store that item. Fix the field or identity
  conflict before sending it again.

The HTTP status can be `202` when some items are rejected. Do not treat a
successful request as proof that every item was accepted. Avoid logging the
event payload, `reference`, `entity_id`, or amount.

## Retry delivery safely

The SDK does not retry ingestion by default. Enable POST retries only when
every event in the batch has a stable `id` and you will resend the same payload.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const receipt = await client.ingestion.ingestMonitoringEvents({
  body: batch,
  request: { retry: { retryNonIdempotent: true } },
});
```

Reconify returns `duplicate` when an earlier attempt stored the event. Reusing
an ID with different content returns `idempotency_conflict`, which points at the
producer's identity mapping rather than at delivery, so an unchanged retry solves nothing.

## Add payment provider data

After you configure a payment integration in the dashboard, copy its opaque
integration reference into a `payment.initiated` event:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const receipt = await client.ingestion.ingestMonitoringEvents({
  body: {
    events: [
      {
        id: "evt_01J3Y0M8VJQ5W1R3E4J4K7N8V4",
        flow: "payment_to_wallet",
        type: "payment.initiated",
        occurred_at: new Date().toISOString(),
        amount: "150.00",
        currency: "USD",
        reference: "order-124",
        entity_id: "wallet_456",
        data: {
          integration_ref: "int_01J9XSTRIPE01",
          provider_transaction_id: "pi_3P8x2K...",
        },
      },
    ],
  },
});
```

`integration_ref` selects the saved connection. The provider transaction ID or
reference tells Reconify what to look up. See [Payment integrations](/guides/payment-integrations)
for supported lookup fields and connector behavior.

## Next

<Columns cols={2}>
  <Card title="Send events" icon="send" href="/guides/api-integration">
    The language-neutral contract, results, and retry rules.
  </Card>

  <Card title="Prepare for production" icon="clipboard-check" href="/guides/production-checklist">
    Review batching, security, observability, and operations.
  </Card>
</Columns>
