Drafts and goals
A draft is an email bind.co writes for the user to send to one of their contacts, ready to review. A goal is the user's instruction for what those emails should achieve. This guide covers what drafts are for, how goals steer them, what happens when the user acts on one, and what your application can rely on.
Reading needs drafts:read; editing, deciding and managing goals need drafts:write, which
includes drafts:read; sending also needs drafts:send.
What drafts are for
Drafts are for reaching out at the right moment: a follow-up to a proposal that went quiet, a renewal coming up, a client who mentioned a new location, a funding round or a new hire, a congratulation, a "here is what happened since we last spoke and what I suggest next". Each draft picks up from the latest conversation with that contact.
Things the user is waiting on, overdue promises and missing paperwork are a different job. They are
operations, which bind.co tracks, de-duplicates and follows up on; see Operations.
For who a contact is to the user, the contact itself already carries contact_summary; see
Contacts and roles.
What a draft contains
{
"draft_id": "drf_4kQ0b1ZpXs2",
"draft_folder": "new",
"contact_name": {"value": "Dana Ruiz", "bind_inference_confidence": 0.95},
"contact_email": "dana@acme.com",
"entity_type": {"value": "CLIENT", "bind_inference_confidence": 0.95},
"entity_stage": {"value": "ACTIVE", "bind_inference_confidence": 0.8},
"client_connection_summary": {"value": "Discussed the Q3 renewal; Dana asked for updated pricing.", "bind_inference_confidence": 0.9},
"client_connection_contact_objective": {"value": "Send the updated pricing.", "bind_inference_confidence": 0.8},
"client_connection_contact_reason": {"value": "Dana asked for it two weeks ago.", "bind_inference_confidence": 0.8},
"client_connection_contact_date": {"value": "2026-10-28T00:00:00Z", "bind_inference_confidence": 0.7},
"client_connection_priority": {"value": 2, "bind_inference_confidence": 0.6},
"draft_email_to": "dana@acme.com",
"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,
"goal": {"draft_goal_id": "gol_9CUsxyeaCIs", "draft_goal_description": "Q4 renewals", "status": "active"}
}
client_connection_summary: where the relationship stands.client_connection_contact_objective: what this one email sets out to achieve, often one step toward the goal.client_connection_contact_reason: why this contact, and why now.client_connection_contact_date: the date bind.co suggests the message goes out.client_connection_contact_draft_subjectandclient_connection_contact_draft_email: what bind.co first suggested, kept as it was.draft_email_subjectanddraft_email_body: what will be sent. Until the user edits them they show bind.co's suggestion.client_connection_priority: the order to work through the drafts, lower first.draft_priority_scoreranks the list, highest first by default.
Every suggested value carries a bind_inference_confidence between 0 and 1, and a value a person
edited has confidence 1. Use it to decide what to show: for example, surface drafts whose
draft_email_body confidence is high, and put the rest behind a "more suggestions" view.
Goals
A goal is plain words written by the user, plus who to write to:
{
"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
}
draft_goal_definitionis the main lever. It shapes each draft's objective, reason, priority and wording. Be specific: "ask active clients about renewing their retainer" gives better drafts than "grow revenue".draft_goal_descriptionis only the goal's name. It does not change what the drafts say.target_role_ids: the roles to write to, such asCLIENT,VENDORorACCOUNTANT. Empty means every role. A goal needstarget_role_idsortarget_contact_ids; one with neither is a422.target_role_stages: for each role, the stages to write to. ForCLIENTthey arePROSPECT,ACTIVE,DORMANT,FORMERandUNKNOWN; a role left out takes every stage.target_contact_ids: only these contacts, when set.draft_goal_min_confidence: how sure bind.co must be that a contact holds the role; 0.8 when not set.
Before saving a goal, GET /v1/drafts/goals/available-roles?min_confidence=0.8 shows, for each role,
how many of the user's contacts hold it and at which stages, so your interface can preview how many
drafts a goal will reach.
A goal is draft until activated, then active; inactive is paused and deleted is removed.
Only active goals get new drafts. Pausing or deleting a goal stops new drafts for it; the drafts it
already has stay, and still list under it.
There is no limit on the number of goals. A contact targeted by three goals can receive three drafts, one per goal.
When the user has no active goal at all, bind.co still writes drafts to their active clients, toward a
general aim of growing the business. Those drafts have goal set to null.
One draft per target per goal
A target is one contact role. Each goal gives each of its targets at most one draft at a time: 20 targets and 3 goals give up to 60 drafts.
GET /v1/drafts?goal_id=gol_9CUsxyeaCIs lists one goal's drafts; GET /v1/drafts/count counts drafts
per folder, for badges:
{"items": [{"draft_folder": "new", "count": 12}, {"draft_folder": "later", "count": 3}]}
Where drafts come from
bind.co writes drafts only for a user who has granted an application both drafts:read and
contacts:read. Drafts start after the user's first mailbox sync, once their contacts and roles are
known.
Drafts draw on the user's conversation history with each contact, not only the newest email. A new or edited goal is drafted from the mail bind.co already holds, so the user does not have to wait for new mail to see its drafts. A draft nobody has handled can be replaced by a newer suggestion.
A replacement is a new draft with a new draft_id; the old one is gone. So do not keep the ids of
unhandled drafts: after drafts.completed, list the drafts again. Ids of drafts the user acted on
stay valid.
What the user can do, and what is permanent
| The user | Route | Folder | What happens next |
|---|---|---|---|
| Ignores it | none | new |
Can be replaced by a newer suggestion, with a new draft_id |
| Edits it | PATCH /v1/drafts/{draft_id} or POST /v1/drafts/{draft_id}/save |
draft |
Kept as edited; never replaced |
| Snoozes it | POST /v1/drafts/{draft_id}/later |
later |
Kept until draft_later_at, then back to new |
| Rejects it | POST /v1/drafts/{draft_id}/reject |
deleted |
Kept; that target gets no other draft for this goal |
| Sends it | POST /v1/drafts/{draft_id}/send |
pinged |
Kept, with the sent message's ids |
Rules your application can rely on:
- A draft the user acted on (edited, snoozed, rejected or sent) is never replaced or rewritten by bind.co.
- A snoozed draft that comes back to
newbehaves like any new draft from then on, so it can be replaced by a newer suggestion. - Rejecting is permanent for that target and that goal, whatever happens to the goal later. The same target can still get drafts from other goals, and from a goal created later.
- When editing, your application can change the objective and reason and send
"draft_refresh_subject_and_body": trueto have bind.co rewrite the subject and body to match.
Sending
POST /v1/drafts/{draft_id}/send sends the draft as last saved, from the user's own Gmail or
Outlook mailbox, as a new email. It takes no body.
{"draft_id": "drf_4kQ0b1ZpXs2", "sent": true, "message_id": "18c2f0a9d4e1b7c3"}
After sending, the draft is in pinged and carries draft_email_message_id and
draft_email_thread_id, the mail provider's ids for the sent email and its conversation.
Edge cases:
- Sending again answers
409 already_sentwith the id already sent; no second email goes out. 502 email_send_failedmeans the provider did not confirm. Itshint.may_have_sentsays whether the email could still have gone: if true, check the user's Sent folder before retrying.
Webhooks
drafts.first_completed: the user's first draft is ready. Sent once per user.drafts.completed: more drafts were added;createdis how many.
List GET /v1/drafts again when either arrives. The webhooks guide has the payloads.