{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/postproxy-dev/json-schema/postproxy-dev-comment-schema.json",
  "title": "Comment",
  "description": "A comment on a published post.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/postproxy-dev-openapi.json#/components/schemas/Comment",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Unique comment identifier (ID)"
    },
    "external_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Platform's native comment ID (null for pending comments)"
    },
    "body": {
      "type": "string",
      "description": "Comment text content"
    },
    "status": {
      "type": "string",
      "enum": [
        "synced",
        "pending",
        "published",
        "failed",
        "failed_waiting_for_retry",
        "delivery_unconfirmed"
      ],
      "description": "Comment status. Only published and failed are terminal — treat every other value as still in progress."
    },
    "error": {
      "type": [
        "string",
        "null"
      ],
      "description": "Error summary if the comment failed to publish (null otherwise)"
    },
    "error_details": {
      "$ref": "#/$defs/PlatformErrorDetails"
    },
    "author_username": {
      "type": [
        "string",
        "null"
      ],
      "description": "Author's display name or username"
    },
    "author_avatar_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Stable Postproxy storage URL of the author's profile picture once mirrored; the platform URL until then"
    },
    "author_external_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Author's platform-specific ID"
    },
    "metadata": {
      "$ref": "#/$defs/CommentMetadata"
    },
    "parent_external_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Parent comment's external ID (null for top-level comments)"
    },
    "like_count": {
      "type": "integer",
      "description": "Number of likes on the comment"
    },
    "is_hidden": {
      "type": "boolean",
      "description": "Whether the comment is hidden"
    },
    "permalink": {
      "type": [
        "string",
        "null"
      ],
      "description": "Direct URL to the comment on the platform (when available)"
    },
    "platform_data": {
      "type": [
        "object",
        "null"
      ],
      "description": "Platform-specific metadata",
      "additionalProperties": true
    },
    "attachments": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/CommentAttachment"
      },
      "description": "Media attached to the comment. Empty array when there are none. Always empty on a freshly created (pending) comment."
    },
    "external_edited_at": {
      "type": [
        "string",
        "null"
      ],
      "description": "ISO 8601 timestamp of the last edit made through Postproxy (null if never edited)"
    },
    "posted_at": {
      "type": [
        "string",
        "null"
      ],
      "description": "ISO 8601 timestamp when the comment was posted on the platform"
    },
    "created_at": {
      "type": "string",
      "description": "ISO 8601 timestamp of record creation"
    },
    "replies": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Comment"
      },
      "description": "All replies (regardless of nesting depth) flattened under the root top-level comment, sorted by created_at ascending. Present on per-post list and get responses."
    }
  },
  "$defs": {
    "Comment": {
      "type": "object",
      "description": "A comment on a published post.",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique comment identifier (ID)"
        },
        "external_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "Platform's native comment ID (null for pending comments)"
        },
        "body": {
          "type": "string",
          "description": "Comment text content"
        },
        "status": {
          "type": "string",
          "enum": [
            "synced",
            "pending",
            "published",
            "failed",
            "failed_waiting_for_retry",
            "delivery_unconfirmed"
          ],
          "description": "Comment status. Only published and failed are terminal — treat every other value as still in progress."
        },
        "error": {
          "type": [
            "string",
            "null"
          ],
          "description": "Error summary if the comment failed to publish (null otherwise)"
        },
        "error_details": {
          "$ref": "#/$defs/PlatformErrorDetails"
        },
        "author_username": {
          "type": [
            "string",
            "null"
          ],
          "description": "Author's display name or username"
        },
        "author_avatar_url": {
          "type": [
            "string",
            "null"
          ],
          "description": "Stable Postproxy storage URL of the author's profile picture once mirrored; the platform URL until then"
        },
        "author_external_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "Author's platform-specific ID"
        },
        "metadata": {
          "$ref": "#/$defs/CommentMetadata"
        },
        "parent_external_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "Parent comment's external ID (null for top-level comments)"
        },
        "like_count": {
          "type": "integer",
          "description": "Number of likes on the comment"
        },
        "is_hidden": {
          "type": "boolean",
          "description": "Whether the comment is hidden"
        },
        "permalink": {
          "type": [
            "string",
            "null"
          ],
          "description": "Direct URL to the comment on the platform (when available)"
        },
        "platform_data": {
          "type": [
            "object",
            "null"
          ],
          "description": "Platform-specific metadata",
          "additionalProperties": true
        },
        "attachments": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/CommentAttachment"
          },
          "description": "Media attached to the comment. Empty array when there are none. Always empty on a freshly created (pending) comment."
        },
        "external_edited_at": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 8601 timestamp of the last edit made through Postproxy (null if never edited)"
        },
        "posted_at": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 8601 timestamp when the comment was posted on the platform"
        },
        "created_at": {
          "type": "string",
          "description": "ISO 8601 timestamp of record creation"
        },
        "replies": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Comment"
          },
          "description": "All replies (regardless of nesting depth) flattened under the root top-level comment, sorted by created_at ascending. Present on per-post list and get responses."
        }
      }
    },
    "CommentAttachment": {
      "type": "object",
      "description": "Media attached to a comment. Postproxy downloads each asset to durable storage; the url is stable once status is processed.",
      "properties": {
        "id": {
          "type": "string",
          "description": "Attachment hashid"
        },
        "type": {
          "type": "string",
          "enum": [
            "image",
            "video",
            "audio",
            "gif",
            "external",
            "file"
          ]
        },
        "url": {
          "type": [
            "string",
            "null"
          ],
          "description": "Stable storage URL to the asset. While status is pending, this temporarily falls back to the source URL on the platform until the file is mirrored to Postproxy storage."
        },
        "status": {
          "type": "string",
          "enum": [
            "pending",
            "processed",
            "failed"
          ],
          "description": "pending (still being mirrored), processed (stored and ready), failed (could not be downloaded)"
        },
        "external_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "Platform-side identifier for the attachment (e.g. Facebook attachment target ID). Omitted when the platform did not provide one."
        }
      }
    },
    "CommentMetadata": {
      "type": [
        "object",
        "null"
      ],
      "description": "Additional author signals fetched asynchronously from the platform after the comment is ingested. Null until the lookup completes; individual keys may be absent depending on platform support.",
      "properties": {
        "author_fetched_at": {
          "type": "string",
          "description": "ISO 8601 timestamp of the last author-info refresh"
        },
        "is_verified_user": {
          "type": "boolean",
          "description": "Author has a verified account (instagram)"
        },
        "is_user_follow_business": {
          "type": "boolean",
          "description": "Author follows the business profile (instagram)"
        },
        "is_business_follow_user": {
          "type": "boolean",
          "description": "The business profile follows the author (instagram)"
        },
        "follower_count": {
          "type": "integer",
          "description": "Author's follower count (instagram)"
        }
      },
      "additionalProperties": true
    },
    "PlatformErrorDetails": {
      "type": [
        "object",
        "null"
      ],
      "description": "Structured platform error (omitted when no platform error info is available).",
      "properties": {
        "platform_error_code": {
          "type": [
            "string",
            "null"
          ],
          "description": "Error code returned by the platform API"
        },
        "platform_error_subcode": {
          "type": [
            "string",
            "null"
          ],
          "description": "Error subcode returned by the platform API"
        },
        "platform_error_message": {
          "type": [
            "string",
            "null"
          ],
          "description": "Error message returned by the platform API"
        },
        "postproxy_note": {
          "type": [
            "string",
            "null"
          ],
          "description": "Additional context from Postproxy about the error"
        }
      }
    }
  }
}