Onboard a phantom site in one call
Give it a domain. It proposes a name, strategy, and plan; say yes and ten minutes later the site is live with its first post writing.
plan_phantom runs the whole recipe from a single input, your website's domain, and it comes in two halves: a dry run that shows you the plan and changes nothing, and an accept that builds it.
1. Preview the plan
With an agent: "Preview a phantom site for acme.com. Don't create anything."
CLI:
letterstory phantom-onboard acme.com
HTTP: POST /api/integrations/tools/plan_phantom with { "domain": "acme.com" }.
The platform reads acme.com's homepage, infers a strategy, proposes a masthead, and returns the plan:
{
"accepted": false,
"domain": "acme.com",
"client_label": "acme",
"proposed_name": "The Ledger Room",
"description": "Practical finance operations for growing companies…",
"direction": null,
"strategy": { "description": "…", "stances": ["…"], "priority_topics": ["…"] },
"defaults": { "cadence_per_week": 6, "cover_canvas": "editorial_image", "posts_to_seed": 1 },
"domain_plan": { "site_domain": null, "mode": "subdomain" },
"theme": null,
"note": "…",
"plan": { "…": "the whole plan, to hand back verbatim" }
}
Read the name and the strategy. direction echoes the beat you passed (null when the platform inferred it), and domain_plan says what will happen about a custom domain (nothing, by default). theme is null unless you pinned one; the site authors its own look otherwise. If the homepage couldn't be read, strategy is null and the note says so; you'll need to supply a name yourself when you accept.
The plan block is the whole decided plan. Hand it back verbatim as plan when you accept and the launch commits exactly what you reviewed, instead of recomputing (and possibly re-deciding) the masthead.
Or pick the beat and the name first
For a fuller preview than the one-line dry run, two read-only tools go before plan_phantom: propose_phantom_plan reads the homepage and returns several distinct editorial angles, each a direction plus the content areas that become the topic map's pillars, along with the client's existing phantoms so a second site doesn't repeat the first. Hand the angle you like to propose_phantom_mastheads and get candidate names for that beat, each with a subheadline and its own priced, purchasable domains. Then pass the chosen direction, pillars, name, and site_domain through overrides when you accept. Neither tool persists or spends anything.
"Show me three angles for a phantom for acme.com, then names and domains for the second one."
2. Accept, with any changes
Agent: "Go ahead, but call it 'The Ledger Room', post four times a week, and seed two posts."
CLI: --accept or any override flag applies. --about sets the editorial direction, --real marks a real client site (the default is a test site), --domain plus --domain-mode handle a custom domain:
letterstory phantom-onboard acme.com --accept
letterstory phantom-onboard acme.com --name "The Ledger Room" --about "finance operations for growing companies" --cadence 4 --posts 2 --cover line_art --theme ledger --real
letterstory phantom-onboard acme.com --accept --domain ledgerroom.com --domain-mode buy_now # spends money
HTTP: the same tool with "accept": true and an overrides object.
| Override | Meaning | Default |
|---|---|---|
name | The masthead. Rejected if it contains your company's name. Required when the homepage couldn't be read. | proposed |
cadence_per_week | Posts per week, 1 to 7, capped by your organization's cadence cap (six a week by default) | 6 |
cover_canvas | Cover image style: editorial_image, full_ai, line_art | editorial_image |
theme | Visual theme (KB-804) | chosen for the subject |
posts_to_seed | First posts to start writing from the topic map, 0 to 10; the strongest open spokes, spread across pillars | 1 |
seed_topic_ids | Pin exactly which topic-map spokes to seed, in order, instead of the strongest | picked |
direction | The publication's editorial beat in plain language ("where bank regulators are heading on agentic AI, for compliance officers"). It becomes the steering prompt for the whole publication, so it shapes the masthead, the topic map, and every post; use it to give a client's second phantom a different beat | inferred |
pillars | The content areas the topic map is built on, verbatim (up to eight). Take them from the propose_phantom_plan angle you chose; omit to let the map choose its own | chosen by the map |
site_domain | A custom domain for the site, bare (no scheme) | none |
domain_mode | subdomain (ignore site_domain, launch on the instant subdomain), buy_now (register it during provisioning; spends money, under $30 and within the organization's domain allowance, two by default), or connect_later (record it, buy nothing) | subdomain |
is_test | Keep the site off the fleet board and every performance tab | true; pass false for a real client site |
customer_ref | For integrators launching sites on behalf of their own customers: your id or email for that customer, free text. Stamped on the site and returned by get_phantom / list_phantoms so you can map sites back to your users | none |
The response is { "accepted": true, "job_id": "…", "status": "running", "stage": "planning" }.
3. Watch it build
The CLI polls for you and prints each stage as it passes. Elsewhere, poll get_phantom_launch_status with the job id.
| Stage | What's happening | Typical time |
|---|---|---|
| planning | Strategy inferred, masthead decided, description written | under a minute |
| provisioning | The site is created on its subdomain and built | 2 to 5 min |
| configuring | Strategy, visuals and logo, own-sitemap internal links and the other passes, writing kernel, cadence, topic map | 3 to 5 min |
| seeding | The first post(s) start writing from open spokes on the new topic map | seconds to start; 20 to 40 min to publish |
| done | The site is live and the seed runs are going on their own |
A verified run from a real homepage reached a live site with its first post queued in about nine minutes.
The status response carries deployment_id (the site), collection_id, config_job_id and seed_job_ids. Those seed ids are collection runs now: follow each with get_collection_run (CLI: collection run-status <id>).
What it never does
- Use your company's name in the masthead, three separate guards, the last of which refuses the create.
- Overwrite a strategy you've already written. If your organization has a manifesto and stances, they're kept.
- Spend money unless you say so. The site goes up on a subdomain;
domain_mode: buy_nowis the only path that registers a domain, and it prices under $30 (KB-606). Prefer to text it in? KB-607 runs this same recipe over iMessage.
If it fails
The status shows failed with a reason in plain words. The ones you might see:
- Couldn't resolve a masthead name for acme.com, the homepage was unreadable and no
namewas given. Run again with a name. - Site provisioning errored / Configuration failed, a step inside broke; the message names it. Start a new onboarding; anything already built (the site, the collection) is kept and reused where possible.
- A refusal at the phantom balance: you are at your live-site limit. Free one, or ask us to raise it.
- A job that stalls is closed after six hours by a background sweep and reported as failed, with whatever it had built left in place.