{
  "openapi": "3.0.3",
  "info": {
    "title": "sondahub Social API",
    "version": "0.6.1",
    "description": "A social network: users, posts, comments, likes and follows — the GraphQL one.\n\nEight hundred users, four thousand posts, eight thousand comments and the likes and follows between them. Deeply related, which is what GraphQL is for: a user, their posts, each post’s comments and their authors in one query.\n\nNo keys, no accounts. Writes (POST, PUT, PATCH, DELETE) are validated and answered exactly as a real server would answer them, then forgotten: sondahub stores nothing, and every such answer says so in _note and in the X-Sondahub-Write: simulated header. Every list takes page, limit, sort, q, fields and expand, plus one filter per field with the operators _ne _gt _gte _lt _lte _like _in.",
    "contact": {
      "name": "sondahub",
      "url": "https://api.sondahub.com"
    }
  },
  "servers": [
    {
      "url": "https://api.sondahub.com"
    }
  ],
  "tags": [
    {
      "name": "users",
      "description": "Members."
    },
    {
      "name": "posts",
      "description": "What people write. hashtags is an array; filter with ?hashtags_like=coffee."
    },
    {
      "name": "comments",
      "description": "Comments on posts; a comment can answer another comment through parent_id."
    },
    {
      "name": "likes",
      "description": "A user liking a post. POST one to like; DELETE it to unlike."
    },
    {
      "name": "follows",
      "description": "follower_id follows followee_id."
    }
  ],
  "paths": {
    "/v1/social/users": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "List users",
        "operationId": "list_users",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: posts, comments, likes, followers, following.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "username",
            "in": "query",
            "required": false,
            "description": "Filter: username equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "description": "Unique handle.",
              "example": "camila_fernandez"
            }
          },
          {
            "name": "display_name",
            "in": "query",
            "required": false,
            "description": "Filter: display_name equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email",
            "in": "query",
            "required": false,
            "description": "Filter: email equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "avatar_url",
            "in": "query",
            "required": false,
            "description": "Filter: avatar_url equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "description": "A generated SVG served by the hub."
            }
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "description": "Filter: location equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "website",
            "in": "query",
            "required": false,
            "description": "Filter: website equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true
            }
          },
          {
            "name": "verified",
            "in": "query",
            "required": false,
            "description": "Filter: verified equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "boolean",
              "nullable": true
            }
          },
          {
            "name": "private",
            "in": "query",
            "required": false,
            "description": "Filter: private equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "boolean",
              "nullable": true
            }
          },
          {
            "name": "followers_count",
            "in": "query",
            "required": false,
            "description": "Filter: followers_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "following_count",
            "in": "query",
            "required": false,
            "description": "Filter: following_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "posts_count",
            "in": "query",
            "required": false,
            "description": "Filter: posts_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "joined_at",
            "in": "query",
            "required": false,
            "description": "Filter: joined_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Create a user",
        "operationId": "create_user",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/users/{id}": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "Get a user",
        "operationId": "get_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "users"
        ],
        "summary": "Replace a user",
        "operationId": "replace_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "users"
        ],
        "summary": "Update part of a user",
        "operationId": "update_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "users"
        ],
        "summary": "Delete a user",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/users/{id}/posts": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The posts of a user",
        "operationId": "user_posts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/users/{id}/comments": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The comments of a user",
        "operationId": "user_comments",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommentList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/users/{id}/likes": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The likes of a user",
        "operationId": "user_likes",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LikeList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/users/{id}/followers": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The followers of a user",
        "operationId": "user_followers",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/users/{id}/following": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "The following of a user",
        "operationId": "user_following",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/posts": {
      "get": {
        "tags": [
          "posts"
        ],
        "summary": "List posts",
        "operationId": "list_posts",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: -published_at.",
            "schema": {
              "type": "string",
              "example": "-published_at"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: author, comments, likes, reply_to.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "author_id",
            "in": "query",
            "required": false,
            "description": "Filter: author_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a user."
            }
          },
          {
            "name": "visibility",
            "in": "query",
            "required": false,
            "description": "Filter: visibility equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "enum": [
                "public",
                "followers",
                "private"
              ],
              "nullable": true,
              "example": "public"
            }
          },
          {
            "name": "reply_to_id",
            "in": "query",
            "required": false,
            "description": "Filter: reply_to_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Set when the post is a reply. The id of a post."
            }
          },
          {
            "name": "likes_count",
            "in": "query",
            "required": false,
            "description": "Filter: likes_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "comments_count",
            "in": "query",
            "required": false,
            "description": "Filter: comments_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "reposts_count",
            "in": "query",
            "required": false,
            "description": "Filter: reposts_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "description": "Filter: language equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "nullable": true,
              "example": "en"
            }
          },
          {
            "name": "published_at",
            "in": "query",
            "required": false,
            "description": "Filter: published_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          },
          {
            "name": "edited_at",
            "in": "query",
            "required": false,
            "description": "Filter: edited_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "posts"
        ],
        "summary": "Create a post",
        "operationId": "create_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/posts/{id}": {
      "get": {
        "tags": [
          "posts"
        ],
        "summary": "Get a post",
        "operationId": "get_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "posts"
        ],
        "summary": "Replace a post",
        "operationId": "replace_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "posts"
        ],
        "summary": "Update part of a post",
        "operationId": "update_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "posts"
        ],
        "summary": "Delete a post",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/posts/{id}/author": {
      "get": {
        "tags": [
          "posts"
        ],
        "summary": "The author of a post",
        "operationId": "post_author",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/posts/{id}/comments": {
      "get": {
        "tags": [
          "posts"
        ],
        "summary": "The comments of a post",
        "operationId": "post_comments",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: -published_at.",
            "schema": {
              "type": "string",
              "example": "-published_at"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommentList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/posts/{id}/likes": {
      "get": {
        "tags": [
          "posts"
        ],
        "summary": "The likes of a post",
        "operationId": "post_likes",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: -published_at.",
            "schema": {
              "type": "string",
              "example": "-published_at"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LikeList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/posts/{id}/reply_to": {
      "get": {
        "tags": [
          "posts"
        ],
        "summary": "The reply_to of a post",
        "operationId": "post_reply_to",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/comments": {
      "get": {
        "tags": [
          "comments"
        ],
        "summary": "List comments",
        "operationId": "list_comments",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: -created_at.",
            "schema": {
              "type": "string",
              "example": "-created_at"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: post, author, parent, replies.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "post_id",
            "in": "query",
            "required": false,
            "description": "Filter: post_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a post."
            }
          },
          {
            "name": "author_id",
            "in": "query",
            "required": false,
            "description": "Filter: author_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a user."
            }
          },
          {
            "name": "parent_id",
            "in": "query",
            "required": false,
            "description": "Filter: parent_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "The id of a comment."
            }
          },
          {
            "name": "likes_count",
            "in": "query",
            "required": false,
            "description": "Filter: likes_count equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "readOnly": true
            }
          },
          {
            "name": "flagged",
            "in": "query",
            "required": false,
            "description": "Filter: flagged equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "boolean",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommentList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "comments"
        ],
        "summary": "Create a comment",
        "operationId": "create_comment",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/comments/{id}": {
      "get": {
        "tags": [
          "comments"
        ],
        "summary": "Get a comment",
        "operationId": "get_comment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "comments"
        ],
        "summary": "Replace a comment",
        "operationId": "replace_comment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "comments"
        ],
        "summary": "Update part of a comment",
        "operationId": "update_comment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "comments"
        ],
        "summary": "Delete a comment",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_comment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/comments/{id}/post": {
      "get": {
        "tags": [
          "comments"
        ],
        "summary": "The post of a comment",
        "operationId": "comment_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/comments/{id}/author": {
      "get": {
        "tags": [
          "comments"
        ],
        "summary": "The author of a comment",
        "operationId": "comment_author",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/comments/{id}/parent": {
      "get": {
        "tags": [
          "comments"
        ],
        "summary": "The parent of a comment",
        "operationId": "comment_parent",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comment"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/comments/{id}/replies": {
      "get": {
        "tags": [
          "comments"
        ],
        "summary": "The replies of a comment",
        "operationId": "comment_replies",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: -created_at.",
            "schema": {
              "type": "string",
              "example": "-created_at"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of related records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CommentList"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/likes": {
      "get": {
        "tags": [
          "likes"
        ],
        "summary": "List likes",
        "operationId": "list_likes",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: user, post.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "description": "Filter: user_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a user."
            }
          },
          {
            "name": "post_id",
            "in": "query",
            "required": false,
            "description": "Filter: post_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a post."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LikeList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "likes"
        ],
        "summary": "Create a like",
        "operationId": "create_like",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LikeInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Like"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/likes/{id}": {
      "get": {
        "tags": [
          "likes"
        ],
        "summary": "Get a like",
        "operationId": "get_like",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Like"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "likes"
        ],
        "summary": "Replace a like",
        "operationId": "replace_like",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LikeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Like"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "likes"
        ],
        "summary": "Update part of a like",
        "operationId": "update_like",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LikeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Like"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "likes"
        ],
        "summary": "Delete a like",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_like",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/likes/{id}/user": {
      "get": {
        "tags": [
          "likes"
        ],
        "summary": "The user of a like",
        "operationId": "like_user",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/likes/{id}/post": {
      "get": {
        "tags": [
          "likes"
        ],
        "summary": "The post of a like",
        "operationId": "like_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/follows": {
      "get": {
        "tags": [
          "follows"
        ],
        "summary": "List follows",
        "operationId": "list_follows",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Comma-separated fields; prefix with - for descending. Default: id.",
            "schema": {
              "type": "string",
              "example": "-id"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Full-text search over the string fields.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "description": "Comma-separated fields to return.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "in": "query",
            "description": "Comma-separated relations to embed: follower, followee.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "query",
            "required": false,
            "description": "Filter: id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "nullable": true,
              "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
              "readOnly": true
            }
          },
          {
            "name": "created_at",
            "in": "query",
            "required": false,
            "description": "Filter: created_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record was created (ISO 8601, UTC).",
              "readOnly": true
            }
          },
          {
            "name": "updated_at",
            "in": "query",
            "required": false,
            "description": "Filter: updated_at equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "nullable": true,
              "description": "When the record last changed.",
              "readOnly": true
            }
          },
          {
            "name": "follower_id",
            "in": "query",
            "required": false,
            "description": "Filter: follower_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a user."
            }
          },
          {
            "name": "followee_id",
            "in": "query",
            "required": false,
            "description": "Filter: followee_id equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "integer",
              "description": "The id of a user."
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter: status equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "pending",
                "blocked"
              ],
              "nullable": true,
              "example": "active"
            }
          },
          {
            "name": "notifications",
            "in": "query",
            "required": false,
            "description": "Filter: notifications equals the value. Suffix the name with _ne, _gt, _gte, _lt, _lte, _like (contains, case-insensitive) or _in (comma list); \"null\" matches missing values.",
            "schema": {
              "type": "boolean",
              "nullable": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowList"
                }
              }
            }
          },
          "400": {
            "description": "A parameter could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "follows"
        ],
        "summary": "Create a follow",
        "operationId": "create_follow",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FollowInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created — simulated: the answer is what a real server would give, nothing is stored (see _note and the X-Sondahub-Write header).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Follow"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/follows/{id}": {
      "get": {
        "tags": [
          "follows"
        ],
        "summary": "Get a follow",
        "operationId": "get_follow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "expand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Follow"
                }
              }
            }
          },
          "304": {
            "description": "Unchanged since the ETag you sent."
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "follows"
        ],
        "summary": "Replace a follow",
        "operationId": "replace_follow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FollowInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Follow"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "follows"
        ],
        "summary": "Update part of a follow",
        "operationId": "update_follow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FollowInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record as it would have been saved — simulated, nothing is stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Follow"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The body failed validation; details lists each field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "follows"
        ],
        "summary": "Delete a follow",
        "description": "Simulated: answers 200 with the record that would have been removed and a note; nothing is stored.",
        "operationId": "delete_follow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "What would have been deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "integer"
                    },
                    "_note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/follows/{id}/follower": {
      "get": {
        "tags": [
          "follows"
        ],
        "summary": "The follower of a follow",
        "operationId": "follow_follower",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/social/follows/{id}/followee": {
      "get": {
        "tags": [
          "follows"
        ],
        "summary": "The followee of a follow",
        "operationId": "follow_followee",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "The related record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "404": {
            "description": "No such record.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "validation_failed"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        }
      },
      "ListMeta": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "pages": {
            "type": "integer"
          }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "username": {
            "type": "string",
            "description": "Unique handle.",
            "example": "camila_fernandez"
          },
          "display_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "bio": {
            "type": "string",
            "nullable": true
          },
          "avatar_url": {
            "type": "string",
            "nullable": true,
            "description": "A generated SVG served by the hub."
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "verified": {
            "type": "boolean",
            "nullable": true
          },
          "private": {
            "type": "boolean",
            "nullable": true
          },
          "followers_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "following_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "posts_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "username",
          "display_name",
          "followers_count",
          "following_count",
          "posts_count"
        ]
      },
      "UserInput": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string",
            "description": "Unique handle.",
            "example": "camila_fernandez"
          },
          "display_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "bio": {
            "type": "string",
            "nullable": true
          },
          "avatar_url": {
            "type": "string",
            "nullable": true,
            "description": "A generated SVG served by the hub."
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "verified": {
            "type": "boolean",
            "nullable": true
          },
          "private": {
            "type": "boolean",
            "nullable": true
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "username",
          "display_name"
        ],
        "example": {
          "username": "camila_fernandez",
          "display_name": "A display name"
        }
      },
      "UserList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/User"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Post": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "author_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "body": {
            "type": "string"
          },
          "hashtags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Shape: string[]"
          },
          "media": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Shape: { kind, url, alt? }[]"
          },
          "visibility": {
            "type": "string",
            "enum": [
              "public",
              "followers",
              "private"
            ],
            "nullable": true,
            "example": "public"
          },
          "reply_to_id": {
            "type": "integer",
            "nullable": true,
            "description": "Set when the post is a reply. The id of a post."
          },
          "likes_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "comments_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "reposts_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "language": {
            "type": "string",
            "nullable": true,
            "example": "en"
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "edited_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "author_id",
          "body",
          "likes_count",
          "comments_count",
          "reposts_count"
        ]
      },
      "PostInput": {
        "type": "object",
        "properties": {
          "author_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "body": {
            "type": "string"
          },
          "hashtags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Shape: string[]"
          },
          "media": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Shape: { kind, url, alt? }[]"
          },
          "visibility": {
            "type": "string",
            "enum": [
              "public",
              "followers",
              "private"
            ],
            "nullable": true,
            "example": "public"
          },
          "reply_to_id": {
            "type": "integer",
            "nullable": true,
            "description": "Set when the post is a reply. The id of a post."
          },
          "language": {
            "type": "string",
            "nullable": true,
            "example": "en"
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "edited_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "author_id",
          "body"
        ],
        "example": {
          "author_id": 1,
          "body": "A body",
          "visibility": "public",
          "language": "en"
        }
      },
      "PostList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Post"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Comment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "post_id": {
            "type": "integer",
            "description": "The id of a post."
          },
          "author_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "parent_id": {
            "type": "integer",
            "nullable": true,
            "description": "The id of a comment."
          },
          "body": {
            "type": "string"
          },
          "likes_count": {
            "type": "integer",
            "nullable": true,
            "readOnly": true
          },
          "flagged": {
            "type": "boolean",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "post_id",
          "author_id",
          "body",
          "likes_count"
        ]
      },
      "CommentInput": {
        "type": "object",
        "properties": {
          "post_id": {
            "type": "integer",
            "description": "The id of a post."
          },
          "author_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "parent_id": {
            "type": "integer",
            "nullable": true,
            "description": "The id of a comment."
          },
          "body": {
            "type": "string"
          },
          "flagged": {
            "type": "boolean",
            "nullable": true
          }
        },
        "required": [
          "post_id",
          "author_id",
          "body"
        ],
        "example": {
          "post_id": 1,
          "author_id": 1,
          "body": "A body"
        }
      },
      "CommentList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Comment"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Like": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "user_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "post_id": {
            "type": "integer",
            "description": "The id of a post."
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "user_id",
          "post_id"
        ]
      },
      "LikeInput": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "post_id": {
            "type": "integer",
            "description": "The id of a post."
          }
        },
        "required": [
          "user_id",
          "post_id"
        ],
        "example": {
          "user_id": 1,
          "post_id": 1
        }
      },
      "LikeList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Like"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "Follow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "nullable": true,
            "description": "Assigned by the server. Seed records keep their ids across restarts; records you create continue after the seed.",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record was created (ISO 8601, UTC).",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the record last changed.",
            "readOnly": true
          },
          "follower_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "followee_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "blocked"
            ],
            "nullable": true,
            "example": "active"
          },
          "notifications": {
            "type": "boolean",
            "nullable": true
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "follower_id",
          "followee_id"
        ]
      },
      "FollowInput": {
        "type": "object",
        "properties": {
          "follower_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "followee_id": {
            "type": "integer",
            "description": "The id of a user."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "blocked"
            ],
            "nullable": true,
            "example": "active"
          },
          "notifications": {
            "type": "boolean",
            "nullable": true
          }
        },
        "required": [
          "follower_id",
          "followee_id"
        ],
        "example": {
          "follower_id": 1,
          "followee_id": 1,
          "status": "active"
        }
      },
      "FollowList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Follow"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      }
    }
  }
}