> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superx.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Top replies to a public post

> The best-liked DIRECT replies to a public post, read live from X.

This walks up to 3 relevance-ranked upstream pages (about 60
candidate replies), ranks what it found by likes and returns the top
`limit`. It is a SAMPLE of the strongest replies, not every reply and
not chronological order, and it cannot page further. To collect
everyone who replied to a post, use the audience collections built in
the SuperX app (`GET /v1/datasets`).

Unlike the same feature inside the SuperX app, replies written by the
account owner themselves are NOT filtered out: an owner-scoped read
has no "active account" to compare against.

Costs a flat THREE live-enrichment units and draws on the shared
300/day live-lookup allowance (one unit of that per page actually
fetched). `data.post` is the post being replied to when the upstream
payload carried it, and null otherwise; it is never a second lookup.

The `X-RateLimit-*` headers on this endpoint report the ENRICHMENT
window, not the ordinary read window.




## OpenAPI

````yaml /api-reference/openapi.yaml get /v1/x/posts/{id}/replies
openapi: 3.1.0
info:
  title: SuperX API
  version: 1.0.0
  description: >
    The SuperX public API: your Twitter/X content, analytics, audience and

    scheduling data over REST.


    All endpoints require an API key (`Authorization: Bearer sxk_...`) except

    `GET /v1/docs`. Keys are created in the SuperX app under Account > API / MCP
    / CLI

    and are server-side secrets.


    Timestamps are UTC ISO-8601 in both directions; inputs must carry an
    explicit

    `Z` or numeric offset. Every authenticated response carries

    `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`
    headers.
  contact:
    name: SuperX
    url: https://superx.so
servers:
  - url: https://api.superx.so
security:
  - apiKey: []
tags:
  - name: Identity
  - name: Content
  - name: Analytics
  - name: Inspiration
  - name: Audience
  - name: Contact Lists
  - name: Signals
  - name: Datasets
    description: |
      The audience collections Ask SuperX builds in the app: the repliers,
      quoters or reposters of a post, the members of an X list, your own
      posts or replies, or a research brief.

      Collect a new one with `POST /v1/datasets` (a big collection answers
      202 and finishes in the background), read it, export it, or copy the
      people in it into a contact list you created. Datasets are kept for 30
      days, and the ones Ask SuperX builds in the app show up here too.
  - name: Engage
    description: |
      The account's saved Engage feeds and the candidate posts in them, for
      an agent to score and a person to act on.

      Read-only by design. These endpoints return feed candidates for a
      person to review; replies are written and sent by a person in the
      SuperX app, which is why there is no reply endpoint here. Sending
      spammy, automated, or AI-generated replies that read as inauthentic
      may get your X account suspended under X's inauthentic-behavior
      rules and your SuperX account terminated. AI suggestions must be
      reviewed and meaningfully edited before they are sent, and you are
      solely responsible for what you post. Reply activity is logged and
      may be audited.
  - name: X Lookups
    description: |
      Read any public post, its top replies, any public profile, or an
      account's latest posts LIVE from X, rather than from SuperX's stored
      data.

      These are owner-scoped, so none of them take an `account_id`: nothing
      about a public lookup is per-X-account. They cost the tighter
      live-enrichment allowance and share a daily allowance of 300 live
      lookups with Ask SuperX inside the app, so use them for what you
      actually need rather than to sweep. Repeat lookups within 15 minutes
      may be served from a short-lived server-side cache.
  - name: Tools
    description: |
      The composer helpers from the SuperX app, over the API: rewrite a post,
      edit one selected piece of it, apply one preset rewrite, check a claim,
      or compare two versions.

      Every one of them returns TEXT and writes nothing. Nothing here is
      posted, scheduled or sent; save what you keep with
      `POST /v1/posts/draft` or `POST /v1/scheduled-posts`. They cost AI
      credits, measured from the models' real cost, and spend no live-data
      allowance.
  - name: Media
  - name: Workers
    description: |
      The posts the account's Workers have written, and the three things a
      person does with one: save it as a draft, schedule it, or dismiss it.

      A Worker is a scheduled AI writer set up in the SuperX app. Creating,
      editing and running one stays in the app, so there is no create or run
      endpoint here. What a run produces lands in the app's "To review" queue
      and is read with `GET /v1/workers/suggestions`.

      NOTHING HERE POSTS TO X. Drafting or scheduling a suggestion writes a
      post the user can see in the app and on `GET /v1/scheduled-posts`,
      exactly like the app's own buttons. AI output must be reviewed and
      meaningfully edited by a person before it goes out, so show the text to
      the user and confirm the time before you schedule anything.
  - name: Scheduling
  - name: Tags
  - name: Context
  - name: Queue
  - name: DMs
    description: |
      Queue direct messages into the account's own DM pipeline, and read or
      cancel what is waiting.

      NOTHING HERE SENDS A MESSAGE. `POST /v1/dm/campaigns` enqueues; the
      SuperX app's scheduler is what sends, within the account's daily and
      monthly DM limits, so the create response is counts, not deliveries.
      Unsent messages can be cancelled until the scheduler picks them up.

      You are responsible for the messages you queue. Unsolicited or
      automated bulk DMs may get an X account suspended under X's rules and
      a SuperX account terminated, so confirm the recipient list and the
      exact wording with the person on whose behalf you are queueing.
  - name: Articles
  - name: Meta
paths:
  /v1/x/posts/{id}/replies:
    get:
      tags:
        - X Lookups
      summary: Top replies to a public post
      description: |
        The best-liked DIRECT replies to a public post, read live from X.

        This walks up to 3 relevance-ranked upstream pages (about 60
        candidate replies), ranks what it found by likes and returns the top
        `limit`. It is a SAMPLE of the strongest replies, not every reply and
        not chronological order, and it cannot page further. To collect
        everyone who replied to a post, use the audience collections built in
        the SuperX app (`GET /v1/datasets`).

        Unlike the same feature inside the SuperX app, replies written by the
        account owner themselves are NOT filtered out: an owner-scoped read
        has no "active account" to compare against.

        Costs a flat THREE live-enrichment units and draws on the shared
        300/day live-lookup allowance (one unit of that per page actually
        fetched). `data.post` is the post being replied to when the upstream
        payload carried it, and null otherwise; it is never a second lookup.

        The `X-RateLimit-*` headers on this endpoint report the ENRICHMENT
        window, not the ordinary read window.
      operationId: getXPostReplies
      parameters:
        - name: id
          in: path
          required: true
          description: Numeric X post id.
          schema:
            type: string
            pattern: ^[0-9]{1,25}$
        - name: limit
          in: query
          description: Replies to return, best-liked first (1-20).
          schema:
            type: integer
            minimum: 1
            maximum: 20
            default: 10
      responses:
        '200':
          description: The top replies found.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      post_id:
                        type: string
                      post:
                        allOf:
                          - $ref: '#/components/schemas/XPost'
                        nullable: true
                        description: >-
                          The post being replied to, when the payload carried
                          it.
                      replies:
                        type: array
                        items:
                          $ref: '#/components/schemas/XPost'
                      replies_scanned:
                        type: integer
                        description: >-
                          Direct replies seen across the pages walked, before
                          the `limit` slice.
                      note:
                        type: string
                        description: What this sample covers, in plain words.
              example:
                data:
                  post_id: '1938765432109876543'
                  post: null
                  replies:
                    - id: '1938767777109876543'
                      url: https://x.com/janedev/status/1938767777109876543
                      text: >-
                        The 30-day constraint is the whole trick. Deadlines beat
                        motivation.
                      created_at: '2026-06-20T15:31:00.000Z'
                      author:
                        x_user_id: '1290011'
                        username: janedev
                        name: Jane
                        avatar_url: https://pbs.twimg.com/profile_images/2/avatar.jpg
                        verified: false
                        followers_count: 3110
                      metrics:
                        likes: 288
                        replies: 12
                        reposts: 4
                        quotes: 0
                        views: 41022
                        bookmarks: 19
                      in_reply_to_id: '1938765432109876543'
                  replies_scanned: 47
                  note: >-
                    Top direct replies by likes, from up to 3 relevance-ranked
                    pages (about 60 candidates). Not exhaustive and not
                    chronological. Replies the account owner wrote themselves
                    are included.
        '400':
          $ref: '#/components/responses/InvalidParameter'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/SubscriptionRequired'
        '404':
          $ref: '#/components/responses/PostNotFound'
        '429':
          $ref: '#/components/responses/LookupQuotaExceeded'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/UpstreamUnavailable'
components:
  headers:
    X-RateLimit-Limit:
      description: The limit of the rate window closest to exhaustion.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests remaining in that window.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix timestamp (seconds) when that window resets.
      schema:
        type: integer
  schemas:
    XPost:
      type: object
      description: |
        One public X post read live. Text is never shortened. Optional keys
        (`is_pinned`, `is_repost`, `entities`, `media`, `card`, `quoted_post`)
        are present only when the post has them.
      properties:
        id:
          type: string
          description: Numeric X post id, as a string.
        url:
          type: string
        text:
          type: string
          description: The full post text.
        created_at:
          type: string
          format: date-time
          nullable: true
        author:
          type: object
          nullable: true
          properties:
            x_user_id:
              type: string
            username:
              type: string
              nullable: true
            name:
              type: string
              nullable: true
            avatar_url:
              type: string
              nullable: true
            verified:
              type: boolean
              nullable: true
              description: |
                Null when the upstream payload for that read does not carry
                it (single-post lookups and their quoted posts).
            followers_count:
              type: integer
              nullable: true
        metrics:
          type: object
          properties:
            likes:
              type: integer
            replies:
              type: integer
            reposts:
              type: integer
            quotes:
              type: integer
            views:
              type: integer
              nullable: true
            bookmarks:
              type: integer
        in_reply_to_id:
          type: string
          nullable: true
          description: Set when this post is a reply; the id of the post it answers.
        is_pinned:
          type: boolean
          description: Present and true only on the account's pinned post (timeline reads).
        is_repost:
          type: boolean
          description: Present and true only on a repost of someone else's post.
        entities:
          type: array
          description: >-
            t.co link mappings, so short links can be rendered as their real
            destination.
          items:
            type: object
            properties:
              url:
                type: string
              display_url:
                type: string
                nullable: true
              expanded_url:
                type: string
                nullable: true
        media:
          type: array
          description: Attached media. `video_url` is a playable MP4 for videos and GIFs.
          items:
            type: object
            properties:
              type:
                type: string
                example: photo
              url:
                type: string
                nullable: true
              video_url:
                type: string
                nullable: true
              width:
                type: integer
              height:
                type: integer
        card:
          type: object
          description: Link preview card, when the post has one.
          properties:
            url:
              type: string
              nullable: true
            title:
              type: string
            description:
              type: string
              nullable: true
            domain:
              type: string
              nullable: true
            image:
              type: string
              nullable: true
        quoted_post:
          allOf:
            - $ref: '#/components/schemas/XPost'
          nullable: true
          description: |
            The post this one quotes, ONE level deep only - a quote of a
            quote is not nested further.
    ErrorEnvelope:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable machine-readable error code.
            message:
              type: string
            retry_after:
              type: integer
              description: Seconds to wait before retrying (rate-limit errors only).
    LegacyErrorEnvelope:
      type: object
      required:
        - error
      description: |
        Legacy shape used ONLY by the shared subscription middleware: a plain
        string `error` field. Seen on `403` when the subscription has lapsed
        (string starts with "subscription_required:") and on `500` when
        subscription verification fails (string starts with "internal_error:").
      properties:
        error:
          type: string
          example: >-
            subscription_required: The SuperX API requires an active
            subscription
  responses:
    InvalidParameter:
      description: A parameter is missing, malformed, or out of range.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: invalid_parameter
              message: since must be a UTC ISO-8601 timestamp
    Unauthorized:
      description: >-
        Missing/malformed Authorization header (`unauthorized`) or an
        unknown/revoked key (`invalid_api_key`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: invalid_api_key
              message: Unknown or revoked API key
    SubscriptionRequired:
      description: |
        Subscription lapsed. NOTE the legacy body shape: `error` is a plain
        string here, not the `{ code, message }` object. Read-only keys on
        write endpoints instead get the object envelope with code
        `insufficient_scope`.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/LegacyErrorEnvelope'
              - $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error: >-
              subscription_required: The SuperX API requires an active
              subscription
    PostNotFound:
      description: |
        No public post with that id: it is deleted, protected, or the id is
        wrong. The upstream batch read reports a missing post and a failed
        read identically, so an occasional transient failure surfaces here
        too - retry once before concluding the post is gone.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: post_not_found
              message: >-
                No public post with that id. It may be deleted, protected, or
                the id may be wrong. A live lookup that fails upstream can also
                report this.
    LookupQuotaExceeded:
      description: |
        A live-lookup 429. Either the plan's per-minute or per-day enrichment
        bucket is exhausted (`rate_limited`), or a daily live-lookup gate
        stopped the call (`lookup_quota_exceeded`). Read `error.code` to tell
        those two apart; both carry `Retry-After`.

        `lookup_quota_exceeded` covers three cases and the body says which:
        your own allowance is used up (`limit` is present, and that allowance
        is shared with Ask SuperX in the app, resetting at midnight UTC); the
        SuperX-wide allowance is used up (no `limit`, since it is not your
        account's budget, still resetting at midnight); or the counter could
        not be verified, in which case the call is refused rather than run
        unmetered (no `limit`, short `retry_after`). Always read
        `error.retry_after` rather than assuming midnight.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - type: object
                properties:
                  error:
                    type: object
                    properties:
                      retry_after:
                        type: integer
                        description: Seconds to wait before retrying.
                      limit:
                        type: integer
                        description: |
                          Your daily live-lookup allowance. Present ONLY when
                          it is your own allowance that ran out; absent for a
                          SuperX-wide cap or an unverifiable counter.
                      reset_at:
                        type: integer
                        description: |
                          Unix seconds at the next UTC midnight. Present on
                          the two allowance cases, absent when the counter
                          could not be verified.
          example:
            error:
              code: lookup_quota_exceeded
              message: >-
                Today's live X lookup allowance (300 lookups) is used up. It is
                shared with Ask SuperX in the app and resets at midnight UTC.
              retry_after: 20400
              limit: 300
              reset_at: 1789430400
    InternalError:
      description: >-
        Unexpected server error. May also use the legacy string envelope when
        subscription verification fails.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - $ref: '#/components/schemas/LegacyErrorEnvelope'
          example:
            error:
              code: internal_error
              message: Failed to fetch posts
    UpstreamError:
      description: A dependent SuperX service returned an unexpected response.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: upstream_error
              message: Failed to fetch scheduled posts. Try again shortly.
    UpstreamUnavailable:
      description: >-
        The scheduling service is temporarily unreachable. Safe to retry; reuse
        your Idempotency-Key on POST.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: upstream_unavailable
              message: >-
                The scheduling service is temporarily unavailable. Retry with
                the same Idempotency-Key.
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        A SuperX API key ("sxk_..."), created in the SuperX app under Account >
        API / MCP / CLI. Keys are server-side secrets.

````