Prospects and sequences

Import prospects, write the steps, set a sending window and daily limits, stop on reply, and launch.

Embed
Preview of the card
<a href="https://hermeticor.com/guides/sequences"><img src="https://hermeticor.com/guides/_api/public/orgs/5fcd8b3c-a27c-4688-972f-de710125592f/spaces/9a3da731-ded5-4536-b84f-8c9a61420ff4/pages/86797db3-467f-4dc4-a6ab-ba86dad2897c/social-card.svg?v=3e7ae33eec8b" alt="Prospects and sequences" width="600" height="315"></a>

A sequence is a series of emails and tasks sent to each prospect, one step at a time, from your mailboxes. It stops by itself when someone replies.

What you need first

  • A connected mailbox (see Connect a sending mailbox).

  • A list of prospects you have a lawful reason to contact.

  • A key with outbound:write and templates:write.

Prospects in the EU, EEA, UK and Canada are blocked for prospecting by default. They are skipped with jurisdiction_blocked.

1. Import prospects

curl -s -X POST "$BASE/v1/outbound/prospects/import" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: prospects-agencies-1" \
  -d '{"onExisting":"update","ownerRule":{"kind":"round_robin"},
       "rows":[{"email":"maya.chen@brightloop.example.com","firstName":"Maya","lastName":"Chen",
                "title":"Founder","company":"Brightloop","country":"US","timezone":"America/New_York"}]}'

The answer lists the profileIds. Up to 5,000 rows per call. A row with a bad email is skipped and reported in errors ({"row":10,"error":"email: invalid"}); the other rows are imported. To catch risky addresses before importing, clean the list (POST /v1/leads/clean {"emails":[...]}; case variants of one address count once).

2. Write the emails

One template per step:

curl -s -X POST "$BASE/v1/templates" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Agencies step 1","kind":"text",
       "version":{"subject":"{{ profile.firstName }}, one tool for every client?",
         "body":{"kind":"text","text":"Hi {{ profile.firstName | default: \"there\" }},\n\nQuick question for {{ profile.company | default: \"your agency\" }}..."}}}'

Merge fields: profile.firstName, lastName, company, title, and vars.<key> for sequence variables.

3. Set a sending window

curl -s -X POST "$BASE/v1/outbound/schedules" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"US business hours","weekdays":[1,2,3,4,5],"startMin":540,"endMin":1020,
       "timezoneSource":"prospect","timezone":"America/New_York"}'

Times are minutes from midnight (540 is 9:00, 1020 is 17:00), in each prospect's own time zone.

4. Build the sequence

curl -s -X POST "$BASE/v1/outbound/sequences" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: seq-agencies-q4" \
  -d '{"name":"Agencies Q4","settings":{
    "scheduleId":"<scheduleId>","mailbox":{"connectionId":"<mailboxId>"},
    "dailyNewLimit":25,"followUpPercent":40,"plainTextOnly":true,
    "stop":{"onReply":"human","onAutoReply":"continue","onOoo":"pause_until_return","onCompanyReply":"stop"},
    "dedupe":{"crossSequence":"skip","contactedWithinDays":60},
    "steps":[
      {"type":"email","templateId":"<step1>","alternates":[{"templateId":"<step1b>","weight":1}],"optimize":true},
      {"type":"email","templateId":"<followUp>","thread":"reply","waitDays":3,"businessDays":true},
      {"type":"task","kind":"linkedin_connect","title":"Connect on LinkedIn","waitDays":2},
      {"type":"email","templateId":"<breakup>","waitDays":5}]}}'

What the key settings do:

  • dailyNewLimit: at most 25 new prospects start each day.

  • followUpPercent: share of the day's sends kept for follow-ups.

  • stop.onReply: "human": a real reply stops that prospect. Auto-replies continue; out-of-office pauses until they are back.

  • stop.onCompanyReply: "stop": a reply from anyone at the same company stops the others.

  • dedupe: skips people already in another sequence or contacted in the last 60 days.

  • Mailbox dailyCap and hourlyCap still apply on top.

5. Check and publish

curl -s "$BASE/v1/outbound/sequences/<sequenceId>/readiness" -H "Authorization: Bearer $HERMETICA_API_KEY"
# {"ready":true}
curl -s -X POST "$BASE/v1/outbound/sequences/<sequenceId>/publish" -H "Authorization: Bearer $HERMETICA_API_KEY"

To change a setting later, PATCH /v1/outbound/sequences/<id> with just that key, for example {"settings":{"dailyNewLimit":40}}.

6. Enroll

curl -s -X POST "$BASE/v1/outbound/sequences/<sequenceId>/enroll" \
  -H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
  -d '{"profileIds":["<profileId>"]}'

The answer lists everyone skipped and why: suppressed, prospect_unsubscribed, blocklisted_domain, jurisdiction_blocked, in_other_sequence, daily_limit or no_mailbox_available.

7. Watch it run

  • GET /v1/outbound/sequences/<id>/sending-status: what is sending today. Per mailbox, atCap is true at the mailbox's own dailyCap or at this sequence's limit for it (sequenceDailyLimit, from settings.senderOverrides); pausedForSequence shows a mailbox paused for this sequence only. A mailbox_held:<id> warning means a mailbox went over its 7-day bounce or complaint limit; it gives the rate, the limit and the call that clears it.

  • GET /v1/outbound/sequences/<id>/prospects/<profileId>/diagnostics: exactly what blocks one person.

  • GET /v1/outbound/inbox?category=positive: interested replies.

  • GET /v1/outbound/analytics?group=sequence: sent, replies, meetings.

Never contact someone

  • One person: PATCH /v1/outbound/prospects/<profileId> {"status":"do_not_contact"}. This suppresses their addresses.

  • A prospect who is unsubscribed or do_not_contact stays that way while the suppression stands: changing the status answers 412. If they really asked to hear from you again, an admin lifts the suppression first (POST /v1/suppressions/<id>/lift), then the status can change.

  • Many people or domains: POST /v1/outbound/dnc {"emails":["..."],"domains":["..."]}.

Every send, enroll and import then answers suppressed for them.

Updated