Skip to content
Live2026 – now02 / 12

Datamagnet Signals

Scheduled monitors that turn LinkedIn activity into webhook alerts

Signal types
7
Schedules
Hourly to weekly
Dispatch tick
15 min
Webhook delivery
7 attempts
Lead score
1 – 3
Databases
2

Signals lets a Datamagnet customer watch a list of people for job changes, new posts or their own reactions and comments, or watch a topic (keyword, industry, company or person) for the people who engage with it. Each signal runs on a schedule from hourly to weekly and delivers change alerts or ICP-qualified leads by signed webhook and email. It is a separate engine behind the main Datamagnet API, built on AWS Lambda, FastAPI and PostgreSQL.

My part. Sole engineer: designed and built the scheduler, Lambda worker, FastAPI control plane, Terraform, monitoring dashboard and the public Signals API, and operates it in production.

The problem

Sales and recruiting teams want to act the moment a champion changes jobs or a prospect engages with a relevant post, but polling an API yourself means building a scheduler, snapshot storage, diffing, de-duplication, ICP filtering, retries and delivery. The hard parts are operational: a run can need more work than one serverless invocation allows, every upstream call is billed, nobody wants the same person reported twice, and a crash between finding a lead and sending it must not lose the lead.

How it is built

Control plane. A FastAPI service on AWS App Runner owns job CRUD, metrics and the customer-facing leads read, authenticated with an API key. Jobs live in a scheduler PostgreSQL database with a next-run timestamp. The main Datamagnet API proxies its public /signal endpoints to this service, resolving the submitted profile URLs concurrently under a deadline so one slow lookup cannot hold the whole request.

Dispatch and execution. An EventBridge rule fires a Lambda every 15 minutes. The dispatcher locks due jobs with FOR UPDATE SKIP LOCKED, parks each one past a buffer window, and invokes one asynchronous Lambda per job, so two invocations can never run the same job at once and a worker that finds its job already ran skips it rather than billing it twice. The API can also trigger a baseline run immediately after a signal is created.

Detection. Profile signals fetch each tracked profile through the Datamagnet API, hash the response and compare it to the stored snapshot; only a changed profile reaches the LLM, which writes a plain-language summary and a confidence score. Engagement signals collect the people who liked or commented on matching posts, de-duplicate them against per-signal seen-profile state, filter and score them against the customer's ICP on a 1 to 3 scale, store them, then deliver. A second watcher database holds snapshots, detected changes, leads and de-duplication state, separate from the scheduler's own tables.

Reliability and operations. Every run has a time and call budget: when it runs out the run ends as partial, delivers what it gathered, records which posts and groups it covered, and the next run starts with what was covered least recently. Webhooks are HMAC-signed and retried on a 7-attempt schedule from a delivery queue; leads are stored as undelivered before sending and a daily sweep re-sends any a crash left behind. Run history is kept for 14 days. Terraform provisions Lambda, App Runner, EventBridge, SNS, ECR and Secrets Manager; GitHub Actions builds and ships both images on push; a Next.js dashboard on Vercel shows success rates and failures, and an SNS alarm emails on Lambda errors.

What it taught me

  • A run killed at the Lambda deadline stores nothing and is billed again when the job comes due; a per-run time and call budget that ends the run as partial and carries coverage forward turned that into bounded, resumable work.
  • Hash before you think: comparing a SHA-256 of the fetched profile with the stored snapshot means most runs never call the LLM at all, and the LLM only ever sees a real change.
  • Store first, deliver second, flag last: writing a lead as undelivered before sending it made a mid-run crash recoverable, and a daily redelivery sweep closes the gap without duplicating what a running job is about to send.

Architecture

A customer creates a signal through the Datamagnet API, which proxies the call to the Signals control plane. The control plane writes the job to the scheduler database and asks the worker for an immediate baseline run. Every 15 minutes EventBridge wakes the dispatcher Lambda, which locks due jobs and fans out one worker per job. Each worker fetches data through the Datamagnet API, compares it with snapshots in the watcher database, sends only real changes to the LLM for a summary, stores the result, and delivers it by signed webhook and email.

  1. Layer 1

    • CustomerClient

      REST, dashboard, MCP

      → Datamagnet API (Create signal)

    • EventBridgeQueue

      Fires every 15 minutes

      → Lambda worker (Every 15 min)

  2. Layer 2

    • Datamagnet APIService

      Auth, credits, URL resolution

      → Signals API (Proxied call)

  3. Layer 3

    • Signals APIService

      FastAPI: jobs, leads, metrics

      → Scheduler DB (Write job) → Lambda worker (Baseline trigger)

  4. Layer 4

    • Lambda workerWorker

      Dispatch, run, deliver

      → Scheduler DB (Lock due jobs) → Datamagnet API (Fetch data) → Watcher DB (Snapshots, leads) → LLM (Classify changes) → Webhooks and email (Webhook, email)

  5. Layer 5

    • Scheduler DBStore

      Jobs, run logs, webhook queue

    • Watcher DBStore

      Snapshots, leads, dedup state

    • LLMModel

      Summarise changes, score fit

    • Webhooks and emailExternal

      Signed POST, SES digest

ClientServiceStoreQueueWorkerModelExternalDashed: feedback loop

Stack

Backend

  • Python 3.13
  • FastAPI
  • psycopg2
  • Pydantic

Data

  • PostgreSQL

Infrastructure

  • AWS Lambda (container image)
  • AWS App Runner
  • Amazon EventBridge
  • Amazon SNS
  • Amazon ECR
  • AWS Secrets Manager
  • AWS SES
  • Terraform
  • GitHub Actions
  • Vercel
  • Sentry

Frontend

  • Next.js
  • Tailwind CSS
  • Recharts

AI

  • OpenAI API
  • OpenRouter