---
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`

Run one step of Xquik's three-step writing workflow. Compose returns questions, editorial rules, and source-specific Radar recommendations. Refine returns goal-specific guidance. Score applies deterministic text checks. It does not predict reach or expose X ranking weights.

## Request body

- union
  - ComposePrepareRequest
    - `step` 'compose', required
    - `topic` string, required — Subject for the post.
    - `goal` 'engagement' | 'followers' | 'authority' | 'conversation' — Editorial goal used to order the rules and questions.
    - `styleUsername` string — Username from a style analysis saved to this account.
  - ComposeRefineRequest
    - `step` 'refine', required
    - `topic` string, required — Subject for the post.
    - `goal` 'engagement' | 'followers' | 'authority' | 'conversation', required — Editorial goal for the guidance.
    - `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
    - `step` 'score', required
    - `draft` string, required — Full post text for deterministic editorial checks.
    - `hasLink` boolean — True when a separate link card is attached.
    - `hasMedia` boolean — Accepted for backward compatibility. Text checks ignore this field.

## Response `200`

Result for the requested workflow step

- union
  - ComposePrepareResult
    - `contentRules` ComposeContentRule[], required — Xquik editorial heuristics, ordered for the goal.
      - `rule` string, required
    - `engagementMultipliers` ComposeSignalLabel[], required — Published engagement signal names. Production multipliers are not published.
      - `action` string, required — Human-readable published signal name.
      - `multiplier` 'Production weight not published by X', 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 — Sources and guidance for researching a fresh post angle.
      - `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 — Published signal names with unpublished weights as null.
      - `context` string, required — Signal direction and publication 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
    - `compositionGuidance` string[], required — Goal, tone, media, and editorial guidance.
    - `examplePatterns` ComposeExamplePattern[], required
      - `description` string, required
      - `pattern` string, required
    - `intentUrl` string, uri, required — X post intent seeded with the topic.
    - `nextStep` string, required
  - ComposeScoreResult
    - `checklist` ComposeScoreCheck[], required — Deterministic editorial checks. 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` 9, 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.

---

[API](https://skmtc.net/xquik-dev/apis/xquik-api-2.md) · [All operations](https://skmtc.net/xquik-dev/apis/xquik-api-2/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/xquik-dev/xquik-api-2/versions/c70f0e286159/schema)
