---
title: "Optimize Outbound Message"
method: POST
path: "/api/platform/v1/messages/optimize"
tags: ["assets"]
---

# Optimize Outbound Message

`POST /api/platform/v1/messages/optimize`

## Request

- Base URL: `https://docs.amdahl.ai`
- URL: `https://docs.amdahl.ai/api/platform/v1/messages/optimize`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Write one outbound email or LinkedIn message in the sender's own voice from context (facts, rules, voice_examples) and return it with a line on what changed. Use when an outbound message needs writing or improving before it is sent. message is optional: where Amdahl writes from context, a draft is not read. Pass evidence: "workspace" to grade against synced conversations (slower) and list unbacked claims in unsupported_claims, kept unless on_unsupported is remove. Sends nothing.

## Request body

- object
  - `context` object: What the message is written FROM, and the quality of the message follows the quality of this. facts are what the sender knows first-hand about the recipient: who they are, why write now, what is offered, the proof that may be cited. rules are what the message must and must not do, including the ask. voice_examples are the sender’s own messages, matched and never copied. keep_cta, max_words, banned_phrases and banned_punctuation are checked exactly. If all you have is the user’s own request, pass it as a fact rather than sending nothing. Blank entries are dropped and any other key is refused.
    - `rules` string[]: Hard constraints on the rewrite, such as "no pricing". They steer the rewrite and are not rewritten or quoted in the message. Up to 20, each up to 500 characters once trimmed.
    - `voice_examples` string[]: Messages the sender wrote themselves. The rewrite matches the sender's voice and does not copy their words. Up to 5, each up to 4000 characters once trimmed.
    - `facts` string[]: What you know first-hand about the recipient or situation that no call recording holds, one fact per entry, such as "Met Priya at the GTM dinner on Sep 24; she said her SDRs rewrite every AI draft". Graded as caller-supplied evidence (tier CALLER, not a customer quote): a claim a fact states is not marked fabricated, a claim that inflates one still is. Up to 10, each up to 1000 characters once trimmed.
    - `keep_cta` boolean: true to keep the draft's closing ask (its last sentence that asks for something) word for word. Checked exactly on every rewrite; the rewrite works on the rest of the message.
    - `max_words` integer: The most words the returned message may have, checked exactly on every rewrite. 10 to 1000.
    - `banned_phrases` string[]: Words or phrases the rewrite leaves out, such as "just" or "reaching out", matched as whole words in any case and checked exactly on every rewrite. Up to 30, each up to 60 characters once trimmed.
    - `banned_punctuation` string[]: Punctuation the rewrite leaves out: any of colon, semicolon, exclamation. Checked exactly on every rewrite; a colon in a time like 2:30pm or in a link does not count.
  - `message` string: Optional, and NOT READ where Amdahl writes from context: nothing is taken out of a draft, not a claim, not a name, not the subject line, and the result carries a draft_ignored note. One exception: a draft sent with no facts in context and no recipient is improved instead, with a draft_improved_no_context note. Put what you know in context.
  - `channel` 'email' | 'linkedin': Where the message will be sent. Send it: with no draft there is nothing to infer it from, and the channel sets the length and format the message is written and judged against. linkedin means a connection note, which carries no sign-off.
  - `on_unsupported` 'flag' | 'remove': What to do with a claim in the draft that nothing in the workspace conversations backs. "flag" (the default) keeps it and lists it in unsupported_claims; "remove" lets the rewrite soften or cut it. Only checked when the workspace has connected conversations.
  - `evidence` 'workspace' | 'off': Optional, default off. workspace grades the draft against what this workspace's customers said in its synced conversations (positioning, grounding, specifics, differentiation), which is slower; off is a fast style pass. Where no conversations can be read the run is graded as off and evidence.reason says why.
  - `include_tries` boolean: Optional, default false. When true, the result also carries `tries`: every version the run scored, the draft first, each with its text, the optimizer's own score and human_tone (1 to 5), the dimensions it aimed at, and which one was returned. It shows how the draft progressed. Those scores come from the judge the rewrites were optimized against, so `lift`, not them, is the before-and-after.
  - `recipient` object: Beta, per workspace: refused unless the workspace has recipient evidence on. Who the message is for: any of email (up to 320 characters), name and company (up to 200 each), domain (up to 253), linkedin_url (up to 300) and attributes. attributes is a flat map of text, number, true/false or null values, such as a whole Clay or CSV row: up to 100 keys of 100 characters, each text value up to 1000 characters. Any other key is refused, and so is an attribute key that names a business, user, tenant or workspace id.
    - `email` string
    - `name` string
    - `company` string
    - `domain` string
    - `linkedin_url` string
    - `attributes` object
  - `recipient_notes` string: Beta, per workspace: refused unless the workspace has recipient evidence on. Free text about the recipient, such as your own research or a pasted CRM note. Up to 10000 characters.
  - `message_type` 'cold' | 're-engage' | 'follow-up' | 'deal': Beta, per workspace: ignored unless the workspace has recipient evidence on. The kind of message: cold, re-engage, follow-up, deal. follow-up is a reply in a thread that is in progress.

## Response `200`

OK

- object
  - `data` unknown

## Other responses

- `400`: Invalid input - failed schema validation
- `401`: Authentication required
- `403`: Forbidden - missing scope or role
- `500`: Internal server error

---

[API](https://skmtc.dev/amdahl/apis/amdahl-platform-api.md) · [All operations](https://skmtc.dev/amdahl/apis/amdahl-platform-api/llms.txt) · [OpenAPI document](https://skmtc.dev/amdahl/apis/amdahl-platform-api/revisions/d4eee33e2472?raw)
