Recipe: client re-engagement

Show a user their clients, why each one is worth contacting now, and an email ready to send.

Why it matters: follow-ups that slip become lost renewals and quiet clients. Your users see who to contact and why, with an email that picks up from their last conversation, and send it in one click.

Scopes: profile:read, contacts:read, drafts:write (includes drafts:read) and drafts:send. Webhooks: contacts.first_completed, contacts.completed, drafts.first_completed, drafts.completed.

1. List the user's clients

curl "https://api.bind.co/v1/roles?entity_type=CLIENT&entity_stage=ACTIVE" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Each row is one contact in one role, with the contact's name, email and the dates of their first and latest email. Ask for entity_stage=DORMANT or FORMER to find clients who went quiet. Show the role values with their confidence; a value a person saved reads 1.

2. Create a goal

A goal tells bind.co what the emails should achieve and who should get one. The definition is what steers the wording, so make it specific:

curl https://api.bind.co/v1/drafts/goals \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"draft_goal_description": "Q4 renewals",
       "draft_goal_definition": "Ask each active client whether they want to renew their retainer for next year.",
       "target_role_ids": ["CLIENT"],
       "target_role_stages": {"CLIENT": ["ACTIVE"]},
       "draft_goal_min_confidence": 0.8,
       "is_active": true}'

The answer is the goal, with its draft_goal_id. Before saving, GET /v1/drafts/goals/available-roles shows, for each role, how many of the user's contacts hold it and which stages they are at.

An active goal is drafted from the user's existing mail, so the drafts do not wait for new mail. Your endpoint receives drafts.completed when they are ready.

3. Show the drafts

curl "https://api.bind.co/v1/drafts?goal_id=gol_9CUsxyeaCIs&folder=new" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "items": [
    {
      "draft_id": "drf_4kQ0b1ZpXs2",
      "draft_folder": "new",
      "contact_name": {"value": "Dana Ruiz", "bind_inference_confidence": 0.95},
      "contact_email": "dana@acme.com",
      "client_connection_summary": {"value": "Discussed the Q3 renewal; Dana asked for updated pricing.", "bind_inference_confidence": 0.9},
      "client_connection_contact_reason": {"value": "Dana asked for it two weeks ago.", "bind_inference_confidence": 0.8},
      "draft_email_subject": {"value": "Updated pricing for Q3", "bind_inference_confidence": 0.8},
      "draft_email_body": {"value": "Hi Dana, as promised, here is the updated pricing...", "bind_inference_confidence": 0.8},
      "draft_priority_score": 98.7
    }
  ],
  "total_items": 1, "total_pages": 1, "page_number": 1, "page_size": 50
}

A good screen shows, per draft: who it is for, client_connection_summary (where the relationship stands), client_connection_contact_reason (why now), and the subject and body. The list is sorted by draft_priority_score, highest first.

4. Let the user act

The user Call Body
Edits the email PATCH /v1/drafts/{draft_id} draft_folder "draft", the new draft_email_subject and draft_email_body, and truth_updates
Wants it later POST /v1/drafts/{draft_id}/later draft_folder "later", draft_later_at (when it comes back) and truth_updates
Dismisses it POST /v1/drafts/{draft_id}/reject draft_folder "deleted" and truth_updates
Sends it POST /v1/drafts/{draft_id}/send none

truth_updates takes all three keys: send truth_updated_at and truth_operation as null, since bind.co sets them, and the user's reason in truth_reason. The reason is kept when the user saves a draft for later or dismisses it; an edit is recorded as an auto-save. An edit:

curl -X PATCH https://api.bind.co/v1/drafts/drf_4kQ0b1ZpXs2 \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"draft_folder": "draft",
       "draft_email_subject": "Updated pricing for Q4",
       "draft_email_body": "Hi Dana, here is the updated pricing for next year...",
       "truth_updates": {"truth_updated_at": null, "truth_operation": null, "truth_reason": null}}'

Sending goes out from the user's own mailbox. A 502 email_send_failed with hint.may_have_sent true means the provider may still have sent it: check the user's Sent folder before retrying. Rejecting is permanent for that contact and goal.

5. Stay current

The Drafts and goals guide covers every rule, including what happens to each folder.

Make it yours