new-site/docs/trucking-state-campaign-send-runbook.md
justin 058d7cfbfe docs: trucking state-campaign send runbook
Ties the prioritized marketing-send plan (NY HUT -> CT HUF -> D&A -> New
Carrier Startup -> CA MCP) to the existing Listmonk builders
(setup_trucking_campaigns.py creates the drafts + tests;
populate_new_carrier_startup_campaign.py builds the data-targeted New
Carrier audience). Draft/populate/test steps are safe and idempotent;
starting a bulk send is flagged as an irreversible operator-only step.
Cross-references the new fulfillment_status machine and the authorization
e-sign so campaign expectations match fulfillment.
2026-06-02 16:51:08 -05:00

4.1 KiB

Trucking State-Campaign Send Runbook

Companion to trucking-marketing-send-plan.md. The plan ranks the sends; this runbook is the exact, repeatable procedure to launch them. Everything up to the final "start the send" step is safe and idempotent. Starting a bulk send is irreversible and is the only step that should be run deliberately by an operator.

Prerequisites

  • DATABASE_URL pointing at production Postgres (FMCSA census + compliance_orders).
  • LISTMONK_URL, LISTMONK_USER, LISTMONK_PASS for the Listmonk instance.
  • Migrations applied through at least 083_fmcsa_campaign_tracking.sql (listmonk_campaign_type, listmonk_sent_at) and, for fulfillment status, 086_state_trucking_fulfillment_status.sql.

Prioritized send order

Lowest fulfillment friction first (see the plan for the rationale):

  1. NY HUT setup — clean tax-pro authorization (E-ZRep / TR-2000).
  2. CT Highway Use Fee — electronic via myconneCT, CSV vehicle import.
  3. DOT Drug & Alcohol Program — no state portal; recurring.
  4. New Carrier Startup Bundle — broad cross-sell; data-targeted.
  5. CA MCP + CARB — medium friction (portal + insurance coordination).

Step 1 — Build/refresh the audience lists

The draft campaigns and their lists are created by:

LISTMONK_URL=LISTMONK_USER=api LISTMONK_PASS=\
  python3 scripts/setup_trucking_campaigns.py

This is safe: it creates draft campaigns (NY HUT, CT HUF, D&A, CA MCP, New Carrier Startup, hazmat) and sends a single test to CAMPAIGN_TEST_EMAIL. It does not start any bulk send.

For the New Carrier Startup list specifically, populate it with the data-targeted, billed-at-cost-aware audience (carriers with usable email, recent FMCSA add_date, small fleet, and no paid Performance West startup order):

# Preview first — read-only, prints sample candidates and a count.
DATABASE_URL=… python3 scripts/populate_new_carrier_startup_campaign.py --dry-run

# Then import (does NOT mark listmonk_sent_at; adding to a list != sending).
DATABASE_URL=LISTMONK_URL=LISTMONK_PASS=\
  python3 scripts/populate_new_carrier_startup_campaign.py --limit 500 --recent-days 180

Subscriber attributes set: company, dot_number, state, city, trucks, drivers, add_date, missing_items_html, startup_score.

State lists (NY/CT/CA) are populated from the FMCSA census by base/operating state. Use the state-segment tooling to attach carriers by phy_state / operating-state to each list before sending.

Step 2 — Review the draft + test send

In Listmonk, open each draft campaign and:

  • confirm the subject and missing_items_html / company merge tags render;
  • confirm the list count is the audience you expect;
  • confirm the test email looks correct in a real inbox (rendering, links, CTA).

Step 3 — Start the send (operator action, irreversible)

Send one campaign at a time, in the priority order above, and watch deliverability/bounces before starting the next. In Listmonk, set the campaign status to running (or scheduled with a send time).

For the scheduled MCS-150 / inactive-USDOT regional sends, the nightly builder build_trucking_campaigns.py already schedules per timezone; the state campaigns here are launched manually so each can be paced.

After a state campaign sends, record campaign-type-specific tracking (listmonk_campaign_type) rather than the global listmonk_sent_at, so an unrelated future campaign to the same carrier is not blocked.

Fulfillment expectation set at send time

Every state-filing campaign points at a paid service whose fulfillment now follows the compliance_orders.fulfillment_status machine (migration 086):

authorization_required -> authorization_signed -> awaiting_customer_delegation
  -> awaiting_secure_credentials -> awaiting_government_fee_approval
  -> awaiting_insurance_filing -> ready_to_file -> filed_waiting_state -> completed

The first customer touch after purchase is the Limited Authorization to File e-sign (the signature is stamped exactly on the form's signature line), so the campaign copy and order pages already disclose the authorization step and the billed-at-cost government fees.