> ## 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 Python

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

A production sender built on `reconify-python` 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.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from datetime import datetime, timezone

from reconify.models import MonitoringBatchRequest, MonitoringEvent

occurred_at = datetime.now(timezone.utc)

batch = MonitoringBatchRequest(
    events=[
        MonitoringEvent(
            id="evt_01J3Y0M8VJQ5W1R3E4J4K7N8S2",
            flow="payment_to_wallet",
            type="payment.succeeded",
            occurred_at=occurred_at,
            amount="150.00",
            currency="USD",
            reference="order-123",
            entity_id="wallet_123",
        ),
        MonitoringEvent(
            id="evt_01J3Y0M8VJQ5W1R3E4J4K7N8T3",
            flow="payment_to_wallet",
            type="wallet.credited",
            occurred_at=occurred_at,
            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. Format `amount` from `Decimal`, never from floating-point
arithmetic for money.

## Send the batch

One call submits the whole batch:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from reconify import Reconify

with Reconify() as client:
    receipt = client.ingestion.ingest_monitoring_events(batch)
```

## Handle every result

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

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
for item in receipt.results:
    if item.status in {"accepted", "duplicate"}:
        delivery_metrics.increment(item.status)
        continue

    logger.error(
        "Reconify rejected an event",
        extra={
            "batch_index": 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.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from reconify import Reconify
from reconify.transport import RetryConfig

with Reconify(
    retry=RetryConfig(max_retries=2, retry_unsafe_methods=True)
) as client:
    receipt = client.ingestion.ingest_monitoring_events(batch)
```

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:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from datetime import datetime, timezone

from reconify.models import (
    MonitoringBatchRequest,
    MonitoringEvent,
    MonitoringEventData,
)

batch = MonitoringBatchRequest(
    events=[
        MonitoringEvent(
            id="evt_01J3Y0M8VJQ5W1R3E4J4K7N8V4",
            flow="payment_to_wallet",
            type="payment.initiated",
            occurred_at=datetime.now(timezone.utc),
            amount="150.00",
            currency="USD",
            reference="order-124",
            entity_id="wallet_456",
            data=MonitoringEventData(
                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>
