done.developers
Building blocks

Writing

How to teach done. how you write with voices and styles, and how to write one message for one person.

This page covers voices, styles, and writing a single message for a single person.

Two things shape every message done. writes for you:

  • A voice describes how a person writes: tone, habits, phrases to avoid, and example messages.
  • A style says what you offer and how campaign messages are written: the offer, the rules to follow, and the angle.

Both are reused by campaigns. You can use them on their own to write one message at a time.

The main calls

Write one message

POST /messages/draft writes one message for one person, in your voice and style, and returns the text. It never sends anything. Use it to preview what done. would say, or to write a note you send yourself. To send messages at scale, use a campaign.

kind is connection_note (the note on a connection request, at most 300 characters) or first_message. person is a person id or a LinkedIn link. customer_profile is required. voice, style and goal are optional. If you leave out voice or style, the workspace's default is used.

curl https://api.done.com/v1/messages/draft \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Idempotency-Key: a47c2e91-5f08-4b3d-86a2-d1e9033b7c5f" \
  -H "Content-Type: application/json" \
  -d '{
    "person": "per_9aQw1XyZ",
    "customer_profile": "cp_3MnB8rTy",
    "voice": "voc_5NcR8wTa",
    "style": "sty_2HgP6vLe",
    "kind": "first_message",
    "goal": "Book a 15 minute call about month-end close."
  }'
{
  "object": "message_draft",
  "text": "Ana, saw your note on close automation. We cut Lumen's close from 9 days to 4. Worth 15 minutes?",
  "kind": "first_message",
  "characters": 101,
  "person": { "id": "per_9aQw1XyZ", "object": "person", "name": "Ana Lima", "headline": "CFO at Lumen Pay", "company": "Lumen Pay", "location": "London, United Kingdom", "linkedin_url": "https://www.linkedin.com/in/ana-lima" }
}

The message uses what done. knows about the person and the customer profile you name. To answer a reply, use POST /conversations/{id}/draft_reply instead.

Make a voice

There are two ways to get a voice.

Write it by hand. POST /voices saves a voice you describe yourself. It is free, and learned_from is manual. tone is one of casual, warm, sharp, reflective, playful, direct or formal. emoji_use is none, rare or moderate.

curl https://api.done.com/v1/voices \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Idempotency-Key: 62d9f1b8-0a37-4c4e-b5d6-8e13a7c20f94" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Casual voice",
    "tone": "casual",
    "style_markers": ["short sentences", "no exclamation marks"],
    "banned_phrases": ["hope this finds you well", "circle back"],
    "emoji_use": "none",
    "greeting": "First name only, no Hi."
  }'

Lists hold up to 24 items of up to 280 characters. greeting, call_to_action, pushback and objections hold up to 600 characters. example_messages holds up to 5 messages of up to 2000 characters.

Learn it from real writing. POST /voices/learn works out how someone writes and saves it as a new voice. In from, pick one source: linkedin_profile (the posts of the person at a LinkedIn link), conversations (messages this workspace sent in conversations you name, up to 30) or samples (up to 30 texts you paste, each up to 4000 characters).

curl https://api.done.com/v1/voices/learn \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Idempotency-Key: f05b3a76-1e9c-4d28-a4b7-93c6e2d81a0e" \
  -H "Content-Type: application/json" \
  -d '{
    "from": { "type": "linkedin_profile", "linkedin_url": "https://www.linkedin.com/in/sam-carter" },
    "name": "Casual voice"
  }'

If the profile has no public posts to learn from, the call is refused with not_enough_writing. Send samples instead, with at least 3 texts the person wrote.

Other voice calls: GET /voices, GET /voices/{id}, PATCH /voices/{id} (send only the fields that change; a list you send replaces the whole list) and DELETE /voices/{id} (for good). A change applies to messages written from now on, including messages in campaigns that already use the voice.

Make a style

POST /styles creates a style of your own: what you offer, the rules messages follow, and the angle. A new style is used by no campaign yet.

curl https://api.done.com/v1/styles \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Idempotency-Key: b81e6d34-92a5-47f0-9c1b-0d7a45e3f268" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Finance leaders, direct",
    "offer": {
      "what_we_do": "We automate month-end close for finance teams at payment companies.",
      "short_line": "month-end close automation"
    },
    "style_rules": {
      "do": ["Keep it under 60 words"],
      "dont": ["Use the word synergy"]
    }
  }'

The offer wording, offer.what_we_do and offer.short_line, is checked and approved when you save, the same way the app does it, because messages may state the offer only with approved wording.

GET /styles lists the styles a workspace can use: its own, and the built-in done. playbooks (built_in is true for those). Filter with built_in.

To start from a built-in playbook, or to change a style that campaigns use without changing those campaigns, copy it:

curl https://api.done.com/v1/styles/sty_2HgP6vLe/copy \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Idempotency-Key: 29c4a8f5-6b10-4e73-8d92-f7e0b315a6c8" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Finance leaders, direct (mine)" }'

To change a style, read it first to get its version, then send the version back with only the fields that change:

curl -X PATCH https://api.done.com/v1/styles/sty_2HgP6vLe \
  -H "Authorization: Bearer $DONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "sv_c2f81e9a40",
    "confirm_used_by_campaigns": true,
    "style_rules": { "do": ["Keep it under 50 words"], "dont": ["Use the word synergy"] }
  }'

What it costs

CallCost
POST /messages/draftabout 3.4 a message. If it fails, nothing is charged.
POST /voices/learnabout 1 per voice learned. The credits are set aside first and released if learning fails.
Make, read, change or delete a voice or stylefree

See Credits and costs.

Rules that apply

  • Writing a message sends nothing. POST /messages/draft returns text only.
  • Built-in styles are read-only. Changing or deleting one is refused with built_in_read_only. Copy it first, then change the copy.
  • A style used by campaigns needs confirmation. If campaigns use the style (used_by_campaigns is more than 0), a change applies to all of them. Send confirm_used_by_campaigns: true, or the change is refused with confirmation_required. Such a style cannot be deleted: that is refused with style_in_use. Point those campaigns at another style first.
  • Styles are versioned. If the style, or the set of campaigns using it, changed since you read it, the change is refused with version_conflict. Read it again and decide again.
  • Daily limit on learned voices. Each workspace may learn 20 voices a day. Past that, the call is refused with 429 daily_limit_reached, and the reset time is in detail and Retry-After.
  • Permissions. Writing a message and learning a voice need spend. Making, changing and deleting voices and styles needs full. Reading needs read.
  • Retries. Send an Idempotency-Key on calls that create or spend, so a retry does not write and charge twice. See Safe retries.

On this page