Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

October 14, 2026

Mail campaigns take new properties at any time

Campaigns now work as reusable sequences of mail. You can add properties to a campaign that accepts them while it is ready, active, or paused, and each property starts at step 1 on its own schedule.
Breaking changes. Review these before you upgrade an integration:
  • Campaign responses report status as ended for campaigns that used to read completed or cancelled, and as ready for campaigns saved with no audience or with no mail queued. If your integration compares status to completed or cancelled, compare it to ended, and handle ready.
  • Request validation errors on the campaign Endpoints now use the standard error body: {"error": {"code": "validation_error", "message": "Validation failed", "request_id": "...", "details": {"issues": [{"path": "...", "message": "..."}]}}}. Before, a failed check returned the validator's own body. Read error.code and error.details.issues instead.
  • An unsupported status filter value on List Campaigns now returns 400 validation_error instead of being ignored.
  • Pausing or resuming an ended campaign returns 409 campaign_ended.
Campaign statuses. Campaigns now have five statuses: draft, ready, active, paused, and ended.
  • ready is new. A campaign is ready when it was saved with no audience or has no mail queued, including after it sends all of its scheduled mail. You can add properties to it.
  • Campaigns that were Completed or Cancelled are now reported as ended. The API returns "status": "ended" for them; no campaign data was changed.
  • The status filter on List Campaigns accepts ended, which matches both. The older filter values completed and cancelled keep working as filters and return the same campaigns as before.
New fields. Campaigns have is_accepting_properties and can_add_properties. Campaigns created before this change, and campaigns created with an audience but without accepts_properties: true, have is_accepting_properties: false and run as before: they read ended when their mail is done.
New Endpoints.
  • Add Properties to Campaign: POST /v1/mail/campaigns/{id}/properties with property_ids and recipient (owner or resident). The response counts added properties and lists each skipped property with its reason.
  • Estimate Adding Properties: GET /v1/mail/campaigns/{id}/properties/estimate?count=N returns the charge due today and later.
  • End Campaign: POST /v1/mail/campaigns/{id}/end ends a ready, active, or paused campaign permanently. It returns 409 campaign_ended for an ended campaign and 409 campaign_is_draft for a draft.
  • DELETE /v1/mail/campaigns/{id} (Cancel Campaign) keeps working: it ends a started campaign the same way, still cancels drafts, and still returns 200 for a campaign that has already ended. Its response adds stopped_mail_count and already_printed_count.
Changed Endpoints.
  • List Campaigns has an accepting_properties=true filter.
  • Create Campaign saves a ready campaign with no charge when you omit the audience; this used to return 400. A Ready campaign accepts properties. A campaign created with an audience accepts properties later only when you set the new accepts_properties field to true, so existing create and launch requests behave as before.
  • Pause Campaign also pauses a ready campaign. Pausing or resuming an ended campaign returns 409 campaign_ended.
CLI and MCP server. The dm mail campaigns add-properties, estimate-add, and end Commands and the matching MCP Tools do the same things. See CLI Commands and the MCP server.