---
title: "Build, refine, or check a post draft"
method: POST
path: "/api/v1/compose"
tags: ["Composition"]
---

# Build, refine, or check a post draft

`POST /api/v1/compose`

Uses xai-org/x-algorithm facts to compose and refine text. Score checks text. It never predicts reach or engagement.

## Request body

- union
  - ComposePrepareRequest — Inputs for preparing source-backed post guidance.
    - `step` 'compose', required
    - `topic` string, required — Subject for the post.
    - `goal` 'engagement' | 'followers' | 'authority' | 'conversation' — User goal used for one follow-up question.
    - `styleUsername` string — Username from a style analysis saved to this account.
  - ComposeRefineRequest — Inputs for refining a post plan.
    - `step` 'refine', required
    - `topic` string, required — Subject to refine into a post.
    - `goal` 'engagement' | 'followers' | 'authority' | 'conversation', required — User goal interpreted against published ranking signals.
    - `tone` string, required — Requested writing tone.
    - `mediaType` 'photo' | 'video' | 'none' — Planned media type.
    - `callToAction` string — Specific action the draft should request.
    - `additionalContext` string — Audience, constraints, sources, or other writing context.
  - ComposeScoreRequest — Inputs for checking a post draft.
    - `step` 'score', required
    - `draft` string, required — Full post text. The endpoint never assigns a ranking score.
    - `hasLink` boolean — Accepted for backward compatibility. No guidance uses it.
    - `hasMedia` boolean — Accepted for backward compatibility. Text checks ignore this field.

## Response `200`

Result for the requested workflow step

- union
  - ComposePrepareResult — Rules, questions, and research guidance for drafting a post.
    - `contentRules` ComposeContentRule[], required — Facts derived only from xai-org/x-algorithm.
      - `rule` string, required
    - `engagementMultipliers` ComposeSignalLabel[], required — Source ranking signals. Repository defaults may vary in production.
      - `action` string, required — Human-readable published signal name.
      - `multiplier` 'Source default; production value can vary', required
    - `engagementVelocity` string, required — Publication limit for timing and decay claims.
    - `followUpQuestions` string[], required
    - `intentUrl` string, uri, required — X post intent seeded with the topic.
    - `nextStep` string, required
    - `radarRecommendations` ComposeRadarRecommendation[], required — Deprecated compatibility field. Always empty.
      - `endpoint` string, required — Radar endpoint for this source.
      - `guidance` string, required — Source-specific drafting guidance.
      - `source` 'reddit' | 'github' | 'trustmrr' | 'hacker_news' | 'google_trends' | 'wikipedia' | 'polymarket', required
      - `useFor` string, required — Current-topic research this source supports.
    - `scorerWeights` ComposeScorerSignal[], required — Source signals with production values withheld as null.
      - `context` string, required — Signal direction and production limit.
      - `signal` string, required — Signal name from X's public ranking repository.
      - `weight` unknown, required
    - `source` string, required — Signal source and evidence limits.
    - `topPenalties` string[], required — Negative engagement predictions in the public model.
    - `savedStyles` ComposeSavedStyle[] — Style analyses saved to the account.
      - `tweetCount` integer, required
      - `username` string, required
    - `styleTweets` string[] — Cached examples for the requested style username.
    - `styleNote` string — Next action when no cached style is available.
  - ComposeRefineResult — Source-backed guidance for refining a post.
    - `compositionGuidance` string[], required — Request context and xai-org/x-algorithm guidance.
    - `examplePatterns` ComposeExamplePattern[], required
      - `description` string, required
      - `pattern` string, required
    - `intentUrl` string, uri, required — X post intent generated for the refined topic.
    - `nextStep` string, required
  - ComposeScoreResult — Posting validation without a fabricated ranking score.
    - `checklist` ComposeScoreCheck[], required — Deterministic input validation. Not a reach prediction.
      - `factor` string, required
      - `passed` boolean, required
      - `suggestion` string — Present only when the check fails.
    - `intentUrl` string, uri — Present only when every check passes.
    - `nextStep` string, required
    - `passed` boolean, required
    - `passedCount` integer, required
    - `topSuggestion` string, required
    - `totalChecks` 1, required

## Other responses

- `400` — Invalid input
- `401` — Unauthenticated
- `429` — Xquik tier rate limit exceeded. The response includes a `Retry-After` header with the number of seconds to wait before retrying.
- `default` — Unexpected error.

## Changes

- **2026-08-24** `d6cb34aefa9f` — 6 breaking, 5 info
  - the `multiplier` response property const value changed from `Production weight not published by X` to `Source default; production value can vary` for the status `200`
  - the `totalChecks` response property const value changed from `9` to `1` for the status `200`
  - the `oneOf[#/components/schemas/ComposePrepareResult]/contentRules` response property's minItems was decreased from `18` to `10` for the response status `200`
  - the `oneOf[#/components/schemas/ComposePrepareResult]/radarRecommendations` response property's minItems was decreased from `7` to `0` for the response status `200`
  - …7 more
- **2026-08-12** `5d4938bb7de3` — 72 warning
  - added the new `closed` enum value to the `allOf[#/components/schemas/Error]/error/oneOf[subschema #1: LegacyErrorCode]/` response property for the response status `429`
  - added the new `closed` enum value to the `allOf[#/components/schemas/Error]/error/oneOf[subschema #2: StructuredError]/code` response property for the response status `429`
  - added the new `closed` enum value to the `error/oneOf[subschema #1: LegacyErrorCode]/` response property for the response status `400`
  - added the new `closed` enum value to the `error/oneOf[subschema #1: LegacyErrorCode]/` response property for the response status `401`
  - …68 more
- …earlier changes not shown

[Full history](https://skmtc.dev/xquik-dev/apis/xquik-api-2/changes/api/v1/compose/post.md)

---

[API](https://skmtc.dev/xquik-dev/apis/xquik-api-2.md) · [All operations](https://skmtc.dev/xquik-dev/apis/xquik-api-2/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/xquik-dev/xquik-api-2/revisions/834c16fa45e8/schema)
