Platform ·DarDev Team · 7 min read

Timeline Notes as an outreach audit trail in Twenty CRM

Twenty CRM timeline Notes record every outreach stage—Queued, Sent, Opened, Clicked, Replied—so sales staff see a full audit trail without digging through logs.

Twenty CRM person timeline showing outreach Notes for Queued Sent Opened and Replied stages

DarDev records every cold-outreach transition as a Note on the Person timeline in Twenty CRM. When platform-bus queues a message, sends tracked mail, syncs an open or click from Listmonk, or detects a reply in the outreach inbox, it writes one Note per stage—Queued, Sent, Opened, Clicked, Replied—so sales staff see a complete audit trail without SSH, log tailing, or a separate spreadsheet.

Twenty owns decisions: who to contact, when to approve, which follow-up task to create. Platform-bus is a thin executor that sends mail and mirrors status back to CRM. The timeline Notes pattern is the glue between those layers. It is how we run 20.tn school outreach today and the same pattern we document in our inside-unified-mailer-stack guide for any CRM-first pipeline on the DarDev platform.

Why Notes instead of fields alone

Person records carry structured fields such as outreachStatus, lastOutreachAt, and outreachPhase. Those fields drive Twenty workflows—filters on SENT trigger a follow-up delay, OPENED creates a hot-lead task, REPLIED routes to a reply follow-up. Fields alone are not enough for humans reviewing a contact: they show the current state, not the history of how you got there.

Timeline Notes append an immutable narrative. A staff member opening a school principal's record sees « Queued — intro preview for École … » followed by « Sent — intro to contact@school.tn » and later « Opened — intro campaign ». That sequence answers audit questions—when did we send, did they engage, did we already follow up—without exporting Listmonk logs or bus JSON.

Pipeline stages and Note labels

The 20.tn outreach pipeline maps cleanly to a small state machine. A person starts at NOT_SENT. A dry-run or preview workflow moves them to QUEUED with a Note describing subject and recipient. Live send-one with outreachApproved true transitions to SENT. Scheduled sync-engagement polls Listmonk for views and clicks, writing OPENED or CLICKED Notes. sync-replies scans the Reply-To inbox and sets REPLIED. Listmonk unsubscribe maps to OPT_OUT. Validation failures surface as ERROR with the reason in the Note body.

  • NOT_SENT → QUEUED: preview intro workflow with dryRun true
  • QUEUED → SENT: send-one after staff sets outreachApproved
  • SENT → OPENED / CLICKED: sync-engagement on a 15-minute schedule
  • SENT / CLICKED → REPLIED: sync-replies on a 30-minute schedule
  • SENT → OPT_OUT: Listmonk unsubscribe webhook or export sync
  • NOT_SENT → ERROR: missing email, failed validation, or bus rejection

Every arrow in that diagram creates exactly one Note on the Person. Bus code centralizes the wording so operators see consistent labels across hundreds of schools. Workflow designers react to outreachStatus field changes; they do not need to parse Note text.

Who writes Notes: platform-bus executor

Twenty workflows call HTTPS endpoints on mail.dardev.net—send-one for tracked Listmonk transactional sends, sync-engagement for opens and clicks, sync-replies for inbox matching. Each handler PATCHes the Person in Twenty and attaches a Note via the REST API. Auth uses a bearer token shared with other internal bus routes; workflows store the secret in Twenty's credential vault, not in Note bodies.

This split keeps orchestration in the CRM UI where sales already work. Staff run Manual workflows on a filtered view—20.tn ready private schools with email—rather than curling bulk send endpoints. Legacy bulk POST /api/20tn/outreach/send remains for ops preview only; production uses per-person send-one so every send produces a traceable Note chain.

Human-in-the-loop without losing the trail

Approval gates sit above the executor. A request-review workflow sets outreachApproved false and creates a Task for staff to edit outreachPersonalLine. After review, staff toggle outreachApproved true and run send intro. The preview workflow runs first with dryRun true, which still writes a Queued Note—so even rejected or revised outreach leaves a breadcrumb.

  1. Run preview intro (dryRun) → Queued Note with subject and recipient visible on timeline
  2. Staff edit personal line and school context on the Person record
  3. Set outreachApproved true after human sign-off
  4. Run send intro → Sent Note; outreachStatus becomes SENT
  5. Engagement workflows create Tasks on OPENED or CLICKED instead of auto-blasting the next mail

Follow-up mail uses a Person updated workflow with a three-day delay after SENT. If staff already called the school, they cancel the workflow run from See Runs—the Sent and any Task Notes remain, but no duplicate follow-up sends. That is the intended balance between automation and judgment.

What staff see on the timeline

Notes are plain text summaries, not full MIME dumps. A Sent Note typically includes phase (intro or followup), recipient email, and campaign identifier. Opened and Clicked Notes reference the Listmonk subscriber event timestamp. Replied Notes link the matched inbox subject line. Operators cross-check against Listmonk subscriber history when needed, but day-to-day triage happens in Twenty alongside company school fields and tasks.

Engagement workflows—opened task, clicked task, replied task—create linked Tasks on the Person and Company with school name, email, and a CRM deep link. Tasks complement Notes: Notes are the audit log; Tasks are the work queue. A clicked hot-lead Task title makes pipeline review fast while the Clicked Note proves when tracking fired.

Setup checklist for your workspace

  1. Run setup_20tn_crm_fields.py (or equivalent) for outreachStatus, outreachApproved, outreachPersonalLine, outreachCustomSubject
  2. Deploy platform-bus with send-one, sync-engagement, and sync-replies routes
  3. Create Twenty workflows from bootstrap payloads: preview, send, request review, follow-up, engagement tasks, scheduled sync HTTP steps
  4. Activate schedule workflows for engagement and reply sync
  5. Test on a small cohort with staff test recipients before ALLOW_LIVE school sends

Mail identity for tracked outreach uses send.dardev.net on Stalwart—never @dardev.net From headers in Listmonk. Reply-To points at a monitored mailbox on the send subdomain so sync-replies can match In-Reply-To headers to CRM people. See why-send-dardev-subdomain for the DNS and reputation rationale behind that split.

Comparing Notes to other audit patterns

Some teams log outreach only in Listmonk or only in CRM custom fields. Listmonk knows delivery and engagement but not sales context—school tier, approval state, or task outcomes. CRM fields alone lack chronology. External spreadsheets drift from production. Timeline Notes inside the same UI where reps work reduce context switching and survive staff turnover better than ad hoc Slack threads.

DarDev Services outreach uses a parallel bus pattern (services-outreach sync and send) with the same philosophical split: CRM orchestrates, bus executes, timeline or notes capture transitions. When you mirror this for another product, keep Note text short, idempotent handlers (sync jobs should not duplicate Notes on re-run), and workflow filters on structured fields rather than parsing Note bodies.

Does every workflow step create a Note?

No. Only bus executor endpoints that change outreach mail state write Notes—send-one, sync-engagement, sync-replies. Task-creating workflows add Tasks; preview dry-runs write Queued Notes; manual CRM edits do not unless they trigger a bus call.

Can staff delete or edit executor Notes?

Staff can edit Notes in Twenty if permissions allow, but they should not. Treat executor Notes as system events. Correct mistakes by running the appropriate workflow again or adding a manual Note explaining human action—do not rewrite Sent timestamps.

What if sync-engagement runs twice on the same open?

Bus handlers should be idempotent: if outreachStatus is already OPENED, skip duplicate Notes and PATCH only when transitioning to a new state. Scheduled sync is safe to run every fifteen minutes.

Where do preview and live sends differ on the timeline?

Preview (dryRun true) writes a Queued Note with subject and recipient but does not call Listmonk live send or set SENT. Live send-one after approval writes Sent and updates outreachStatus.

How does this relate to Listmonk tracking?

Listmonk records opens and clicks on subscribers. sync-engagement maps subscriber email back to Twenty Person and writes CRM Notes plus field updates. Listmonk remains the tracking source; Twenty is the sales-facing audit trail.

Get company news

Releases and announcements — confirm from your inbox.

Subscribe to updates