---
title: "POST /v2/social/posts/{post_id}/replies"
method: POST
path: "/v2/social/posts/{post_id}/replies"
tags: ["Social Community"]
---

# POST /v2/social/posts/{post_id}/replies

`POST /v2/social/posts/{post_id}/replies`

## Request

- Base URL: `https://api.arbital.xyz` (the document declares no server; this is the origin it was published from)
- URL: `https://api.arbital.xyz/v2/social/posts/{post_id}/replies`
- Auth: HTTP bearer

Replies to a community post. Participation is community: any authenticated, unrestricted account that can read the post and has no block in either direction with the post author. Nothing is published to X. Caption is at most 2000 Unicode code points after trimming; C0 controls other than tab, newline and carriage return are rejected. Accepts ordered post_reply media_ids; body may be omitted or empty only with nonempty media or an external gif reference. Binding commits with the reply. Disabled writes return 503 social_media_disabled and invalid media returns 400 invalid_social_media. Also accepts one public KLIPY gif reference with optional caption, without a media upload. Reject gif with nonempty media_ids, null references, arbitrary URLs and unknown reference fields. SOCIAL_EXTERNAL_GIFS_ENABLED defaults false; disabled GIF-reference writes return 503 social_media_disabled independently of the upload gate. The backend stores the reference atomically and performs no provider calls or GIF-byte moderation. Receiver lookup restrictions must be reviewed before activation.

## Path parameters

- `post_id` string, uuid, required

## Request body

- CreateSocialPostReplyRequest: A nonblank body of at most 2000 Unicode code points, or nonempty post_reply media_ids. Body may be omitted or empty only with media or an external gif reference. Parent and ancestor authorization and text moderation still apply. Alternatively accepts one external gif reference with an optional caption; gif and nonempty media_ids are mutually exclusive. Absent gif is omitted; null is invalid. SOCIAL_EXTERNAL_GIFS_ENABLED defaults to false and gates GIF-reference writes independently of uploaded media; disabled writes return 503 social_media_disabled. Native mentions support stable Early user IDs only. Imported-thesis/trade routes reject mention/key fields. No financial authority or external identity inference is granted.
  - `body` string
  - `media_ids` : Upload IDs in gallery order. Each must belong to the actor, be approved, ready, unexpired and unbound, and match the write scope and exact chat when applicable. Up to four still images or one GIF; no mixed gallery. Binding is atomic with the parent write.
  - `gif` SocialExternalGifReference, required: A selected public KLIPY GIF reference, not an approved social-media upload. The backend validates syntax and stores only these identifiers; it does not call KLIPY or approve, cache or store its bytes. Resolve from the end-user client, verify both returned id and slug, apply receiver-side content restrictions and display provider attribution. Missing, filtered or mismatched items are unavailable. Never send an Arbital bearer token to the provider.
    - `provider` 'klipy', required
    - `id` string, required: Canonical positive decimal provider identifier. Keep as a string; never coerce to a JavaScript number. The absolute-end assertion rejects trailing newlines.
    - `slug` string, required: Exact provider lookup slug, including case. Do not derive a URL or accept arbitrary provider media URLs. The absolute-end assertion rejects trailing newlines.
  - `mentions` NativeMentionInput[]: Explicit native targets; no targets are inferred from plain @text. Offsets use Unicode code points in the exact canonical body; no trimming is allowed when nonempty.
    - `kind` 'early_user', required
    - `user_id` string, uuid, required
    - `offset` integer, required: Zero-based Unicode code-point offset, not UTF-16 units or graphemes.
    - `length` integer, required
  - `client_content_id` string, uuid: Actor/source-kind scoped creation key. Matching replay returns the original readable source; a changed command returns 409. Required with nonempty mentions.

## Response `201`

The created reply

- SocialPostReply: A reply on a community post. Token comment threads and chat messages use separate APIs; their ids cannot address post replies. Optional gif contains the saved external reference only for a visible, nondeleted native reply. It remains readable when GIF-reference writes are disabled and is omitted for deleted placeholders. It is distinct from approved uploaded media and is never returned with nonempty media.
  - `author` SocialPostAuthor, required
    - `display_name` string, nullable, required
    - `profile_image_url` string, nullable, required: Approved profile image or stable CALLD default avatar URL.
    - `user_id` string, uuid, required
    - `username` string, required
    - `x_avatar_url` string, nullable, required
  - `body` string, nullable, required: Null after parent deletion; empty for a media-only or external-GIF-only reply. Removing the last image preserves the empty body and deleted media slot.
  - `created_at_ms` string, required
  - `deleted` boolean, required
  - `id` string, uuid, required
  - `parent_reply_id` string, uuid, nullable, required: Exact direct parent reply on the same post; null for a direct reply to the post.
  - `post_id` string, uuid, required
  - `reply_count` integer, required: Nondeleted visible direct replies, excluding deeper descendants.
  - `viewer_can_delete` boolean, required: Whether the viewer owns this undeleted reply and may delete it.
  - `media` union: Ordered immutable slots, with unique IDs and zero-based ordinals matching array positions. Up to four still images, or exactly one GIF. Deletion preserves the slot and original ID. Replies, messages and recap comments omit this field when there are no slots; posts return an empty array.
    - union[]
      - union
        - SocialMediaImage
          - `id` string, uuid, required
          - `media_kind` 'image', required
          - `mime_type` 'image/jpeg' | 'image/png' | 'image/webp', required
          - `size_bytes` integer, required
          - `width` integer, required
          - `height` integer, required
          - `access_path` string, required: Authenticated relative byte-read path for this media ID; never a public or signed storage URL.
          - `ordinal` integer, required
          - `deleted` false
          - `delivery` SocialMediaDelivery: Optional HTTP-only delivery capability, issued after current access checks. URLs expire together at expires_at. Clients load the thumbnail in feeds and the full normalized image or animated GIF when opened. Refresh by re-reading the parent endpoint; access_path remains an authenticated fallback. Never persist, broadcast or share these viewer-specific URLs.
            - `url` string, uri, required: Short-lived Cloudflare Worker URL for the full normalized image or GIF. Treat it as opaque; refetch authorized parent metadata before expires_at to renew.
            - `expires_at` string, date-time, required
            - `thumbnail` object: Bounded WebP preview. Animated GIFs use an approved still poster.
              - …
        - DeletedSocialMedia: Permanent bound slot after media removal. Only these three fields remain; the parent remains renderable even when its body is empty and every image is deleted.
          - `id` string, uuid, required
          - `ordinal` integer, required
          - `deleted` true, required
    - SocialMediaGif[]
      - `id` string, uuid, required
      - `media_kind` 'gif', required
      - `mime_type` 'image/gif', required
      - `size_bytes` integer, required
      - `width` integer, required
      - `height` integer, required
      - `access_path` string, required: Authenticated relative byte-read path for this media ID; never a public or signed storage URL.
      - `source_tenor_url` string
      - `ordinal` integer, required
      - `deleted` false
      - `delivery` SocialMediaDelivery: Optional HTTP-only delivery capability, issued after current access checks. URLs expire together at expires_at. Clients load the thumbnail in feeds and the full normalized image or animated GIF when opened. Refresh by re-reading the parent endpoint; access_path remains an authenticated fallback. Never persist, broadcast or share these viewer-specific URLs.
        - `url` string, uri, required: Short-lived Cloudflare Worker URL for the full normalized image or GIF. Treat it as opaque; refetch authorized parent metadata before expires_at to renew.
        - `expires_at` string, date-time, required
        - `thumbnail` object: Bounded WebP preview. Animated GIFs use an approved still poster.
          - `url` string, uri, required
          - `mime_type` 'image/webp', required
          - `size_bytes` integer, required
          - `width` integer, required
          - `height` integer, required
  - `gif` SocialExternalGifReference: A selected public KLIPY GIF reference, not an approved social-media upload. The backend validates syntax and stores only these identifiers; it does not call KLIPY or approve, cache or store its bytes. Resolve from the end-user client, verify both returned id and slug, apply receiver-side content restrictions and display provider attribution. Missing, filtered or mismatched items are unavailable. Never send an Arbital bearer token to the provider.
    - `provider` 'klipy', required
    - `id` string, required: Canonical positive decimal provider identifier. Keep as a string; never coerce to a JavaScript number. The absolute-end assertion rejects trailing newlines.
    - `slug` string, required: Exact provider lookup slug, including case. Do not derive a URL or accept arbitrary provider media URLs. The absolute-end assertion rejects trailing newlines.
  - `mentions` NativeReadMention[], required: Ordered historical entities with current viewer-scoped identity. Empty for legacy, imported or tombstoned content. A read failure is explicit, never a fabricated empty array.
    - `kind` 'early_user', required
    - `user_id` string, uuid, required
    - `offset` integer, required: Zero-based Unicode code-point offset, not UTF-16 units or graphemes.
    - `length` integer, required
    - `text` string, required: Immutable exact authored span, including @.
    - `availability` 'available' | 'unavailable', required
    - `current_profile` NativeMentionProfile, required
      - `user_id` string, uuid, required
      - `username` string, required
      - `display_name` string, nullable, required
      - `profile_image_url` string, nullable, required
    - `profile_target` NativeMentionTarget, required
      - `kind` 'early_user', required
      - `user_id` string, uuid, required
    - `notification_supported` true, required

## Other responses

- `400`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.
- `401`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.
- `403`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.
- `404`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.
- `409`: content_idempotency_conflict or mention_target_changed; no partial creation.
- `422`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.
- `429`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.
- `503`: Stable machine-readable problem. HTTP 429 and 503 responses include retry and cache-validity fields plus Retry-After and X-Request-ID headers.

---

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