This channel exists for one job: keeping your own database in sync with DimeTrades’ market catalog in real time, without polling. Every other WebSocket channel (Orderbook & Market Updates) requires you to already know a market’s id before you can hear about it — this one doesn’t. You subscribe once and receive every create and status change, for every market and event, in every category, whether it was triggered by an admin or happened automatically (e.g. a sports market auto-halting on a live odds lock).
The five-minute summary. Connect and emit SUBSCRIBE_LIFECYCLE_EVENTS — no payload, no market id. You’ll receive a LIFECYCLE_EVENT message for every market/event create or status change from that point forward, each carrying a sequenceId. If you ever see a gap in sequenceId (a reconnect, a dropped connection, anything), call GET /api/partner/market-lifecycle-events/replay with the missing ids to recover them — DimeTrades keeps no cursor or delivery record for you; detecting and recovering gaps is entirely your side.

1. Subscribing

No authentication is required to subscribe to this channel today. Unlike SUBSCRIBE_USER_UPDATES, this event is registered with no auth requirement — connecting and subscribing needs no token at all. Treat this as reachable by anyone who can connect to the WebSocket server, not brand-scoped. (The REST replay endpoint in section 3 is different — that one is brand-authenticated.)
No catch-up snapshot is sent on subscribe — unlike the public trades channel, this is live delivery only. If you need history (including everything that happened before you ever connected), use the replay endpoint in section 3. Unsubscribe the same way with UNSUBSCRIBE_LIFECYCLE_EVENTS.

2. The LIFECYCLE_EVENT message

marketId and eventId are always strings, never numbers — even though they look numeric. Parse them as strings; comparing one to a numeric literal will never match.

Settlement fields

A *_STATUS_CHANGED event whose toStatus is settled additionally carries: Neither targetSettlementPrice nor targetPrice is present on a sports or categorical-outcome settlement — those markets have no price concept at all, so only result appears:
Ordering: on an active, continuously connected socket, delivery is strictly ordered — an event’s EVENT_CREATED always arrives before any MARKET_CREATED for a market under it. The one case this doesn’t hold across is a reconnect: a live message can arrive before a replay response you requested for an earlier gap finishes — merge by sequenceId, don’t assume socket arrival order is final. Delivery is at-least-once, not exactly-once. Deduplicate by sequenceId before applying an event to your own state.
A new market/event almost always starts at pending, not open — never assume MARKET_CREATED/EVENT_CREATED means tradeable. Creating an event or market through the admin back office always defaults to status: pending with no way to submit it as open directly — confirmed both by reading the creation code and by a live test (a freshly created event + markets all came back pending). Opening it is a separate, later *_STATUS_CHANGED event (fromStatus: pending, toStatus: open) that may arrive seconds, minutes, or much later. Gate any “is this live yet” logic on the market/event’s current status, not on having seen a *_CREATED event for it.

3. Recovering a gap — the replay endpoint

Same server-to-server auth as every other /api/partner/* route.
  • Pass a comma-separated list of the sequenceIds you’re missing — not a range, not a cursor. You are the one who knows which ids you have and haven’t processed; DimeTrades keeps no per-partner delivery record to derive this from.
  • Up to 500 ids per request. A larger backlog is your own client-side loop — chunk your missing-id list into calls of 500 or fewer.
  • The response always contains every match for every id you asked for, in one reply — there is no pagination on this endpoint.
  • missingIds means exactly that — not found. It deliberately does not tell you why: an id that was never assigned to a committed change and an id that’s aged out of retention look identical here. If an id you need is missing and you can’t account for it:
If you’re asking for an id close to or above the highest sequenceId you’ve seen live, it may simply not have happened yet — don’t treat it as permanently lost on the first try. Retry shortly.
Replayable history is 7 days by default (admin-configurable, so treat 7 days as the floor to design against, not a guarantee it will never be shorter). A row is only ever deleted once it’s confirmed published to Kafka, so you will never lose an id that hasn’t actually been delivered somewhere yet — but once a row is both published and past the retention window, it’s gone for good. If you were disconnected longer than that, reconcile your state against the existing GET /events / GET /events/details endpoints instead of relying on replay to fill an arbitrarily old gap. Don’t let your own reconciliation loop fall behind by more than a few days without running — a backlog that reaches the retention window becomes a permanent, unrecoverable gap.

4. Putting it together

A minimal, correct client:
  1. Subscribe to SUBSCRIBE_LIFECYCLE_EVENTS.
  2. Track the highest sequenceId you’ve successfully applied.
  3. On every LIFECYCLE_EVENT, if its sequenceId isn’t exactly one more than your last applied id, you have a gap — call the replay endpoint for the missing range, apply what comes back (sorted by sequenceId), then apply the message that revealed the gap.
  4. Deduplicate everything by sequenceId — both across replay and live delivery, and across your own retries.
  5. On reconnect, you don’t get anything different: your local “last applied id” is still the right thing to compare the next live message against, and replay is still how you fill anything in between.
There is no server-side session, cursor, or acknowledgement to manage. All of the above is state you keep yourself.