---
title: "Read this product run's calendar, up to 100 saved source drafts and their current canonical Feed state. Requires read. Honour queue_position and needs_data. channel_state is a stored projection; check calendar_sync and linkage before acting. x_production_enabled is the existing twitter_thread switch. Read coverage before planning: unknown or incomplete history is not an empty review pile. No generation or spend."
method: GET
path: "/api/v1/content/calendar"
---

# Read this product run's calendar, up to 100 saved source drafts and their current canonical Feed state. Requires read. Honour queue_position and needs_data. channel_state is a stored projection; check calendar_sync and linkage before acting. x_production_enabled is the existing twitter_thread switch. Read coverage before planning: unknown or incomplete history is not an empty review pile. No generation or spend.

`GET /api/v1/content/calendar`

## Request

- Base URL: `https://afterlaunch.io`
- URL: `https://afterlaunch.io/api/v1/content/calendar`
- Auth: HTTP bearer

## Response `200`

Up to 200 calendar pieces, ordered by queue position then recency, and up to 100 saved records ordered by source output update time.

- object
  - `data` object, required
    - `enrollment_id` string, uuid, required
    - `timezone` string, required
    - `calendar` object[], required
      - `id` string, uuid, required
      - `title` string, required
      - `angle` string, nullable, required
      - `kind` 'opinion' | 'educational' | 'amplify', required
      - `channels` string[], required
      - `channel_state` object, required: Stored per-channel projection, including status and output_id when present. For linked content, the canonical move and calendar_sync expose lifecycle drift. Other channels are preserved.
      - `evidence` unknown, required
      - `status` 'pool' | 'queued' | 'done' | 'dismissed', required
      - `queue_position` integer, nullable, required
      - `link` string, nullable, required
      - `notes` string, nullable, required
      - `needs_data` boolean, required
      - `updated_at` string, date-time, required
    - `coverage` object, required
      - `ideas` object, required
        - `returned` integer, required
        - `total` integer, nullable, required
        - `complete` boolean, required: Exact response count equals all returned, decoded records. False for unknown counts or truncation. This is a point-in-time read, not a reservation.
      - `drafts` object, required
        - `returned` integer, required
        - `total` integer, nullable, required
        - `complete` boolean, required: Exact response count equals all returned, decoded records. False for unknown counts or truncation. This is a point-in-time read, not a reservation.
    - `drafts` object[], required
      - `output_id` string, uuid, required
      - `idea_id` string, uuid, required
      - `run_key` string, required
      - `channel` 'x', required
      - `title` string, required
      - `source_url` string, nullable, required: Source evidence; also the exact destination for a classified legacy reply.
      - `why` string, required
      - `claim_ids` string[], required
      - `claims` object[], required
        - `id` string, uuid, required
        - `text` string, required
        - `number` string, required
        - `caveat` string, required
      - `output_status` string, required: Raw source output status. posted alone proves neither founder confirmation nor published words.
      - `status` string, required: Current canonical move status when linked, otherwise raw output status. Prepared attempt content never implies shipped.
      - `source_draft` object, nullable, required: Current source candidate, or output fallback. Null when drafts are withheld. Not published words.
        - `storage` 'candidate' | 'output'
        - `candidate_id` string, nullable
        - `text` string
      - `move` object, nullable, required: Ownership-bound Feed read, carrying the actual move id. A collection app_url does not open the move in focus.
        - `id` string, uuid
        - `identity_key` string, nullable
        - `source_key` string
        - `source_output_id` string, uuid
        - `action_kind` string, nullable
        - `target` string, nullable
        - `status` string
        - `updated_at` string, date-time
        - `draft_content` string, nullable
        - `draft_kind` 'full_draft' | 'brief' | 'null', nullable
      - `prepared_result` object, nullable, required: Current attempt from readPreparedMoveResult, including job/attempt identity, state, prepared_content and recorded published_url. Preparation is not publication; prepared_content is not reported final copy. Private material is withheld at the shared tier boundary.
      - `legacy_publication_report` object, nullable, required: Only the old pilot explicit human_reported confirmation and its stored words/link. Never reconstructed from output status or a draft.
        - `basis` 'human_reported'
        - `text` string
        - `url` string
      - `drafts_withheld` boolean, required
      - `drafts_match` boolean, nullable, required
      - `linkage` 'linked' | 'incomplete' | 'legacy_terminal', required
      - `linkage_reason` string, nullable, required
      - `calendar_sync` 'linked' | 'missing' | 'different_output' | 'lifecycle_differs', required: Comparison with stored channel_state. The move lifecycle is authoritative; this reader does not silently repair completion projections.
      - `updated_at` string, date-time, required: Source output update time. The move and attempt carry their own timestamps.
    - `x_production_enabled` boolean, required
    - `can_record_drafts` boolean, required: True when access permits filing and X production is disabled or has not been configured. The first draft write can create disabled storage; this read creates nothing. This is not an OAuth connection check.
  - `meta` object, required
    - `enrollment_id` string, uuid, required
    - `generated_at` string, date-time, required

## Other responses

- `401`: Missing, invalid or revoked API key.
- `403`: The key does not carry the scope this endpoint requires.
- `404`: The key is not bound to the current product run.
- `429`: Per-key rate limit exceeded. 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)
