{
  "openapi": "3.0.3",
  "info": {
    "title": "Mateflow Community Open API",
    "version": "1.0.0",
    "description": "Site-scoped public API for Mateflow communities. One API key is bound to one community and carries a fixed set of scopes. Every endpoint is POST with a JSON body; the site is derived from the key, so no site id is ever sent.\n\nNote that the generator this contract comes from does not emit `required` on request bodies — treat every request property as optional here and read the required fields from the developer guide at https://mateflow.com/developers/api.",
    "contact": {
      "name": "Mateflow",
      "url": "https://mateflow.com/developers"
    },
    "x-published": "2026-09-14"
  },
  "paths": {
    "/site_open_api/v1/capabilities/get": {
      "post": {
        "operationId": "SiteOpenService_GetCapabilities",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetCapabilitiesRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/feed/featured": {
      "post": {
        "operationId": "SiteOpenService_ListFeaturedFeed",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListFeaturedFeedReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeaturedSiteFeedRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/feed/list": {
      "post": {
        "operationId": "SiteOpenService_ListFeed",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListFeedReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteFeedListRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/feed/top": {
      "post": {
        "operationId": "SiteOpenService_ListTopFeed",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListTopFeedReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteFeedListTopRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/media/get_signed_urls": {
      "post": {
        "operationId": "SiteOpenService_GetMediaSignedURLs",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetMediaSignedURLsReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetMediaSignedURLsRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/media/get_token": {
      "post": {
        "operationId": "SiteOpenService_GetMediaToken",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetMediaTokenReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaFileTokenRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/member/get": {
      "post": {
        "operationId": "SiteOpenService_GetMember",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetMemberReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetMemberRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/member/lookup": {
      "post": {
        "operationId": "SiteOpenService_LookupMember",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LookupMemberReqBody"
              }
            }
          },
          "description": "LookupMemberReq resolves an address you already hold to a member id.\n// Exact match only, and deliberately no fuzzy/prefix form: this is an existence\noracle for any address the caller cares to try, so it stays as close to\n\"confirm what I already know\" as possible."
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LookupMemberRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/batch_get": {
      "post": {
        "operationId": "SiteOpenService_BatchGetPosts",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchGetPostsReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchGetPostsRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/create": {
      "post": {
        "operationId": "SiteOpenService_CreatePost",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePostReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPostRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/delete": {
      "post": {
        "operationId": "SiteOpenService_DeletePost",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeletePostReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BaseMsgRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/direct_replies/list": {
      "post": {
        "operationId": "SiteOpenService_ListDirectReplies",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListDirectRepliesReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListDirectRepliesRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/featured_posts": {
      "post": {
        "operationId": "SiteOpenService_FeaturedPosts",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeaturedPostsReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeaturedPostsRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/get": {
      "post": {
        "operationId": "SiteOpenService_GetPost",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetPostReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPostRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/replies/list": {
      "post": {
        "operationId": "SiteOpenService_ListPostReplies",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListPostRepliesReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListPostRepliesRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/reply_descendants/list": {
      "post": {
        "operationId": "SiteOpenService_ListReplyDescendants",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListReplyDescendantsReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListReplyDescendantsRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/search": {
      "post": {
        "operationId": "SiteOpenService_SearchPosts",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchPostsReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchPostsRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/thread_chain": {
      "post": {
        "operationId": "SiteOpenService_GetThreadChain",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetThreadChainReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetThreadChainRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/post/update": {
      "post": {
        "operationId": "SiteOpenService_UpdatePost",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePostReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BaseMsgRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/site/get": {
      "post": {
        "operationId": "SiteOpenService_GetSite",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteInfoWithBasicSettingsRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/space/feed/list": {
      "post": {
        "operationId": "SiteOpenService_ListSpaceFeed",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListSpaceFeedReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpaceFeedListRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/space/feed/top": {
      "post": {
        "operationId": "SiteOpenService_ListTopSpaceFeed",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListTopSpaceFeedReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpaceFeedListTopRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/space/get": {
      "post": {
        "operationId": "SiteOpenService_GetSpace",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetSpaceReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetSpaceRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/site_open_api/v1/space/list": {
      "post": {
        "operationId": "SiteOpenService_ListSpaces",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListSpacesReqBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListSpacesRespBody"
                }
              }
            },
            "description": "Successful response"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            },
            "description": "Error. The HTTP status follows the platform ErrCode; the body shape is identical for every error."
          }
        },
        "tags": [
          "SiteOpenService"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ActivityCountInfo": {
        "properties": {
          "favs": {
            "format": "int64",
            "type": "integer"
          },
          "likes": {
            "format": "int64",
            "type": "integer"
          },
          "quotes": {
            "format": "int64",
            "type": "integer"
          },
          "reactions": {
            "description": "Reactions breakdown; likes == Σ reactions[].count. docs_new/post_reactions.",
            "items": {
              "$ref": "#/components/schemas/PostReactionInfo"
            },
            "type": "array"
          },
          "replies": {
            "format": "int64",
            "type": "integer"
          },
          "reposts": {
            "format": "int64",
            "type": "integer"
          },
          "views": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "ActivityInfo": {
        "properties": {
          "accepted_answer_id": {
            "type": "string"
          },
          "answers_count": {
            "format": "int64",
            "type": "integer"
          },
          "body": {
            "type": "string"
          },
          "can_view_quoted_post": {
            "type": "boolean"
          },
          "content_locked": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "edited_at": {
            "type": "string"
          },
          "first_replies": {
            "items": {
              "$ref": "#/components/schemas/BaseActivityInfo"
            },
            "type": "array"
          },
          "has_media": {
            "type": "boolean"
          },
          "has_more": {
            "type": "boolean"
          },
          "has_more_replies": {
            "type": "boolean"
          },
          "hidden_reply_count": {
            "format": "int32",
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "interaction_type": {
            "type": "string"
          },
          "is_accepted_answer": {
            "type": "boolean"
          },
          "is_featured": {
            "type": "boolean"
          },
          "is_hidden": {
            "description": "Admin moderation state (docs_new/admin_post_hide_lock_review_20260902 §B1).\nis_hidden can only ever be true for the AUTHOR of the post: every other\nviewer gets not_found for a hidden row, so clients may render the\n\"hidden, only you can see this\" notice off this flag directly.\nis_hidden_reason / is_locked_reason are moderator-written copy that IS\nshown to the author — never treat them as internal notes.\ncan_edit is already false while hidden; do not recompute it client-side.",
            "type": "boolean"
          },
          "is_hidden_reason": {
            "type": "string"
          },
          "is_locked": {
            "description": "Moderator post-lock (post_lock_reply_enforcement). Frozen reply tree:\nwhen true, only site admins / space moderators can add new replies.",
            "type": "boolean"
          },
          "is_locked_reason": {
            "type": "string"
          },
          "is_pinned": {
            "type": "boolean"
          },
          "is_scheduled": {
            "type": "boolean"
          },
          "is_sensitive": {
            "description": "Content warning (18-composer.md §4).",
            "type": "boolean"
          },
          "likes_count": {
            "format": "int64",
            "type": "integer"
          },
          "locked_space_id": {
            "type": "string"
          },
          "mentions": {
            "items": {
              "$ref": "#/components/schemas/MentionInfo"
            },
            "type": "array"
          },
          "object_type": {
            "type": "string"
          },
          "operations": {
            "$ref": "#/components/schemas/ActivityOperations"
          },
          "post_attachments": {
            "items": {
              "$ref": "#/components/schemas/PostAttachment"
            },
            "type": "array"
          },
          "post_audio": {
            "$ref": "#/components/schemas/PostAudio"
          },
          "post_blog": {
            "$ref": "#/components/schemas/PostBlog"
          },
          "post_event": {
            "$ref": "#/components/schemas/PostEvent"
          },
          "post_gif": {
            "$ref": "#/components/schemas/PostGif"
          },
          "post_media_files": {
            "items": {
              "$ref": "#/components/schemas/PostMediaFile"
            },
            "type": "array"
          },
          "post_oembed": {
            "$ref": "#/components/schemas/PostOembed"
          },
          "post_poll": {
            "$ref": "#/components/schemas/PostPoll"
          },
          "qa_status": {
            "description": "Q&A fields (only present when space_type = QA)",
            "type": "string"
          },
          "quote_id": {
            "type": "string"
          },
          "quote_post": {
            "$ref": "#/components/schemas/BaseActivityInfo"
          },
          "quoted_post_restricted": {
            "type": "boolean"
          },
          "ranking": {
            "format": "double",
            "type": "number"
          },
          "replies_count": {
            "format": "int64",
            "type": "integer"
          },
          "reply_id": {
            "type": "string"
          },
          "reply_post": {
            "$ref": "#/components/schemas/BaseActivityInfoWithQuote"
          },
          "reply_root_id": {
            "type": "string"
          },
          "reply_root_post": {
            "$ref": "#/components/schemas/BaseActivityInfoWithQuote"
          },
          "repost_id": {
            "type": "string"
          },
          "repost_post": {
            "$ref": "#/components/schemas/BaseActivityInfoWithQuote"
          },
          "restriction_reason": {
            "type": "string"
          },
          "review_status": {
            "description": "Publish outcome of post/create (site_space_admin_review_20260802 B1).\nOnly post/create fills these, and only when the post did NOT publish\nimmediately: a space with require_post_approval on (or auto-moderation\nflagging the content) stores the post with review_status=\"pending\" and\nwrites no activity row yet, and a scheduled post publishes later. Both\ncases return a data object carrying just the id, so without an explicit\nmarker the composer cannot tell \"published\" from \"waiting for review\"\nfrom \"scheduled\". Absent on the normal publish path.",
            "type": "string"
          },
          "scheduled_at": {
            "type": "string"
          },
          "sensitive_reason": {
            "type": "string"
          },
          "site_id": {
            "type": "string"
          },
          "space": {
            "$ref": "#/components/schemas/SpaceBrief"
          },
          "stats": {
            "$ref": "#/components/schemas/ActivityCountInfo"
          },
          "status": {
            "description": "Post status + scheduled_at (18-composer.md §2.3).",
            "type": "string"
          },
          "teaser_excerpt": {
            "description": "Teaser fields for preview mode",
            "type": "string"
          },
          "teaser_has_more": {
            "type": "boolean"
          },
          "teaser_media_count": {
            "format": "int32",
            "type": "integer"
          },
          "thread": {
            "$ref": "#/components/schemas/PostThreadInfo"
          },
          "thread_depth": {
            "format": "int32",
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/ActivityUserInfo"
          },
          "user_id": {
            "type": "string"
          },
          "verb": {
            "type": "string"
          },
          "views_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "ActivityOperations": {
        "properties": {
          "actor_role": {
            "description": "Highest-precedence role the viewer has for this post:\nowner / site_admin / space_admin / space_moderator / member / guest.\nTelemetry + delete-endpoint routing on the frontend; see §4.8.",
            "type": "string"
          },
          "can_delete": {
            "description": "owner OR site_admin OR space.can_moderate",
            "type": "boolean"
          },
          "can_edit": {
            "description": "owner + non-rejected + non-hidden + status in {draft,scheduled,published}",
            "type": "boolean"
          },
          "can_feature": {
            "description": "site_admin only, on published top-level posts",
            "type": "boolean"
          },
          "can_moderate": {
            "description": "site_admin OR space.can_moderate (NOT owner)",
            "type": "boolean"
          },
          "can_pin": {
            "description": "depends on pin_context (§4.5); false unless caller passed pin_context",
            "type": "boolean"
          },
          "can_reply": {
            "description": "May the viewer reply to / quote / repost this post. Folds together the\nthread-root interaction_type gate (Everyone / Following / Mentioned /\nNobody), posts.is_locked, and the space's allow_member_reply, so the\nclient no longer calls /post/check_interaction once per rendered post.\nAuthor and site admins are always true. Absent for anonymous viewers on\nolder clients; treat absent as false.",
            "type": "boolean"
          },
          "can_report": {
            "description": "logged-in non-owner non-site-admin on non-deleted post",
            "type": "boolean"
          },
          "favorited": {
            "type": "boolean"
          },
          "is_owner": {
            "description": "post_permissions/01 §3.1 — per-viewer permission bits. All optional so\nthe field is omitted entirely for unauthenticated callers in older\nclients that have not yet rolled out the server-side gating path.",
            "type": "boolean"
          },
          "liked": {
            "type": "boolean"
          },
          "my_reaction": {
            "description": "Reactions (docs_new/post_reactions): the viewer's current emoji. \"\" / omitted\n= no reaction. liked == (my_reaction != \"\"). QnA keeps liked ⟺ upvoted.",
            "type": "string"
          },
          "reposted": {
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "ActivityUserInfo": {
        "properties": {
          "admin_role": {
            "type": "string"
          },
          "avatar": {
            "description": "avatar — RAW storage key; do NOT use in <img src>. Use avatar_url.",
            "type": "string"
          },
          "avatar_url": {
            "description": "Media URL field (populated at read time)\navatar_url — signed CDN URL, ready for <img src>.",
            "type": "string"
          },
          "bio": {
            "type": "string"
          },
          "current_badge": {
            "$ref": "#/components/schemas/GamificationBadgeInfo"
          },
          "current_level": {
            "$ref": "#/components/schemas/GamificationLevelInfo"
          },
          "current_member_tier": {
            "$ref": "#/components/schemas/MemberTierBadgeInfo"
          },
          "display_name": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "is_deleted": {
            "type": "boolean"
          },
          "is_verified": {
            "type": "boolean"
          },
          "member_tags": {
            "items": {
              "$ref": "#/components/schemas/MemberTagInfo"
            },
            "type": "array"
          },
          "username": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ApiErrorResponse": {
        "description": "Standard error envelope (API_ERROR_SPEC §0). `code` is the platform ErrCode enum — NOT the HTTP status — and the same code always carries the same localized `msg`.",
        "properties": {
          "code": {
            "description": "Platform ErrCode (e.g. 10004 permission denied, 20103 workspace access version conflict, 20105 workspace ownership transfer required).",
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "additionalProperties": true,
            "description": "Machine-readable detail. Always carries `error_code` (snake_case); capability denials add `required_capability`, `scope_type`, `scope_id`; 20105 (workspace_ownership_transfer_required) adds `workspace_count`, `member_count`, `site_count` — decimal strings, counted across every workspace the caller owns that still holds members or communities.",
            "properties": {
              "error_code": {
                "type": "string"
              },
              "member_count": {
                "description": "20105 only: active members summed across those workspaces.",
                "type": "string"
              },
              "required_capability": {
                "type": "string"
              },
              "scope_id": {
                "type": "string"
              },
              "scope_type": {
                "type": "string"
              },
              "site_count": {
                "description": "20105 only: communities summed across those workspaces; excludes ones already pending purge.",
                "type": "string"
              },
              "workspace_count": {
                "description": "20105 only: workspaces the caller owns that still hold members or communities.",
                "type": "string"
              }
            },
            "type": "object"
          },
          "msg": {
            "description": "Localized, stable per (code, language).",
            "type": "string"
          },
          "request_id": {
            "description": "Correlation id; quote it in support tickets.",
            "type": "string"
          }
        },
        "required": [
          "code",
          "msg"
        ],
        "type": "object"
      },
      "AuthStatSite": {
        "properties": {
          "label": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "AuthTestimonialSite": {
        "properties": {
          "avatar": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "quote": {
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "BaseActivityInfo": {
        "properties": {
          "accepted_answer_id": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "can_view_quoted_post": {
            "type": "boolean"
          },
          "content_locked": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "edited_at": {
            "type": "string"
          },
          "has_media": {
            "type": "boolean"
          },
          "has_more": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "interaction_type": {
            "type": "string"
          },
          "is_accepted_answer": {
            "type": "boolean"
          },
          "is_featured": {
            "type": "boolean"
          },
          "is_locked": {
            "description": "Reply-tree freeze flag, mirroring ActivityInfo.is_locked. Carried here so\na nested body can render the \"comments are closed\" state without the\nclient re-fetching the post.",
            "type": "boolean"
          },
          "is_locked_reason": {
            "description": "Why the reply tree is frozen, paired with is_locked above\n(admin_post_hide_lock_review_20260902 §B2). Empty when not locked.\nDeliberately NO is_hidden here: a nested body (quote / reply / root) can\nbelong to somebody else, and the hidden flag is the author's own private\nstate. It is exposed on ActivityInfo only, which the read path already\nguarantees is author-only for hidden rows.",
            "type": "string"
          },
          "is_sensitive": {
            "description": "Content warning (18-composer.md §4). is_sensitive controls feed spoiler\noverlay; sensitive_reason is the optional caption (<=120 chars).",
            "type": "boolean"
          },
          "locked_space_id": {
            "type": "string"
          },
          "mentions": {
            "items": {
              "$ref": "#/components/schemas/MentionInfo"
            },
            "type": "array"
          },
          "object_type": {
            "type": "string"
          },
          "operations": {
            "$ref": "#/components/schemas/ActivityOperations"
          },
          "post_attachments": {
            "items": {
              "$ref": "#/components/schemas/PostAttachment"
            },
            "type": "array"
          },
          "post_audio": {
            "$ref": "#/components/schemas/PostAudio"
          },
          "post_blog": {
            "$ref": "#/components/schemas/PostBlog"
          },
          "post_event": {
            "$ref": "#/components/schemas/PostEvent"
          },
          "post_gif": {
            "$ref": "#/components/schemas/PostGif"
          },
          "post_media_files": {
            "items": {
              "$ref": "#/components/schemas/PostMediaFile"
            },
            "type": "array"
          },
          "post_oembed": {
            "$ref": "#/components/schemas/PostOembed"
          },
          "post_poll": {
            "$ref": "#/components/schemas/PostPoll"
          },
          "qa_status": {
            "description": "Q&A fields (only present when space_type = QA)",
            "type": "string"
          },
          "quote_id": {
            "type": "string"
          },
          "quoted_post_restricted": {
            "type": "boolean"
          },
          "ranking": {
            "format": "double",
            "type": "number"
          },
          "reply_id": {
            "type": "string"
          },
          "reply_root_id": {
            "type": "string"
          },
          "repost_id": {
            "type": "string"
          },
          "restriction_reason": {
            "type": "string"
          },
          "scheduled_at": {
            "type": "string"
          },
          "sensitive_reason": {
            "type": "string"
          },
          "site_id": {
            "type": "string"
          },
          "space": {
            "$ref": "#/components/schemas/SpaceBrief"
          },
          "stats": {
            "$ref": "#/components/schemas/ActivityCountInfo"
          },
          "status": {
            "description": "Post status (18-composer.md §2.3): draft | scheduled | published | archived | deleted.",
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/ActivityUserInfo"
          },
          "user_id": {
            "type": "string"
          },
          "verb": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "BaseActivityInfoWithQuote": {
        "properties": {
          "accepted_answer_id": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "can_view_quoted_post": {
            "type": "boolean"
          },
          "content_locked": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "edited_at": {
            "type": "string"
          },
          "first_replies": {
            "items": {
              "$ref": "#/components/schemas/BaseActivityInfo"
            },
            "type": "array"
          },
          "has_media": {
            "type": "boolean"
          },
          "has_more": {
            "type": "boolean"
          },
          "has_more_replies": {
            "type": "boolean"
          },
          "hidden_reply_count": {
            "format": "int32",
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "interaction_type": {
            "type": "string"
          },
          "is_accepted_answer": {
            "type": "boolean"
          },
          "is_locked": {
            "description": "Reply-tree freeze flag, mirroring ActivityInfo.is_locked.",
            "type": "boolean"
          },
          "is_locked_reason": {
            "description": "Lock reason on a nested body; see BaseActivityInfo for why is_hidden is\nnot mirrored here.",
            "type": "string"
          },
          "is_sensitive": {
            "description": "Content warning (18-composer.md §4).",
            "type": "boolean"
          },
          "locked_space_id": {
            "type": "string"
          },
          "mentions": {
            "items": {
              "$ref": "#/components/schemas/MentionInfo"
            },
            "type": "array"
          },
          "object_type": {
            "type": "string"
          },
          "operations": {
            "$ref": "#/components/schemas/ActivityOperations"
          },
          "post_attachments": {
            "items": {
              "$ref": "#/components/schemas/PostAttachment"
            },
            "type": "array"
          },
          "post_audio": {
            "$ref": "#/components/schemas/PostAudio"
          },
          "post_blog": {
            "$ref": "#/components/schemas/PostBlog"
          },
          "post_event": {
            "$ref": "#/components/schemas/PostEvent"
          },
          "post_gif": {
            "$ref": "#/components/schemas/PostGif"
          },
          "post_media_files": {
            "items": {
              "$ref": "#/components/schemas/PostMediaFile"
            },
            "type": "array"
          },
          "post_oembed": {
            "$ref": "#/components/schemas/PostOembed"
          },
          "post_poll": {
            "$ref": "#/components/schemas/PostPoll"
          },
          "qa_status": {
            "description": "Q&A fields (only present when space_type = QA)",
            "type": "string"
          },
          "quote_id": {
            "type": "string"
          },
          "quote_post": {
            "$ref": "#/components/schemas/BaseActivityInfo"
          },
          "quoted_post_restricted": {
            "type": "boolean"
          },
          "ranking": {
            "format": "double",
            "type": "number"
          },
          "reply_id": {
            "type": "string"
          },
          "reply_root_id": {
            "type": "string"
          },
          "repost_id": {
            "type": "string"
          },
          "restriction_reason": {
            "type": "string"
          },
          "scheduled_at": {
            "type": "string"
          },
          "sensitive_reason": {
            "type": "string"
          },
          "site_id": {
            "type": "string"
          },
          "space": {
            "$ref": "#/components/schemas/SpaceBrief"
          },
          "stats": {
            "$ref": "#/components/schemas/ActivityCountInfo"
          },
          "status": {
            "type": "string"
          },
          "thread_depth": {
            "format": "int32",
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/ActivityUserInfo"
          },
          "user_id": {
            "type": "string"
          },
          "verb": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "BaseMsgRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "BatchGetPostsData": {
        "properties": {
          "missing_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "BatchGetPostsReqBody": {
        "properties": {
          "ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "BatchGetPostsRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/BatchGetPostsData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContentSettingsInfo": {
        "description": "Content settings for space templates (Gallery requires media, Radio requires audio)",
        "properties": {
          "require_audio": {
            "type": "boolean"
          },
          "require_media": {
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "CreatePostAudioReq": {
        "properties": {
          "artist": {
            "type": "string"
          },
          "cover": {
            "type": "string"
          },
          "file": {
            "type": "string"
          },
          "kind": {
            "description": "\"track\" (uploaded work, default when omitted) or \"voice\" (recorded message)",
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreatePostGifReq": {
        "properties": {
          "giphy_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreatePostMediaItem": {
        "description": "Structured media payload for create/update (18-composer.md §1.1). Send\nEITHER media_ids (legacy, no alt text) OR medias on a given request — not\nboth. `alt` is optional; empty string means explicitly clear; unset means\n\"leave existing alt untouched\" (relevant for update paths).",
        "properties": {
          "alt": {
            "type": "string"
          },
          "media_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreatePostOembedReq": {
        "properties": {
          "description": {
            "type": "string"
          },
          "image": {
            "type": "string"
          },
          "nonce_str": {
            "type": "string"
          },
          "sig_issued_at": {
            "description": "RFC3339 UTC 签发时间与站点 hashid,均按返回的字符串原文参与签名。",
            "type": "string"
          },
          "sig_site_id": {
            "type": "string"
          },
          "sign": {
            "type": "string"
          },
          "sign_v2": {
            "description": "v2 signature (HMAC-SHA256) covering all OG fields + sig_issued_at +\nsig_site_id. When sign_v2 is present it is verified in preference to the\nlegacy MD5 `sign`; during migration either is accepted.",
            "type": "string"
          },
          "site_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "youtube_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreatePostPollReq": {
        "description": "A poll is all-or-nothing: option_1, option_2 and expire_at are required\ntogether. Send the block with every field empty when there is no poll (that\nis what the composer does when the author never opens the poll editor); fill\nin any one of them and the missing ones come back as field errors rather than\nbeing dropped.",
        "properties": {
          "allow_multiple_selection": {
            "description": "Settings: only 3 core settings (poll_type, max_selections, show_results_before_vote, show_voter_list removed)",
            "type": "boolean"
          },
          "allow_vote_change": {
            "type": "boolean"
          },
          "expire_at": {
            "description": "How long the poll runs, as a DURATION BUCKET counted from the moment the\npost is created — one of 1h / 6h / 12h / 1d / 3d / 7d / 14d / 30d. It is\nnot a timestamp: an ISO-8601 date or an epoch is rejected, and there is no\n\"runs forever\" poll (post_polls.expire_at is NOT NULL).\nNote the response side spells the same name differently: PostPoll.expire_at\nis the resolved deadline, formatted as a timestamp.",
            "type": "string"
          },
          "is_anonymous": {
            "type": "boolean"
          },
          "option_1": {
            "type": "string"
          },
          "option_2": {
            "type": "string"
          },
          "option_3": {
            "type": "string"
          },
          "option_4": {
            "type": "string"
          },
          "option_5": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "CreatePostReqBody": {
        "properties": {
          "attachment_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "audio": {
            "$ref": "#/components/schemas/CreatePostAudioReq"
          },
          "author_user_id": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "gif": {
            "$ref": "#/components/schemas/CreatePostGifReq"
          },
          "idempotency_key": {
            "type": "string"
          },
          "interaction_type": {
            "type": "string"
          },
          "is_sensitive": {
            "description": "Content warning.",
            "type": "boolean"
          },
          "media_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "medias": {
            "description": "Structured media with alt text. Supersedes media_ids; sending both is\nrejected with 10005 by the shared create path.",
            "items": {
              "$ref": "#/components/schemas/CreatePostMediaItem"
            },
            "type": "array"
          },
          "oembed": {
            "$ref": "#/components/schemas/CreatePostOembedReq"
          },
          "poll": {
            "$ref": "#/components/schemas/CreatePostPollReq"
          },
          "quote_id": {
            "type": "string"
          },
          "reply_id": {
            "type": "string"
          },
          "scheduled_at": {
            "format": "int64",
            "type": "integer"
          },
          "sensitive_reason": {
            "type": "string"
          },
          "space_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "topic_ids": {
            "description": "Topic binding. Topics must belong to space_id.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "DeletePostReqBody": {
        "properties": {
          "actor_user_id": {
            "type": "string"
          },
          "idempotency_key": {
            "type": "string"
          },
          "post_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "FeaturedPostsData": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "has_more": {
            "type": "boolean"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "FeaturedPostsReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "space_id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "FeaturedPostsRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/FeaturedPostsData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "FeaturedSiteFeedData": {
        "properties": {
          "next_cursor": {
            "type": "string"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "FeaturedSiteFeedRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/FeaturedSiteFeedData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GamificationBadgeInfo": {
        "properties": {
          "color": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "tier": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GamificationLevelInfo": {
        "properties": {
          "color": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "min_points": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetCapabilitiesData": {
        "description": "---------------------------------------------------------------------------\nC batch: resource discovery\n---------------------------------------------------------------------------",
        "properties": {
          "api_access": {
            "description": "Whether the site's plan includes API access. Omitted when it could not be\ndetermined; absent is not \"denied\".",
            "type": "boolean"
          },
          "api_version": {
            "description": "Matches the path prefix (\"v1\"). There is no separate contract-version\nscheme yet; this exists so one can be introduced without a breaking\nresponse change.",
            "type": "string"
          },
          "quota_limit": {
            "description": "Daily request budget. Omitted together when it could not be read.\n// Describes the counter that actually produces 22204: every call that gets\npast key validation spends one, on every endpoint. Asking for it here\ndoes NOT spend one — this endpoint is exempt from the reservation, and\nthe value is read without incrementing.\n// limit -1 means unlimited. reset_at is RFC3339.",
            "format": "int64",
            "type": "integer"
          },
          "quota_reset_at": {
            "type": "string"
          },
          "quota_used": {
            "format": "int64",
            "type": "integer"
          },
          "scopes": {
            "description": "The scopes THIS key carries, already expanded — never a bare \"*\".",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "site_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetCapabilitiesRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/GetCapabilitiesData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetMediaSignedURLsData": {
        "properties": {
          "urls": {
            "items": {
              "$ref": "#/components/schemas/SignedURLResultData"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "GetMediaSignedURLsReqBody": {
        "properties": {
          "access_level": {
            "enum": [
              "Public",
              "SemiPrivate",
              "Private"
            ],
            "format": "enum",
            "type": "string"
          },
          "author_user_id": {
            "type": "string"
          },
          "is_direct_message": {
            "type": "boolean"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/MediaSignedURLItem"
            },
            "type": "array"
          },
          "space_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetMediaSignedURLsRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/GetMediaSignedURLsData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetMediaTokenReqBody": {
        "properties": {
          "author_user_id": {
            "type": "string"
          },
          "media_context": {
            "type": "string"
          },
          "scope": {
            "description": "What the token will be used for. Omitted or empty means \"upload\".\n// Note this differs from site/media_file.thrift MediaFileTokenReq, where an\nabsent scope mints upload+read+delete. Widest-by-default is wrong for a\ncredential handed to a third-party integration, and it also used to skip\nthe grace-period plan gate, which only fires for upload-scoped requests.",
            "type": "string"
          },
          "space_id": {
            "description": "The course's space id (hashid), required for a non-site-admin course\nmanager to be recognized when media_context = \"course_video\".",
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetMemberData": {
        "properties": {
          "member": {
            "$ref": "#/components/schemas/OpenMember"
          }
        },
        "type": "object"
      },
      "GetMemberReqBody": {
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetMemberRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/GetMemberData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetPostReqBody": {
        "properties": {
          "id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetPostRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/ActivityInfo"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetSpaceReqBody": {
        "properties": {
          "id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetSpaceRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SpaceInfo"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetThreadChainData": {
        "properties": {
          "has_more": {
            "type": "boolean"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          },
          "total_depth": {
            "format": "int32",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "GetThreadChainReqBody": {
        "properties": {
          "from_level": {
            "format": "int32",
            "type": "integer"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "post_id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "GetThreadChainRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/GetThreadChainData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListDirectRepliesData": {
        "properties": {
          "next_cursor": {
            "type": "string"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "ListDirectRepliesReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "post_id": {
            "type": "string"
          },
          "sort": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListDirectRepliesRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/ListDirectRepliesData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListFeaturedFeedReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListFeedReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "since_id": {
            "description": "Pull only what is newer than a post you already have. Mirrors\nsite/site_feed.thrift SiteFeedReq.since_id.\n// NOT an incremental sync cursor: it surfaces new posts only, never edits\nor deletions, so a consumer polling it will silently drift from the\nsource. Use it to top up a timeline, not to mirror one.",
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListPostRepliesData": {
        "properties": {
          "next_cursor": {
            "type": "string"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "ListPostRepliesReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "post_id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListPostRepliesRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/ListPostRepliesData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListReplyDescendantsData": {
        "properties": {
          "next_cursor": {
            "type": "string"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "ListReplyDescendantsReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "post_id": {
            "type": "string"
          },
          "sort": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListReplyDescendantsRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/ListReplyDescendantsData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListSpaceFeedReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "qa_filter": {
            "description": "Fields 5-8 mirror site/space_feed.thrift SpaceFeedReq one for one; keep\nthe validators byte-identical so the two surfaces cannot disagree about\nwhich combinations are legal.",
            "type": "string"
          },
          "qa_sort": {
            "type": "string"
          },
          "search": {
            "type": "string"
          },
          "sort": {
            "description": "\"newest\" (default) = reverse chronological; \"top\" = platform ranking.\nIgnored in QA spaces, which order by qa_sort instead.\n// `cursor` encoding follows `sort`, so a cursor minted under one sort is\nnot valid under another — reset paging when it changes.",
            "type": "string"
          },
          "space_id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListSpacesData": {
        "properties": {
          "next_cursor": {
            "type": "string"
          },
          "spaces": {
            "items": {
              "$ref": "#/components/schemas/SpaceInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "ListSpacesReqBody": {
        "properties": {
          "cursor": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "search_query": {
            "type": "string"
          },
          "viewer_user_id": {
            "description": "Read the catalogue as this member: which spaces are visible depends on\nmembership. Omitted = anonymous, i.e. publicly readable spaces only.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListSpacesRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/ListSpacesData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListTopFeedReqBody": {
        "properties": {
          "cursor": {
            "format": "double",
            "type": "number"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "ListTopSpaceFeedReqBody": {
        "properties": {
          "cursor": {
            "format": "double",
            "type": "number"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "space_id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "LookupMemberData": {
        "properties": {
          "found": {
            "type": "boolean"
          },
          "member": {
            "$ref": "#/components/schemas/OpenMember"
          }
        },
        "type": "object"
      },
      "LookupMemberReqBody": {
        "properties": {
          "email": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "LookupMemberRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/LookupMemberData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MediaFileTokenInfo": {
        "properties": {
          "expires_at": {
            "type": "string"
          },
          "token": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MediaFileTokenRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/MediaFileTokenInfo"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MediaSignedURLItem": {
        "properties": {
          "file_cate": {
            "enum": [
              "Media",
              "Avatar",
              "Header",
              "Audio",
              "File"
            ],
            "format": "enum",
            "type": "string"
          },
          "file_ext": {
            "type": "string"
          },
          "file_name": {
            "type": "string"
          },
          "file_type": {
            "enum": [
              "Image",
              "Video",
              "Audio",
              "File"
            ],
            "format": "enum",
            "type": "string"
          },
          "media_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MemberTagInfo": {
        "properties": {
          "color": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MemberTierBadgeInfo": {
        "properties": {
          "color": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "MentionInfo": {
        "properties": {
          "avatar_url": {
            "type": "string"
          },
          "display_name": {
            "type": "string"
          },
          "end_position": {
            "format": "int32",
            "type": "integer"
          },
          "start_position": {
            "format": "int32",
            "type": "integer"
          },
          "user_id": {
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "OpenMember": {
        "description": "OpenMember is a deliberately narrow projection of the member record.\n// NOT base.User: that carries email, custom profile fields and counters that a\nserver-side integration has no standing claim to. Fields are added here one at\na time, with a reason — the default is that a field is absent.",
        "properties": {
          "avatar_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "display_name": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "role": {
            "description": "\"owner\" / \"admin\" / \"moderator\" / \"member\". Resolved server-side; owner is\nderived from is_creator, not from the admin_role column, which has no\nowner value.",
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PendingAccessRequestInfo": {
        "properties": {
          "id": {
            "type": "string"
          },
          "requested_at": {
            "type": "string"
          },
          "reviewed_at": {
            "type": "string"
          },
          "reviewer_message": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostAttachment": {
        "properties": {
          "content_type": {
            "type": "string"
          },
          "file_ext": {
            "type": "string"
          },
          "file_name": {
            "type": "string"
          },
          "file_size": {
            "format": "int64",
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "url": {
            "description": "Signed URL field (populated when Cloudflare signing is enabled)",
            "type": "string"
          },
          "url_expires_at": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostAudio": {
        "properties": {
          "artist": {
            "type": "string"
          },
          "content_type": {
            "type": "string"
          },
          "cover": {
            "type": "string"
          },
          "cover_url": {
            "type": "string"
          },
          "duration": {
            "format": "double",
            "type": "number"
          },
          "file": {
            "type": "string"
          },
          "file_ext": {
            "type": "string"
          },
          "file_url": {
            "description": "Signed URL fields (populated when Cloudflare signing is enabled)",
            "type": "string"
          },
          "kind": {
            "description": "\"track\" | \"voice\"; pre-kind data reads back as \"track\". The vd matters on\nthe admin surface, where this struct doubles as a request body\n(PostAdminDraftUpdatePatch.audio).",
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url_expires_at": {
            "type": "string"
          },
          "waveform_url": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostBlog": {
        "properties": {
          "cover": {
            "type": "string"
          },
          "cover_url": {
            "description": "Media URL field",
            "type": "string"
          },
          "meta_description": {
            "type": "string"
          },
          "meta_title": {
            "description": "SEO meta fields",
            "type": "string"
          },
          "og_image": {
            "type": "string"
          },
          "og_image_url": {
            "description": "Signed CDN URL built from og_image when it is a media hash ID. Empty when\nog_image already holds a fully qualified URL, or when og_image is empty.",
            "type": "string"
          },
          "read_time_minutes": {
            "description": "Estimated reading time in minutes",
            "format": "int32",
            "type": "integer"
          },
          "scheduled_at": {
            "description": "ISO 8601 string when status = \"scheduled\".",
            "type": "string"
          },
          "status": {
            "description": "One of draft | scheduled | published | archived.",
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "tags": {
            "description": "Tag slugs associated with this blog (populated at read time from hashtag_posts).",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "PostEvent": {
        "properties": {
          "attendee_count": {
            "format": "int64",
            "type": "integer"
          },
          "cover": {
            "type": "string"
          },
          "cover_url": {
            "description": "Media URL field",
            "type": "string"
          },
          "end_date": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "location_city": {
            "type": "string"
          },
          "location_name": {
            "type": "string"
          },
          "max_attendees": {
            "format": "int64",
            "type": "integer"
          },
          "online_url": {
            "type": "string"
          },
          "start_date": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostGif": {
        "properties": {
          "giphy_id": {
            "type": "string"
          },
          "giphy_url": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostMediaFile": {
        "properties": {
          "alt": {
            "description": "Accessibility alt text (18-composer.md §1). Empty string when legacy\nmedia had no alt; frontend falls back to \"[image]\" for screen readers.",
            "type": "string"
          },
          "aspect": {
            "format": "double",
            "type": "number"
          },
          "blurhash": {
            "type": "string"
          },
          "file_cate": {
            "type": "string"
          },
          "file_ext": {
            "type": "string"
          },
          "file_name": {
            "type": "string"
          },
          "file_type": {
            "type": "string"
          },
          "hls_error_msg": {
            "description": "non-empty only when hls_status=\"failed\"",
            "type": "string"
          },
          "hls_status": {
            "description": "Sprint 3 follow-up (P1 #5): HLS lifecycle + moderation state so the\nfrontend can render four-state video players and occlude taken_down\ncontent without a second fetch. Distinct from hashtag.moderation_status\n— the media vocabulary is {approved, reported, taken_down}.",
            "type": "string"
          },
          "hls_url": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "large_url": {
            "type": "string"
          },
          "medium_url": {
            "type": "string"
          },
          "moderation_status": {
            "description": "approved / reported / taken_down",
            "type": "string"
          },
          "playback_error_msg": {
            "description": "non-empty only when playback_status=\"failed\"",
            "type": "string"
          },
          "playback_kind": {
            "description": "\"\" / original / remux_mp4 / preview_mp4",
            "type": "string"
          },
          "playback_status": {
            "description": "Playback quick pass (2026-04-21): browser-playable MP4 fast-path,\ndecoupled from HLS transcoding. Let the player start once\nplayback_status=\"ready\" without waiting for adaptive bitrate.\nplayback_kind=original   → playback_url reuses the original URL\nplayback_kind=remux_mp4  → ffmpeg -c copy output at playback/{id}/playback.mp4\nplayback_kind=preview_mp4 → re-encoded 480p/720p H.264 preview",
            "type": "string"
          },
          "playback_url": {
            "description": "empty unless playback_status=\"ready\"",
            "type": "string"
          },
          "processing_error": {
            "description": "non-empty only when processing_status=\"failed\"",
            "type": "string"
          },
          "processing_status": {
            "description": "Async upload pipeline (2026-04-19): covers upload → thumbnail →\nblurhash generation, independent of hls_status. Frontend renders\nplaceholder while pending/processing; reconcile with status_batch\nsince the embedded value may be stale (set at post-create time).",
            "type": "string"
          },
          "thumb_url": {
            "type": "string"
          },
          "url": {
            "description": "Signed URL fields (populated when Cloudflare signing is enabled)",
            "type": "string"
          },
          "url_expires_at": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostOembed": {
        "properties": {
          "description": {
            "type": "string"
          },
          "image": {
            "type": "string"
          },
          "site_name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "youtube_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostPoll": {
        "properties": {
          "allow_multiple_selection": {
            "type": "boolean"
          },
          "allow_vote_change": {
            "type": "boolean"
          },
          "can_edit": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "expire_at": {
            "description": "Resolved deadline, formatted as a timestamp — NOT the duration bucket\n(\"7d\" etc.) that CreatePostPollReq.expire_at takes on the way in.",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "is_anonymous": {
            "type": "boolean"
          },
          "max_selections": {
            "format": "int32",
            "type": "integer"
          },
          "option_1": {
            "type": "string"
          },
          "option_2": {
            "type": "string"
          },
          "option_3": {
            "type": "string"
          },
          "option_4": {
            "type": "string"
          },
          "option_5": {
            "description": "Option 5 (NEW)",
            "type": "string"
          },
          "poll_type": {
            "description": "Settings (NEW)",
            "type": "string"
          },
          "show_results_before_vote": {
            "type": "boolean"
          },
          "show_voter_list": {
            "type": "boolean"
          },
          "status": {
            "description": "Status (NEW)",
            "type": "string"
          },
          "total_voters": {
            "format": "int64",
            "type": "integer"
          },
          "total_votes": {
            "description": "Aggregations (NEW)",
            "format": "int64",
            "type": "integer"
          },
          "updated_at": {
            "type": "string"
          },
          "user_vote": {
            "description": "User's vote",
            "format": "int32",
            "type": "integer"
          },
          "user_votes": {
            "description": "For multi-select",
            "items": {
              "format": "int32",
              "type": "integer"
            },
            "type": "array"
          },
          "votes_1": {
            "format": "int64",
            "type": "integer"
          },
          "votes_2": {
            "format": "int64",
            "type": "integer"
          },
          "votes_3": {
            "format": "int64",
            "type": "integer"
          },
          "votes_4": {
            "format": "int64",
            "type": "integer"
          },
          "votes_5": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "PostReactionInfo": {
        "description": "PostReactionInfo — per-emoji breakdown entry (docs_new/post_reactions).\nNamed with the Post prefix to stay globally unique in site_swagger (distinct\nfrom the chat-side MessageReactionData).",
        "properties": {
          "count": {
            "format": "int32",
            "type": "integer"
          },
          "reacted_by_me": {
            "type": "boolean"
          },
          "reaction": {
            "description": "unicode emoji or \"custom:<id>\"",
            "type": "string"
          }
        },
        "type": "object"
      },
      "PostThreadInfo": {
        "description": "Thread navigation info (18-composer.md §5.2). Emitted only for posts that\nbelong to a thread (batch-created via post/thread/create, or whose root\ncarries a thread marker). position is 0-indexed; total is the known size.",
        "properties": {
          "position": {
            "format": "int32",
            "type": "integer"
          },
          "root_post_id": {
            "type": "string"
          },
          "thread_id": {
            "type": "string"
          },
          "total": {
            "format": "int32",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "SearchPostsData": {
        "properties": {
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "page": {
            "format": "int32",
            "type": "integer"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          },
          "total_hits": {
            "format": "int64",
            "type": "integer"
          },
          "total_pages": {
            "format": "int32",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "SearchPostsReqBody": {
        "properties": {
          "filter_type": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "limit": {
            "format": "int32",
            "type": "integer"
          },
          "page": {
            "format": "int32",
            "type": "integer"
          },
          "query": {
            "type": "string"
          },
          "sort": {
            "type": "string"
          },
          "space_id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "viewer_user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SearchPostsRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SearchPostsData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SidebarWidgetSite": {
        "properties": {
          "content": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "key": {
            "type": "string"
          },
          "position": {
            "format": "int32",
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "description": "\"builtin\" | \"html\" | \"embed\"",
            "type": "string"
          },
          "visibility": {
            "description": "\"all\" | \"guest\" | \"member\"",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SignedURLResultData": {
        "properties": {
          "expires_at": {
            "type": "string"
          },
          "hls_url": {
            "description": "HLS streaming URL (populated for video files after transcoding)",
            "type": "string"
          },
          "large_url": {
            "type": "string"
          },
          "media_id": {
            "type": "string"
          },
          "medium_url": {
            "type": "string"
          },
          "original_url": {
            "type": "string"
          },
          "playback_kind": {
            "description": "\"\" / original / remux_mp4 / preview_mp4",
            "type": "string"
          },
          "playback_status": {
            "description": "not_applicable / pending / processing / ready / failed",
            "type": "string"
          },
          "playback_url": {
            "description": "Playback quick pass (2026-04-21): browser-playable MP4 fast-path,\nready before HLS. Empty unless playback_status=\"ready\".",
            "type": "string"
          },
          "thumb_url": {
            "type": "string"
          },
          "waveform_url": {
            "description": "Waveform JSON signed URL (populated for audio files)",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SiteAppearanceInfo": {
        "properties": {
          "auth_background_image": {
            "description": "§10 Auth pages background image — shared by every page mounted on\nAuthLayout (sign_in / sign_up / forgot_password / reset / 2FA / SSO).\nAnonymous frontends render auth_background_image_url; if it's empty\nthey fall back to the dark monogram + theme spotlight default.",
            "type": "string"
          },
          "auth_background_image_url": {
            "type": "string"
          },
          "auth_stats": {
            "items": {
              "$ref": "#/components/schemas/AuthStatSite"
            },
            "type": "array"
          },
          "auth_testimonials": {
            "description": "§9 Login page social proof — delivered as typed lists so the\nanonymous login/sign-up page doesn't need to parse JSON itself.\nEmpty lists mean \"section hidden\".",
            "items": {
              "$ref": "#/components/schemas/AuthTestimonialSite"
            },
            "type": "array"
          },
          "default_appearance": {
            "type": "string"
          },
          "discover_feed_top_window": {
            "description": "Phase 4 — Discover Top window (\"day\" | \"week\" | \"month\" | \"all\").\nEmpty string indicates never-saved; frontends should treat it as \"week\"\nto match server default, which is also what a legacy \"year\" value reads\nback as. Only meaningful when discover_feed_type == \"Top\".",
            "type": "string"
          },
          "discover_feed_type": {
            "description": "Feed Display",
            "type": "string"
          },
          "favicon": {
            "type": "string"
          },
          "favicon_url": {
            "type": "string"
          },
          "header_logo_mode": {
            "description": "Navigation header logo form — closed enum \"wordmark\" | \"icon_name\" |\n\"icon\" (default \"wordmark\" = historic behavior). wordmark = horizontal\nlogo; icon_name = square logo + site name; icon = square logo only.\nThe public header (HeaderLogo) reads this; unknown/empty fall back to\n\"wordmark\".",
            "type": "string"
          },
          "logo": {
            "description": "Logos & Branding",
            "type": "string"
          },
          "logo_dark": {
            "type": "string"
          },
          "logo_dark_url": {
            "type": "string"
          },
          "logo_size": {
            "description": "Navigation logo display height — closed enum \"sm\" | \"md\" | \"lg\",\ndefault \"md\" (historic 36px). The public header (HeaderLogo) maps\nsm→28px / md→36px / lg→44px; unknown/empty values fall back to \"md\".",
            "type": "string"
          },
          "logo_url": {
            "description": "Signed URL fields",
            "type": "string"
          },
          "mobile_app_icon": {
            "type": "string"
          },
          "mobile_app_promotion_enabled": {
            "description": "Site-owner opt-in to show members the (Mateflow-branded) mobile app.\nOnly consumed when site.white_label is true — the full gate is\n`!white_label || mobile_app_promotion_enabled`, so non-white-label\nsites keep promoting regardless of this flag and need no backfill.\nReadable by guests: /download is a public page.",
            "type": "boolean"
          },
          "mobile_theme": {
            "description": "Field ID 11 (default_space_layout) removed 2026-06-01 — inert (never\nseeded new spaces; C-end renders per-space space_layout). See\ndocs_new/admin_appearance_interface/backend_requirements.md §1.1.\nMobile Appearance",
            "type": "string"
          },
          "open_graph_image": {
            "type": "string"
          },
          "open_graph_image_url": {
            "type": "string"
          },
          "sidebar_widgets": {
            "description": "Field IDs 40–43 (guest/member landing_page + landing_url) were removed\npre-launch.\nPhase 3 — Sidebar Widgets delivered as typed list so frontends can\nrender without parsing JSON themselves. Custom widget `content` is\nalready sanitized at write time; safe to render.",
            "items": {
              "$ref": "#/components/schemas/SidebarWidgetSite"
            },
            "type": "array"
          },
          "square_logo": {
            "type": "string"
          },
          "square_logo_dark": {
            "type": "string"
          },
          "square_logo_dark_url": {
            "type": "string"
          },
          "square_logo_url": {
            "type": "string"
          },
          "theme_revision": {
            "description": "Theme cache-bust key — monotonically increases whenever the currently\npublished theme is mutated (publish / update_current / revert).\nFrontends append ?v=<theme_revision> to the public\n/site_api/v1/theme/current.css URL so CDN/browser caches are\ninvalidated atomically without resorting to no-cache headers.",
            "format": "int64",
            "type": "integer"
          },
          "url_expires_at": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SiteFeedListData": {
        "properties": {
          "next_cursor": {
            "type": "string"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "SiteFeedListRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SiteFeedListData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SiteFeedListTopData": {
        "properties": {
          "next_cursor": {
            "format": "double",
            "type": "number"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "SiteFeedListTopRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SiteFeedListTopData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SiteInfo": {
        "properties": {
          "allow_search_engine_indexing": {
            "type": "boolean"
          },
          "complimentary_expires_at": {
            "description": "ISO8601 expiry of a complimentary grant; \"\" = indefinite/permanent. Only\nmeaningful when subscription_status == complimentary（\"\"→「永久免费」, 否则「免费至 {date}」).",
            "type": "string"
          },
          "contact_email": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "creator_id": {
            "type": "string"
          },
          "custom_domain": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "is_private": {
            "type": "boolean"
          },
          "maintenance_message": {
            "type": "string"
          },
          "maintenance_mode": {
            "type": "boolean"
          },
          "max_members": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "stat": {
            "$ref": "#/components/schemas/SiteStatInfo"
          },
          "status": {
            "type": "string"
          },
          "subdomain": {
            "type": "string"
          },
          "subscription_status": {
            "description": "status (field 6) is operational only (active/suspended/pending_purge).\nBilling state lives in subscription_status (trial/expired/complimentary…);\nsuspend_reason explains a suspension. See docs_new/site_status.",
            "type": "string"
          },
          "suspend_reason": {
            "type": "string"
          },
          "tagline": {
            "description": "Brand identity / contact / visibility / maintenance — surfaced from\n/settings/general/{fetch,update}. The public site uses these to render\nthe tagline under site_name, the support email on auth pages, the\nrobots meta / sitemap gating, and the maintenance interstitial.\n// Backend invariant: when is_private == true, allow_search_engine_indexing\nis forced false on the read path regardless of the persisted value.",
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "white_label": {
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "SiteInfoWithBasicSettingsData": {
        "properties": {
          "site": {
            "$ref": "#/components/schemas/SiteInfo"
          },
          "site_appearance": {
            "$ref": "#/components/schemas/SiteAppearanceInfo"
          },
          "site_setting": {
            "$ref": "#/components/schemas/SiteSettingSimpleInfo"
          }
        },
        "type": "object"
      },
      "SiteInfoWithBasicSettingsRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SiteInfoWithBasicSettingsData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SiteSettingSimpleInfo": {
        "description": "Field id 2 (password_min_length) retired — never enforced; do NOT reuse.",
        "properties": {
          "allow_mentions": {
            "type": "boolean"
          },
          "cookie_policy_url": {
            "type": "string"
          },
          "default_language": {
            "type": "string"
          },
          "default_timezone": {
            "type": "string"
          },
          "direct_messaging_enabled": {
            "description": "Communication",
            "type": "boolean"
          },
          "enable_turnstile": {
            "description": "allow_registration retired; replaced by SiteRegistrationSetting.mode\n(canonical) on /site_admin_api/v1/settings/registration/fetch. Field\nid 1 left vacant to keep wire-compat predictable.",
            "type": "boolean"
          },
          "enable_two_factor_auth": {
            "description": "Site-level 2FA switch (public, read-only). Source: site_securities, same\nflag as the admin /settings/security/fetch endpoint. false → the member\nsettings page must hide the 2FA section; /user/settings/2fa/enable/init\nand /enable/confirm reject with 22827 in that state. Members who already\nenabled 2FA keep their login challenge / recovery codes / disable path.",
            "type": "boolean"
          },
          "gamification_enabled": {
            "type": "boolean"
          },
          "group_messaging_enabled": {
            "type": "boolean"
          },
          "has_courses": {
            "description": "Lifetime content markers (public, read-only). Source: sites.has_courses /\nsites.has_events. \"Has this site ever created a course / an event\", NOT\n\"does it have one right now\": drafts, archived and deleted ones all count,\nand the flag never falls back to false once set. Site-wide, never filtered\nby the caller's permissions. The member frontend hides the Courses / Events main-nav entries for\nordinary members when these are false, so that a site whose plan enables\nthe feature but which never used it stops shipping two dead links. Admins\nkeep seeing the entries — hiding them from the owner too would remove the\nonly route to the action that flips the flag. Deliberately booleans and\nnot counts: a count would end up on a badge and drag per-viewer visibility\nback in. See docs_new/site_nav_empty_menu_20260908.",
            "type": "boolean"
          },
          "has_events": {
            "type": "boolean"
          },
          "leaderboard_period": {
            "type": "string"
          },
          "leaderboard_size": {
            "format": "int32",
            "type": "integer"
          },
          "leaderboard_visible": {
            "description": "Leaderboard config (public, read-only). Source: site_gamification, same\ndata as the admin /settings/gamification/fetch endpoint. Without these\nthe member FE cannot honour the admin's leaderboard switch/period/size —\nleaderboard_visible=false only emptied the response server-side while the\nwidget kept rendering.\nleaderboard_period: weekly | monthly | all_time (the admin enum; the\nleaderboard endpoints additionally accept daily on time_range).",
            "type": "boolean"
          },
          "minimum_age": {
            "description": "GDPR Art.8 age gate (public, read-only). Source: site_legals, same data\nas /settings/legal/fetch. Lets the signup page render the age\naffirmation / DOB field. minimum_age default 16; require_dob=false =\nlight affirmation checkbox.",
            "format": "int32",
            "type": "integer"
          },
          "points_name": {
            "type": "string"
          },
          "points_reward_icon": {
            "type": "string"
          },
          "privacy_policy_url": {
            "type": "string"
          },
          "reaction_set": {
            "description": "L1 reaction quick-bar set (docs_new/post_reactions §3.7). Always populated\n(empty → default 7). Member FE reads this to render the reaction bar.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "reactions_enabled": {
            "type": "boolean"
          },
          "registration_mode": {
            "description": "Registration mode for the /signup page to branch on. Values:\nopen | invite_only | approval | closed. See addendum §4.",
            "type": "string"
          },
          "require_dob": {
            "type": "boolean"
          },
          "show_rank_on_profile": {
            "type": "boolean"
          },
          "terms_of_service_url": {
            "description": "Legal policy URLs (public, read-only). Source: site_legals table, same\ndata as the admin /settings/legal/fetch endpoint. Lets the footer +\nsignup/login consent notice render Terms / Privacy / Cookie links from\nthe public bootstrap. gdpr_compliance is admin-only and NOT exposed.",
            "type": "string"
          },
          "turnstile_site_key": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SiteStatInfo": {
        "properties": {
          "blog_count": {
            "format": "int64",
            "type": "integer"
          },
          "event_count": {
            "format": "int64",
            "type": "integer"
          },
          "member_count": {
            "format": "int64",
            "type": "integer"
          },
          "post_count": {
            "format": "int64",
            "type": "integer"
          },
          "space_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "SpaceAccessInfoItem": {
        "description": "Access info for space list card rendering (API layer)",
        "properties": {
          "access_type": {
            "type": "string"
          },
          "currency": {
            "description": "ISO 4217; empty when unpriced",
            "type": "string"
          },
          "has_access": {
            "type": "boolean"
          },
          "membership_status": {
            "type": "string"
          },
          "price_cents": {
            "description": "CENTS; 0 when unpriced",
            "format": "int64",
            "type": "integer"
          },
          "price_display": {
            "description": "Pre-formatted, and it ALREADY carries the period suffix for subscriptions\n(\"$9.99/month\"); buyout has none (\"$9.99\"). Do NOT append your own cadence —\nthat renders \"$9.99/month/mo\". Two hard limits make it display-only: the\nperiod word is hardcoded English, and the symbol table covers USD/EUR/GBP,\nso every other currency renders with \"$\". Prefer the structured fields below.",
            "type": "string"
          },
          "price_period": {
            "description": "Structured mirror of price_display. Same vocabulary as the course DTOs'\nlowest_tier_period, so both surfaces read alike. Needed on its own when the\ncadence has to be carried rather than printed — e.g. pre-selecting the plan\nthe user was just quoted, instead of re-deriving it by regex.",
            "type": "string"
          },
          "space_access_level": {
            "type": "string"
          },
          "subscription_status": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceArchiveInfo": {
        "properties": {
          "archive_reason": {
            "description": "operator-supplied reason, may be \"\"",
            "type": "string"
          },
          "archived_at": {
            "description": "unix seconds, as string for parity with other timestamps",
            "type": "string"
          },
          "archived_by": {
            "description": "hashid; \"\" when unknown",
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceBrief": {
        "description": "SpaceBrief is a compact embedded space reference (mirrors ActivityUserInfo): a\nspace's identity + display media with CDN URLs resolved at read time. Reused\nwherever a response embeds the space a row belongs to.",
        "properties": {
          "avatar": {
            "type": "string"
          },
          "avatar_url": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "icon_url": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "space_type": {
            "description": "Post | Blog | Media | Chat | Podcast | Course | QA.\n// Lets a client apply a space-TYPE rule to an embedded post without a second\nlookup. Reposting is the current case: it does not exist in a QA space at\nall (a type rule, not a permission, so no audience or exemption grants\nit), and the only other available signal was qa_status — which top-level\nquestions carry but ANSWERS DO NOT, so a repost entry point keyed on it\nstill leaks on answers.",
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceContentCategoryInfo": {
        "properties": {
          "count": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceFeedListData": {
        "properties": {
          "is_preview": {
            "description": "Preview mode fields",
            "type": "boolean"
          },
          "next_cursor": {
            "type": "string"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          },
          "preview_limit": {
            "format": "int32",
            "type": "integer"
          },
          "total_hits": {
            "description": "Search-mode only: Meilisearch estimated total matches, for facet counts.\nAbsent (or 0) when `search` was not supplied. Never use it for pagination —\n`next_cursor` non-empty is the only \"has more\" signal.",
            "format": "int64",
            "type": "integer"
          },
          "total_posts_count": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "SpaceFeedListRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SpaceFeedListData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceFeedListTopData": {
        "properties": {
          "next_cursor": {
            "format": "double",
            "type": "number"
          },
          "posts": {
            "items": {
              "$ref": "#/components/schemas/ActivityInfo"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "SpaceFeedListTopRespBody": {
        "properties": {
          "code": {
            "format": "int32",
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/SpaceFeedListTopData"
          },
          "msg": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceInfo": {
        "properties": {
          "access_info": {
            "$ref": "#/components/schemas/SpaceAccessInfoItem"
          },
          "active_members_count": {
            "format": "int64",
            "type": "integer"
          },
          "allow_member_event": {
            "type": "boolean"
          },
          "allow_member_like": {
            "type": "boolean"
          },
          "allow_member_live": {
            "type": "boolean"
          },
          "allow_member_post": {
            "type": "boolean"
          },
          "allow_member_reply": {
            "type": "boolean"
          },
          "allow_member_repost": {
            "type": "boolean"
          },
          "archive_info": {
            "$ref": "#/components/schemas/SpaceArchiveInfo"
          },
          "avatar": {
            "type": "string"
          },
          "avatar_url": {
            "type": "string"
          },
          "content_settings": {
            "$ref": "#/components/schemas/ContentSettingsInfo"
          },
          "cover": {
            "type": "string"
          },
          "cover_url": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "default_reply_view": {
            "description": "Default reply display form: \"flat\" | \"tree\". FE reads this as the space\ndefault; per-viewer overrides are handled entirely on the front-end.",
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "events_enabled": {
            "type": "boolean"
          },
          "featured": {
            "type": "boolean"
          },
          "has_events": {
            "description": "Whether this Space holds any event a member could open, so the tab can be\nrendered (or not) before any event request goes out. Counts past events,\nexcludes cancelled/deleted/unapproved. Absent = \"not computed\" — show the\ntab; only an explicit false means there is nothing to show.",
            "type": "boolean"
          },
          "hide_members_count": {
            "type": "boolean"
          },
          "icon": {
            "type": "string"
          },
          "icon_url": {
            "description": "Media URL fields (populated at read time)",
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "live_enabled": {
            "description": "The live module's switches, so a console can render the toggle it writes\nthrough space/permissions/update.",
            "type": "boolean"
          },
          "members_count": {
            "format": "int64",
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "operations": {
            "$ref": "#/components/schemas/SpaceOperationsInfo"
          },
          "owner_user_id": {
            "description": "The space creator's user id (hashid). operations.is_admin is true for the\nowner, every appointed space admin AND every site admin, so it cannot\nsingle the owner out; space_role on a member row only ever holds\nmember | admin | moderator and has no \"owner\" value either. This is the\nonly field that identifies the one member whom member management refuses\nto act on (space_owner_protected), so a client can grey that row out\ninstead of discovering it from a rejection. Absent when the owner is\nunknown; treat absence as \"cannot tell\", not as \"no owner\".",
            "type": "string"
          },
          "posts_count": {
            "format": "int64",
            "type": "integer"
          },
          "preview_config": {
            "$ref": "#/components/schemas/SpacePreviewConfigInfo"
          },
          "preview_stats": {
            "$ref": "#/components/schemas/SpacePreviewStatsInfo"
          },
          "replies_count": {
            "format": "int64",
            "type": "integer"
          },
          "require_event_approval": {
            "description": "Whether member-created events in this Space wait for admin approval.\nThe column and every consumer of it (create → pending, list visibility,\nRSVP gate, the back-office review queue) have existed since Phase 3, but\nno API could ever write it, so the queue could not receive anything\n(docs_new/event_module_review_20260909/06 §6). Exposed here so the space\nsettings console can render the toggle it now writes.",
            "type": "boolean"
          },
          "site_id": {
            "type": "string"
          },
          "space_category_id": {
            "type": "string"
          },
          "space_layout": {
            "type": "string"
          },
          "space_privacy": {
            "type": "string"
          },
          "space_type": {
            "type": "string"
          },
          "subscription_info": {
            "$ref": "#/components/schemas/SpaceSubscriptionConfigInfo"
          },
          "teaser_data": {
            "$ref": "#/components/schemas/SpaceTeaserDataInfo"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceOperationsInfo": {
        "properties": {
          "access_denial_reason": {
            "description": "Enhanced access control fields",
            "type": "string"
          },
          "can_comment": {
            "description": "Granular permissions",
            "type": "boolean"
          },
          "can_create_event": {
            "description": "Event permissions",
            "type": "boolean"
          },
          "can_invite": {
            "type": "boolean"
          },
          "can_join": {
            "description": "---- Access model (see spaces migration 20260808120000) ----\n// can_join is the single signal the join CTA renders from. Do NOT infer it\nfrom space_privacy: a publicly readable space may still admit nobody, and\na member-only one may be open to all.\njoin_policy = open    -> \"Join\"\njoin_policy = request -> \"Request to join\" (can_join=false once pending)\njoin_policy = paid    -> price CTA\njoin_policy = invite  -> render nothing",
            "type": "boolean"
          },
          "can_moderate": {
            "type": "boolean"
          },
          "can_post": {
            "type": "boolean"
          },
          "can_preview": {
            "type": "boolean"
          },
          "can_react": {
            "type": "boolean"
          },
          "can_request_access": {
            "type": "boolean"
          },
          "can_view_analytics": {
            "type": "boolean"
          },
          "can_view_members": {
            "type": "boolean"
          },
          "has_access": {
            "type": "boolean"
          },
          "is_admin": {
            "type": "boolean"
          },
          "is_banned": {
            "type": "boolean"
          },
          "is_member": {
            "type": "boolean"
          },
          "is_moderator": {
            "type": "boolean"
          },
          "is_muted": {
            "type": "boolean"
          },
          "join_policy": {
            "description": "open | request | paid | invite",
            "type": "string"
          },
          "membership_status": {
            "type": "string"
          },
          "mute_until": {
            "description": "Mute expiry for the current user — ISO8601 string. Absent for permanent\nmute or when not muted.",
            "type": "string"
          },
          "notification_level": {
            "description": "Current user's per-space notification level: all / highlights /\nmentions_only / off. Set only for authenticated viewers; defaults to\n\"all\" when the user hasn't customized it — the neutral level, which\ndefers to the global per-category notification settings. \"highlights\"\nis an explicit choice and suppresses likes and reposts only —\nreplies, quotes, @mentions, accepted answers and course updates all\nstill deliver; \"mentions_only\" also silences course updates. There is\nno new-post stream to suppress: that notification type has no producer\nand is not planned. The levels gate space-scoped notifications only —\nevent reminders/updates (you RSVP'd) and moderation verdicts on your\nown posts are never gated by them. Distinct from is_muted, which is a\nmoderation (silenced-by-admin) flag, not a notification pref.",
            "type": "string"
          },
          "pending_access_request": {
            "$ref": "#/components/schemas/PendingAccessRequestInfo"
          },
          "permission_level": {
            "format": "int32",
            "type": "integer"
          },
          "post_permission": {
            "description": "viewers | members | staff — who may start a topic here.",
            "type": "string"
          },
          "reply_permission": {
            "description": "viewers | members | staff — who may reply, like or repost here.",
            "type": "string"
          },
          "space_access_level": {
            "description": "Space access level (canonical rendering level)",
            "type": "string"
          },
          "subscription_status": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpacePreviewConfigInfo": {
        "description": "Tier comparison item (API layer)\nPreview configuration for a space",
        "properties": {
          "blur_last_post": {
            "type": "boolean"
          },
          "custom_unlock_message": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "post_limit": {
            "format": "int32",
            "type": "integer"
          },
          "show_engagement_stats": {
            "type": "boolean"
          },
          "show_member_count": {
            "type": "boolean"
          },
          "show_post_count": {
            "type": "boolean"
          }
        },
        "type": "object"
      },
      "SpacePreviewStatsInfo": {
        "description": "Preview stats for non-member display",
        "properties": {
          "active_discussions": {
            "format": "int64",
            "type": "integer"
          },
          "content_categories": {
            "items": {
              "$ref": "#/components/schemas/SpaceContentCategoryInfo"
            },
            "type": "array"
          },
          "recent_highlights": {
            "items": {
              "$ref": "#/components/schemas/SpaceRecentHighlightInfo"
            },
            "type": "array"
          },
          "top_contributors": {
            "items": {
              "$ref": "#/components/schemas/SpaceTopContributorInfo"
            },
            "type": "array"
          },
          "total_members": {
            "format": "int64",
            "type": "integer"
          },
          "total_posts": {
            "format": "int64",
            "type": "integer"
          },
          "weekly_new_posts": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "SpaceRecentHighlightInfo": {
        "properties": {
          "comments_count": {
            "format": "int64",
            "type": "integer"
          },
          "likes_count": {
            "format": "int64",
            "type": "integer"
          },
          "post_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceSubscriptionConfigInfo": {
        "description": "Subscription/monetization configuration for a space (API layer)",
        "properties": {
          "access_type": {
            "description": "free, subscription, one_time, subscription_or_one_time",
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "monthly_price": {
            "description": "cents",
            "format": "int64",
            "type": "integer"
          },
          "one_time_price": {
            "description": "cents",
            "format": "int64",
            "type": "integer"
          },
          "preview_enabled": {
            "type": "boolean"
          },
          "preview_post_limit": {
            "format": "int32",
            "type": "integer"
          },
          "price_display": {
            "description": "pre-formatted buyout/subscription price; mirrors SpaceAccessInfoItem.price_display so teaser/locked views never hand-build \"$\"",
            "type": "string"
          },
          "required_tier_id": {
            "type": "string"
          },
          "required_tier_name": {
            "type": "string"
          },
          "trial_days": {
            "format": "int32",
            "type": "integer"
          },
          "yearly_price": {
            "description": "cents",
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      },
      "SpaceTeaserDataInfo": {
        "description": "Teaser display data for a space",
        "properties": {
          "top_tags": {
            "items": {
              "$ref": "#/components/schemas/SpaceContentCategoryInfo"
            },
            "type": "array"
          },
          "total_members": {
            "format": "int64",
            "type": "integer"
          },
          "total_posts": {
            "format": "int64",
            "type": "integer"
          },
          "weekly_activity": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "SpaceTopContributorInfo": {
        "properties": {
          "avatar": {
            "type": "string"
          },
          "display_name": {
            "type": "string"
          },
          "post_count": {
            "format": "int64",
            "type": "integer"
          },
          "user_id": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "UpdatePostReqBody": {
        "properties": {
          "actor_user_id": {
            "type": "string"
          },
          "attachment_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "audio": {
            "$ref": "#/components/schemas/CreatePostAudioReq"
          },
          "body": {
            "type": "string"
          },
          "gif": {
            "$ref": "#/components/schemas/CreatePostGifReq"
          },
          "idempotency_key": {
            "type": "string"
          },
          "interaction_type": {
            "type": "string"
          },
          "is_sensitive": {
            "description": "Content warning.",
            "type": "boolean"
          },
          "media_ids": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "medias": {
            "description": "Structured media with alt text. Supersedes media_ids; sending both is\nrejected with 10005 by the shared update path.",
            "items": {
              "$ref": "#/components/schemas/CreatePostMediaItem"
            },
            "type": "array"
          },
          "oembed": {
            "$ref": "#/components/schemas/CreatePostOembedReq"
          },
          "poll": {
            "$ref": "#/components/schemas/CreatePostPollReq"
          },
          "post_id": {
            "type": "string"
          },
          "quote_id": {
            "type": "string"
          },
          "reply_id": {
            "type": "string"
          },
          "scheduled_at": {
            "description": "Reschedule, or cancel a pending schedule.\n// Unix seconds, matching CreatePostReq.scheduled_at — deliberately NOT the\nRFC3339 string the member API uses here, so the two open-API post writes\nagree with each other. Omit the field to leave the schedule untouched.\n// <= 0 cancels the schedule and returns the post to draft — but ONLY blog\nposts have a draft state to return to. Cancelling on a plain post is\nrefused with 10005 / schedule_cancel_unsupported rather than accepted,\nbecause the underlying behaviour there is \"publish immediately\": an\nintegration asking to cancel would instead make the content public early,\nfan it out to the feed and fire notifications, none of which a follow-up\ncall can undo.",
            "format": "int64",
            "type": "integer"
          },
          "sensitive_reason": {
            "type": "string"
          },
          "space_id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "topic_ids": {
            "description": "Topic rebinding. Mirrors create.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "version": {
            "format": "int64",
            "type": "integer"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "description": "Site API key. Takes precedence when both credentials are sent.",
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      },
      "BearerAuth": {
        "description": "The same site API key, sent as `Authorization: Bearer <key>`.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "SiteOpenService",
      "description": "Community Open API — posts, feeds, spaces, members and media."
    }
  ],
  "servers": [
    {
      "url": "https://api.mateflow.com",
      "description": "Production"
    }
  ]
}
