Menu

Reference

Changelog

Every change a client can notice, dated, newest first.

Every change a client can notice, newest first. Additive changes ship without a new version date; see Versioning.

2026-10-28: A campaign step's message_mode

  • Every campaign step now carries a read only message_mode: template sends the step's template_id; ai sends a first message written for each lead, and template_id is its fallback. The mode is set in the app.
  • PUT /v1/campaigns/{campaign_id}/steps keeps each step's mode by its position; a step added at a new position is template. No version change: the field is additive to 2026-10-08.

2026-10-28: lead.updated names every field the lead serves

  • lead.updated now also names niche, bio, fb_handle and assigned_rep_id in changed_fields when they change, whoever changed them: a person in the app, the API, or a profile enrichment filling the niche and bio. Before, a change of only these fields sent no event.
  • No version change: the names are additive to 2026-10-08.

2026-10-28: The onboarding refusal, and revoked keys' endpoints

  • An organization that has not finished setting up its DM Hero account answers 403 ONBOARDING_REQUIRED_403 on every operation, the five original Clay endpoints and MCP included. It is now listed with the errors every operation can return. Finish the setup in the app, then retry.
  • Revoking a key switches off the webhook endpoints it, or a key it was rotated from, created through the API: they show is_active: false with disabled_reason: "key_revoked" and their queued deliveries are cancelled. See Authentication.

2026-10-28: lead.status_changed on every status change

  • lead.status_changed now follows every change of a lead's status, not only the ones made by hand or through the API: the first campaign DM, a reply, an opt out and its undo, a booking and its undo, a bulk action, and an Instagram account found missing each send one, beside the event they already sent (lead.contacted, lead.replied, lead.opted_out, lead.booked), which are unchanged.
  • A new field, cause, says what made the change: operator, api, bulk, dm_sent, reply, opt_out, booking or automation. One event per change; a status set to the value it already had sends none.
  • lead.status_changed is now listed as a high volume event. No version change: the field is additive to 2026-10-08.

2026-10-27: Text that cannot be stored, and the campaign-leads replay

  • Every operation, the five original Clay endpoints included, answers 400 VALIDATION_FAILED_400 with the reason text_invalid for a string or object key holding U+0000 (the NUL character) or an unpaired UTF-16 surrogate. Before, such text failed with a 500 or was stored with the character replaced. Nothing is written.
  • A replay of POST /v1/campaign-leads under the same Idempotency-Key now carries the first answer's rep_ig_username and updated_fields instead of null and an empty list. lead_status is still read fresh.

2026-10-23: Custom fields across the leads API

  • Every lead the API returns carries custom_fields with every field the workspace defines, in display order, null when the lead has no value. Keys only a Clay compatible key wrote follow as stored.
  • GET /v1/leads filters on custom fields: cf.<key>=<text>, cf.<key>.contains=<text>, cf.<key>.present=true and cf.<key>.missing=true, at most 5, ANDed. A key the workspace has not defined answers 400 CUSTOM_FIELD_UNKNOWN_400.
  • Lead filters in bulk actions and exports take the same conditions as filter.custom_fields: [{ key, op, value }].
  • A new bulk action, set_custom_fields, sets or clears values on many leads through preview and confirm.
  • The API's export adds one custom_fields.<key> column per field, which POST /v1/leads/imports reads back unchanged.
  • lead.updated names a changed custom field in changed_fields as custom_fields.<key>, whoever changed it.
  • The MCP tools search_leads and bulk_update_leads take custom field conditions and set_custom_fields.
  • A new guide, Custom fields. No version change: everything is additive to 2026-10-08.

2026-10-21: The developer API

  • The API moves to its own host, https://api.dmhero.ai/v1. The original paths on app.dmhero.ai/api/v1 keep answering.
  • Resources for leads, tags, folders, custom fields, suppressions, import, export and bulk jobs, templates, campaigns and enrollments, reps and the AI Setter mode, analytics, conversations (metadata), webhook endpoints and deliveries, and discovery.
  • Developer keys with scopes per resource, rep restriction, IP allowlists, and rotation with a grace period.
  • Every error carries request_id and doc_url (additive for the five original endpoints, whose error and code values are unchanged).
  • Idempotency-Key on writes, cursor pagination on every list, RateLimit-* headers on every response.
  • New webhook events, including lead.created, lead.updated, lead.status_changed, lead.deleted, lead.enrolled, enrollment.removed, enrollment.completed, dm.sent, campaign.status_changed, campaign.completed, rep.attention_required, job.completed, discovery.run.progress and discovery.run.completed.
  • An MCP server at https://api.dmhero.ai/mcp with task-shaped tools and two step confirmation.
  • The OpenAPI 3.1 document at https://api.dmhero.ai/v1/openapi.json, and these docs.
  • No version change: everything is additive to 2026-10-08.

2026-10-08: Integrations: the first API and outbound webhooks

  • Five endpoints for Clay and scripts: GET /v1/me, GET /v1/campaigns, POST /v1/leads, GET /v1/leads/lookup and POST /v1/campaign-leads, with API keys scoped to leads:read, leads:write, campaigns:read and campaigns:enroll.
  • Signed outbound webhooks (x-dmhero-signature) with schema version 2026-10-08: lead.replied, lead.booked, booking.unattributed, lead.opted_out, lead.opt_out_reverted, setter.needs_human, lead.contacted, lead.booking_canceled, lead.reply_classified and test.ping.
  • Clay and generic endpoint presets, retries with backoff, and a delivery log.
Changelog | DM Hero Developers