Integration with Websockets
Real-time market data — game lines, halves/quarters/innings, and player/team props — is delivered to traders over WebSockets, powered by Talaria, ProphetX's in-house WebSocket platform. This guide covers the full integration: connecting, discovering events, registering subscriptions, and consuming updates.
Talaria is a wire-protocol-compatible in-house replacement for a third-party hosted WebSocket vendor ProphetX previously used — it speaks the identical wire protocol (same event names, same double-JSON-encoded frames, same channel/auth signing scheme) so existing integrations need, at most, a host repoint. That's why the literal event strings below (
pusher:connection_established,pusher:subscribe,pusher:signin,pusher_internal:subscription_succeeded,pusher:error, and the"service": "pusher"field) still read that way — that's the wire protocol's own name, not a vendor reference, and it's unchanged on purpose. Nothing else in this guide targets that vendor: connect to, and think of this entirely as, Talaria.
What you need to do
We're splitting market updates that today all flow through a single shared channel into dedicated channels per event (and per prop type). This keeps your feed focused and scales better as market coverage grows.
| You consume | Action required | Deadline |
|---|---|---|
Main markets (game lines, halves, quarters, innings — this set now also includes sup_moneyline and moneyline_3_way, not just moneyline/spread/total) | Start to plan your migration now | August 12, 2026 |
| Player Props | Subscribe to the new channels | July 29, 2026 |
Migrate from POST /partner/mm/pusher to POST /partner/v4/mm/websocket to get access to the new channel types. The new channels are available in your sandbox environment now — start testing there before the deadlines above.
Before you begin
- Generate API tokens from the sandbox UI.
- Exchange your access key and secret key for a session token by calling
POST /auth/login. - Store the
access_tokenand send it in theAuthorizationheader asBearer <access_token>.
1. What's changing: the channel model
Today, market_selections updates for every event and every market type flow through one shared channel. Going forward, they're split by event and, for props, by market sub-type:
| Channel | Pattern | Carries |
|---|---|---|
| Main public channel (existing — being phased out for market data) | private-broadcast-service=6-device_type=5 | Carries main-market updates during the migration window; after August 12, 2026 it no longer carries market_selections at all. (Other message types on this channel are unaffected.) |
| Event channel (new) | private-broadcast-service=6-device_type=5-event={event_id} | All main-market updates for one event |
| Sub-markets channel (new) | private-broadcast-service=6-device_type=5-event={event_id}-subtype={sub_type} | One channel per prop sub_type, per event |
Both new channel types publish the same pair of binding events: legacy market_selections and CFTC-vocabulary v2.market_selections (strike/price/quantity instead of line/odds/stake) — only the routing changes, not which events are available. Bind v2.market_selections, not the legacy market_selections, to get the CFTC-updated payload shape.
What about the old, third-party-hosted service itself?
Separately from the channel migration above, ProphetX is also retiring the legacy externally-hosted service that Talaria replaces. A few things worth knowing:
- This is already live in sandbox. Sandbox hands back a
ws_hosttoday, so if you're connecting there, you're already on Talaria. - Production is currently running both in parallel (dual-publish), with the legacy service still primary — nothing changes for production connections yet.
- September 16, 2026 is the cutover date. On that date, we stop using the official Pusher-hosted service entirely and move fully onto Talaria. Nothing you need to do differently in your code because of this — everything in this guide (the wire protocol, the event names, the
service: "pusher"field) stays the same before and after that cutover, since Talaria will keep speaking this same wire protocol regardless of which service is behind it.
If you're seeing pusher:connection_established after connecting to a ws_host value, that's expected — see the callout above.
2. Connecting
Step 1 — Get your connection config. Don't hardcode these values — fetch them, since they can change:
GET <BASE_URL>/partner/websocket/connection-config
Headers: { "Authorization": "<token>", "Content-Type": "application/json" }
Example response:
{
"app_id": "<app_id>",
"key": "<app_key>",
"cluster": "<cluster>",
"ws_host": "<talaria_host>",
"service": "pusher"
}clusteris unchanged from before the migration.ws_hostis the new field: when present, connect to it instead of the default Pusher cluster host. It's live in sandbox now. If it's ever absent from the response, fall back to resolving the Pusher cluster host as before — that's the deliberate rollback path on our end, not a bug on yours.- There's no
ws_portorhttp_hostfield — don't build against either.
Step 2 — Connect to Talaria using that config, and capture your socket_id from the pusher:connection_established event:
{
"event": "pusher:connection_established",
"data": "{\"socket_id\":\"123.456\"}"
}Note: data is a JSON string containing JSON — decode it twice to get socket_id.
3. Discover event and market IDs
Before registering, you need the event_id for every event you care about, and — for props — the sub_type for every prop market on that event.
| You need | Endpoint | Field |
|---|---|---|
| Event ID | GET /partner/mm/get_sport_events?tournament_id={id} | event_id |
| Sub-type | GET /partner/v4/mm/get_multiple_markets?event_ids={ids} | sub_type (optional field — read defensively) |
There's currently no endpoint that tells you which sub_types are classified "main" vs. "prop" for a given tournament — that classification is server-side configuration that varies by tournament and can change over time. Subscribing to the event channel always gets you every current main market for that event, regardless of what the underlying list holds at any given time — you don't need to track the main/prop split yourself for that channel.
Ensure you are using the V4 versions of get_markets or get_multiple_markets when searching for sub_type
Fallback reference: sub-types by tournament (point-in-time snapshot)
If you need a starting point before you can call the endpoints above, here's the current breakdown by tournament. This will go stale, and the main/prop split can change — treat it as a reference, not a contract.
NFL (tournament_id: 31)
Main markets: 1st_quarter_moneyline, 1st_quarter_spread, 1st_quarter_total, first_half_moneyline, first_half_spread, first_half_total, moneyline, spread, sup_moneyline, to_go_to_overtime, total
Prop sub-types: first_team_to_score, player_defensive_interception, player_interceptions_thrown, player_longest_pass, player_longest_reception, player_longest_rush, player_to_score_first_touchdown, player_to_score_last_touchdown, player_total_assists, player_total_field_goals_made, player_total_kicking_points, player_total_pass_completions, player_total_passing_attempts, player_total_passing_rushing_yards, player_total_passing_touchdowns, player_total_passing_yards, player_total_receiving_yards, player_total_receptions, player_total_rushing_attempts, player_total_rushing_receiving_yards, player_total_rushing_yards, player_total_sacks, player_total_tackles, player_total_tackles_assists, team_total_points, to_score_a_touchdown
NBA (tournament_id: 132)
Main markets: first_half_moneyline, first_half_spread, first_half_total, moneyline, spread, sup_moneyline, total
Prop sub-types: player_to_record_a_double_double, player_to_record_a_triple_double, player_total_3_pointers_made_milestones, player_total_assists, player_total_assists_milestones, player_total_blocks, player_total_field_goals_attempted, player_total_free_throws_made, player_total_points, player_total_points_assists, player_total_points_milestones, player_total_points_rebounds, player_total_points_rebounds_assists, player_total_rebounds, player_total_rebounds_assists, player_total_rebounds_milestones, player_total_steals, player_total_steals_blocks, player_total_three_pointers_made, player_total_turnovers, team_total_points
Premier League (tournament_id: 17)
Main markets: moneyline, moneyline_3_way, spread, sup_moneyline, total
Prop sub-types: both_teams_to_score, first_team_to_score, player_to_give_assist, player_to_have_at_least_1_shot, player_to_have_at_least_1_shot_on_target, player_to_have_at_least_2_shots, player_to_have_at_least_2_shots_on_target, player_to_have_at_least_3_shots_on_target, player_to_receive_a_card, player_to_receive_a_red_card, player_to_score_a_goal, player_to_score_at_least_2_goals, player_to_score_at_least_3_goals, player_to_score_or_give_assist, player_total_assists_milestones, player_total_saves_milestones, player_total_shots_milestones, player_total_shots_on_target_milestones, player_total_tackles_milestones, team_clean_sheet, total_goal_odd_even
MLB (tournament_id: 109)
Main markets: 1st_5th_inning_moneyline, 1st_5th_inning_spread, 1st_5th_inning_total, 1st_inning_moneyline, 1st_inning_spread, 1st_inning_total, moneyline, spread, sup_moneyline, total
Prop sub-types: player_doubles, player_hits_allowed, player_pitcher_to_record_a_win, player_singles, player_stolen_bases, player_total_bases, player_total_batting_strikeouts, player_total_earned_runs_allowed, player_total_hits, player_total_hits_runs_rbis, player_total_home_runs, player_total_operator_fantasy_points, player_total_outs_recorded, player_total_pitching_strikeouts, player_total_pitching_strikeouts_milestones, player_total_rbis, player_total_runs, player_total_walks, player_walks_allowed, team_total_runs
UEFA Champions League (tournament_id: 7)
Main markets: moneyline, moneyline_3_way, spread, sup_moneyline, total
Prop sub-types: both_teams_to_score, player_to_give_assist, player_to_have_at_least_1_shot, player_to_have_at_least_1_shot_on_target, player_to_have_at_least_2_shots, player_to_have_at_least_2_shots_on_target, player_to_have_at_least_3_shots_on_target, player_to_receive_a_card, player_to_receive_a_red_card, player_to_score_a_goal, player_to_score_at_least_2_goals, player_to_score_at_least_3_goals, player_to_score_or_give_assist, player_total_assists_milestones, player_total_saves_milestones, player_total_shots_milestones, player_total_shots_on_target_milestones, player_total_tackles_milestones, team_clean_sheet, total_goal_odd_even
MLS (tournament_id: 242)
Main markets: moneyline, moneyline_3_way, spread, total
Prop sub-types: both_teams_to_score, player_to_give_assist, player_to_have_at_least_1_shot, player_to_have_at_least_1_shot_on_target, player_to_have_at_least_2_shots, player_to_have_at_least_2_shots_on_target, player_to_have_at_least_3_shots_on_target, player_to_score_a_goal, player_to_score_at_least_2_goals, player_to_score_at_least_3_goals, player_to_score_or_give_assist, player_total_assists_milestones, player_total_saves_milestones, player_total_shots_milestones, player_total_shots_on_target_milestones, player_total_tackles_milestones, team_clean_sheet, total_goal_odd_even
WNBA (tournament_id: 1600000176)
Main markets: first_half_moneyline, first_half_spread, first_half_total, moneyline, spread, sup_moneyline, total
Prop sub-types: player_to_record_a_double_double, player_to_record_a_triple_double, player_total_3_pointers_made_milestones, player_total_assists, player_total_assists_milestones, player_total_points, player_total_points_assists, player_total_points_assists_milestones, player_total_points_milestones, player_total_points_rebounds, player_total_points_rebounds_assists, player_total_points_rebounds_assists_milestones, player_total_points_rebounds_milestones, player_total_rebounds, player_total_rebounds_assists, player_total_rebounds_milestones, player_total_three_pointers_made
World Cup (tournament_id: 53)
Main markets: moneyline, moneyline_3_way, spread, sup_moneyline, total
Prop sub-types: both_teams_to_score, player_to_give_assist, player_to_have_at_least_1_shot, player_to_have_at_least_1_shot_on_target, player_to_have_at_least_2_shots, player_to_have_at_least_2_shots_on_target, player_to_have_at_least_3_shots_on_target, player_to_score_a_goal, player_to_score_at_least_2_goals, player_to_score_at_least_3_goals, player_to_score_or_give_assist, team_clean_sheet, total_goal_odd_even
NCAAB (tournament_id: 648)
Main markets: first_half_moneyline, first_half_spread, first_half_total, moneyline, spread, sup_moneyline, total
Prop sub-types: player_total_assists, player_total_blocks, player_total_points, player_total_points_assists, player_total_points_rebounds, player_total_points_rebounds_assists, player_total_rebounds, player_total_rebounds_assists, player_total_steals, player_total_three_pointers_made, player_total_turnovers, team_total_points
NCAA / NCAAF (tournament_id: 27653)
Main markets: 1st_quarter_moneyline, 1st_quarter_spread, 1st_quarter_total, first_half_moneyline, first_half_spread, first_half_total, moneyline, spread, sup_moneyline, total
Prop sub-types: first_team_to_score, player_interceptions_thrown, player_total_completions, player_total_passing_attempts, player_total_passing_touchdowns, player_total_passing_yards, player_total_receiving_yards, player_total_receptions, player_total_rushing_yards, team_total_points, to_score_a_touchdown
NHL (tournament_id: 234)
Main markets: moneyline, moneyline_3_way, spread, sup_moneyline, total
Prop sub-types: first_period_goal_in_first_ten_minutes, player_powerplay_points, player_to_score_a_goal, player_total_assists, player_total_blocked_shots, player_total_goals_allowed, player_total_points, player_total_saves, player_total_shots_on_goal, team_total_goals
UFC (tournament_id: 1500000003)
Main markets: moneyline, sup_moneyline, total
Prop sub-types: fight_to_go_the_distance, fighter_to_win_by_any_knockout_submission_dq, fighter_to_win_by_decision, fighter_to_win_by_knockout_tko, fighter_to_win_by_split_or_majority_decision, fighter_to_win_by_submission, fighter_to_win_by_unanimous_decision, fighter_total_significant_strikes_landed
Club World Cup (tournament_id: 36)
Main markets: moneyline, spread, total
Prop sub-types: both_teams_to_score, team_clean_sheet, total_goal_odd_even
Presidents Cup (tournament_id: 1600000163)
Main markets: 1st_5th_inning_moneyline, 1st_5th_inning_spread, 1st_5th_inning_total, 1st_inning_moneyline, 1st_inning_spread, 1st_inning_total, moneyline, spread, sup_moneyline, total
Prop sub-types: team_total_runs
Golf (tournament_id: 1600000234)
Main markets: 1st_round_matchup, 2nd_round_matchup, 3rd_round_matchup, 4th_round_matchup, make_the_cut, moneyline, sup_moneyline, tournament_matchup, tournament_top_10_finish, tournament_top_20_finish, tournament_top_5_finish, tournament_winner
Prop sub-types: none currently
Tennis — 68 ATP/WTA tour events + Grand Slams (M/W draws of Australian Open, French Open, Wimbledon; full ATP/WTA season calendar)
Main markets: 1st_set_moneyline, moneyline, spread, total, total_sets, sup_moneyline
Prop sub-types: player_a_to_win_a_set, player_b_to_win_a_set
4. Register your subscription
POST <BASE_URL>/partner/v4/mm/websocket
Headers: { "Authorization": "<token>", "Content-Type": "application/json", "X-CFTC-Terminology": "true" }
X-CFTC-Terminology: true is what gets you the service=6 channels and the v2.market_selections binding this guide documents (Section 1). Omit it and you're registered on the legacy service=3 path instead, with CFTC-vocabulary events unavailable.
{
"socket_id": "1234.5678",
"service": "pusher",
"subscriptions": [
{ "type": "event", "ids": ["18756"] },
{ "type": "event_subtype", "ids": ["18756:player_to_record_a_double_double"] }
]
}event_subtypeid format is"{event_id}:{sub_type}".- The response reflects your complete desired set of subscriptions. Each call's
authorized_channelechoes back auth for exactly the channels you listed in that call. This does not by itself tear down channels from an earlier call that you omit this time — see Unsubscribing below for how to actually remove a channel. servicedefaults to"pusher"if omitted — this is the wire protocol's name, not a vendor reference (see the note at the top of this guide), and it stays literally"pusher"under Talaria.
Response
{
"auth": "<string>",
"data": {
"success": true,
"status": "<string>",
"updated_at": 1784813285,
"subscriptions": [
{ "type": "<string>", "ids": ["<string>"] }
],
"authorized_channel": [
{
"channel_name": "<string>",
"auth": "<string>",
"binding_events": [
{ "name": "<string>", "type": "<string>" }
],
"scope": { "event_id": 0, "sub_type": "<string>" }
}
],
"channel_count": 0,
"channel_limit": 0,
"authenticated": { "auth": "<string>", "user_data": "<string>" }
}
}scope appears only on Event channels ({"event_id": ...}) and Sub-markets channels ({"event_id": ..., "sub_type": ...}) — it's not present on the main public channel or your private user channel.
Example response (sanitized)
{
"auth": "<app_key>:<hmac_signature>",
"data": {
"success": true,
"status": "CONNECTED",
"updated_at": 1784813285,
"subscriptions": [
{ "type": "tournament", "ids": ["109"] }
],
"authorized_channel": [
{
"channel_name": "private-broadcast-service=6-device_type=5",
"auth": "<app_key>:<hmac_signature_1>",
"binding_events": [
{ "name": "tournament_109", "type": "tournament" },
{ "name": "general", "type": "general" }
]
},
{
"channel_name": "private-service=6-device_type=5-user=<your_account_id>",
"auth": "<app_key>:<hmac_signature_2>",
"binding_events": [
{ "name": "orders", "type": "orders" },
{ "name": "health_check", "type": "private_system_signal" }
]
},
{
"channel_name": "private-broadcast-service=6-device_type=5-event=10078829",
"auth": "<app_key>:<hmac_signature_3>",
"binding_events": [
{ "name": "market_selections", "type": "market_selections" },
{ "name": "v2.market_selections", "type": "market_selections" }
],
"scope": { "event_id": 10078829 }
},
{
"channel_name": "private-broadcast-service=6-device_type=5-event=10078829-subtype=player_total_hits",
"auth": "<app_key>:<hmac_signature_4>",
"binding_events": [
{ "name": "market_selections", "type": "market_selections" },
{ "name": "v2.market_selections", "type": "market_selections" }
],
"scope": { "event_id": 10078829, "sub_type": "player_total_hits" }
}
],
"channel_count": 4,
"channel_limit": 400,
"authenticated": {
"auth": "<app_key>:<hmac_signature_5>",
"user_data": "{\"id\":\"<your_account_id>\"}"
}
}
}Field notes:
subscriptions— echoes back what you registered.authorized_channel— one entry per channel you're authorized on. Usechannel_name+authto subscribe.binding_eventstells you which event name(s) to bind on that channel — each has anameto bind and atypedescribing the category of payload (tournament,general,orders,private_system_signal,market_selections). The main public channel and your private user channel each carry two binding events; Event and Sub-markets channels also carry two —market_selections(legacy schema) andv2.market_selections(CFTC schema) — bindv2.market_selections.scope— present on Event/Sub-markets channels only. Classify incoming messages byscope, not by channel name.channel_count/channel_limit— your current usage and cap. Always readchannel_limitfrom the response — don't hardcode it, as it's configured per deployment environment (sandbox/staging is lower than production) and can change.authenticated—auth+user_dataneeded to complete the sign-in handshake (next section).rejected— a partner may see this array if some requested subscriptions couldn't be honored (see Rejection reasons).- Each channel's
authonly works for that channel — reusing one channel'sauthto subscribe to a different channel will fail.
5. Unsubscribing
To stop receiving updates on a channel you're currently subscribed to, send the wire-protocol unsubscribe event directly — re-registering with a smaller subscription set does not do this on its own (see the note in Section 4):
{
"event": "pusher:unsubscribe",
"data": {
"channel": "private-broadcast-service=6-device_type=5-event=18756-subtype=first_half_moneyline"
}
}- This is fire-and-forget — Talaria stops delivering on that channel immediately, but sends back no confirmation event. Don't wait for one.
- It's scoped to one channel per call — send one
pusher:unsubscribeper channel you want to drop. - Disconnecting the socket unsubscribes you from everything. Reconnecting gets you a fresh
socket_idwith no channels carried over — you re-register from a clean slate (Section 4). - There's no per-channel REST endpoint for this. The only REST-level teardown is the legacy
DELETE /partner/mm/pusher, which terminates the entire connection, not a single channel — it has no/v4equivalent and isn't a substitute forpusher:unsubscribe.
6. Connecting end-to-end: the full handshake
-
Get connection config —
GET /partner/websocket/connection-config(Section 2) -
Connect to Talaria and capture
socket_idfrompusher:connection_established(Section 2) -
Discover
event_id/sub_typevia REST (Section 3) -
Register your subscription —
POST /partner/v4/mm/websocket(Section 4) -
Sign in, using the
authenticatedblock from the register response:{ "event": "pusher:signin", "data": { "auth": "<app_key>:<hmac_signature>", "user_data": "{\"user_id\":\"<your_account_id>\"}" } } -
Wait for confirmation:
{ "event": "pusher:signin_success", "data": {} } -
Subscribe to each authorized channel, using that channel's own
auth+channel_namepair from Section 4:{ "event": "pusher:subscribe", "data": { "auth": "<app_key>:<hmac_signature>", "channel": "private-broadcast-service=6-device_type=5-event=18756-subtype=first_half_moneyline" } } -
Wait for confirmation, per channel:
{ "event": "pusher_internal:subscription_succeeded", "data": "{}", "channel": "<channel-name>" } -
Bind
v2.market_selectionsand consume (next section).
7. Consuming events
- Bind
v2.market_selectionson each authorized channel — that's the CFTC-vocabulary event (strike/price/quantity). The legacymarket_selectionsevent is also bound on the same channels, carrying the old vocabulary (line/odds/stake); only bind it if you still need that shape. This applies only to the new Event and Sub-markets channels — if you're already consuming the main public channel today, it doesn't change and needs no re-binding. - Want a public trade tape? That's a separate event —
trade_execution(or, on the legacy vocabulary,matched_bet) — and it is not on the Event/Sub-markets channelmarket_selectionslives on. It's bound on the channel from a{"type": "tournament", ...}subscription instead, under the binding name your registration response actually lists (tournament_{id}and/orv2.tournament_{id}) — see WebSocket Events for the exact binding names and payload shape. It's anonymized (price and size, no order ownership). If you need fills on your own resting orders specifically, that's theordersevent on your private user channel instead. - Each channel has its own
authstring, returned per-entry inauthorized_channel. Subscribe to a channel using that channel's ownauth— reusing another channel'sauthwill fail. - Payload shape is unchanged from before the channel split.
- Classify incoming messages by
scope, not by channel name — this is the single most important behavior change to get right, since Event and Sub-markets channels all publish under the same event name.
8. Sub-type canonicalization
Channel names can't contain - or =, so sub_type values are canonicalized on the way in: lowercased; spaces, /, and - become underscores; anything else is dropped.
| You send | Channel carries |
|---|---|
MoneyLine | moneyline |
First Half Total | first_half_total |
{Player Total/Blocked-Shots} | player_total_blocked_shots |
{} (empty/invalid) | rejected — malformed_id |
Send whatever your market data gave you as-is; use the canonical value echoed back in scope.sub_type as your source of truth for matching.
Current classification rules:
- Halves, quarters, and innings are main markets, not props — e.g.
first_half_total,1st_quarter_spread,1st_5th_inning_moneylineride the Event channel. sup_moneylineandmoneyline_3_wayare main markets, despite the naming.player_*andteam_*are almost always props (the large majority of sub-types), but not exclusively —both_teams_to_score,first_team_to_score, andtotal_goal_odd_evenare props too, without that prefix.- The main-market list is per-tournament server configuration and can change — don't replicate it client-side. Subscribing to the
eventchannel always gets you all current main markets for that event.
9. Channel capacity planning
- Your channel limit per socket is configured per deployment environment, not per account. The main public channel and your private user channel don't count against it. Read
channel_limitfrom the response every time — don't hardcode it, and don't assume it's the same across environments (sandbox/staging is lower than production). - The limit counts the cumulative union of channels for a socket — re-registering with different events keeps consuming headroom, it doesn't reset.
- Reconnecting resets it — a new
socket_idgives you a clean slate. - Going over the cap rejects the entire request, with HTTP 400 and reason
exceed_subscription_count. - You get one Sub-markets channel per (event, sub_type) pair. For example, NFL carries 26 prop sub-types — at a 400-channel limit, roughly 15 concurrent NFL events at full prop coverage (~390 channels) would approach the cap. Subscribe selectively rather than to every event's full prop set, and size your usage against the actual
channel_limityour account gets back.
10. Rejection reasons
| Reason | Cause |
|---|---|
wildcard_not_allowed | ids: ["all"] — name each event explicitly instead |
malformed_id | Non-numeric event id, or missing : separator in an event_subtype id |
unknown_type | Unrecognized type value |
11. Keep-alive & error handling
- ProphetX actively sends a
health_checkmessage so you can confirm reachability — this is separate from Talaria's own connection ping. - Respond to the transport's own ping/pong: protocol v5+ requires responding to every
pusher:pingwithpusher:pong; later protocol versions can rely on default WebSocket ping handling. - Transport-level errors arrive as
pusher:error.
12. Migration checklist
- Fetch
event_id, thensub_typeper market (Section 3) — don't hardcode the snapshot tables, and don't assume a static main/prop rule - Send
event/event_subtypeentries insubscriptions[], as a complete set on every call (Section 4) - Classify messages by
scope, not channel name or event name (Sections 4 & 7) - Send
X-CFTC-Terminology: truewhen registering, and bindv2.market_selectionson every authorized channel (Sections 4 & 7) - Handle
rejected[]and HTTP 400exceed_subscription_count(Sections 9 & 10) - Re-send the complete subscription set on every register call — don't append (Section 4)
- Send
pusher:unsubscribefor any channel you no longer want, rather than relying on a smaller re-register alone (Section 5) - Migrate props before July 29, 2026; migrate main markets before August 12, 2026
- Handle the transport's ping/pong and the ProphetX
health_checkmessage separately (Section 11)
Updated 6 days ago
