I see prospects who replied on LinkedIn but my dashboard says 0 replies — what's wrong?

This was a real bug — fixed Apr 30, 2026 (LL#255). Reply detection on the LinkedIn side relies on a column called enrollment_id on every inbound message row, but every inbound linkedin_messages row written by the Unipile webhook ingest path (and the polling fallback) was being persisted with enrollment_id=NULL because neither path performed the canonical enrollment lookup before the INSERT.

Net: every inbound LinkedIn message landed in the database with no campaign attribution, every downstream reader (the linkedin_replied_at stamp on campaign_prospects, the auto-stop-on-reply check, the analytics reply-rate roll-up) silently filtered it out, and the dashboard showed 0 replies even when prospects had clearly responded. The worst part: campaigns kept sending follow-ups to prospects who had already replied.

The fix adds a canonical lookupEnrollmentForInboundMessage helper that the webhook handler and the poller fallback BOTH call before the INSERT — so every inbound message is now correctly attributed to its enrollment if one exists. We also ran a one-shot 120+ row backfill that retro-fits the lookup against historical NULL rows.

What you should see now:

Going forward, every inbound LinkedIn message is correctly attributed at write time, so this regression cannot recur. A CI grep test rejects any new INSERT INTO linkedin_messages outside the canonical helper file as defense in depth.

Back to all documentation | Contact support