Events

Cursor-paginated event log for reconciliation and missed webhooks

Every domain event ListBee emits is persisted and queryable via GET /v1/events. Use it to reconcile orders when your webhook endpoint was down, to bootstrap a worker against historical activity, or as a polling-primary delivery channel when you don’t want to expose a public callback.

Events outlive webhook delivery — even if agent_callback_url failed all 7 retries, the event is still here.

Event types

TypeFires when
order.paidStripe confirmed payment
order.fulfilledDeliverable attached (static or /fulfill)
order.refundedFull refund issued
order.disputedStripe dispute opened

Listing lifecycle (create/publish/archive) is not emitted — the agent is the mutator, so it’s self-knowledge.

Listing events

Cursor-paginated. Filter by type, listing_id, order_id, and after (event ID).

1result = client.events.list(type="order.paid", limit=50)
2
3for event in result.data:
4 print(event.id, event.type, event.order_id, event.created_at)
5
6if result.has_more:
7 next_page = client.events.list(
8 type="order.paid",
9 cursor=result.cursor,
10 )

Event shape

1{
2 "object": "event",
3 "id": "evt_01J3K4M5N6P7Q8R9S0T1U2V3W4",
4 "type": "order.paid",
5 "account_id": "acc_7kQ2xY9mN3pR5tW1vB8a",
6 "listing_id": "lst_7kQ2xY9mN3pR5tW1vB8a",
7 "order_id": "ord_9xM4kP7nR2qT5wY1",
8 "created_at": "2026-04-17T10:23:00Z",
9 "data": {
10 "object": "order",
11 "id": "ord_9xM4kP7nR2qT5wY1",
12 "status": "paid",
13 "amount": 4900
14 }
15}

data is the same structured payload delivered to agent_callback_url — no follow-up API call needed to enrich it.

Reconciling missed webhooks

Keep a cursor (last processed event ID) in durable storage. After a restart or outage, poll from the cursor forward:

1import time
2
3last_seen = load_cursor() # e.g. from Redis or a local file
4
5while True:
6 page = client.events.list(after=last_seen, limit=100)
7 for event in page.data:
8 handle(event)
9 last_seen = event.id
10 save_cursor(last_seen)
11
12 if not page.has_more:
13 time.sleep(30)

This pattern works as a standalone channel (no webhook URL needed) or as a backstop behind a webhook consumer.

When to use events vs webhooks

Use casePrefer
Real-time reaction, public HTTPS endpointagent_callback_url
Stateless workers, no public endpointGET /v1/events poll
Reconciliation after receiver outageGET /v1/events + cursor, or POST /v1/orders/{id}/redeliver
Debugging or backfill of historical activityGET /v1/events

Webhook delivery has retries and a circuit breaker — events are always durable regardless. See Fulfillment for delivery mechanics.

Key fields

FieldTypeDescription
idstringEvent ID (evt_) — use as cursor
typestringorder.paid, order.fulfilled, order.refunded, order.disputed
account_idstringAccount that owns the event
listing_idstringRelated listing, if applicable
order_idstringRelated order, if applicable
created_atstringUTC timestamp
dataobjectEvent payload — same shape as webhook delivery
  • Fulfillment — webhook delivery, retries, redelivery
  • OrdersPOST /v1/orders/{id}/redeliver for one-order replay