Skip to content

Fix contact subscription and verification semantics for list/campaign sends #57

@alexeygrigorev

Description

@alexeygrigorev

Context

CMP will rely on Datamailer contacts for campaigns and future recipient-list sends. The current contact state semantics are not safe enough for this.

Observed during CMP/Datamailer protocol review:

  • CMP contact upsert examples use status: subscribed, but existing CMP sync may omit it during some flows.
  • Datamailer defaults missing contact upsert status to pending.
  • Campaign snapshot logic skips contacts whose client/audience subscription is not subscribed.
  • verified=true in the contact API verifies the subscription, but campaign snapshot eligibility checks the global contact verification timestamp.
  • Contact status and campaign snapshot should agree about whether a contact can receive marketing/list/campaign email.

Desired behavior

  • Contact upsert with status=subscribed and verified=true makes the contact eligible for marketing/list/campaign sends unless suppressed.
  • Contact status and campaign/list snapshot eligibility use the same verification/subscription semantics.
  • Transactional sends continue to bypass marketing unsubscribe where appropriate, but still respect hard suppressions such as hard bounce and complaint.

Acceptance criteria

  • Add or update tests showing a contact upserted through the client API with status=subscribed and verified=true is eligible for campaign/list snapshot.
  • Contact status can_send_marketing matches campaign/list eligibility for the same contact.
  • Pending/unsubscribed contacts are skipped from campaign/list sends.
  • Hard bounced or complained contacts are skipped/suppressed.
  • Document the exact meaning of verified=true for contacts and subscriptions.

Related

This blocks Datamailer recipient lists and CMP-driven course email targeting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions