Primitives / Openers
Openers
A prospect in, a hand-approved cold-email opening line out.
Openers picks the best opening line for each prospect from a library of handwritten, human-approved lines. Nothing is generated: the model only chooses and fills placeholders that must pass a check.
- Unit
- Opener endpoint
- A run produces
- the best line plus ranked candidates, or no_match
- In the app
- /ledes
- API reference
- All openers tools
Try it
run_lede over REST: POST /api/lede/ingest/{endpoint_id}. Needs an API key with lede:write.
curl -X POST https://app.letterstory.com/api/lede/ingest/<endpoint_id> \
-H "x-integrations-key: ls_..." \
-H "content-type: application/json" \
-d '{
"max_candidates": 0,
"tone": "...",
"default_lede": "...",
"enrich": false,
"distinctiveness_floor": 0,
"deadline_ms": 0,
"disabled_ledes": [],
"high_temperature": false,
"optimize_diversity": false,
"recent_ledes": [],
"first_name": "...",
"last_name": "...",
"name": "...",
"email": "...",
"title": "...",
"years_at_company": 0,
"company": "...",
"company_url": "...",
"school": "...",
"city": "...",
"country": "...",
"linkedin_url": "...",
"notes": "..."
}'1. Constraints: what you configure
namedefaults.max_candidatesdefaults.tonedefaults.default_lededefaults.enrichmax_candidatestonedefault_ledeenrichcompany_urlemailcompanytitlenotestone is warm, direct, playful or formal. Pass at least one identifying field for the prospect; the rest sharpen the match.
2. Mechanism: what always happens
- 1Resolve the company from a URL, work email or name, then enrich it: brand, logo, a homepage capture and market evidence.
- 2Filter the handwritten library, then one model pass profiles the company and ranks lines by id. It never writes a line.
- 3Placeholders render deterministically, and every model-derived value must pass a whitelist or prefix check. A claim that fails drops its line.
- 4Candidates are ordered by confidence times rarity. Every run is logged; an unexpected failure is logged as an error, not as no match.
3. Intelligence: who picks values
An API key sets the tone, how many candidates and a fallback line.
Letterstory's opinion is the curated library itself, the claim checks and the rarity table. It never writes on your behalf.
4. Verification: did it hold
Experimental: no verification record yet. Runs are synchronous and record their request.
Surfaces
Same call over MCP (tools/call) and REST.
| Job | MCP tool | REST |
|---|---|---|
| Run | run_lede | POST /api/lede/ingest/{endpoint_id} |
| History | list_lede_runs | POST /api/integrations/tools/list_lede_runs |
lede_account_history | GET /api/lede/history | |
| Endpoints | list_lede_endpoints | POST /api/integrations/tools/list_lede_endpoints |
create_lede_endpoint | POST /api/integrations/tools/create_lede_endpoint | |
delete_lede_endpoint | POST /api/integrations/tools/delete_lede_endpoint | |
| Endpoint config | get_lede_endpoint_config | POST /api/integrations/tools/get_lede_endpoint_config |
set_lede_endpoint_config | POST /api/integrations/tools/set_lede_endpoint_config | |
| Balance | get_lede_balance | POST /api/integrations/tools/get_lede_balance |
CLI: letterstory lede run <id>
Only matched runs draw opener credits; no_match (even when your fallback line is served) and errors are free.