Menu

Get started

Quickstart

Create a key, make a first call, add a lead, enroll it and receive a signed webhook.

Ten minutes from nothing to a lead enrolled in a campaign and a signed webhook arriving at your server. You need a DM Hero workspace with an active subscription, one connected rep, one campaign, and a terminal with curl.

1. Create a key

  1. In DM Hero, open Settings, then Integrations, then Developer.
  2. Choose Create key. Name it after what will use it, for example CRM sync or Support agent.
  3. Tick the scopes this quickstart needs: leads:read, leads:write, campaigns:read, enrollments:write and webhooks:manage (the last one needs an owner or an admin).
  4. Leave the reps unrestricted and pick an expiry. Create the key.
  5. Copy the key now. It starts with dmh_live_ and is shown once; DM Hero stores only its hash.

Keep it in an environment variable, never in code:

bash
export DMHERO_API_KEY="dmh_live_..."
Warning: Treat the key like a password. Anyone holding it acts as you in this workspace. If it ever leaks, revoke it in the app at once and create a new one (see Authentication).

2. Make your first call

bash
curl https://api.dmhero.ai/v1/me -H "Authorization: Bearer $DMHERO_API_KEY"

The answer names the workspace, the key, the reps it may act as, the organization and the key's requests per minute in each rate class:

json
{
  "workspace": {
    "id": "8d0b6a52-6f0e-4d63-9a51-2b7c3f1e9a10",
    "name": "Acme Coaching"
  },
  "api_key": {
    "id": "c4d1f3a2-0b5e-4e7a-8c9d-1f2e3a4b5c6d",
    "name": "CRM sync",
    "prefix": "AbCdEf012345",
    "scopes": [
      "leads:read",
      "leads:write",
      "campaigns:read",
      "enrollments:write",
      "webhooks:manage"
    ],
    "expires_at": "2027-01-19T09:30:00.000Z",
    "allowed_cidrs": null,
    "api_surface": "developer"
  },
  "reps": [
    {
      "id": "5e9f7c1a-2b3d-4e5f-8a9b-0c1d2e3f4a5b",
      "ig_username": "acme.anna"
    }
  ],
  "organization": {
    "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "plan": "multi_reps"
  },
  "limits": {
    "read": {
      "per_minute": 600
    },
    "write": {
      "per_minute": 600
    },
    "heavy": {
      "per_minute": 20
    },
    "send": {
      "per_minute": 60
    },
    "discovery_quote": {
      "per_minute": 30
    },
    "discovery_spend": {
      "per_minute": 10
    }
  },
  "developer_api_enabled": true
}

Every response also carries a DMHero-Request-Id header. Quote it if you ever contact support about a request.

3. Add a lead

POST /v1/leads creates the lead, or updates the one already matching its external_id or Instagram handle, so you can send the same record twice without making a duplicate:

bash
curl -X POST https://api.dmhero.ai/v1/leads \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "ig_handle": "jane.doe",
    "first_name": "Jane",
    "last_name": "Doe",
    "external_id": "crm-1042",
    "tags": ["webinar"]
  }'
json
{ "lead_id": "0b8e2c6d-4f1a-4b7e-9d3c-6a5f4e3d2c1b", "result": "created", "updated_fields": [], "lead_status": "new" }

4. Enroll it in a campaign

Find the campaign's id:

bash
curl "https://api.dmhero.ai/v1/campaigns?status=active" -H "Authorization: Bearer $DMHERO_API_KEY"

Then enroll the lead. The extension of the assigned rep sends the first DM at its next turn, within the rep's DM cap:

bash
curl -X POST https://api.dmhero.ai/v1/campaigns/CAMPAIGN_ID/enrollments \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "lead_ids": ["0b8e2c6d-4f1a-4b7e-9d3c-6a5f4e3d2c1b"] }'

A lead that is already in another campaign, opted out, or is on a rep's excluded list is skipped, and the answer says why in skipped_reasons. Steps 3 and 4 also exist as one call, POST /v1/campaign-leads, which is what the Clay recipe uses.

5. Receive a webhook

Point an endpoint at a URL your server listens on (HTTPS, port 443) and subscribe it to the events you care about:

bash
curl -X POST https://api.dmhero.ai/v1/webhook-endpoints \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name": "My server",
    "url": "https://example.com/dmhero/webhooks",
    "event_types": ["lead.replied", "lead.booked", "lead.opted_out"]
  }'

The answer carries signing_secret, once. Store it: every delivery is signed with it in the x-dmhero-signature header, and your server must check that signature before trusting the body (how to verify). Then ask for a test event:

bash
curl -X POST https://api.dmhero.ai/v1/webhook-endpoints/ENDPOINT_ID/test \
  -H "Authorization: Bearer $DMHERO_API_KEY"

A test.ping arrives at your URL within seconds. From now on, when Jane replies to the campaign DM, lead.replied arrives the same way.

Note: Next: learn the error envelope your code should branch on, and read Idempotency before you retry anything that writes.
Quickstart | DM Hero Developers