Fixture {{ event.fixture_id || '-' }} · Player {{ event.player_id }} · {{ event.market_type }}
In {{ eventIngressHttpPath(event) }}
Out {{ eventOutboundEndpointsLine(event) }}
Fixtures list, in-memory snapshots, request stream, and Abelson outgoing decisions.
{{ stats.bind_host || '-' }}:{{ stats.port || '-' }}{{ stats.detected_ip || 'unknown' }}{{ stats.enabled_clients ?? 0 }} enabled{{ clientConfigFile }}
{{ clientsReloadMessage }}
{{ clientConfigReloadHint }}
{{ stats.monitoring_url || 'waiting for service' }}{{ card.label }}
{{ card.value }}
{{ webhookDeliveriesError }}
{{ monitoringClearMessage }}
Requests & Outgoings
Service base — {{ stats.base_url }}
· each row shows the inbound route on this service and outbound Abelson POST URLs when present.
Fixture {{ event.fixture_id || '-' }} · Player {{ event.player_id }} · {{ event.market_type }}
In {{ eventIngressHttpPath(event) }}
Out {{ eventOutboundEndpointsLine(event) }}
| Select | Event | Market | League | Match | Endpoint | Request | Response | Source | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| No API outgoings yet.Memory + SSE only — enable Load ClickHouse for historical rows. | ||||||||||||||||||||||||||||||||||||||||||||||||
|
#{{ item.fixtureIdLabel }}
{{ item.matchLabel }}
{{ item.leagueLabel }}
{{ item.rowCount }} outgoing{{ item.rowCount === 1 ? '' : 's' }}
{{ item.errorCount }} failed
|
||||||||||||||||||||||||||||||||||||||||||||||||
| {{ webhookDeliveriesFormatWhen(item.row.requested_at) }} | {{ item.row.event_type || '—' }} | {{ item.row.market || '—' }} | {{ item.row.fixture_id != null ? item.row.fixture_id : '—' }} | {{ item.row.league_name != null && item.row.league_name !== '' ? item.row.league_name : '—' }} | {{ item.row.match_label != null && item.row.match_label !== '' ? item.row.match_label : '—' }} | {{ item.row.endpoint_url || '—' }} | {{ item.row.response_status != null ? item.row.response_status : '—' }} | {{ item.row.duration_ms != null && item.row.duration_ms !== '' ? (Number(item.row.duration_ms).toFixed(Number(item.row.duration_ms) >= 100 ? 1 : 2) + 'ms') : '—' }} | {{ webhookDeliveriesFormatBytes(item.row.request_bytes) }} | {{ webhookDeliveriesFormatBytes(item.row.response_bytes) }} | {{ item.row.source_ip && item.row.source_ip !== '' ? item.row.source_ip : '—' }} | |||||||||||||||||||||||||||||||||||||
|
Current state sent to API client As of {{ webhookDeliveriesFormatWhen(item.row.requested_at) }}
Snapshot history (newest first)
{{ webhookDeliveryHistoryLoadingKey === webhookDeliveryKey(item.row) ? 'Loading snapshots…' : webhookDeliveryHistoryScopeLabel(item.row) }}
Loading historical snapshots for this bucket…
{{ webhookDeliveryHistoryError(item.row) }}
No historical snapshots were returned for this bucket on this client. Increase backend retention/fetch limit if expected.
{{ webhookDeliveriesFormatWhen(snap.timestamp) }}
{{ tag.label }}
Latest
{{ snap.selections.length }} {{ snap.selections.length === 1 ? 'player' : 'players' }} · Source {{ snap.source }}
API client response Response returned by {{ item.row.client_name || item.row.endpoint_url || 'client endpoint' }}
{{ item.row.response_status != null ? item.row.response_status : '—' }}
{{ webhookDeliveryDurationText(item.row.duration_ms) }}
{{ item.row.error }} {{ webhookDeliveryResponseDisplay(item.row) }}
|
||||||||||||||||||||||||||||||||||||||||||||||||
API outgoings diagnostics
Scanned {{ webhookDeliveriesScan.merged_events }} events (memory cap {{ webhookDeliveriesMeta.max_in_memory_events || '—' }}, fetch limit {{ webhookDeliveriesMeta.fetch_limit || '—' }}) → {{ webhookDeliveriesScan.eligible_events }} eligible, {{ webhookDeliveriesScan.delivery_rows_built }} delivery rows, table shows {{ webhookDeliveriesMeta.total }}.
send_abelson {{ webhookDeliveriesScan.event_type_send_abelson }} · updated {{ webhookDeliveriesScan.event_type_updated }} · skipped_unchanged {{ webhookDeliveriesScan.decision_skipped_unchanged }} · with client_results {{ webhookDeliveriesScan.with_client_results }} · posted_wire_only {{ webhookDeliveriesScan.with_posted_wire_only }}
Last manual: seq {{ webhookDeliveriesScan.last_send_abelson.seq }} · {{ webhookDeliveriesScan.last_send_abelson.decision }} · sent={{ webhookDeliveriesScan.last_send_abelson.sent }} · eligible={{ webhookDeliveriesScan.last_send_abelson.eligible }} · pass_unchanged={{ webhookDeliveriesScan.last_send_abelson.pass_unchanged }} · skip_unchanged={{ webhookDeliveriesScan.last_send_abelson.skip_unchanged_payloads }} · client_results={{ webhookDeliveriesScan.last_send_abelson.client_results }}
Trace log: {{ webhookDeliveriesMeta.trace_log || 'logs/api_outgoings_trace.log' }}
Snapshot history (newest first)
Fixture #{{ webhookDeliveryHistoryTimelineModal.row.fixture_id ?? '—' }} · {{ webhookDeliveryHistoryTimelineModal.row.match_label || '—' }} · {{ webhookDeliveryHistoryTimelineModal.row.endpoint_url || webhookDeliveryHistoryTimelineModal.row.client_name || '—' }}
Current state sent to API client
As of {{ webhookDeliveriesFormatWhen(webhookDeliveryHistoryTimelineModal.row.requested_at) }}
| Player | Player ID | Team ID | Price | % | Susp | Settlement | Active |
|---|---|---|---|---|---|---|---|
| No selections in this payload. | |||||||
| {{ sel.name || '—' }} | {{ sel.player_id ?? '—' }} | {{ sel.team_id ?? '—' }} | {{ sel.raw_price ?? '—' }} | {{ webhookDeliveryFormatPercent(sel.player_percentage) }} | {{ sel.suspended ? 'Yes' : 'No' }} | {{ webhookDeliverySelectionStateText(sel) }} | |
| Player | Active | Price | % | Suspended | Settlement | Source | Change |
|---|
| {{ sel.name || '—' }} | {{ webhookDeliverySelectionActive(sel) ? 'Active' : 'Closed' }} | {{ sel.raw_price ?? '—' }} | {{ webhookDeliveryFormatPercent(sel.player_percentage) }} | {{ sel.suspended ? 'Yes' : 'No' }} | {{ webhookDeliverySelectionStateText(sel) }} | {{ snap.source }} | {{ webhookDeliveryChangeLabel(sel.__change) }} |
| All selections hidden by filters. | |||||||
Nothing in the outgoing payload changed. The C++ change-detection (snapshots_equal) also compares fields that are never transmitted — they collapse into "Suspended": {{ webhookDeliverySnapshotHiddenCompareFields().join(', ') }}. A re-send with no visible change is almost always one of these.
| Field | Previous | Current | Source (LineSnapshot) |
|---|---|---|---|
| {{ f.label }} hidden on table | {{ f.previous }} | {{ f.current }} | {{ f.source }} |
| No changed fields for this player. | |||
Snapshot JSON overview
Delivery overview
Change badges vs previous snapshot: {{ webhookDeliveryJsonModalComparedToLabel }}
Compared fields (per player, vs prior delivery in bucket): {{ webhookDeliveryChangeCompareFields.join(', ') }}
API client response
{{ webhookDeliveryResponseDisplay(webhookDeliveryJsonModalRow) }}
{{ webhookDeliveryJsonModalPayloadDiff.diffLineCount }} differing line{{ webhookDeliveryJsonModalPayloadDiff.diffLineCount === 1 ? '' : 's' }} changed (same row) this snapshot only previous only
This snapshot · request_payload
{{ webhookDeliveriesFormatWhen(webhookDeliveryJsonModalSnap ? webhookDeliveryJsonModalSnap.timestamp : webhookDeliveryJsonModalRow.requested_at) }} {{ tag.label }}
Previous snapshot · request_payload
{{ webhookDeliveriesFormatWhen(webhookDeliveryJsonModalPreviousDelivery.requested_at) }} {{ tag.label }}
No prior delivery in this bucket.
This snapshot
{{ prettyJson(webhookDeliveryJsonModalRow) }}
Previous snapshot
{{ webhookDeliveryJsonModalPreviousDelivery ? prettyJson(webhookDeliveryJsonModalPreviousDelivery) : '—' }}
Fixture outbound
{{ fixtureOutboundOverlayEntries.length }} events kept for this fixture in this browser session · server ring buffer still caps globally
Memory now (balanced lines cached for this fixture)
{{ outboundOverlaySnapshots.length }} row{{ outboundOverlaySnapshots.length === 1 ? '' : 's' }} ·
MySQL / cache
· max updated_at
{{ outboundOverlayLatestSnapshotTimes ? formatMonitoringDateTime(outboundOverlayLatestSnapshotTimes) : '—' }}
·
last Abelson wire POST
(recorded_at)
{{ outboundOverlayLatestWireSentDisplay }}
updated_at is the line row from the DB when the snapshot was cached.
Wire time is when this service logged a send (sent: true in the event stream), not the partner’s HTTP response time.
Each row is one outbound POST bucket: market_type|over|line or market_type|under|line. Players on that row are exactly that bucket’s selections[].
No over/under odds on snapshots — nothing to bucket.
| Bucket (one POST) | Roster players in selections[] | Selection rows over row or under row only |
|---|---|---|
|
{{ bucket.market_type }}
{{ bucket.displaySide }}
{{ fmt(bucket.balance_line) }}
{{ bucket.bucketKey }}
{{ bucket.snapshots.length }} selection{{ bucket.snapshots.length === 1 ? '' : 's' }}
|
{{ p.player_name || ('#' + p.player_id) }}
Sus
|
{{ p.player_name || ('Player ' + p.player_id) }}
{{ outboundSuspended(p) ? 'Suspended' : 'Active' }}
▲
{{ fmt(p.balance_line) }}
O
{{ fmtOddsShort(p.over_odds) }}
is_suspended
{{ outboundSuspended(p) ? 'true' : 'false' }}
{{ String(p.status) }}
{{ overlayFmtProbability(p.over_probability) }}
— %
{{ p.player_name || ('Player ' + p.player_id) }}
{{ outboundSuspended(p) ? 'Suspended' : 'Active' }}
▼
{{ fmt(p.balance_line) }}
U
{{ fmtOddsShort(p.under_odds) }}
is_suspended
{{ outboundSuspended(p) ? 'true' : 'false' }}
{{ String(p.status) }}
{{ overlayFmtProbability(p.under_probability) }}
— %
|
| Player | Market | Outcomes | Sus | Status |
|---|---|---|---|---|
| {{ row.player_name || ('#' + row.player_id) }} | {{ row.market_type }} |
▲
{{ fmt(row.balance_line) }}
O
{{ ' ' + fmtOddsShort(row.over_odds) }}
{{ overlayFmtProbability(row.over_probability) }}
▼
{{ fmt(row.balance_line) }}
U
{{ ' ' + fmtOddsShort(row.under_odds) }}
{{ overlayFmtProbability(row.under_probability) }}
|
{{ outboundSuspended(row) ? 'yes' : 'no' }} | {{ row.status || '—' }} |
Chronological send / decision trail
Newest first. Highlights line-field changes vs previous when stored.
Player {{ ev.player_id }} · {{ ev.market_type }}