---
title: "Put a thread the caller found, or a move the owner's plan calls for, onto this product run's moves list as a pending move. Scope 'act'; free, unmetered, every plan. Nothing is generated: the row carries the caller's title, reason, target if one was given, sources, the plan channel it serves if named, and the draft if one was written. It lands at the tail of the list in the shape the feed mints for its kind, so it gets the same brief, hand-off and ship rule (a long_form_content page counts as shipped only with its live URL). Kinds: community_reply and community_answer (a thread), directory_listing (a directory), citation_outreach (a page the AI engines cite), earned_media, cold_outreach and long_form_content. The first four need a target; the rest take one optionally. Deduplicated: a repeat of the same kind and target, or the same kind and normalised title when there is no target, lands on one row (reported as already listed, with the existing move id, and without using a daily slot), and a thread the radar already found is not duplicated. Posture is resolved from the kind and the venue exactly as the feed resolves it: a Reddit or Hacker News target is never one the AI acts on (draft_only, or founder_voice for outreach), and outreach goes out from the owner's own address. Bounded per product run per day, claimed atomically before the write: 20 community threads, and 10 of the other kinds."
method: POST
path: "/api/v1/moves/propose"
---

# Put a thread the caller found, or a move the owner's plan calls for, onto this product run's moves list as a pending move. Scope 'act'; free, unmetered, every plan. Nothing is generated: the row carries the caller's title, reason, target if one was given, sources, the plan channel it serves if named, and the draft if one was written. It lands at the tail of the list in the shape the feed mints for its kind, so it gets the same brief, hand-off and ship rule (a long_form_content page counts as shipped only with its live URL). Kinds: community_reply and community_answer (a thread), directory_listing (a directory), citation_outreach (a page the AI engines cite), earned_media, cold_outreach and long_form_content. The first four need a target; the rest take one optionally. Deduplicated: a repeat of the same kind and target, or the same kind and normalised title when there is no target, lands on one row (reported as already listed, with the existing move id, and without using a daily slot), and a thread the radar already found is not duplicated. Posture is resolved from the kind and the venue exactly as the feed resolves it: a Reddit or Hacker News target is never one the AI acts on (draft_only, or founder_voice for outreach), and outreach goes out from the owner's own address. Bounded per product run per day, claimed atomically before the write: 20 community threads, and 10 of the other kinds.

`POST /api/v1/moves/propose`

## Request

- Base URL: `https://afterlaunch.io`
- URL: `https://afterlaunch.io/api/v1/moves/propose`
- Auth: HTTP bearer

## Request body

- object
  - `title` string, required: The move, as the owner would name it.
  - `why` string, required: What was read, or what the plan says, that makes it worth the owner's time.
  - `kind` 'community_reply' | 'community_answer' | 'directory_listing' | 'citation_outreach' | 'earned_media' | 'cold_outreach' | 'long_form_content', required
  - `target` string: The https address of the thread, directory or cited page (required for community_reply, community_answer, directory_listing and citation_outreach); optional for the other kinds.
  - `draft` string: Optional draft.
  - `sources` string[]: Optional: up to five https addresses the why rests on.
  - `serves` 'linkedin' | 'site' | 'placements' | 'x' | 'reddit' | 'quora' | 'youtube' | 'outreach' | 'other': Optional: the channel in the owner's plan this move serves. Stored on the move's evidence and shown on its card in Growth moves.

## Response `200`

proposed says whether a row was added; move_id is the move either way; posture and posture_reason say who may do it.

- object
  - `data` object, required
  - `meta` object, required
    - `enrollment_id` string, uuid, required
    - `generated_at` string, date-time, required

## Other responses

- `400`: A field is outside its bounds, kind is not proposable, target is missing for a kind that needs one or is not an https address, or serves is not one of the plan channels.
- `401`: Missing, invalid or revoked API key.
- `403`: The key does not carry the scope this endpoint requires.
- `429`: This product run has reached today's proposal limit for this kind. Honour Retry-After.

---

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