openapi: "3.0.3" info: title: "e621 API" version: "dadc1e4c50658851c0205e6ecbfa4723a976b0ab" description: | An API for accessing user information and other resources on e621 and e926. ## Authentication Endpoints with `x-access-level` above `anonymous` require authentication. Credentials are the account username and an API key issued by `/api_keys.json`, submitted as either HTTP Basic (username, API key) or the query/body parameters `login` and `api_key`. The `x-access-level` extension declares the minimum privilege level for an operation: `anonymous`, `logged_in`, `member`, `janitor`, `moderator`, `admin`. servers: - url: "https://e621.net" description: "Production server for e621" - url: "https://e926.net" description: "SFW server for e926" security: - {} - BasicAuth: [] - ApiKeyLogin: [] ApiKeyQuery: [] paths: /posts.json: get: operationId: "getPosts" x-access-level: "anonymous" tags: - "posts" summary: "Get a list of posts" description: | Returns a list of posts filtered by tags. When `v2=true`, the response uses the v2 Post format selected by `mode` (`basic` default, `extended`, or `thumbnail`). Otherwise the legacy format wrapped in `{ "posts": [...] }` is returned. parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of posts to retrieve per page" schema: type: "integer" - name: "tags" in: "query" required: false description: "Filter posts by tags" schema: type: "string" - $ref: "#/components/parameters/PostV2Flag" - $ref: "#/components/parameters/PostV2Mode" responses: 200: description: "A list of posts matching the search criteria" content: application/json: schema: oneOf: - type: "object" description: "Legacy response (default, or when `v2` is not \"true\"). The post array is wrapped under `posts`." properties: posts: type: "array" items: $ref: "#/components/schemas/Post" - type: "array" description: "v2 basic format response (when `v2=true` and `mode` is unset or `basic`)." items: $ref: "#/components/schemas/PostV2Basic" - type: "array" description: "v2 extended format response (when `v2=true` and `mode=extended`)." items: $ref: "#/components/schemas/PostV2Extended" - type: "array" description: "v2 thumbnail format response (when `v2=true` and `mode=thumbnail`)." items: $ref: "#/components/schemas/PostV2Thumbnail" 400: description: "Invalid request parameters" 500: description: "Server error" /posts/{id}.json: get: operationId: "getPost" x-access-level: "anonymous" tags: - "posts" summary: "Get a post by ID" description: | Returns detailed information about a specific post identified by its ID. When `v2=true`, the response uses the v2 Post format selected by `mode` (`basic` default, `extended`, or `thumbnail`). Otherwise the legacy format wrapped in `{ "post": {...} }` is returned. parameters: - name: "id" in: "path" required: true description: "The unique ID of the post to retrieve" schema: type: "integer" - $ref: "#/components/parameters/PostV2Flag" - $ref: "#/components/parameters/PostV2Mode" responses: 200: description: "Successful response containing post details" content: application/json: schema: oneOf: - type: "object" description: "Legacy response (default, or when `v2` is not \"true\"). The post is wrapped under `post`." properties: post: $ref: "#/components/schemas/Post" - $ref: "#/components/schemas/PostV2Basic" - $ref: "#/components/schemas/PostV2Extended" - $ref: "#/components/schemas/PostV2Thumbnail" 404: description: "Post not found" 500: description: "Server error" /users.json: get: operationId: "getUsers" x-access-level: "anonymous" tags: - "users" summary: "Get a list of users" description: "Returns a list of users based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of users to retrieve per page" schema: type: "integer" - name: "search[id]" in: "query" required: false description: "Filter by user ID" schema: type: "string" - name: "search[name]" in: "query" required: false description: "Filter by username" schema: type: "string" - name: "search[about]" in: "query" required: false description: "Filter by user's \"About\" section" schema: type: "string" - name: "search[avatar_id]" in: "query" required: false description: "Filter by avatar ID" schema: type: "integer" - name: "search[level]" in: "query" required: false description: "Filter by user's access level" schema: type: "integer" - name: "search[min_level]" in: "query" required: false description: "Filter by minimum access level" schema: type: "integer" - name: "search[max_level]" in: "query" required: false description: "Filter by maximum access level" schema: type: "integer" - name: "search[can_upload_free]" in: "query" required: false description: "Filter by upload permissions" schema: type: "boolean" - name: "search[can_approve_posts]" in: "query" required: false description: "Filter by post approval permissions" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Order the results by a specific field" schema: $ref: "#/components/schemas/GetUsersSearchOrder" responses: 200: description: "A list of users matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/User" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createUser" x-access-level: "anonymous" tags: - "users" summary: "Create a new user account" description: "Registers a new user account. Only available when not logged in and signups are enabled." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateUserBody" responses: 201: description: "User account created" content: application/json: schema: $ref: "#/components/schemas/User" 422: description: "Validation error" /users/{id}.json: get: operationId: "getUser" x-access-level: "anonymous" tags: - "users" summary: "Get user information by ID or username" description: "Returns detailed information about a user identified by their ID or username." parameters: - name: "id" in: "path" required: true description: "The ID or username of the user to retrieve" schema: type: "string" description: "Can be either the user's ID (integer) or username (string)" responses: 200: description: "Successful response containing user details" content: application/json: schema: $ref: "#/components/schemas/UserProfile" 404: description: "User not found" 500: description: "Server error" patch: operationId: "updateUser" x-access-level: "logged_in" tags: - "users" summary: "Update the current user's settings" description: "Updates the currently authenticated user's account settings. Users can only update their own account unless they are an admin." parameters: - name: "id" in: "path" required: true description: "The ID of the user to update (must be the current user unless admin)" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateUserBody" responses: 200: description: "User updated successfully" content: application/json: schema: $ref: "#/components/schemas/UserProfile" 403: description: "Access denied" 422: description: "Validation error" /users/me.json: get: operationId: "getCurrentUser" x-access-level: "logged_in" tags: - "users" summary: "Get the current authenticated user" description: "Returns the currently authenticated user's full profile information." responses: 200: description: "Current user details" content: application/json: schema: $ref: "#/components/schemas/UserProfile" 401: description: "Not authenticated" /users/{id}/upload_limit.json: get: operationId: "getUserUploadLimit" x-access-level: "logged_in" tags: - "users" summary: "Get a user's upload limit information" description: "Returns detailed upload limit information for a user." parameters: - name: "id" in: "path" required: true description: "The ID or username of the user" schema: type: "string" responses: 200: description: "User upload limit information" content: application/json: schema: $ref: "#/components/schemas/UserProfile" 404: description: "User not found" /dmails.json: get: operationId: "getDmails" x-access-level: "member" tags: - "dmails" summary: "Get a list of DMails" description: "Returns a list of DMails for the currently authenticated user." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of DMails to retrieve per page" schema: type: "integer" - name: "search[title_matches]" in: "query" required: false description: "Filter by title text" schema: type: "string" - name: "search[message_matches]" in: "query" required: false description: "Filter by message body text" schema: type: "string" - name: "search[to_name]" in: "query" required: false description: "Filter by recipient username" schema: type: "string" - name: "search[to_id]" in: "query" required: false description: "Filter by recipient user ID" schema: type: "integer" - name: "search[from_name]" in: "query" required: false description: "Filter by sender username" schema: type: "string" - name: "search[from_id]" in: "query" required: false description: "Filter by sender user ID" schema: type: "integer" - name: "search[is_read]" in: "query" required: false description: "Filter by read status" schema: type: "boolean" - name: "search[is_deleted]" in: "query" required: false description: "Filter by deleted status" schema: type: "boolean" responses: 200: description: "A list of DMails" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Dmail" 403: description: "Access denied" /dmails/{id}.json: get: operationId: "getDmail" x-access-level: "member" tags: - "dmails" summary: "Get a DMail by ID" description: "Returns a specific DMail. Only visible to the owner, or moderators for system/ticketed DMails." parameters: - name: "id" in: "path" required: true description: "The ID of the DMail" schema: type: "integer" responses: 200: description: "DMail details" content: application/json: schema: $ref: "#/components/schemas/Dmail" 403: description: "Access denied" 404: description: "DMail not found" delete: operationId: "deleteDmail" x-access-level: "member" tags: - "dmails" summary: "Delete a DMail" description: "Marks a DMail as deleted and read." parameters: - name: "id" in: "path" required: true description: "The ID of the DMail" schema: type: "integer" responses: 200: description: "DMail deleted" 403: description: "Access denied" 404: description: "DMail not found" /dmails/{id}/mark_as_read.json: put: operationId: "markDmailAsRead" x-access-level: "member" tags: - "dmails" summary: "Mark a DMail as read" description: "Marks a specific DMail as read and decrements the unread count." parameters: - name: "id" in: "path" required: true description: "The ID of the DMail" schema: type: "integer" responses: 200: description: "DMail marked as read" 403: description: "Access denied" 404: description: "DMail not found" /dmails/{id}/mark_as_unread.json: put: operationId: "markDmailAsUnread" x-access-level: "member" tags: - "dmails" summary: "Mark a DMail as unread" description: "Marks a specific DMail as unread and increments the unread count." parameters: - name: "id" in: "path" required: true description: "The ID of the DMail" schema: type: "integer" responses: 200: description: "DMail marked as unread" 403: description: "Access denied" 404: description: "DMail not found" /dmails/mark_all_as_read.json: put: operationId: "markAllDmailsAsRead" x-access-level: "member" tags: - "dmails" summary: "Mark all DMails as read" description: "Marks all of the current user's unread DMails as read and resets the unread count." responses: 200: description: "All DMails marked as read" 403: description: "Access denied" /api_keys.json: get: operationId: "getApiKeys" x-access-level: "member" tags: - "api_keys" summary: "Get a list of API keys" description: "Returns a list of the current user's API keys. Requires reauthentication." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of API keys to retrieve per page" schema: type: "integer" - name: "search[name_matches]" in: "query" required: false description: "Filter by key name" schema: type: "string" - name: "search[is_expired]" in: "query" required: false description: "Filter by expired status" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Sort order" schema: type: "string" responses: 200: description: "A list of API keys" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/ApiKey" 403: description: "Access denied" post: operationId: "createApiKey" x-access-level: "member" tags: - "api_keys" summary: "Create a new API key" description: "Creates a new API key for the current user. Requires reauthentication." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateApiKeyBody" responses: 201: description: "API key created" content: application/json: schema: $ref: "#/components/schemas/ApiKey" 422: description: "Validation error" /api_keys/{id}.json: delete: operationId: "deleteApiKey" x-access-level: "member" tags: - "api_keys" summary: "Delete an API key" description: "Permanently deletes an API key. Requires reauthentication." parameters: - name: "id" in: "path" required: true description: "The ID of the API key" schema: type: "integer" responses: 200: description: "API key deleted" 404: description: "API key not found" /api_keys/{id}/regenerate.json: post: operationId: "regenerateApiKey" x-access-level: "member" tags: - "api_keys" summary: "Regenerate an expired API key" description: "Regenerates an expired API key with a new token and expiration. Only expired keys can be regenerated." parameters: - name: "id" in: "path" required: true description: "The ID of the API key" schema: type: "integer" responses: 200: description: "API key regenerated" content: application/json: schema: $ref: "#/components/schemas/ApiKey" 422: description: "API key is not expired" /bans.json: get: operationId: "getBans" x-access-level: "anonymous" tags: - "bans" summary: "Get a list of bans" description: "Returns a list of bans based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of bans to retrieve per page" schema: type: "integer" - name: "search[user_id]" in: "query" required: false description: "Filter by banned user ID" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter by banned username" schema: type: "string" - name: "search[banner_id]" in: "query" required: false description: "Filter by staff user ID who issued the ban" schema: type: "integer" - name: "search[banner_name]" in: "query" required: false description: "Filter by staff username who issued the ban" schema: type: "string" - name: "search[reason_matches]" in: "query" required: false description: "Filter by ban reason text" schema: type: "string" - name: "search[expired]" in: "query" required: false description: "Filter by expired status (true = past bans, false = active bans)" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Sort order" schema: $ref: "#/components/schemas/GetBansSearchOrder" responses: 200: description: "A list of bans" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Ban" 400: description: "Invalid request parameters" /bans/{id}.json: get: operationId: "getBan" x-access-level: "anonymous" tags: - "bans" summary: "Get a ban by ID" description: "Returns details of a specific ban." parameters: - name: "id" in: "path" required: true description: "The ID of the ban" schema: type: "integer" responses: 200: description: "Ban details" content: application/json: schema: $ref: "#/components/schemas/Ban" 404: description: "Ban not found" /user_name_change_requests.json: get: operationId: "getUserNameChangeRequests" x-access-level: "moderator" tags: - "user_name_change_requests" summary: "Get a list of name change requests" description: "Returns a list of user name change requests." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of requests to retrieve per page" schema: type: "integer" - name: "search[original_name]" in: "query" required: false description: "Filter by original username" schema: type: "string" - name: "search[desired_name]" in: "query" required: false description: "Filter by desired username" schema: type: "string" responses: 200: description: "A list of name change requests" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/UserNameChangeRequest" 403: description: "Access denied" /user_name_change_requests/{id}.json: get: operationId: "getUserNameChangeRequest" x-access-level: "member" tags: - "user_name_change_requests" summary: "Get a name change request by ID" description: "Returns details of a specific name change request. Members can view their own requests, moderators can view all." parameters: - name: "id" in: "path" required: true description: "The ID of the name change request" schema: type: "integer" responses: 200: description: "Name change request details" content: application/json: schema: $ref: "#/components/schemas/UserNameChangeRequest" 403: description: "Access denied" 404: description: "Name change request not found" /staff_notes.json: get: operationId: "getStaffNotes" x-access-level: "janitor" tags: - "staff_notes" summary: "Get a list of staff notes" description: "Returns a list of staff notes. Requires staff-level access." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of staff notes to retrieve per page" schema: type: "integer" - name: "search[user_id]" in: "query" required: false description: "Filter by subject user ID" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter by subject username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by note creator user ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by note creator username" schema: type: "string" - name: "search[updater_id]" in: "query" required: false description: "Filter by note updater user ID" schema: type: "integer" - name: "search[updater_name]" in: "query" required: false description: "Filter by note updater username" schema: type: "string" - name: "search[body_matches]" in: "query" required: false description: "Filter by note body text" schema: type: "string" - name: "search[without_system_user]" in: "query" required: false description: "Exclude notes created by the system user" schema: type: "boolean" - name: "search[include_deleted]" in: "query" required: false description: "Include deleted notes" schema: type: "boolean" responses: 200: description: "A list of staff notes" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/StaffNote" 403: description: "Access denied" post: operationId: "createStaffNote" x-access-level: "janitor" tags: - "staff_notes" summary: "Create a staff note" description: "Creates a new staff note on a user. Requires staff-level access." parameters: - name: "user_id" in: "query" required: true description: "The ID of the user to add the note to" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateStaffNoteBody" responses: 201: description: "Staff note created" content: application/json: schema: $ref: "#/components/schemas/StaffNote" 403: description: "Access denied" 422: description: "Validation error" /staff_notes/{id}.json: get: operationId: "getStaffNote" x-access-level: "janitor" tags: - "staff_notes" summary: "Get a staff note by ID" description: "Returns details of a specific staff note. Requires staff-level access." parameters: - name: "id" in: "path" required: true description: "The ID of the staff note" schema: type: "integer" responses: 200: description: "Staff note details" content: application/json: schema: $ref: "#/components/schemas/StaffNote" 403: description: "Access denied" 404: description: "Staff note not found" /tickets.json: get: operationId: "getTickets" x-access-level: "anonymous" tags: - "tickets" summary: "Get a list of tickets" description: "Returns a list of tickets based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of tickets to retrieve per page" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the ticket" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the ticket" schema: type: "string" - name: "search[id]" in: "query" required: false description: "Filter by ticket ID" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by the creator's username" schema: type: "string" - name: "search[accused_name]" in: "query" required: false description: "Filter by the accused user's username" schema: type: "string" - name: "search[claimant_name]" in: "query" required: false description: "Filter by the claimant's username" schema: type: "string" - name: "search[reason]" in: "query" required: false description: "Filter by the reason for the ticket" schema: type: "string" - name: "search[qtype]" in: "query" required: false description: "Filter by the type of the ticket (e.g., user, comment, post)" schema: $ref: "#/components/schemas/TicketQtype" - name: "search[status]" in: "query" required: false description: "Filter by the status of the ticket" schema: $ref: "#/components/schemas/GetTicketsSearchStatus" - name: "search[disp_id]" in: "query" required: false description: "Filter by the reported content ID" schema: type: "integer" responses: 200: description: "A list of tickets matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Ticket" 400: description: "Invalid request parameters" 500: description: "Server error" /tickets/{id}.json: get: operationId: "getTicket" x-access-level: "member" tags: - "tickets" summary: "Get a ticket by ID" description: "Returns detailed information about a specific ticket identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the ticket to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing ticket details" content: application/json: schema: $ref: "#/components/schemas/Ticket" 404: description: "Ticket not found" 500: description: "Server error" put: operationId: "updateTicket" x-access-level: "moderator" tags: - "tickets" summary: "Update a ticket" description: "Updates a ticket's status and response. Automatically claims the ticket for the current user." parameters: - name: "id" in: "path" required: true description: "The unique ID of the ticket" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateTicketBody" responses: 200: description: "The updated ticket" content: application/json: schema: $ref: "#/components/schemas/Ticket" 422: description: "Validation error" 403: description: "Access denied" /tickets/{id}/claim.json: post: operationId: "claimTicket" x-access-level: "moderator" tags: - "tickets" summary: "Claim a ticket" description: "Claims a pending ticket to indicate you are handling it." parameters: - name: "id" in: "path" required: true description: "The unique ID of the ticket" schema: type: "integer" responses: 200: description: "The claimed ticket" content: application/json: schema: $ref: "#/components/schemas/Ticket" 403: description: "Access denied" /tickets/{id}/unclaim.json: post: operationId: "unclaimTicket" x-access-level: "moderator" tags: - "tickets" summary: "Unclaim a ticket" description: "Releases your claim on a ticket so others can handle it." parameters: - name: "id" in: "path" required: true description: "The unique ID of the ticket" schema: type: "integer" responses: 200: description: "The unclaimed ticket" content: application/json: schema: $ref: "#/components/schemas/Ticket" 403: description: "Access denied" /appeals.json: get: operationId: "getAppeals" x-access-level: "anonymous" tags: - "appeals" summary: "Get a list of appeals" description: | Returns appeals visible to the current user. Non-staff users only see their own appeals. Several search filters are restricted to staff. parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of appeals to retrieve per page" schema: type: "integer" - name: "search[qtype]" in: "query" required: false description: "Filter by appeal type" schema: $ref: "#/components/schemas/AppealQtype" - name: "search[status]" in: "query" required: false description: "Filter by appeal status" schema: $ref: "#/components/schemas/GetAppealsSearchStatus" - name: "search[order]" in: "query" required: false description: "Sort order" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator ID. Non-staff may only filter on their own ID." schema: type: "integer" - name: "search[disp_id]" in: "query" required: false description: "Filter by the appealed content ID (staff only)" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username (staff only)" schema: type: "string" - name: "search[accused_name]" in: "query" required: false description: "Filter by accused username (staff only)" schema: type: "string" - name: "search[accused_id]" in: "query" required: false description: "Filter by accused user ID (staff only)" schema: type: "integer" - name: "search[claimant_id]" in: "query" required: false description: "Filter by claimant ID (staff only)" schema: type: "integer" - name: "search[claimant_name]" in: "query" required: false description: "Filter by claimant username (staff only)" schema: type: "string" - name: "search[reason]" in: "query" required: false description: "Filter by reason text (staff only)" schema: type: "string" responses: 200: description: "A list of appeals matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Appeal" 500: description: "Server error" post: operationId: "createAppeal" x-access-level: "member" tags: - "appeals" summary: "Create an appeal" description: "Creates a new appeal. For `qtype=flag`, only the uploader of the flagged post may create the appeal." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateAppealBody" responses: 302: description: "Redirects to the created appeal on success" 403: description: "Access denied" 422: description: "Validation error" /appeals/{id}.json: get: operationId: "getAppeal" x-access-level: "member" tags: - "appeals" summary: "Get an appeal by ID" description: "Returns detailed information about a specific appeal." parameters: - name: "id" in: "path" required: true description: "The unique ID of the appeal to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing appeal details" content: application/json: schema: $ref: "#/components/schemas/Appeal" 403: description: "Access denied" 404: description: "Appeal not found" put: operationId: "updateAppeal" x-access-level: "janitor" tags: - "appeals" summary: "Update an appeal" description: | Updates an appeal's status and response. Claims the appeal for the current user. If already claimed by someone else, the request redirects to a confirmation page unless `force_claim=true` is set. parameters: - name: "id" in: "path" required: true description: "The unique ID of the appeal" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateAppealBody" responses: 200: description: "The updated appeal" content: application/json: schema: $ref: "#/components/schemas/Appeal" 403: description: "Access denied" 422: description: "Validation error" /appeals/{id}/claim.json: post: operationId: "claimAppeal" x-access-level: "janitor" tags: - "appeals" summary: "Claim an appeal" description: "Claims a pending appeal to indicate you are handling it." parameters: - name: "id" in: "path" required: true description: "The unique ID of the appeal" schema: type: "integer" responses: 200: description: "The claimed appeal" content: application/json: schema: $ref: "#/components/schemas/Appeal" 403: description: "Access denied" /appeals/{id}/unclaim.json: post: operationId: "unclaimAppeal" x-access-level: "janitor" tags: - "appeals" summary: "Unclaim an appeal" description: "Releases the current user's claim on an appeal. Approved appeals cannot be unclaimed." parameters: - name: "id" in: "path" required: true description: "The unique ID of the appeal" schema: type: "integer" responses: 200: description: "The unclaimed appeal" content: application/json: schema: $ref: "#/components/schemas/Appeal" 403: description: "Access denied" /user_feedbacks.json: get: operationId: "getUserFeedbacks" x-access-level: "anonymous" tags: - "user_feedbacks" summary: "Get a list of user feedbacks" description: "Returns a list of user feedbacks based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of feedbacks to retrieve per page" schema: type: "integer" - name: "search[category]" in: "query" required: false description: "Filter by feedback category" schema: $ref: "#/components/schemas/UserFeedbackCategory" - name: "search[deleted]" in: "query" required: false description: "Filter by deletion status of the feedback" schema: $ref: "#/components/schemas/GetUserFeedbacksSearchDeleted" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the feedback" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the feedback" schema: type: "string" responses: 200: description: "A list of user feedbacks matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/UserFeedback" 400: description: "Invalid request parameters" 500: description: "Server error" /user_feedbacks/{id}.json: get: operationId: "getUserFeedback" x-access-level: "anonymous" tags: - "user_feedbacks" summary: "Get a user feedback by ID" description: "Returns detailed information about a specific user feedback identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the user feedback to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing user feedback details" content: application/json: schema: $ref: "#/components/schemas/UserFeedback" 404: description: "User feedback not found" 500: description: "Server error" put: operationId: "updateUserFeedback" x-access-level: "moderator" tags: - "user_feedbacks" summary: "Update a user feedback" description: "Updates the body and/or category of an existing user feedback." parameters: - name: "id" in: "path" required: true description: "The unique ID of the user feedback to update" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateUserFeedbackBody" responses: 200: description: "Successfully updated user feedback" content: application/json: schema: $ref: "#/components/schemas/UserFeedback" 403: description: "Not authorized to edit this feedback" 404: description: "User feedback not found" 422: description: "Validation error" /user_feedbacks/{id}/delete.json: put: operationId: "deleteUserFeedback" x-access-level: "moderator" tags: - "user_feedbacks" summary: "Soft-delete a user feedback" description: "Marks a user feedback as deleted without permanently removing it." parameters: - name: "id" in: "path" required: true description: "The unique ID of the user feedback to delete" schema: type: "integer" responses: 200: description: "Successfully deleted user feedback" 403: description: "Not authorized to delete this feedback" 404: description: "User feedback not found" /user_feedbacks/{id}/undelete.json: put: operationId: "undeleteUserFeedback" x-access-level: "moderator" tags: - "user_feedbacks" summary: "Undelete a user feedback" description: "Restores a previously soft-deleted user feedback." parameters: - name: "id" in: "path" required: true description: "The unique ID of the user feedback to undelete" schema: type: "integer" responses: 200: description: "Successfully undeleted user feedback" 403: description: "Not authorized to undelete this feedback" 404: description: "User feedback not found" /post_approvals.json: get: operationId: "getPostApprovals" x-access-level: "anonymous" tags: - "approvals" summary: "Get a list of post approvals" description: "Returns a list of post approvals based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of approvals to retrieve per page" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter approvals by approver username" schema: type: "integer" - name: "search[post_tags_match]" in: "query" required: false description: "Filter approvals by matching post tagss" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the approval" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the approval" schema: type: "string" - name: "search[id]" in: "query" required: false description: "Filter by approval ID" schema: type: "string" responses: 200: description: "A list of approvals matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Approval" 400: description: "Invalid request parameters" 500: description: "Server error" /uploads.json: get: operationId: "getUploads" x-access-level: "janitor" tags: - "uploads" summary: "Get a list of uploads" description: "Returns a list of uploads based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of uploads to retrieve per page" schema: type: "integer" - name: "search[uploader_name]" in: "query" required: false description: "Filter uploads by uploader's username" schema: type: "string" - name: "search[post_tags_match]" in: "query" required: false description: "Filter uploads by post tags" schema: type: "string" - name: "search[source_matches]" in: "query" required: false description: "Filter uploads by source" schema: type: "string" - name: "search[status]" in: "query" required: false description: "Filter uploads by status" schema: $ref: "#/components/schemas/GetUploadsSearchStatus" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the upload" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the upload" schema: type: "string" responses: 200: description: "A list of uploads matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Upload" 400: description: "Invalid request parameters" 500: description: "Server error" /uploads/{id}.json: get: operationId: "getUpload" x-access-level: "janitor" tags: - "uploads" summary: "Get an upload by ID" description: "Returns detailed information about a specific upload identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the upload to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing upload details" content: application/json: schema: $ref: "#/components/schemas/Upload" 404: description: "Upload not found" 500: description: "Server error" /post_flags.json: get: operationId: "getPostFlags" x-access-level: "anonymous" tags: - "post_flags" summary: "Get a list of post flags" description: "Returns a list of post flags based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of post flags to retrieve per page" schema: type: "integer" - name: "search[reason_matches]" in: "query" required: false description: "Filter post flags by matching reason text" schema: type: "string" - name: "search[post_tags_match]" in: "query" required: false description: "Filter post flags by matching post tags" schema: type: "string" - name: "search[post_id]" in: "query" required: false description: "Filter post flags by post ID" schema: type: "integer" - name: "search[type]" in: "query" required: false description: "Filter post flags by type (e.g., flag or deletion)" schema: $ref: "#/components/schemas/PostFlagType" - name: "search[is_resolved]" in: "query" required: false description: "Filter post flags by resolution status" schema: type: "boolean" - name: "search[creator_name]" in: "query" required: false description: "Filter post flags by the creator's username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter post flags by creator ID" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter post flags by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter post flags by last update date" schema: type: "string" - name: "search[id]" in: "query" required: false description: "Filter post flags by flag ID" schema: type: "string" responses: 200: description: "A list of post flags matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PostFlag" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createPostFlag" x-access-level: "member" tags: - "post_flags" summary: "Create a post flag" description: "Creates a new flag or deletion request for a post." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreatePostFlagBody" responses: 201: description: "Post flag created" content: application/json: schema: $ref: "#/components/schemas/PostFlag" 422: description: "Validation error" /post_flags/{id}.json: get: operationId: "getPostFlag" x-access-level: "anonymous" tags: - "post_flags" summary: "Get a post flag by ID" description: "Returns detailed information about a specific post flag identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post flag to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing post flag details" content: application/json: schema: $ref: "#/components/schemas/PostFlag" 404: description: "Post flag not found" 500: description: "Server error" /post_versions.json: get: operationId: "getPostVersions" x-access-level: "anonymous" tags: - "post_versions" summary: "Get a list of post versions" description: "Returns a list of post versions based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of post versions to retrieve per page" schema: type: "integer" - name: "search[updater_name]" in: "query" required: false description: "Filter post versions by the updater's username" schema: type: "string" - name: "search[post_id]" in: "query" required: false description: "Filter post versions by post ID" schema: type: "integer" - name: "search[reason]" in: "query" required: false description: "Filter post versions by the reason for the update" schema: type: "string" - name: "search[description]" in: "query" required: false description: "Filter post versions by description" schema: type: "string" - name: "search[description_changed]" in: "query" required: false description: "Filter post versions by whether the description was changed" schema: type: "boolean" - name: "search[rating_changed]" in: "query" required: false description: "Filter post versions by whether the rating was changed" schema: $ref: "#/components/schemas/GetPostVersionsSearchRatingChanged" - name: "search[rating]" in: "query" required: false description: "Filter post versions by rating" schema: $ref: "#/components/schemas/PostRating" - name: "search[parent_id]" in: "query" required: false description: "Filter post versions by parent post ID" schema: type: "integer" - name: "search[parent_id_changed]" in: "query" required: false description: "Filter post versions by whether the parent ID was changed" schema: type: "boolean" - name: "search[tags]" in: "query" required: false description: "Filter post versions by tags" schema: type: "string" - name: "search[tags_added]" in: "query" required: false description: "Filter post versions by tags added" schema: type: "string" - name: "search[tags_removed]" in: "query" required: false description: "Filter post versions by tags removed" schema: type: "string" - name: "search[locked_tags]" in: "query" required: false description: "Filter post versions by locked tags" schema: type: "string" - name: "search[locked_tags_added]" in: "query" required: false description: "Filter post versions by locked tags added" schema: type: "string" - name: "search[locked_tags_removed]" in: "query" required: false description: "Filter post versions by locked tags removed" schema: type: "string" - name: "search[source_changed]" in: "query" required: false description: "Filter post versions by whether the source was changed" schema: type: "boolean" - name: "search[uploads]" in: "query" required: false description: "Filter post versions by uploads status" schema: $ref: "#/components/schemas/GetPostVersionsSearchUploads" - name: "search[created_at]" in: "query" required: false description: "Filter post versions by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter post versions by last update date" schema: type: "string" responses: 200: description: "A list of post versions matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PostVersion" 400: description: "Invalid request parameters" 500: description: "Server error" /post_versions/{id}/undo.json: put: operationId: "undoPostVersion" x-access-level: "member" tags: - "post_versions" summary: "Undo a post version" description: "Reverts the changes made in a specific post version." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post version to undo" schema: type: "integer" responses: 200: description: "The post version was undone" 403: description: "Access denied" /post_versions/{id}/hide.json: put: operationId: "hidePostVersion" x-access-level: "bd_staff" tags: - "post_versions" summary: "Hide a post version" description: "Hides a post version from public view." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post version to hide" schema: type: "integer" responses: 302: description: "Redirects back after hiding" 403: description: "Access denied" /post_versions/{id}/unhide.json: put: operationId: "unhidePostVersion" x-access-level: "bd_staff" tags: - "post_versions" summary: "Unhide a post version" description: "Restores a hidden post version to public view." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post version to unhide" schema: type: "integer" responses: 302: description: "Redirects back after unhiding" 403: description: "Access denied" /post_replacements.json: get: operationId: "getPostReplacements" x-access-level: "anonymous" tags: - "post_replacements" summary: "Get a list of post replacements" description: "Returns a list of post replacements based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of replacements to retrieve per page" schema: type: "integer" - name: "search[md5]" in: "query" required: false description: "Filter replacements by the MD5 hash of the file" schema: type: "string" - name: "search[post_id]" in: "query" required: false description: "Filter replacements by post ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter replacements by the creator's username" schema: type: "string" - name: "search[approver_name]" in: "query" required: false description: "Filter replacements by the approver's username" schema: type: "string" - name: "search[uploader_name_on_approve]" in: "query" required: false description: "Filter replacements by the uploader's username at approval time" schema: type: "string" - name: "search[status]" in: "query" required: false description: "Filter replacements by status" schema: $ref: "#/components/schemas/GetPostReplacementsSearchStatus" - name: "search[created_at]" in: "query" required: false description: "Filter replacements by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter replacements by last update date" schema: type: "string" - name: "search[id]" in: "query" required: false description: "Filter replacements by replacement ID" schema: type: "string" responses: 200: description: "A list of post replacements matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PostReplacement" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createPostReplacement" x-access-level: "member" tags: - "post_replacements" summary: "Create a post replacement" description: "Creates a new post replacement for a given post." requestBody: required: true content: multipart/form-data: schema: $ref: "#/components/schemas/CreatePostReplacementBody" responses: 200: description: "The created post replacement" content: application/json: schema: type: "object" properties: success: type: "boolean" location: type: "string" message: type: "string" 412: description: "Replacement validation failed" 403: description: "Access denied" /post_replacements/{id}.json: delete: operationId: "destroyPostReplacement" x-access-level: "admin" tags: - "post_replacements" summary: "Destroy a post replacement" description: "Permanently removes a post replacement." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post replacement" schema: type: "integer" responses: 200: description: "The post replacement was destroyed" content: application/json: schema: $ref: "#/components/schemas/PostReplacement" 403: description: "Access denied" 404: description: "Post replacement not found" /post_replacements/{id}/approve.json: put: operationId: "approvePostReplacement" x-access-level: "approver" tags: - "post_replacements" summary: "Approve a post replacement" description: "Approves a pending post replacement." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post replacement" schema: type: "integer" - name: "penalize_current_uploader" in: "query" required: false description: "Whether to penalize the current uploader" schema: type: "boolean" responses: 200: description: "The approved post replacement" content: application/json: schema: $ref: "#/components/schemas/PostReplacement" 400: description: "Replacement approval failed" 403: description: "Access denied" /post_replacements/{id}/reject.json: put: operationId: "rejectPostReplacement" x-access-level: "approver" tags: - "post_replacements" summary: "Reject a post replacement" description: "Rejects a pending post replacement." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post replacement" schema: type: "integer" responses: 200: description: "The rejected post replacement" content: application/json: schema: $ref: "#/components/schemas/PostReplacement" 403: description: "Access denied" /post_replacements/{id}/promote.json: post: operationId: "promotePostReplacement" x-access-level: "approver" tags: - "post_replacements" summary: "Promote a post replacement" description: "Promotes a post replacement to a new post." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post replacement" schema: type: "integer" responses: 200: description: "The promoted post replacement" content: application/json: schema: $ref: "#/components/schemas/Post" 422: description: "Promotion failed" 403: description: "Access denied" /post_replacements/{id}/toggle_penalize.json: put: operationId: "togglePenalizePostReplacement" x-access-level: "approver" tags: - "post_replacements" summary: "Toggle penalize on a post replacement" description: "Toggles the penalize flag on a post replacement." parameters: - name: "id" in: "path" required: true description: "The unique ID of the post replacement" schema: type: "integer" responses: 200: description: "The updated post replacement" content: application/json: schema: $ref: "#/components/schemas/PostReplacement" 403: description: "Access denied" /mod_actions.json: get: operationId: "getModActions" x-access-level: "anonymous" tags: - "mod_actions" summary: "Get a list of moderation actions" description: "Returns a list of moderation actions based on search criteria." parameters: - name: "search[creator_name]" in: "query" required: false description: "Filter by the name of the creator of the moderation action" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by the ID of the creator of the moderation action" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the moderation action" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the moderation action" schema: type: "string" - name: "search[id]" in: "query" required: false description: "Filter by the ID of the moderation action" schema: type: "string" - name: "search[action]" in: "query" required: false description: "Filter by the type of moderation action" schema: $ref: "#/components/schemas/GetModActionsSearchAction" responses: 200: description: "A list of moderation actions matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/ModAction" 400: description: "Invalid request parameters" 500: description: "Server error" /mod_actions/{id}.json: get: operationId: "getModAction" x-access-level: "anonymous" tags: - "mod_actions" summary: "Get a moderation action by ID" description: "Returns detailed information about a specific moderation action identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the moderation action to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing moderation action details" content: application/json: schema: $ref: "#/components/schemas/ModAction" 404: description: "Moderation action not found" 500: description: "Server error" /bulk_update_requests.json: get: operationId: "getBulkUpdateRequests" x-access-level: "anonymous" tags: - "bulk_update_requests" summary: "Get a list of bulk update requests" description: "Returns a list of bulk update requests filtered by various criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of bulk update requests to retrieve per page" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter by the username of the creator" schema: type: "string" - name: "search[approver_name]" in: "query" required: false description: "Filter by the username of the approver" schema: type: "string" - name: "search[title_matches]" in: "query" required: false description: "Filter by the title of the request" schema: type: "string" - name: "search[script_matches]" in: "query" required: false description: "Filter by script content in the request" schema: type: "string" - name: "search[status]" in: "query" required: false description: "Filter by the status of the request" schema: $ref: "#/components/schemas/BulkUpdateRequestStatus" - name: "search[order]" in: "query" required: false description: "Order the results by a specific field" schema: $ref: "#/components/schemas/GetBulkUpdateRequestsSearchOrder" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the request" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the request" schema: type: "string" responses: 200: description: "A list of bulk update requests matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/BulkUpdateRequest" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createBulkUpdateRequest" x-access-level: "member" tags: - "bulk_update_requests" summary: "Create a bulk update request" description: "Creates a new bulk update request." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateBulkUpdateRequestBody" responses: 200: description: "The created bulk update request" content: application/json: schema: $ref: "#/components/schemas/BulkUpdateRequest" 422: description: "Validation error" 403: description: "Access denied" /bulk_update_requests/{id}.json: get: operationId: "getBulkUpdateRequest" x-access-level: "anonymous" tags: - "bulk_update_requests" summary: "Get a bulk update request by ID" description: "Returns detailed information about a specific bulk update request identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the bulk update request to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing bulk update request details" content: application/json: schema: $ref: "#/components/schemas/BulkUpdateRequest" 404: description: "Bulk update request not found" 500: description: "Server error" put: operationId: "updateBulkUpdateRequest" x-access-level: "member" tags: - "bulk_update_requests" summary: "Update a bulk update request" description: "Updates an existing bulk update request. Only the creator or admin can update." parameters: - name: "id" in: "path" required: true description: "The unique ID of the bulk update request" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateBulkUpdateRequestBody" responses: 200: description: "The updated bulk update request" content: application/json: schema: $ref: "#/components/schemas/BulkUpdateRequest" 422: description: "Validation error" 403: description: "Access denied" delete: operationId: "destroyBulkUpdateRequest" x-access-level: "member" tags: - "bulk_update_requests" summary: "Reject a bulk update request" description: "Rejects a bulk update request. Only the creator or admin can reject." parameters: - name: "id" in: "path" required: true description: "The unique ID of the bulk update request" schema: type: "integer" responses: 200: description: "The bulk update request was rejected" content: application/json: schema: $ref: "#/components/schemas/BulkUpdateRequest" 403: description: "Access denied" /bulk_update_requests/{id}/approve.json: post: operationId: "approveBulkUpdateRequest" x-access-level: "admin" tags: - "bulk_update_requests" summary: "Approve a bulk update request" description: "Approves and executes a bulk update request." parameters: - name: "id" in: "path" required: true description: "The unique ID of the bulk update request" schema: type: "integer" responses: 200: description: "The approved bulk update request" content: application/json: schema: $ref: "#/components/schemas/BulkUpdateRequest" 422: description: "Approval failed" 403: description: "Access denied" /tag_aliases.json: get: operationId: "getTagAliases" x-access-level: "anonymous" tags: - "tag_aliases" summary: "Get a list of tag aliases" description: "Returns a list of tag aliases filtered by various criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of tag aliases to retrieve per page" schema: type: "integer" - name: "search[name_matches]" in: "query" required: false description: "Filter by matching names" schema: type: "string" - name: "search[antecedent_name]" in: "query" required: false description: "Filter by the antecedent name of the alias" schema: type: "string" - name: "search[consequent_name]" in: "query" required: false description: "Filter by the consequent name of the alias" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by the creator's username" schema: type: "string" - name: "search[approver_name]" in: "query" required: false description: "Filter by the approver's username" schema: type: "string" - name: "search[antecedent_tag_category]" in: "query" required: false description: "Filter by the tag category of the antecedent tag" schema: type: "integer" - name: "search[consequent_tag_category]" in: "query" required: false description: "Filter by the tag category of the consequent tag" schema: type: "integer" - name: "search[status]" in: "query" required: false description: "Filter by the status of the tag alias" schema: $ref: "#/components/schemas/GetTagAliasesSearchStatus" - name: "search[order]" in: "query" required: false description: "Order the results by a specific field" schema: $ref: "#/components/schemas/GetTagAliasesSearchOrder" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the request" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the request" schema: type: "string" responses: 200: description: "A list of tag aliases matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/TagAlias" 400: description: "Invalid request parameters" 500: description: "Server error" /tag_aliases/{id}.json: get: operationId: "getTagAlias" x-access-level: "anonymous" tags: - "tag_aliases" summary: "Get a tag alias by ID" description: "Returns detailed information about a specific tag alias identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the tag alias to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing tag alias details" content: application/json: schema: $ref: "#/components/schemas/TagAlias" 404: description: "Tag alias not found" 500: description: "Server error" /tag_implications.json: get: operationId: "getTagImplications" x-access-level: "anonymous" tags: - "tag_implications" summary: "Get a list of tag implications" description: "Returns a list of tag implications filtered by various criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of tag implications to retrieve per page" schema: type: "integer" - name: "search[name_matches]" in: "query" required: false description: "Filter by matching names" schema: type: "string" - name: "search[antecedent_name]" in: "query" required: false description: "Filter by the antecedent name of the implication" schema: type: "string" - name: "search[consequent_name]" in: "query" required: false description: "Filter by the consequent name of the implication" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by the creator's username" schema: type: "string" - name: "search[approver_name]" in: "query" required: false description: "Filter by the approver's username" schema: type: "string" - name: "search[antecedent_tag_category]" in: "query" required: false description: "Filter by the tag category of the antecedent tag" schema: type: "integer" - name: "search[consequent_tag_category]" in: "query" required: false description: "Filter by the tag category of the consequent tag" schema: type: "integer" - name: "search[status]" in: "query" required: false description: "Filter by the status of the tag implication" schema: $ref: "#/components/schemas/GetTagImplicationsSearchStatus" - name: "search[order]" in: "query" required: false description: "Order the results by a specific field" schema: $ref: "#/components/schemas/GetTagImplicationsSearchOrder" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the request" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by the last update date of the request" schema: type: "string" responses: 200: description: "A list of tag implications matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/TagImplication" 400: description: "Invalid request parameters" 500: description: "Server error" /tag_implications/{id}.json: get: operationId: "getTagImplication" x-access-level: "anonymous" tags: - "tag_implications" summary: "Get a tag implication by ID" description: "Returns detailed information about a specific tag implication identified by its ID." parameters: - name: "id" in: "path" required: true description: "The unique ID of the tag implication to retrieve" schema: type: "integer" responses: 200: description: "Successful response containing tag implication details" content: application/json: schema: $ref: "#/components/schemas/TagImplication" 404: description: "Tag implication not found" 500: description: "Server error" /post_events.json: get: operationId: "getPostEvents" x-access-level: "anonymous" tags: - "post_events" summary: "Get a list of post events" description: | Returns a list of post events filtered by various criteria. When `v2=true`, the response is an unwrapped array. Otherwise the array is wrapped under `post_events`. parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of post events to retrieve per page" schema: type: "integer" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by the creator's username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by the creator's ID" schema: type: "integer" - name: "search[action]" in: "query" required: false description: "Filter by the action performed" schema: $ref: "#/components/schemas/PostEventAction" - name: "search[created_at]" in: "query" required: false description: "Filter by the creation date of the event" schema: type: "string" - name: "search[id]" in: "query" required: false description: "Filter by event ID" schema: type: "string" - $ref: "#/components/parameters/PostV2Flag" responses: 200: description: "A list of post events matching the search criteria" content: application/json: schema: oneOf: - type: "object" description: "Legacy response (default). The array is wrapped under `post_events`." properties: post_events: type: "array" items: $ref: "#/components/schemas/PostEvent" - type: "array" description: "Unwrapped response (when `v2=true`)." items: $ref: "#/components/schemas/PostEvent" 400: description: "Invalid request parameters" 500: description: "Server error" /artists.json: get: operationId: "getArtists" x-access-level: "anonymous" tags: - "artists" summary: "Get a list of artists" description: "Returns a list of artists based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of artists to retrieve per page" schema: type: "integer" - name: "search[name]" in: "query" required: false description: "Filter by exact artist name" schema: type: "string" - name: "search[any_name_matches]" in: "query" required: false description: "Filter by partial name match (searches name, other names, and group name)" schema: type: "string" - name: "search[any_name_or_url_matches]" in: "query" required: false description: "Filter by name or URL match" schema: type: "string" - name: "search[url_matches]" in: "query" required: false description: "Filter by URL match" schema: type: "string" - name: "search[group_name]" in: "query" required: false description: "Filter by group name" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by the creator's username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by the creator's user ID" schema: type: "integer" - name: "search[linked_user_name]" in: "query" required: false description: "Filter by the linked user's username" schema: type: "string" - name: "search[linked_user_id]" in: "query" required: false description: "Filter by the linked user's ID" schema: type: "integer" - name: "search[is_linked]" in: "query" required: false description: "Filter by whether a user is linked" schema: type: "boolean" - name: "search[has_tag]" in: "query" required: false description: "Filter by whether the artist has a tag with posts" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Sort order" schema: $ref: "#/components/schemas/GetArtistsSearchOrder" responses: 200: description: "A list of artists matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Artist" 400: description: "Invalid request parameters" 500: description: "Server error" /artists/{id}.json: get: operationId: "getArtist" x-access-level: "anonymous" tags: - "artists" summary: "Get an artist by ID or name" description: "Returns detailed information about a specific artist." parameters: - name: "id" in: "path" required: true description: "The artist ID or name" schema: type: "string" responses: 200: description: "Successful response containing artist details" content: application/json: schema: $ref: "#/components/schemas/Artist" 404: description: "Artist not found" /edit_histories.json: get: operationId: "getEditHistories" x-access-level: "moderator" tags: - "edit_histories" summary: "Search edit histories" description: "Returns a list of edit histories for comments, forum posts, and blips." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results to retrieve per page" schema: type: "integer" - name: "search[body_matches]" in: "query" required: false description: "Filter by body text" schema: type: "string" - name: "search[subject_matches]" in: "query" required: false description: "Filter by subject text" schema: type: "string" - name: "search[versionable_type]" in: "query" required: false description: "Filter by edited item type" schema: $ref: "#/components/schemas/GetEditHistoryType" - name: "search[versionable_id]" in: "query" required: false description: "Filter by edited item ID" schema: type: "integer" - name: "search[editor_name]" in: "query" required: false description: "Filter by editor username" schema: type: "string" - name: "search[editor_id]" in: "query" required: false description: "Filter by editor user ID" schema: type: "integer" - name: "search[order]" in: "query" required: false description: "Sort order" schema: $ref: "#/components/schemas/GetEditHistoriesSearchOrder" responses: 200: description: "A list of edit histories matching the search criteria" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/EditHistory" 400: description: "Invalid request parameters" 500: description: "Server error" /edit_histories/{id}.json: get: operationId: "getEditHistory" x-access-level: "moderator" tags: - "edit_histories" summary: "Get edit history for a specific item" description: "Returns all edit history versions for a specific comment, forum post, or blip." parameters: - name: "id" in: "path" required: true description: "The ID of the edited item" schema: type: "integer" - name: "type" in: "query" required: true description: "The type of the edited item" schema: $ref: "#/components/schemas/GetEditHistoryType" responses: 200: description: "Edit history versions for the item" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/EditHistory" 404: description: "Item not found" /comments.json: get: operationId: "searchComments" x-access-level: "anonymous" tags: - "comments" summary: "Search comments" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[id]" in: "query" required: false description: "Filter by comment ID" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by update date" schema: type: "string" - name: "search[body_matches]" in: "query" required: false description: "Filter by comment body text" schema: type: "string" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID" schema: type: "integer" - name: "search[post_tags_match]" in: "query" required: false description: "Filter by post tags" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[post_note_updater_name]" in: "query" required: false description: "Filter by note updater username" schema: type: "string" - name: "search[post_note_updater_id]" in: "query" required: false description: "Filter by note updater user ID" schema: type: "integer" - name: "search[poster_id]" in: "query" required: false description: "Filter by post uploader ID" schema: type: "integer" - name: "search[poster_name]" in: "query" required: false description: "Filter by post uploader username" schema: type: "string" - name: "search[is_sticky]" in: "query" required: false description: "Filter by sticky status" schema: type: "boolean" - name: "search[do_not_bump_post]" in: "query" required: false description: "Filter by do not bump post status" schema: type: "boolean" - name: "search[is_hidden]" in: "query" required: false description: "Filter by hidden status (moderator only)" schema: type: "boolean" - name: "search[ip_addr]" in: "query" required: false description: "Filter by creator IP address (admin only)" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Sort order (post_id, score, updated_at)" schema: type: "string" - name: "search[advanced_search]" in: "query" required: false description: "Use advanced search for body_matches" schema: type: "boolean" - name: "group_by" in: "query" required: false description: "Group results by post" schema: $ref: "#/components/schemas/SearchCommentsGroupBy" responses: 200: description: "A list of comments" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Comment" post: operationId: "createComment" x-access-level: "member" tags: - "comments" summary: "Create a comment" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateCommentBody" responses: 201: description: "Comment created" content: application/json: schema: $ref: "#/components/schemas/Comment" 422: description: "Validation error" /comments/{id}.json: get: operationId: "getComment" x-access-level: "anonymous" tags: - "comments" summary: "Get a comment by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the comment" schema: type: "integer" responses: 200: description: "A comment" content: application/json: schema: $ref: "#/components/schemas/Comment" 404: description: "Comment not found" patch: operationId: "updateComment" x-access-level: "member" tags: - "comments" summary: "Update a comment" parameters: - name: "id" in: "path" required: true description: "The ID of the comment" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateCommentBody" responses: 200: description: "Comment updated" content: application/json: schema: $ref: "#/components/schemas/Comment" 422: description: "Validation error" delete: operationId: "deleteComment" x-access-level: "admin" tags: - "comments" summary: "Delete a comment" parameters: - name: "id" in: "path" required: true description: "The ID of the comment" schema: type: "integer" responses: 200: description: "Comment deleted" 404: description: "Comment not found" /comments/{id}/hide.json: post: operationId: "hideComment" x-access-level: "member" tags: - "comments" summary: "Hide a comment" parameters: - name: "id" in: "path" required: true description: "The ID of the comment" schema: type: "integer" responses: 200: description: "Comment hidden" content: application/json: schema: $ref: "#/components/schemas/Comment" 403: description: "Access denied" 404: description: "Comment not found" /comments/{id}/unhide.json: post: operationId: "unhideComment" x-access-level: "moderator" tags: - "comments" summary: "Unhide a comment" parameters: - name: "id" in: "path" required: true description: "The ID of the comment" schema: type: "integer" responses: 200: description: "Comment unhidden" content: application/json: schema: $ref: "#/components/schemas/Comment" 403: description: "Access denied" 404: description: "Comment not found" /comments/{id}/warning.json: post: operationId: "warningComment" x-access-level: "moderator" tags: - "comments" summary: "Mark or unmark a comment with a warning" parameters: - name: "id" in: "path" required: true description: "The ID of the comment" schema: type: "integer" - name: "record_type" in: "query" required: true description: "The type of warning to apply or \"unmark\" to remove" schema: $ref: "#/components/schemas/WarningBlipRecordType" responses: 200: description: "Comment warning updated" content: application/json: schema: type: "object" properties: html: type: "string" posts: type: "object" 403: description: "Access denied" 404: description: "Comment not found" /comment_votes.json: get: operationId: "searchCommentVotes" x-access-level: "moderator" tags: - "comment_votes" summary: "Search comment votes" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "search[comment_id]" in: "query" required: false description: "Filter by comment ID" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter by voter username" schema: type: "string" - name: "search[user_id]" in: "query" required: false description: "Filter by voter user ID" schema: type: "integer" - name: "search[comment_creator_id]" in: "query" required: false description: "Filter by comment creator ID" schema: type: "integer" - name: "search[comment_creator_name]" in: "query" required: false description: "Filter by comment creator username" schema: type: "string" - name: "search[timeframe]" in: "query" required: false description: "Filter by number of days ago" schema: type: "integer" - name: "search[score]" in: "query" required: false description: "Filter by vote score (1 or -1)" schema: $ref: "#/components/schemas/CreatePostVoteBodyScore" - name: "search[user_ip_addr]" in: "query" required: false description: "Filter by voter IP address (admin only)" schema: type: "string" - name: "search[duplicates_only]" in: "query" required: false description: "Show only duplicate IP votes (admin only)" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Sort order (ip_addr)" schema: type: "string" responses: 200: description: "A list of comment votes" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/CommentVote" /comment_votes/lock.json: post: operationId: "lockCommentVotes" x-access-level: "moderator" tags: - "comment_votes" summary: "Lock comment votes by ID" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/LockPostVotesBody" responses: 200: description: "Comment votes locked" 403: description: "Access denied" /comment_votes/delete.json: post: operationId: "deleteCommentVotes" x-access-level: "admin" tags: - "comment_votes" summary: "Delete comment votes by ID" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/LockPostVotesBody" responses: 200: description: "Comment votes deleted" 403: description: "Access denied" /comments/{comment_id}/votes.json: post: operationId: "createCommentVote" x-access-level: "member" tags: - "comment_votes" summary: "Vote on a comment" parameters: - name: "comment_id" in: "path" required: true description: "The ID of the comment to vote on" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateCommentVoteBody" responses: 200: description: "Vote registered" content: application/json: schema: type: "object" properties: score: type: "integer" description: "The new comment score" our_score: type: "integer" description: "The user's vote score (0 if unvoted)" 422: description: "Vote error" delete: operationId: "deleteCommentVote" x-access-level: "member" tags: - "comment_votes" summary: "Remove vote on a comment" parameters: - name: "comment_id" in: "path" required: true description: "The ID of the comment to unvote" schema: type: "integer" responses: 200: description: "Vote removed" 422: description: "Unvote error" /blips.json: get: operationId: "searchBlips" x-access-level: "anonymous" tags: - "blips" summary: "Search blips" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[id]" in: "query" required: false description: "Filter by blip ID" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by update date" schema: type: "string" - name: "search[body_matches]" in: "query" required: false description: "Filter by blip body text" schema: type: "string" - name: "search[response_to]" in: "query" required: false description: "Filter by parent blip ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[ip_addr]" in: "query" required: false description: "Filter by creator IP address (admin only)" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Sort order (updated_at)" schema: type: "string" responses: 200: description: "A list of blips" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Blip" post: operationId: "createBlip" x-access-level: "member" tags: - "blips" summary: "Create a blip" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateBlipBody" responses: 201: description: "Blip created" content: application/json: schema: $ref: "#/components/schemas/Blip" 422: description: "Validation error" /blips/{id}.json: get: operationId: "getBlip" x-access-level: "anonymous" tags: - "blips" summary: "Get a blip by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the blip" schema: type: "integer" responses: 200: description: "A blip" content: application/json: schema: $ref: "#/components/schemas/Blip" 404: description: "Blip not found" patch: operationId: "updateBlip" x-access-level: "member" tags: - "blips" summary: "Update a blip" parameters: - name: "id" in: "path" required: true description: "The ID of the blip" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateBlipBody" responses: 200: description: "Blip updated" content: application/json: schema: $ref: "#/components/schemas/Blip" 422: description: "Validation error" delete: operationId: "destroyBlip" x-access-level: "admin" tags: - "blips" summary: "Destroy a blip" description: "Permanently removes a blip. For soft-deletion, use `POST /blips/{id}/delete.json`." parameters: - name: "id" in: "path" required: true description: "The ID of the blip" schema: type: "integer" responses: 200: description: "Blip destroyed" 404: description: "Blip not found" /blips/{id}/delete.json: post: operationId: "deleteBlip" x-access-level: "member" tags: - "blips" summary: "Soft-delete a blip" description: "Marks a blip as deleted, hiding it from normal views. Previously named `hide`." parameters: - name: "id" in: "path" required: true description: "The ID of the blip" schema: type: "integer" responses: 200: description: "Blip deleted" content: application/json: schema: $ref: "#/components/schemas/Blip" 403: description: "Access denied" 404: description: "Blip not found" /blips/{id}/undelete.json: post: operationId: "undeleteBlip" x-access-level: "moderator" tags: - "blips" summary: "Undelete a blip" description: "Restores a soft-deleted blip. Previously named `unhide`." parameters: - name: "id" in: "path" required: true description: "The ID of the blip" schema: type: "integer" responses: 200: description: "Blip undeleted" content: application/json: schema: $ref: "#/components/schemas/Blip" 403: description: "Access denied" 404: description: "Blip not found" /blips/{id}/warning.json: post: operationId: "warningBlip" x-access-level: "moderator" tags: - "blips" summary: "Mark or unmark a blip with a warning" parameters: - name: "id" in: "path" required: true description: "The ID of the blip" schema: type: "integer" - name: "record_type" in: "query" required: true description: "The type of warning to apply or \"unmark\" to remove" schema: $ref: "#/components/schemas/WarningBlipRecordType" responses: 200: description: "Blip warning updated" content: application/json: schema: type: "object" properties: html: type: "string" posts: type: "object" 403: description: "Access denied" 404: description: "Blip not found" /forum_topics.json: get: operationId: "searchForumTopics" x-access-level: "anonymous" tags: - "forum_topics" summary: "Search forum topics" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[id]" in: "query" required: false description: "Filter by forum topic ID" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by update date" schema: type: "string" - name: "search[title_matches]" in: "query" required: false description: "Filter by title text" schema: type: "string" - name: "search[title]" in: "query" required: false description: "Filter by exact title" schema: type: "string" - name: "search[category_id]" in: "query" required: false description: "Filter by forum category ID" schema: type: "integer" - name: "search[is_sticky]" in: "query" required: false description: "Filter by sticky status" schema: type: "boolean" - name: "search[is_locked]" in: "query" required: false description: "Filter by locked status" schema: type: "boolean" - name: "search[is_hidden]" in: "query" required: false description: "Filter by hidden status" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Sort order (sticky)" schema: type: "string" responses: 200: description: "A list of forum topics" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/ForumTopic" post: operationId: "createForumTopic" x-access-level: "member" tags: - "forum_topics" summary: "Create a forum topic" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateForumTopicBody" responses: 201: description: "Forum topic created" content: application/json: schema: $ref: "#/components/schemas/ForumTopic" 422: description: "Validation error" /forum_topics/{id}.json: get: operationId: "getForumTopic" x-access-level: "anonymous" tags: - "forum_topics" summary: "Get a forum topic by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" - name: "page" in: "query" required: false description: "The page number for forum posts pagination" schema: type: "integer" responses: 200: description: "A forum topic" content: application/json: schema: $ref: "#/components/schemas/ForumTopic" 404: description: "Forum topic not found" patch: operationId: "updateForumTopic" x-access-level: "member" tags: - "forum_topics" summary: "Update a forum topic" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateForumTopicBody" responses: 200: description: "Forum topic updated" content: application/json: schema: $ref: "#/components/schemas/ForumTopic" 422: description: "Validation error" delete: operationId: "deleteForumTopic" x-access-level: "admin" tags: - "forum_topics" summary: "Delete a forum topic" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" responses: 200: description: "Forum topic deleted" 404: description: "Forum topic not found" /forum_topics/{id}/hide.json: post: operationId: "hideForumTopic" x-access-level: "member" tags: - "forum_topics" summary: "Hide a forum topic" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" responses: 200: description: "Forum topic hidden" content: application/json: schema: $ref: "#/components/schemas/ForumTopic" 403: description: "Access denied" 404: description: "Forum topic not found" /forum_topics/{id}/unhide.json: post: operationId: "unhideForumTopic" x-access-level: "moderator" tags: - "forum_topics" summary: "Unhide a forum topic" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" responses: 200: description: "Forum topic unhidden" content: application/json: schema: $ref: "#/components/schemas/ForumTopic" 403: description: "Access denied" 404: description: "Forum topic not found" /forum_topics/{id}/subscribe.json: post: operationId: "subscribeForumTopic" x-access-level: "member" tags: - "forum_topics" summary: "Subscribe to a forum topic" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" responses: 200: description: "Subscribed to forum topic" 404: description: "Forum topic not found" /forum_topics/{id}/unsubscribe.json: post: operationId: "unsubscribeForumTopic" x-access-level: "member" tags: - "forum_topics" summary: "Unsubscribe from a forum topic" parameters: - name: "id" in: "path" required: true description: "The ID of the forum topic" schema: type: "integer" responses: 200: description: "Unsubscribed from forum topic" 404: description: "Forum topic not found" /forum_topics/mark_all_as_read.json: post: operationId: "markAllForumTopicsAsRead" x-access-level: "member" tags: - "forum_topics" summary: "Mark all forum topics as read" responses: 200: description: "All forum topics marked as read" /forum_posts.json: get: operationId: "searchForumPosts" x-access-level: "anonymous" tags: - "forum_posts" summary: "Search forum posts" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[id]" in: "query" required: false description: "Filter by forum post ID" schema: type: "integer" - name: "search[created_at]" in: "query" required: false description: "Filter by creation date" schema: type: "string" - name: "search[updated_at]" in: "query" required: false description: "Filter by update date" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[topic_id]" in: "query" required: false description: "Filter by forum topic ID" schema: type: "integer" - name: "search[topic_title_matches]" in: "query" required: false description: "Filter by topic title text" schema: type: "string" - name: "search[body_matches]" in: "query" required: false description: "Filter by post body text" schema: type: "string" - name: "search[topic_category_id]" in: "query" required: false description: "Filter by topic category ID" schema: type: "integer" - name: "search[is_hidden]" in: "query" required: false description: "Filter by hidden status" schema: type: "boolean" responses: 200: description: "A list of forum posts" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/ForumPost" post: operationId: "createForumPost" x-access-level: "member" tags: - "forum_posts" summary: "Create a forum post" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateForumPostBody" responses: 201: description: "Forum post created" content: application/json: schema: $ref: "#/components/schemas/ForumPost" 422: description: "Validation error" /forum_posts/{id}.json: get: operationId: "getForumPost" x-access-level: "anonymous" tags: - "forum_posts" summary: "Get a forum post by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the forum post" schema: type: "integer" responses: 200: description: "A forum post" content: application/json: schema: $ref: "#/components/schemas/ForumPost" 404: description: "Forum post not found" patch: operationId: "updateForumPost" x-access-level: "member" tags: - "forum_posts" summary: "Update a forum post" parameters: - name: "id" in: "path" required: true description: "The ID of the forum post" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateForumPostBody" responses: 200: description: "Forum post updated" content: application/json: schema: $ref: "#/components/schemas/ForumPost" 422: description: "Validation error" delete: operationId: "deleteForumPost" x-access-level: "admin" tags: - "forum_posts" summary: "Delete a forum post" parameters: - name: "id" in: "path" required: true description: "The ID of the forum post" schema: type: "integer" responses: 200: description: "Forum post deleted" 404: description: "Forum post not found" /forum_posts/{id}/hide.json: post: operationId: "hideForumPost" x-access-level: "member" tags: - "forum_posts" summary: "Hide a forum post" parameters: - name: "id" in: "path" required: true description: "The ID of the forum post" schema: type: "integer" responses: 200: description: "Forum post hidden" content: application/json: schema: $ref: "#/components/schemas/ForumPost" 403: description: "Access denied" 404: description: "Forum post not found" /forum_posts/{id}/unhide.json: post: operationId: "unhideForumPost" x-access-level: "moderator" tags: - "forum_posts" summary: "Unhide a forum post" parameters: - name: "id" in: "path" required: true description: "The ID of the forum post" schema: type: "integer" responses: 200: description: "Forum post unhidden" content: application/json: schema: $ref: "#/components/schemas/ForumPost" 403: description: "Access denied" 404: description: "Forum post not found" /forum_posts/{id}/warning.json: post: operationId: "warningForumPost" x-access-level: "moderator" tags: - "forum_posts" summary: "Mark or unmark a forum post with a warning" parameters: - name: "id" in: "path" required: true description: "The ID of the forum post" schema: type: "integer" - name: "record_type" in: "query" required: true description: "The type of warning to apply or \"unmark\" to remove" schema: $ref: "#/components/schemas/WarningBlipRecordType" responses: 200: description: "Forum post warning updated" content: application/json: schema: type: "object" properties: html: type: "string" posts: type: "object" 403: description: "Access denied" 404: description: "Forum post not found" /forum_posts/{forum_post_id}/votes.json: post: operationId: "createForumPostVote" x-access-level: "member" tags: - "forum_post_votes" summary: "Vote on a forum post" parameters: - name: "forum_post_id" in: "path" required: true description: "The ID of the forum post to vote on" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateForumPostVoteBody" responses: 201: description: "Vote created" content: application/json: schema: $ref: "#/components/schemas/ForumPostVote" 403: description: "Access denied" delete: operationId: "deleteForumPostVote" x-access-level: "member" tags: - "forum_post_votes" summary: "Remove vote on a forum post" parameters: - name: "forum_post_id" in: "path" required: true description: "The ID of the forum post to unvote" schema: type: "integer" responses: 200: description: "Vote removed" 404: description: "Vote not found" /tags.json: get: operationId: "searchTags" x-access-level: "anonymous" tags: - "tags" summary: "Search tags" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[name_matches]" in: "query" required: false description: "Search by tag name pattern (supports wildcards)" schema: type: "string" - name: "search[name]" in: "query" required: false description: "Filter by exact tag name (comma-separated for multiple)" schema: type: "string" - name: "search[category]" in: "query" required: false description: "Filter by tag category ID (comma-separated for multiple)" schema: type: "string" - name: "search[hide_empty]" in: "query" required: false description: "Hide tags with no posts (default true)" schema: type: "string" - name: "search[has_wiki]" in: "query" required: false description: "Filter by whether the tag has a wiki page" schema: type: "string" - name: "search[has_artist]" in: "query" required: false description: "Filter by whether the tag has an artist entry" schema: type: "string" - name: "search[is_locked]" in: "query" required: false description: "Filter by locked status" schema: type: "string" - name: "search[fuzzy_name_matches]" in: "query" required: false description: "Search by fuzzy tag name match" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Sort order for results" schema: $ref: "#/components/schemas/SearchTagsSearchOrder" responses: 200: description: "A list of tags" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Tag" /tags/{id}.json: get: operationId: "getTag" x-access-level: "anonymous" tags: - "tags" summary: "Get a tag by ID or name" parameters: - name: "id" in: "path" required: true description: "The ID or name of the tag" schema: type: "string" responses: 200: description: "Tag details" content: application/json: schema: $ref: "#/components/schemas/Tag" 404: description: "Tag not found" put: operationId: "updateTag" x-access-level: "member" tags: - "tags" summary: "Update a tag" parameters: - name: "id" in: "path" required: true description: "The ID of the tag to update" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateTagBody" responses: 200: description: "Tag updated" content: application/json: schema: $ref: "#/components/schemas/Tag" 403: description: "Access denied" 422: description: "Validation error" /tags/preview.json: post: operationId: "previewTags" x-access-level: "member" tags: - "tags" summary: "Preview tag information" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PreviewTagsBody" responses: 200: description: "Tag preview data" content: application/json: schema: type: "object" /tag_type_versions.json: get: operationId: "searchTagTypeVersions" x-access-level: "anonymous" tags: - "tag_type_versions" summary: "Search tag type change history" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[tag]" in: "query" required: false description: "Filter by tag name" schema: type: "string" - name: "search[user_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" responses: 200: description: "A list of tag type versions" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/TagTypeVersion" /wiki_pages.json: get: operationId: "searchWikiPages" x-access-level: "anonymous" tags: - "wiki_pages" summary: "Search wiki pages" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[title]" in: "query" required: false description: "Filter by title (supports wildcards)" schema: type: "string" - name: "search[body_matches]" in: "query" required: false description: "Search by body text" schema: type: "string" - name: "search[other_names_match]" in: "query" required: false description: "Search by other names" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" - name: "search[hide_deleted]" in: "query" required: false description: "Hide deleted wiki pages" schema: type: "string" - name: "search[parent]" in: "query" required: false description: "Filter by parent wiki page" schema: type: "string" - name: "search[other_names_present]" in: "query" required: false description: "Filter by whether other names are present" schema: type: "string" - name: "search[is_locked]" in: "query" required: false description: "Filter by locked status" schema: type: "string" - name: "search[is_deleted]" in: "query" required: false description: "Filter by deleted status" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Sort order for results" schema: $ref: "#/components/schemas/SearchWikiPagesSearchOrder" responses: 200: description: "A list of wiki pages" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/WikiPage" post: operationId: "createWikiPage" x-access-level: "member" tags: - "wiki_pages" summary: "Create a wiki page" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateWikiPageBody" responses: 201: description: "Wiki page created" content: application/json: schema: $ref: "#/components/schemas/WikiPage" 422: description: "Validation error" /wiki_pages/{id}.json: get: operationId: "getWikiPage" x-access-level: "anonymous" tags: - "wiki_pages" summary: "Get a wiki page by ID or title" parameters: - name: "id" in: "path" required: true description: "The ID or title of the wiki page" schema: type: "string" responses: 200: description: "Wiki page details" content: application/json: schema: $ref: "#/components/schemas/WikiPage" 404: description: "Wiki page not found" put: operationId: "updateWikiPage" x-access-level: "member" tags: - "wiki_pages" summary: "Update a wiki page" parameters: - name: "id" in: "path" required: true description: "The ID of the wiki page to update" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateWikiPageBody" responses: 200: description: "Wiki page updated" content: application/json: schema: $ref: "#/components/schemas/WikiPage" 403: description: "Access denied" 422: description: "Validation error" delete: operationId: "deleteWikiPage" x-access-level: "admin" tags: - "wiki_pages" summary: "Delete a wiki page" parameters: - name: "id" in: "path" required: true description: "The ID of the wiki page to delete" schema: type: "integer" responses: 200: description: "Wiki page deleted" 404: description: "Wiki page not found" /wiki_pages/{id}/revert.json: put: operationId: "revertWikiPage" x-access-level: "member" tags: - "wiki_pages" summary: "Revert a wiki page to a previous version" parameters: - name: "id" in: "path" required: true description: "The ID of the wiki page to revert" schema: type: "integer" - name: "version_id" in: "query" required: true description: "The ID of the version to revert to" schema: type: "integer" responses: 200: description: "Wiki page reverted" content: application/json: schema: $ref: "#/components/schemas/WikiPage" 404: description: "Wiki page or version not found" /wiki_pages/show_or_new.json: get: operationId: "showOrNewWikiPage" x-access-level: "anonymous" tags: - "wiki_pages" summary: "Show an existing wiki page or prepare to create a new one" parameters: - name: "title" in: "query" required: false description: "The title to look up or create" schema: type: "string" responses: 200: description: "Wiki page found or new page prepared" content: application/json: schema: $ref: "#/components/schemas/WikiPage" 302: description: "Redirect to existing wiki page" /wiki_page_versions.json: get: operationId: "searchWikiPageVersions" x-access-level: "anonymous" tags: - "wiki_page_versions" summary: "Search wiki page version history" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[updater_id]" in: "query" required: false description: "Filter by updater user ID" schema: type: "integer" - name: "search[updater_name]" in: "query" required: false description: "Filter by updater username" schema: type: "string" - name: "search[wiki_page_id]" in: "query" required: false description: "Filter by wiki page ID" schema: type: "integer" - name: "search[title]" in: "query" required: false description: "Filter by title" schema: type: "string" - name: "search[body]" in: "query" required: false description: "Filter by body text" schema: type: "string" - name: "search[is_locked]" in: "query" required: false description: "Filter by locked status" schema: type: "string" - name: "search[is_deleted]" in: "query" required: false description: "Filter by deleted status" schema: type: "string" responses: 200: description: "A list of wiki page versions" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/WikiPageVersion" /wiki_page_versions/{id}.json: get: operationId: "getWikiPageVersion" x-access-level: "anonymous" tags: - "wiki_page_versions" summary: "Get a wiki page version by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the wiki page version" schema: type: "integer" responses: 200: description: "Wiki page version details" content: application/json: schema: $ref: "#/components/schemas/WikiPageVersion" 404: description: "Wiki page version not found" /wiki_page_versions/diff.json: get: operationId: "diffWikiPageVersions" x-access-level: "anonymous" tags: - "wiki_page_versions" summary: "Diff two wiki page versions" parameters: - name: "thispage" in: "query" required: true description: "The ID of the first wiki page version" schema: type: "integer" - name: "otherpage" in: "query" required: true description: "The ID of the second wiki page version" schema: type: "integer" responses: 200: description: "Diff result between two versions" /notes.json: get: operationId: "searchNotes" x-access-level: "anonymous" tags: - "notes" summary: "Search notes" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[body_matches]" in: "query" required: false description: "Search by note body text" schema: type: "string" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "string" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID (comma-separated for multiple)" schema: type: "string" - name: "search[post_tags_match]" in: "query" required: false description: "Filter by post tags" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" responses: 200: description: "A list of notes" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Note" post: operationId: "createNote" x-access-level: "member" tags: - "notes" summary: "Create a note" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateNoteBody" responses: 200: description: "Note created" content: application/json: schema: type: "object" properties: note: type: "string" description: "JSON-encoded note object" dtext: type: "string" description: "Rendered DText body" 422: description: "Validation error" content: application/json: schema: type: "object" properties: success: type: "boolean" reasons: type: "array" items: type: "string" /notes/{id}.json: get: operationId: "getNote" x-access-level: "anonymous" tags: - "notes" summary: "Get a note by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the note" schema: type: "integer" responses: 200: description: "Note details" content: application/json: schema: $ref: "#/components/schemas/Note" 404: description: "Note not found" put: operationId: "updateNote" x-access-level: "member" tags: - "notes" summary: "Update a note" parameters: - name: "id" in: "path" required: true description: "The ID of the note to update" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateNoteBody" responses: 200: description: "Note updated" content: application/json: schema: type: "object" properties: note: type: "string" description: "JSON-encoded note object" dtext: type: "string" description: "Rendered DText body" posts: type: "object" description: "Deferred post data" 422: description: "Validation error" content: application/json: schema: type: "object" properties: success: type: "boolean" reasons: type: "array" items: type: "string" delete: operationId: "deleteNote" x-access-level: "member" tags: - "notes" summary: "Delete a note (sets is_active to false)" parameters: - name: "id" in: "path" required: true description: "The ID of the note to delete" schema: type: "integer" responses: 200: description: "Note deleted" 404: description: "Note not found" /notes/{id}/revert.json: put: operationId: "revertNote" x-access-level: "member" tags: - "notes" summary: "Revert a note to a previous version" parameters: - name: "id" in: "path" required: true description: "The ID of the note to revert" schema: type: "integer" - name: "version_id" in: "query" required: true description: "The ID of the version to revert to" schema: type: "integer" responses: 200: description: "Note reverted" content: application/json: schema: $ref: "#/components/schemas/Note" 404: description: "Note or version not found" /note_versions.json: get: operationId: "searchNoteVersions" x-access-level: "anonymous" tags: - "note_versions" summary: "Search note version history" parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of results per page" schema: type: "integer" - name: "search[updater_id]" in: "query" required: false description: "Filter by updater user ID" schema: type: "integer" - name: "search[updater_name]" in: "query" required: false description: "Filter by updater username" schema: type: "string" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID (comma-separated for multiple)" schema: type: "string" - name: "search[note_id]" in: "query" required: false description: "Filter by note ID (comma-separated for multiple)" schema: type: "string" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "string" - name: "search[body_matches]" in: "query" required: false description: "Search by body text" schema: type: "string" responses: 200: description: "A list of note versions" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/NoteVersion" /pools.json: get: operationId: "searchPools" x-access-level: "anonymous" tags: - "pools" summary: "Search pools" description: "Returns a paginated list of pools matching the given search criteria." parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of pools to retrieve per page" schema: type: "integer" - name: "search[name_matches]" in: "query" required: false description: "Filter by pool name (wildcards supported)" schema: type: "string" - name: "search[description_matches]" in: "query" required: false description: "Filter by description text" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" - name: "search[category]" in: "query" required: false description: "Filter by pool category" schema: $ref: "#/components/schemas/PoolCategory" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Sort order" schema: $ref: "#/components/schemas/GetArtistsSearchOrder" responses: 200: description: "A list of pools" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Pool" post: operationId: "createPool" x-access-level: "member" tags: - "pools" summary: "Create a new pool" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreatePoolBody" responses: 200: description: "Pool created" content: application/json: schema: $ref: "#/components/schemas/Pool" 422: description: "Validation error" /pools/{id}.json: get: operationId: "getPool" x-access-level: "anonymous" tags: - "pools" summary: "Get a pool by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the pool" schema: type: "integer" responses: 200: description: "Pool details" content: application/json: schema: $ref: "#/components/schemas/Pool" 404: description: "Pool not found" put: operationId: "updatePool" x-access-level: "member" tags: - "pools" summary: "Update a pool" parameters: - name: "id" in: "path" required: true description: "The ID of the pool to update" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdatePoolBody" responses: 200: description: "Pool updated" content: application/json: schema: $ref: "#/components/schemas/Pool" 404: description: "Pool not found" 422: description: "Validation error" delete: operationId: "deletePool" x-access-level: "janitor" tags: - "pools" summary: "Delete a pool" parameters: - name: "id" in: "path" required: true description: "The ID of the pool to delete" schema: type: "integer" responses: 200: description: "Pool deleted" 403: description: "Access denied" 404: description: "Pool not found" /pool_versions.json: get: operationId: "searchPoolVersions" x-access-level: "member" tags: - "pools" summary: "Search pool versions" description: "Returns a paginated list of pool version history entries." parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of versions to retrieve per page" schema: type: "integer" - name: "search[pool_id]" in: "query" required: false description: "Filter by pool ID" schema: type: "integer" - name: "search[updater_id]" in: "query" required: false description: "Filter by updater user ID" schema: type: "integer" - name: "search[updater_name]" in: "query" required: false description: "Filter by updater username" schema: type: "string" - name: "search[ip_addr]" in: "query" required: false description: "Filter by IP address (admin only)" schema: type: "string" responses: 200: description: "A list of pool versions" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PoolVersion" /pool_element.json: post: operationId: "addPoolElement" x-access-level: "member" tags: - "pools" summary: "Add a post to a pool" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddPoolElementBody" responses: 200: description: "Post added to pool" content: application/json: schema: $ref: "#/components/schemas/Pool" 404: description: "Pool or post not found" 422: description: "Validation error" delete: operationId: "removePoolElement" x-access-level: "member" tags: - "pools" summary: "Remove a post from a pool" parameters: - name: "pool_id" in: "query" required: false description: "The ID of the pool" schema: type: "integer" - name: "pool_name" in: "query" required: false description: "The name of the pool (alternative to pool_id)" schema: type: "string" - name: "post_id" in: "query" required: true description: "The ID of the post to remove" schema: type: "integer" responses: 200: description: "Post removed from pool" content: application/json: schema: $ref: "#/components/schemas/Pool" 404: description: "Pool or post not found" /pool_element/recent.json: get: operationId: "getRecentPoolElements" x-access-level: "member" tags: - "pools" summary: "Get recently used pools" description: "Returns a list of pools the current user recently added posts to." responses: 200: description: "A list of recent pools" content: application/json: schema: type: "array" items: type: "object" properties: id: type: "integer" description: "The pool ID" name: type: "string" description: "The pool name" /post_sets.json: get: operationId: "searchPostSets" x-access-level: "anonymous" tags: - "post_sets" summary: "Search post sets" description: "Returns a paginated list of post sets matching the given search criteria." parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of sets to retrieve per page" schema: type: "integer" - name: "post_id" in: "query" required: false description: "Filter sets containing this post ID" schema: type: "integer" - name: "maintainer_id" in: "query" required: false description: "Filter sets maintained by this user ID" schema: type: "integer" - name: "search[name]" in: "query" required: false description: "Filter by set name (wildcards supported)" schema: type: "string" - name: "search[shortname]" in: "query" required: false description: "Filter by shortname" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Sort order" schema: $ref: "#/components/schemas/SearchPostSetsSearchOrder" responses: 200: description: "A list of post sets" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PostSet" post: operationId: "createPostSet" x-access-level: "member" tags: - "post_sets" summary: "Create a new post set" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreatePostSetBody" responses: 200: description: "Post set created" content: application/json: schema: $ref: "#/components/schemas/PostSet" 422: description: "Validation error" /post_sets/{id}.json: get: operationId: "getPostSet" x-access-level: "anonymous" tags: - "post_sets" summary: "Get a post set by ID" parameters: - name: "id" in: "path" required: true description: "The ID of the post set" schema: type: "integer" responses: 200: description: "Post set details" content: application/json: schema: $ref: "#/components/schemas/PostSet" 403: description: "Access denied" 404: description: "Post set not found" put: operationId: "updatePostSet" x-access-level: "member" tags: - "post_sets" summary: "Update a post set" parameters: - name: "id" in: "path" required: true description: "The ID of the post set to update" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdatePostSetBody" responses: 200: description: "Post set updated" content: application/json: schema: $ref: "#/components/schemas/PostSet" 403: description: "Access denied" 422: description: "Validation error" delete: operationId: "deletePostSet" x-access-level: "member" tags: - "post_sets" summary: "Delete a post set" parameters: - name: "id" in: "path" required: true description: "The ID of the post set to delete" schema: type: "integer" responses: 200: description: "Post set deleted" 403: description: "Access denied" 404: description: "Post set not found" /post_sets/for_select.json: get: operationId: "getPostSetsForSelect" x-access-level: "member" tags: - "post_sets" summary: "Get post sets for selection" description: "Returns owned and maintained post sets formatted for use in selection dropdowns." responses: 200: description: "Post sets grouped by ownership" content: application/json: schema: type: "object" properties: Owned: type: "array" items: type: "array" items: oneOf: - type: "string" - type: "integer" Maintained: type: "array" items: type: "array" items: oneOf: - type: "string" - type: "integer" /post_sets/{id}/post_list.json: get: operationId: "getPostSetPostList" x-access-level: "member" tags: - "post_sets" summary: "Get the post list for a post set" parameters: - name: "id" in: "path" required: true description: "The ID of the post set" schema: type: "integer" responses: 200: description: "Post set details with post list" content: application/json: schema: $ref: "#/components/schemas/PostSet" 403: description: "Access denied" 404: description: "Post set not found" /post_sets/{id}/add_posts.json: post: operationId: "addPostSetPosts" x-access-level: "member" tags: - "post_sets" summary: "Add posts to a post set" parameters: - name: "id" in: "path" required: true description: "The ID of the post set" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddPostSetPostsBody" responses: 200: description: "Posts added to set" content: application/json: schema: $ref: "#/components/schemas/PostSet" 403: description: "Access denied" 422: description: "Validation error" /post_sets/{id}/remove_posts.json: post: operationId: "removePostSetPosts" x-access-level: "member" tags: - "post_sets" summary: "Remove posts from a post set" parameters: - name: "id" in: "path" required: true description: "The ID of the post set" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddPostSetPostsBody" responses: 200: description: "Posts removed from set" content: application/json: schema: $ref: "#/components/schemas/PostSet" 403: description: "Access denied" /favorites.json: get: operationId: "getFavorites" x-access-level: "anonymous" tags: - "favorites" summary: "Get a list of favorited posts" description: | Returns a list of posts favorited by the specified user or the current user. Accepts the same `v2` and `mode` parameters as `/posts.json`. parameters: - name: "user_id" in: "query" required: false description: "The user ID whose favorites to retrieve (defaults to current user)" schema: type: "integer" - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of posts to retrieve per page" schema: type: "integer" - $ref: "#/components/parameters/PostV2Flag" - $ref: "#/components/parameters/PostV2Mode" responses: 200: description: "A list of favorited posts" content: application/json: schema: oneOf: - type: "object" description: "Legacy response (default)." properties: posts: type: "array" items: $ref: "#/components/schemas/Post" - type: "array" items: $ref: "#/components/schemas/PostV2Basic" - type: "array" items: $ref: "#/components/schemas/PostV2Extended" - type: "array" items: $ref: "#/components/schemas/PostV2Thumbnail" post: operationId: "addFavorite" x-access-level: "member" tags: - "favorites" summary: "Favorite a post" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddFavoriteBody" responses: 200: description: "Post favorited" content: application/json: schema: type: "object" properties: post_id: type: "integer" description: "The ID of the favorited post" favorite_count: type: "integer" description: "The new favorite count for the post" 422: description: "Validation error" 423: description: "Favorites are being transferred" /favorites/{id}.json: delete: operationId: "removeFavorite" x-access-level: "member" tags: - "favorites" summary: "Unfavorite a post" parameters: - name: "id" in: "path" required: true description: "The ID of the post to unfavorite" schema: type: "integer" responses: 200: description: "Post unfavorited" content: application/json: schema: type: "object" properties: post_id: type: "integer" description: "The ID of the unfavorited post" favorite_count: type: "integer" description: "The new favorite count for the post" 422: description: "Validation error" 423: description: "Favorites are being transferred" /posts/{post_id}/favorites.json: get: operationId: "getPostFavorites" x-access-level: "anonymous" tags: - "favorites" summary: "Get users who favorited a post" description: "Returns a paginated list of users who favorited the specified post." parameters: - name: "post_id" in: "path" required: true description: "The ID of the post" schema: type: "integer" - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of users to retrieve per page (max 100)" schema: type: "integer" responses: 200: description: "A list of users who favorited the post" content: application/json: schema: type: "array" items: type: "object" properties: id: type: "integer" description: "The user ID" name: type: "string" description: "The username" 403: description: "Access denied when the post has `hide_favorites_list` enabled and the caller is not staff" 404: description: "Post not found" /post_votes.json: get: operationId: "getPostVotes" x-access-level: "moderator" tags: - "post_votes" summary: "Get a list of post votes" description: "Returns a paginated list of post votes based on search criteria." parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of post votes to retrieve per page" schema: type: "integer" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID" schema: type: "integer" - name: "search[user_name]" in: "query" required: false description: "Filter by voter username" schema: type: "string" - name: "search[user_id]" in: "query" required: false description: "Filter by voter user ID" schema: type: "integer" - name: "search[post_creator_id]" in: "query" required: false description: "Filter by post uploader ID" schema: type: "integer" - name: "search[post_creator_name]" in: "query" required: false description: "Filter by post uploader username" schema: type: "string" - name: "search[timeframe]" in: "query" required: false description: "Filter by votes within the last N days" schema: type: "integer" - name: "search[score]" in: "query" required: false description: "Filter by vote score (1 or -1)" schema: $ref: "#/components/schemas/CreatePostVoteBodyScore" - name: "search[user_ip_addr]" in: "query" required: false description: "Filter by voter IP address (admin only)" schema: type: "string" - name: "search[duplicates_only]" in: "query" required: false description: "Show only duplicate IP votes (admin only)" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Sort order (admin only, supports ip_addr)" schema: type: "string" responses: 200: description: "A list of post votes" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PostVote" 403: description: "Access denied" /post_votes/lock.json: post: operationId: "lockPostVotes" x-access-level: "moderator" tags: - "post_votes" summary: "Lock post votes" description: "Locks the specified post votes, preventing further voting changes." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/LockPostVotesBody" responses: 200: description: "Votes locked" 403: description: "Access denied" /post_votes/delete.json: post: operationId: "deletePostVotes" x-access-level: "admin" tags: - "post_votes" summary: "Delete post votes" description: "Deletes the specified post votes." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/LockPostVotesBody" responses: 200: description: "Votes deleted" 403: description: "Access denied" /posts/{post_id}/votes.json: post: operationId: "createPostVote" x-access-level: "member" tags: - "post_votes" summary: "Vote on a post" description: "Casts a vote on the specified post. Voting again with the same score will remove the vote unless no_unvote is set." parameters: - name: "post_id" in: "path" required: true description: "The ID of the post to vote on" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreatePostVoteBody" responses: 200: description: "Vote cast successfully" content: application/json: schema: type: "object" properties: score: type: "integer" description: "The new total score of the post" up: type: "integer" description: "The new upvote score of the post" down: type: "integer" description: "The new downvote score of the post" our_score: type: "integer" description: "The current user's vote score (0 if unvoted)" 422: description: "Validation error" delete: operationId: "deletePostVote" x-access-level: "member" tags: - "post_votes" summary: "Remove vote from a post" description: "Removes the current user's vote from the specified post." parameters: - name: "post_id" in: "path" required: true description: "The ID of the post to remove the vote from" schema: type: "integer" responses: 200: description: "Vote removed" 422: description: "Validation error" /post_flags/{id}/clear_note.json: post: operationId: "clearPostFlagNote" x-access-level: "janitor" tags: - "post_flags" summary: "Clear a post flag note" description: "Removes the note from the specified post flag." parameters: - name: "id" in: "path" required: true description: "The ID of the post flag" schema: type: "integer" responses: 200: description: "Note cleared" content: application/json: schema: $ref: "#/components/schemas/PostFlag" 404: description: "Post flag not found" /posts/{post_id}/flag.json: delete: operationId: "resolvePostFlag" x-access-level: "janitor" tags: - "post_flags" summary: "Resolve a post flag" description: "Resolves the active flag on a post, optionally approving the post." parameters: - name: "post_id" in: "path" required: true description: "The ID of the flagged post" schema: type: "integer" - name: "approval" in: "query" required: false description: "Set to \"approve\" to also approve the post" schema: $ref: "#/components/schemas/ResolvePostFlagApproval" responses: 200: description: "Post flag resolved" 404: description: "Post not found" /moderator/post/approval.json: post: operationId: "approvePost" x-access-level: "approver" tags: - "moderator" summary: "Approve a post" description: "Approves a pending post for publication." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddFavoriteBody" responses: 201: description: "Post approved" 403: description: "Cannot approve this post" delete: operationId: "unapprovePost" x-access-level: "approver" tags: - "moderator" summary: "Unapprove a post" description: "Removes approval from a post." parameters: - name: "post_id" in: "query" required: true description: "The ID of the post to unapprove" schema: type: "integer" responses: 200: description: "Post unapproved" 403: description: "Cannot unapprove this post" /moderator/post/disapprovals.json: get: operationId: "getPostDisapprovals" x-access-level: "approver" tags: - "moderator" summary: "Get a list of post disapprovals" description: "Returns a paginated list of post disapprovals." parameters: - name: "page" in: "query" required: false description: "The page number for pagination" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of disapprovals to retrieve per page" schema: type: "integer" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by disapprover username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by disapprover user ID" schema: type: "integer" - name: "search[reason]" in: "query" required: false description: "Filter by reason (borderline_quality, borderline_relevancy, other)" schema: $ref: "#/components/schemas/PostDisapprovalReason" - name: "search[message]" in: "query" required: false description: "Filter by message text" schema: type: "string" - name: "search[post_tags_match]" in: "query" required: false description: "Filter by post tags" schema: type: "string" - name: "search[has_message]" in: "query" required: false description: "Filter by presence of message" schema: type: "boolean" responses: 200: description: "A list of post disapprovals" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/PostDisapproval" 403: description: "Access denied" post: operationId: "createPostDisapproval" x-access-level: "approver" tags: - "moderator" summary: "Create a post disapproval" description: "Disapproves a post with a reason and optional message." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreatePostDisapprovalBody" responses: 200: description: "Post disapproval created" content: application/json: schema: $ref: "#/components/schemas/PostDisapproval" 422: description: "Validation error" /moderator/post/posts/{id}/delete.json: post: operationId: "moderatorDeletePost" x-access-level: "approver" tags: - "moderator" summary: "Delete a post" description: "Deletes a post with a reason. Can optionally copy sources, tags, or move favorites to a parent post." parameters: - name: "id" in: "path" required: true description: "The ID of the post to delete" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ModeratorDeletePostBody" responses: 200: description: "Post deleted" content: application/json: schema: $ref: "#/components/schemas/Post" 422: description: "Validation error" /moderator/post/posts/{id}/undelete.json: post: operationId: "moderatorUndeletePost" x-access-level: "approver" tags: - "moderator" summary: "Undelete a post" description: "Restores a previously deleted post." parameters: - name: "id" in: "path" required: true description: "The ID of the post to undelete" schema: type: "integer" responses: 200: description: "Post undeleted" content: application/json: schema: $ref: "#/components/schemas/Post" 404: description: "Post not found" /moderator/post/posts/{id}/expunge.json: post: operationId: "moderatorExpungePost" x-access-level: "admin" tags: - "moderator" summary: "Expunge a post" description: "Permanently removes a post and its files from the system." parameters: - name: "id" in: "path" required: true description: "The ID of the post to expunge" schema: type: "integer" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/ModeratorExpungePostBody" responses: 200: description: "Post expunged" content: application/json: schema: $ref: "#/components/schemas/Post" 404: description: "Post not found" /moderator/post/posts/{id}/move_favorites.json: post: operationId: "moderatorMoveFavorites" x-access-level: "approver" tags: - "moderator" summary: "Move favorites to parent post" description: "Transfers favorites and post sets from this post to its parent post." parameters: - name: "id" in: "path" required: true description: "The ID of the post to move favorites from" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ModeratorMoveFavoritesBody" responses: 302: description: "Redirects to the post page after moving favorites" /moderator/post/posts/{id}/ban.json: post: operationId: "moderatorBanPost" x-access-level: "approver" tags: - "moderator" summary: "Ban a post" description: "Bans a post, preventing it from being reposted." parameters: - name: "id" in: "path" required: true description: "The ID of the post to ban" schema: type: "integer" responses: 200: description: "Post banned" content: application/json: schema: $ref: "#/components/schemas/Post" 404: description: "Post not found" /moderator/post/posts/{id}/unban.json: post: operationId: "moderatorUnbanPost" x-access-level: "approver" tags: - "moderator" summary: "Unban a post" description: "Removes the ban on a post, allowing it to be reposted." parameters: - name: "id" in: "path" required: true description: "The ID of the post to unban" schema: type: "integer" responses: 200: description: "Post unbanned" content: application/json: schema: $ref: "#/components/schemas/Post" 404: description: "Post not found" /moderator/post/posts/{id}/regenerate_thumbnails.json: post: operationId: "moderatorRegenerateThumbnails" x-access-level: "janitor" tags: - "moderator" summary: "Regenerate post thumbnails" description: "Regenerates the image samples and thumbnails for a post." parameters: - name: "id" in: "path" required: true description: "The ID of the post to regenerate thumbnails for" schema: type: "integer" responses: 200: description: "Thumbnails regenerated" content: application/json: schema: $ref: "#/components/schemas/Post" 404: description: "Post not found" /moderator/post/posts/{id}/regenerate_videos.json: post: operationId: "moderatorRegenerateVideos" x-access-level: "janitor" tags: - "moderator" summary: "Regenerate post video samples" description: "Regenerates the video samples for a post. Cannot be used on deleted posts." parameters: - name: "id" in: "path" required: true description: "The ID of the post to regenerate video samples for" schema: type: "integer" responses: 200: description: "Video samples regenerated" content: application/json: schema: $ref: "#/components/schemas/Post" 403: description: "Cannot regenerate thumbnails on deleted images" 404: description: "Post not found" /moderator/ip_addrs.json: get: operationId: "getModeratorIpAddrs" x-access-level: "admin" tags: - "moderator" summary: "Search IP address usage" description: "Searches for IP address usage across the site by user ID, username, or IP address." parameters: - name: "search[user_id]" in: "query" required: false description: "Filter by user ID (comma-separated for multiple)" schema: type: "string" - name: "search[user_name]" in: "query" required: false description: "Filter by username (comma-separated for multiple)" schema: type: "string" - name: "search[ip_addr]" in: "query" required: false description: "Filter by IP address (comma-separated for multiple, supports CIDR notation)" schema: type: "string" - name: "search[add_ip_mask]" in: "query" required: false description: "Automatically add a /24 (IPv4) or /64 (IPv6) mask to a single IP address" schema: type: "boolean" responses: 200: description: "IP address search results" content: application/json: schema: type: "object" properties: sums: type: "object" description: "Activity counts grouped by type and user/IP" users: type: "object" description: "User objects keyed by user ID" 403: description: "Access denied" /moderator/ip_addrs/export.json: get: operationId: "exportModeratorIpAddrs" x-access-level: "admin" tags: - "moderator" summary: "Export IP address data" description: "Exports IP address data with full history included." parameters: - name: "search[user_id]" in: "query" required: false description: "Filter by user ID (comma-separated for multiple)" schema: type: "string" - name: "search[user_name]" in: "query" required: false description: "Filter by username (comma-separated for multiple)" schema: type: "string" - name: "search[ip_addr]" in: "query" required: false description: "Filter by IP address (comma-separated for multiple, supports CIDR notation)" schema: type: "string" - name: "search[add_ip_mask]" in: "query" required: false description: "Automatically add a /24 (IPv4) or /64 (IPv6) mask to a single IP address" schema: type: "boolean" responses: 200: description: "Exported IP address data" content: application/json: schema: type: "array" items: type: "string" description: "Unique IP addresses" 403: description: "Access denied" /avoid_postings.json: get: operationId: "getAvoidPostings" x-access-level: "anonymous" tags: - "avoid_postings" summary: "Get a list of avoid posting entries" description: "Returns a list of avoid posting (Do Not Post) entries." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of entries to retrieve per page" schema: type: "integer" - name: "search[creator_name]" in: "query" required: false description: "Filter by the creator's username" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by the creator's user ID" schema: type: "integer" - name: "search[artist_name]" in: "query" required: false description: "Filter by exact artist name" schema: type: "string" - name: "search[artist_id]" in: "query" required: false description: "Filter by artist ID" schema: type: "integer" - name: "search[any_name_matches]" in: "query" required: false description: "Filter by partial name match (searches name, other names, and group name)" schema: type: "string" - name: "search[any_other_name_matches]" in: "query" required: false description: "Filter by other name match" schema: type: "string" - name: "search[group_name]" in: "query" required: false description: "Filter by group name" schema: type: "string" - name: "search[details]" in: "query" required: false description: "Filter by details text" schema: type: "string" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Order the results" schema: $ref: "#/components/schemas/GetAvoidPostingsSearchOrder" responses: 200: description: "A list of avoid posting entries" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/AvoidPosting" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createAvoidPosting" x-access-level: "staff" tags: - "avoid_postings" summary: "Create an avoid posting entry" description: "Creates a new avoid posting (Do Not Post) entry." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateAvoidPostingBody" responses: 200: description: "The created avoid posting entry" content: application/json: schema: $ref: "#/components/schemas/AvoidPosting" 422: description: "Validation error" 403: description: "Access denied" /avoid_postings/{id}.json: get: operationId: "getAvoidPosting" x-access-level: "anonymous" tags: - "avoid_postings" summary: "Get an avoid posting entry by ID or name" description: "Returns detailed information about a specific avoid posting entry. The ID can be a numeric ID or an artist name." parameters: - name: "id" in: "path" required: true description: "The ID or artist name of the avoid posting entry" schema: type: "string" responses: 200: description: "Successful response containing avoid posting details" content: application/json: schema: $ref: "#/components/schemas/AvoidPosting" 404: description: "Avoid posting entry not found" 500: description: "Server error" put: operationId: "updateAvoidPosting" x-access-level: "staff" tags: - "avoid_postings" summary: "Update an avoid posting entry" description: "Updates an existing avoid posting entry." parameters: - name: "id" in: "path" required: true description: "The ID or artist name of the avoid posting entry" schema: type: "string" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateAvoidPostingBody" responses: 200: description: "The updated avoid posting entry" content: application/json: schema: $ref: "#/components/schemas/AvoidPosting" 422: description: "Validation error" 403: description: "Access denied" /avoid_postings/{id}/delete.json: put: operationId: "deleteAvoidPosting" x-access-level: "staff" tags: - "avoid_postings" summary: "Soft-delete an avoid posting entry" description: "Marks an avoid posting entry as inactive (soft delete)." parameters: - name: "id" in: "path" required: true description: "The ID or artist name of the avoid posting entry" schema: type: "string" responses: 302: description: "Redirects back after soft-deleting" 403: description: "Access denied" /avoid_postings/{id}/undelete.json: put: operationId: "undeleteAvoidPosting" x-access-level: "staff" tags: - "avoid_postings" summary: "Undelete an avoid posting entry" description: "Restores a soft-deleted avoid posting entry to active status." parameters: - name: "id" in: "path" required: true description: "The ID or artist name of the avoid posting entry" schema: type: "string" responses: 302: description: "Redirects back after undeleting" 403: description: "Access denied" /avoid_posting_versions.json: get: operationId: "getAvoidPostingVersions" x-access-level: "anonymous" tags: - "avoid_postings" summary: "Get a list of avoid posting versions" description: "Returns a list of avoid posting version history entries." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of versions to retrieve per page" schema: type: "integer" - name: "search[updater_name]" in: "query" required: false description: "Filter by updater username" schema: type: "string" - name: "search[updater_id]" in: "query" required: false description: "Filter by updater user ID" schema: type: "integer" - name: "search[artist_name]" in: "query" required: false description: "Filter by artist name" schema: type: "string" - name: "search[artist_id]" in: "query" required: false description: "Filter by artist ID" schema: type: "integer" - name: "search[any_name_matches]" in: "query" required: false description: "Filter by partial name match" schema: type: "string" - name: "search[any_other_name_matches]" in: "query" required: false description: "Filter by other name match" schema: type: "string" - name: "search[group_name]" in: "query" required: false description: "Filter by group name" schema: type: "string" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "boolean" responses: 200: description: "A list of avoid posting versions" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/AvoidPostingVersion" 400: description: "Invalid request parameters" 500: description: "Server error" /takedowns.json: get: operationId: "getTakedowns" x-access-level: "anonymous" tags: - "takedowns" summary: "Get a list of takedowns" description: "Returns a list of takedown requests. Most fields are hidden from non-staff users." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of takedowns to retrieve per page" schema: type: "integer" - name: "search[status]" in: "query" required: false description: "Filter by takedown status" schema: $ref: "#/components/schemas/TakedownStatus" - name: "search[source]" in: "query" required: false description: "Filter by source (moderator only)" schema: type: "string" - name: "search[reason]" in: "query" required: false description: "Filter by reason (moderator only)" schema: type: "string" - name: "search[creator_name]" in: "query" required: false description: "Filter by creator username (moderator only)" schema: type: "string" - name: "search[creator_id]" in: "query" required: false description: "Filter by creator user ID (moderator only)" schema: type: "integer" - name: "search[post_id]" in: "query" required: false description: "Filter by post ID (moderator only)" schema: type: "integer" - name: "search[notes]" in: "query" required: false description: "Filter by notes (moderator only)" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Order the results (admin only)" schema: $ref: "#/components/schemas/GetTakedownsSearchOrder" responses: 200: description: "A list of takedown requests" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Takedown" 400: description: "Invalid request parameters" 500: description: "Server error" /takedowns/{id}.json: get: operationId: "getTakedown" x-access-level: "anonymous" tags: - "takedowns" summary: "Get a takedown by ID" description: "Returns detailed information about a specific takedown request." parameters: - name: "id" in: "path" required: true description: "The unique ID of the takedown" schema: type: "integer" - name: "code" in: "query" required: false description: "Verification code to view takedown instructions" schema: type: "string" responses: 200: description: "Successful response containing takedown details" content: application/json: schema: $ref: "#/components/schemas/Takedown" 404: description: "Takedown not found" 500: description: "Server error" put: operationId: "updateTakedown" x-access-level: "moderator" tags: - "takedowns" summary: "Update a takedown" description: "Updates a takedown request. Can also process the takedown." parameters: - name: "id" in: "path" required: true description: "The unique ID of the takedown" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateTakedownBody" responses: 200: description: "The updated takedown" content: application/json: schema: $ref: "#/components/schemas/Takedown" 422: description: "Validation error" 403: description: "Access denied" delete: operationId: "destroyTakedown" x-access-level: "moderator" tags: - "takedowns" summary: "Destroy a takedown" description: "Permanently destroys a takedown request." parameters: - name: "id" in: "path" required: true description: "The unique ID of the takedown" schema: type: "integer" responses: 200: description: "The takedown was destroyed" content: application/json: schema: $ref: "#/components/schemas/Takedown" 403: description: "Access denied" 404: description: "Takedown not found" /takedowns/count_matching_posts.json: post: operationId: "countMatchingTakedownPosts" x-access-level: "moderator" tags: - "takedowns" summary: "Count posts matching a tag query" description: "Returns the count of posts matching the given tag query. Used when adding posts to a takedown by tags." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddTakedownPostsByTagsBody" responses: 200: description: "The count of matching posts" content: application/json: schema: type: "object" properties: matched_post_count: type: "integer" description: "The number of posts matching the tag query" 403: description: "Access denied" /takedowns/{id}/add_by_ids.json: post: operationId: "addTakedownPostsByIds" x-access-level: "moderator" tags: - "takedowns" summary: "Add posts to a takedown by IDs" description: "Adds posts to a takedown request using post IDs." parameters: - name: "id" in: "path" required: true description: "The unique ID of the takedown" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddTakedownPostsByIdsBody" responses: 200: description: "Posts added successfully" content: application/json: schema: type: "object" properties: added_count: type: "integer" description: "Number of posts added" added_post_ids: type: "array" items: type: "integer" description: "IDs of posts that were added" 403: description: "Access denied" /takedowns/{id}/add_by_tags.json: post: operationId: "addTakedownPostsByTags" x-access-level: "moderator" tags: - "takedowns" summary: "Add posts to a takedown by tags" description: "Adds posts to a takedown request using a tag query." parameters: - name: "id" in: "path" required: true description: "The unique ID of the takedown" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddTakedownPostsByTagsBody" responses: 200: description: "Posts added successfully" content: application/json: schema: type: "object" properties: added_count: type: "integer" description: "Number of posts added" added_post_ids: type: "array" items: type: "integer" description: "IDs of posts that were added" 403: description: "Access denied" /takedowns/{id}/remove_by_ids.json: post: operationId: "removeTakedownPostsByIds" x-access-level: "moderator" tags: - "takedowns" summary: "Remove posts from a takedown by IDs" description: "Removes posts from a takedown request using post IDs." parameters: - name: "id" in: "path" required: true description: "The unique ID of the takedown" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AddTakedownPostsByIdsBody" responses: 200: description: "Posts removed successfully" 403: description: "Access denied" /ip_bans.json: get: operationId: "getIpBans" x-access-level: "admin" tags: - "ip_bans" summary: "Get a list of IP bans" description: "Returns a list of IP bans." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of IP bans to retrieve per page" schema: type: "integer" - name: "search[ip_addr]" in: "query" required: false description: "Filter by IP address" schema: type: "string" - name: "search[banner_id]" in: "query" required: false description: "Filter by banning staff user ID" schema: type: "integer" - name: "search[banner_name]" in: "query" required: false description: "Filter by banning staff username" schema: type: "string" - name: "search[reason]" in: "query" required: false description: "Filter by ban reason" schema: type: "string" responses: 200: description: "A list of IP bans" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/IpBan" 403: description: "Access denied" 500: description: "Server error" post: operationId: "createIpBan" x-access-level: "admin" tags: - "ip_bans" summary: "Create an IP ban" description: "Creates a new IP ban." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateIpBanBody" responses: 200: description: "The created IP ban" content: application/json: schema: $ref: "#/components/schemas/IpBan" 422: description: "Validation error" 403: description: "Access denied" /ip_bans/{id}.json: delete: operationId: "destroyIpBan" x-access-level: "admin" tags: - "ip_bans" summary: "Destroy an IP ban" description: "Removes an IP ban." parameters: - name: "id" in: "path" required: true description: "The unique ID of the IP ban" schema: type: "integer" responses: 200: description: "The IP ban was destroyed" content: application/json: schema: $ref: "#/components/schemas/IpBan" 403: description: "Access denied" 404: description: "IP ban not found" /artist_versions.json: get: operationId: "getArtistVersions" x-access-level: "anonymous" tags: - "artists" summary: "Get a list of artist versions" description: "Returns a list of artist version history entries." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of versions to retrieve per page" schema: type: "integer" - name: "search[name]" in: "query" required: false description: "Filter by artist name" schema: type: "string" - name: "search[updater_name]" in: "query" required: false description: "Filter by updater username" schema: type: "string" - name: "search[updater_id]" in: "query" required: false description: "Filter by updater user ID" schema: type: "integer" - name: "search[artist_id]" in: "query" required: false description: "Filter by artist ID" schema: type: "integer" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "boolean" - name: "search[order]" in: "query" required: false description: "Order the results" schema: $ref: "#/components/schemas/GetArtistVersionsSearchOrder" responses: 200: description: "A list of artist versions" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/ArtistVersion" 400: description: "Invalid request parameters" 500: description: "Server error" /artist_urls.json: get: operationId: "getArtistUrls" x-access-level: "anonymous" tags: - "artists" summary: "Get a list of artist URLs" description: "Returns a list of artist URLs with their associated artist information." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of URLs to retrieve per page" schema: type: "integer" - name: "search[artist_id]" in: "query" required: false description: "Filter by artist ID" schema: type: "integer" - name: "search[artist_name]" in: "query" required: false description: "Filter by artist name" schema: type: "string" - name: "search[is_active]" in: "query" required: false description: "Filter by active status" schema: type: "boolean" - name: "search[url]" in: "query" required: false description: "Filter by URL" schema: type: "string" - name: "search[url_matches]" in: "query" required: false description: "Filter by URL match (wildcards supported)" schema: type: "string" - name: "search[normalized_url]" in: "query" required: false description: "Filter by normalized URL" schema: type: "string" - name: "search[normalized_url_matches]" in: "query" required: false description: "Filter by normalized URL match (wildcards supported)" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Order the results" schema: type: "string" responses: 200: description: "A list of artist URLs" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/ArtistUrl" 400: description: "Invalid request parameters" 500: description: "Server error" /upload_whitelists.json: get: operationId: "getUploadWhitelists" x-access-level: "anonymous" tags: - "upload_whitelists" summary: "Get a list of upload whitelist entries" description: "Returns a list of upload whitelist entries." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of entries to retrieve per page" schema: type: "integer" - name: "search[allowed]" in: "query" required: false description: "Filter by allowed status" schema: type: "boolean" - name: "search[domain]" in: "query" required: false description: "Filter by domain" schema: type: "string" - name: "search[path]" in: "query" required: false description: "Filter by path" schema: type: "string" - name: "search[note]" in: "query" required: false description: "Filter by note" schema: type: "string" - name: "search[reason]" in: "query" required: false description: "Filter by reason" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Order the results" schema: $ref: "#/components/schemas/GetUploadWhitelistsSearchOrder" responses: 200: description: "A list of upload whitelist entries" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/UploadWhitelist" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createUploadWhitelist" x-access-level: "admin" tags: - "upload_whitelists" summary: "Create an upload whitelist entry" description: "Creates a new upload whitelist entry." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateUploadWhitelistBody" responses: 200: description: "The created upload whitelist entry" content: application/json: schema: $ref: "#/components/schemas/UploadWhitelist" 422: description: "Validation error" 403: description: "Access denied" /upload_whitelists/{id}.json: delete: operationId: "destroyUploadWhitelist" x-access-level: "admin" tags: - "upload_whitelists" summary: "Destroy an upload whitelist entry" description: "Removes an upload whitelist entry." parameters: - name: "id" in: "path" required: true description: "The unique ID of the whitelist entry" schema: type: "integer" responses: 200: description: "The whitelist entry was destroyed" content: application/json: schema: $ref: "#/components/schemas/UploadWhitelist" 403: description: "Access denied" 404: description: "Whitelist entry not found" /upload_whitelists/is_allowed.json: get: operationId: "isUploadUrlAllowed" x-access-level: "anonymous" tags: - "upload_whitelists" summary: "Check if a URL is allowed for upload" description: "Checks if a given URL is whitelisted for upload." parameters: - name: "url" in: "query" required: true description: "The URL to check" schema: type: "string" responses: 200: description: "The whitelist check result" content: application/json: schema: type: "object" properties: url: type: "string" description: "The URL that was checked" domain: type: "string" description: "The domain of the URL" is_allowed: type: "boolean" description: "Whether the URL is allowed" reason: type: "string" description: "The reason for the result" /popular.json: get: operationId: "getPopularPosts" x-access-level: "anonymous" tags: - "posts" summary: "Get popular posts" description: | Returns a list of popular posts for a given date and time scale. Accepts the same `v2` and `mode` parameters as `/posts.json`. parameters: - name: "date" in: "query" required: false description: "The date to get popular posts for (YYYY-MM-DD format)" schema: type: "string" format: "date" - name: "scale" in: "query" required: false description: "The time scale for popularity" schema: $ref: "#/components/schemas/GetPopularPostsScale" - $ref: "#/components/parameters/PostV2Flag" - $ref: "#/components/parameters/PostV2Mode" responses: 200: description: "A list of popular posts" content: application/json: schema: oneOf: - type: "object" description: "Legacy response (default)." properties: posts: type: "array" items: $ref: "#/components/schemas/Post" - type: "array" items: $ref: "#/components/schemas/PostV2Basic" - type: "array" items: $ref: "#/components/schemas/PostV2Extended" - type: "array" items: $ref: "#/components/schemas/PostV2Thumbnail" 422: description: "Invalid parameters" 500: description: "Server error" /iqdb_queries.json: get: operationId: "getIqdbQuery" x-access-level: "anonymous" tags: - "iqdb" summary: "Search for similar images (GET)" description: "Queries the IQDB service for visually similar images using a post ID, URL, or hash." parameters: - name: "search[post_id]" in: "query" required: false description: "Find images similar to this post" schema: type: "integer" - name: "search[url]" in: "query" required: false description: "Find images similar to the image at this URL" schema: type: "string" - name: "search[hash]" in: "query" required: false description: "Find images similar to this perceptual hash" schema: type: "string" - name: "search[score_cutoff]" in: "query" required: false description: "Minimum similarity score threshold" schema: type: "number" - name: "v2" in: "query" required: false description: "If `\"true\"`, the `post` field uses the basic v2 Post format instead of the legacy serialization." schema: $ref: "#/components/schemas/GetIqdbQueryV2" responses: 200: description: "A list of similar image matches" content: application/json: schema: type: "object" properties: posts: type: "array" items: $ref: "#/components/schemas/IqdbQuery" 404: description: "File not found or too large" 500: description: "IQDB service error" post: operationId: "postIqdbQuery" x-access-level: "anonymous" tags: - "iqdb" summary: "Search for similar images (POST)" description: "Queries the IQDB service for visually similar images. Supports file upload in addition to URL and post ID." parameters: - name: "v2" in: "query" required: false description: "If `\"true\"`, the `post` field uses the basic v2 Post format instead of the legacy serialization." schema: $ref: "#/components/schemas/GetIqdbQueryV2" requestBody: required: true content: multipart/form-data: schema: $ref: "#/components/schemas/PostIqdbQueryBody" responses: 200: description: "A list of similar image matches" content: application/json: schema: type: "object" properties: posts: type: "array" items: $ref: "#/components/schemas/IqdbQuery" 404: description: "File not found or too large" 500: description: "IQDB service error" /related_tag.json: get: operationId: "getRelatedTag" x-access-level: "member" tags: - "tags" summary: "Get related tags" description: "Returns tags related to the given query tag." parameters: - name: "search[query]" in: "query" required: true description: "The tag to find related tags for" schema: type: "string" - name: "search[category_id]" in: "query" required: false description: "Filter by tag category ID" schema: type: "integer" responses: 200: description: "Related tags for the query" content: application/json: schema: $ref: "#/components/schemas/RelatedTag" 403: description: "Access denied" /related_tag/bulk.json: get: operationId: "getRelatedTagBulk" x-access-level: "member" tags: - "tags" summary: "Get related tags in bulk" description: "Returns related tags for a bulk query." parameters: - name: "query" in: "query" required: true description: "The tag query for bulk related tag lookup" schema: type: "string" - name: "category_id" in: "query" required: false description: "Filter by tag category ID" schema: type: "integer" responses: 200: description: "Bulk related tag results" content: application/json: schema: $ref: "#/components/schemas/RelatedTag" 403: description: "Access denied" post: operationId: "postRelatedTagBulk" x-access-level: "member" tags: - "tags" summary: "Get related tags in bulk (POST)" description: "Returns related tags for a bulk query via POST." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PostRelatedTagBulkBody" responses: 200: description: "Bulk related tag results" content: application/json: schema: $ref: "#/components/schemas/RelatedTag" 403: description: "Access denied" /dtext_preview.json: post: operationId: "createDtextPreview" x-access-level: "anonymous" tags: - "utilities" summary: "Preview DText formatting" description: "Renders DText markup into HTML." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateDtextPreviewBody" responses: 200: description: "The rendered DText preview" content: application/json: schema: type: "object" properties: html: type: "string" description: "The rendered HTML" posts: type: "object" description: "Deferred post data referenced in the DText" /mascots.json: get: operationId: "getMascots" x-access-level: "anonymous" tags: - "mascots" summary: "Get a list of mascots" description: "Returns a list of site mascots." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of mascots to retrieve per page" schema: type: "integer" responses: 200: description: "A list of mascots" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/Mascot" 400: description: "Invalid request parameters" 500: description: "Server error" post: operationId: "createMascot" x-access-level: "admin" tags: - "mascots" summary: "Create a mascot" description: "Creates a new site mascot." requestBody: required: true content: multipart/form-data: schema: $ref: "#/components/schemas/CreateMascotBody" responses: 200: description: "The created mascot" content: application/json: schema: $ref: "#/components/schemas/Mascot" 422: description: "Validation error" 403: description: "Access denied" /mascots/{id}.json: put: operationId: "updateMascot" x-access-level: "admin" tags: - "mascots" summary: "Update a mascot" description: "Updates an existing mascot." parameters: - name: "id" in: "path" required: true description: "The unique ID of the mascot" schema: type: "integer" requestBody: required: true content: multipart/form-data: schema: $ref: "#/components/schemas/UpdateMascotBody" responses: 200: description: "The updated mascot" content: application/json: schema: $ref: "#/components/schemas/Mascot" 422: description: "Validation error" 403: description: "Access denied" delete: operationId: "destroyMascot" x-access-level: "admin" tags: - "mascots" summary: "Destroy a mascot" description: "Permanently removes a mascot." parameters: - name: "id" in: "path" required: true description: "The unique ID of the mascot" schema: type: "integer" responses: 200: description: "The mascot was destroyed" content: application/json: schema: $ref: "#/components/schemas/Mascot" 403: description: "Access denied" 404: description: "Mascot not found" /help_pages.json: get: operationId: "getHelpPages" x-access-level: "anonymous" tags: - "help_pages" summary: "Get a list of help pages" description: "Returns a list of all help pages sorted by title." responses: 200: description: "A list of help pages" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/HelpPage" 500: description: "Server error" post: operationId: "createHelpPage" x-access-level: "admin" tags: - "help_pages" summary: "Create a help page" description: "Creates a new help page." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateHelpPageBody" responses: 200: description: "The created help page" content: application/json: schema: $ref: "#/components/schemas/HelpPage" 422: description: "Validation error" 403: description: "Access denied" /help_pages/{id}.json: get: operationId: "getHelpPage" x-access-level: "anonymous" tags: - "help_pages" summary: "Get a help page by ID or name" description: "Returns detailed information about a specific help page." parameters: - name: "id" in: "path" required: true description: "The ID or name of the help page" schema: type: "string" responses: 200: description: "Successful response containing help page details" content: application/json: schema: $ref: "#/components/schemas/HelpPage" 404: description: "Help page not found" 500: description: "Server error" put: operationId: "updateHelpPage" x-access-level: "admin" tags: - "help_pages" summary: "Update a help page" description: "Updates an existing help page." parameters: - name: "id" in: "path" required: true description: "The ID of the help page" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateHelpPageBody" responses: 200: description: "The updated help page" content: application/json: schema: $ref: "#/components/schemas/HelpPage" 422: description: "Validation error" 403: description: "Access denied" delete: operationId: "destroyHelpPage" x-access-level: "admin" tags: - "help_pages" summary: "Destroy a help page" description: "Permanently removes a help page." parameters: - name: "id" in: "path" required: true description: "The ID of the help page" schema: type: "integer" responses: 200: description: "The help page was destroyed" content: application/json: schema: $ref: "#/components/schemas/HelpPage" 403: description: "Access denied" 404: description: "Help page not found" /news_updates.json: get: operationId: "getNewsUpdates" x-access-level: "anonymous" tags: - "news_updates" summary: "Get a list of news updates" description: "Returns a list of news updates ordered by most recent first." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of news updates to retrieve per page" schema: type: "integer" responses: 200: description: "A list of news updates" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/NewsUpdate" 400: description: "Invalid request parameters" 500: description: "Server error" /email_blacklists.json: get: operationId: "getEmailBlacklists" x-access-level: "admin" tags: - "email_blacklists" summary: "Get a list of email blacklist entries" description: "Returns a list of blacklisted email domains." parameters: - name: "page" in: "query" required: false description: "The page number to retrieve" schema: type: "integer" - name: "limit" in: "query" required: false description: "The number of entries to retrieve per page" schema: type: "integer" - name: "search[domain]" in: "query" required: false description: "Filter by domain" schema: type: "string" - name: "search[reason]" in: "query" required: false description: "Filter by reason" schema: type: "string" - name: "search[order]" in: "query" required: false description: "Order the results" schema: $ref: "#/components/schemas/GetEmailBlacklistsSearchOrder" responses: 200: description: "A list of email blacklist entries" content: application/json: schema: type: "array" items: $ref: "#/components/schemas/EmailBlacklist" 403: description: "Access denied" 500: description: "Server error" post: operationId: "createEmailBlacklist" x-access-level: "admin" tags: - "email_blacklists" summary: "Create an email blacklist entry" description: "Creates a new email blacklist entry." requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateEmailBlacklistBody" responses: 200: description: "The created email blacklist entry" content: application/json: schema: $ref: "#/components/schemas/EmailBlacklist" 422: description: "Validation error" 403: description: "Access denied" /email_blacklists/{id}.json: delete: operationId: "destroyEmailBlacklist" x-access-level: "admin" tags: - "email_blacklists" summary: "Destroy an email blacklist entry" description: "Removes an email blacklist entry." parameters: - name: "id" in: "path" required: true description: "The unique ID of the blacklist entry" schema: type: "integer" responses: 200: description: "The blacklist entry was destroyed" content: application/json: schema: $ref: "#/components/schemas/EmailBlacklist" 403: description: "Access denied" 404: description: "Blacklist entry not found" components: securitySchemes: BasicAuth: type: "http" scheme: "basic" description: "HTTP Basic with the account username and an API key from `/api_keys.json`. The account password is not accepted." ApiKeyLogin: type: "apiKey" in: "query" name: "login" description: "Account username. Must be sent together with `api_key`." ApiKeyQuery: type: "apiKey" in: "query" name: "api_key" description: "API key from `/api_keys.json`. Must be sent together with `login`." parameters: PostV2Flag: name: "v2" in: "query" required: false description: "If `\"true\"`, the response uses the v2 Post format. Otherwise the legacy format is returned." schema: type: "string" enum: - "true" PostV2Mode: name: "mode" in: "query" required: false description: "Selects the v2 Post payload shape. Only effective when `v2=true`. Default `basic`." schema: type: "string" enum: - "basic" - "extended" - "thumbnail" - "thumbnails" schemas: Post: type: "object" required: - "id" - "created_at" - "updated_at" - "file" - "preview" - "sample" - "score" - "tags" - "locked_tags" - "change_seq" - "flags" - "rating" - "fav_count" - "sources" - "pools" - "relationships" - "uploader_id" - "description" - "comment_count" - "has_notes" properties: id: type: "integer" description: "The unique ID of the post" created_at: type: "string" format: "date-time" description: "The time when the post was created" updated_at: type: "string" format: "date-time" description: "The last time the post was updated" file: $ref: "#/components/schemas/File" preview: $ref: "#/components/schemas/Preview" sample: $ref: "#/components/schemas/Sample" score: $ref: "#/components/schemas/Score" tags: $ref: "#/components/schemas/Tags" locked_tags: type: "array" items: type: "string" description: "An array of tags that are locked" change_seq: type: "integer" description: "The sequence number of changes to the post" flags: $ref: "#/components/schemas/Flags" rating: $ref: "#/components/schemas/PostRating" fav_count: type: "integer" description: "The number of times the post has been favorited" sources: type: "array" items: type: "string" description: "An array of sources for the post" pools: type: "array" items: type: "integer" description: "An array of pool IDs associated with the post" relationships: $ref: "#/components/schemas/Relationships" approver_id: type: "integer" nullable: true description: "The ID of the user who approved the post, if applicable" uploader_id: type: "integer" description: "The ID of the user who uploaded the post" uploader_name: type: "string" description: "The username of the user who uploaded the post" description: type: "string" description: "The description of the post" comment_count: type: "integer" description: "The number of comments on the post" is_favorited: type: "boolean" description: "Whether the post is favorited by the current user" has_notes: type: "boolean" description: "Whether the post has any notes attached" duration: type: "number" nullable: true description: "The duration of the post, if applicable" File: type: "object" required: - "width" - "height" - "ext" - "size" - "md5" - "url" properties: width: type: "integer" description: "The width of the file in pixels" height: type: "integer" description: "The height of the file in pixels" ext: $ref: "#/components/schemas/FileExt" size: type: "integer" description: "The size of the file in bytes" md5: type: "string" description: "The MD5 hash of the file" url: type: "string" description: "The URL of the file" Preview: type: "object" required: - "width" - "height" - "url" properties: width: type: "integer" description: "The width of the preview in pixels" height: type: "integer" description: "The height of the preview in pixels" url: type: "string" description: "The URL of the preview image" alt: type: "string" nullable: true description: "The URL of the WebP preview image" Sample: type: "object" required: - "has" - "height" - "width" - "url" properties: has: type: "boolean" description: "Whether the sample exists" height: type: "integer" description: "The height of the sample image in pixels" width: type: "integer" description: "The width of the sample image in pixels" url: type: "string" description: "The URL of the sample image" alt: type: "string" nullable: true description: "The URL of the WebP sample image" alternates: $ref: "#/components/schemas/SampleAlternates" Score: type: "object" required: - "up" - "down" - "total" properties: up: type: "integer" description: "The number of upvotes on the post" down: type: "integer" description: "The number of downvotes on the post" total: type: "integer" description: "The total score (upvotes minus downvotes)" Tags: type: "object" required: - "general" - "artist" - "contributor" - "copyright" - "character" - "species" - "invalid" - "meta" - "lore" properties: general: type: "array" items: type: "string" description: "An array of general tags" artist: type: "array" items: type: "string" description: "An array of artist tags" contributor: type: "array" items: type: "string" description: "An array of contributor tags" copyright: type: "array" items: type: "string" description: "An array of copyright tags" character: type: "array" items: type: "string" description: "An array of character tags" species: type: "array" items: type: "string" description: "An array of species tags" invalid: type: "array" items: type: "string" description: "An array of invalid tags" meta: type: "array" items: type: "string" description: "An array of meta tags" lore: type: "array" items: type: "string" description: "An array of lore tags" Flags: type: "object" required: - "pending" - "flagged" - "note_locked" - "status_locked" - "rating_locked" - "deleted" properties: pending: type: "boolean" description: "Whether the post is pending approval" flagged: type: "boolean" description: "Whether the post is flagged" note_locked: type: "boolean" description: "Whether notes on the post are locked" status_locked: type: "boolean" description: "Whether the status of the post is locked" rating_locked: type: "boolean" description: "Whether the rating of the post is locked" deleted: type: "boolean" description: "Whether the post is deleted" Relationships: type: "object" required: - "has_children" - "has_active_children" - "children" properties: parent_id: type: "integer" nullable: true description: "The ID of the parent post, if applicable" has_children: type: "boolean" description: "Whether the post has any child posts" has_active_children: type: "boolean" description: "Whether the post has any active child posts" children: type: "array" items: type: "integer" description: "An array of child post IDs" UserProfile: type: "object" description: "A detailed representation of a user." required: - "id" - "name" - "created_at" - "level" - "base_upload_limit" - "post_upload_count" - "post_update_count" - "note_update_count" - "is_banned" - "can_approve_posts" - "can_upload_free" - "level_string" properties: wiki_page_version_count: type: "integer" description: "Number of wiki page versions created by the user" artist_version_count: type: "integer" description: "Number of artist versions created by the user" pool_version_count: type: "integer" description: "Number of pool versions created by the user" forum_post_count: type: "integer" description: "Number of forum posts created by the user" comment_count: type: "integer" description: "Number of comments made by the user" flag_count: type: "integer" description: "Number of flags made by the user" favorite_count: type: "integer" description: "Number of favorites added by the user" positive_feedback_count: type: "integer" description: "Number of positive feedbacks received by the user" neutral_feedback_count: type: "integer" description: "Number of neutral feedbacks received by the user" negative_feedback_count: type: "integer" description: "Number of negative feedbacks received by the user" upload_limit: type: "integer" description: "The user's current upload limit" profile_about: type: "string" description: "The user's \"About\" profile section" profile_artinfo: type: "string" description: "The user's art information profile section" id: type: "integer" description: "The unique ID of the user" created_at: type: "string" format: "date-time" description: "The timestamp when the user account was created" name: type: "string" description: "The username of the user" level: type: "integer" description: "The user's access level (numerical)" base_upload_limit: type: "integer" description: "The base upload limit for the user" post_upload_count: type: "integer" description: "Number of posts uploaded by the user" post_update_count: type: "integer" description: "Number of post updates made by the user" note_update_count: type: "integer" description: "Number of note updates made by the user" is_banned: type: "boolean" description: "Whether the user is banned" can_approve_posts: type: "boolean" description: "Whether the user can approve posts" can_upload_free: type: "boolean" description: "Whether the user can upload without restrictions" level_string: type: "string" description: "The user's access level (textual description)" avatar_id: type: "integer" description: "The ID of the user's avatar image" is_verified: type: "boolean" description: "Whether the user has verified their email" has_cropped_avatar: type: "boolean" description: "Whether the user has a server-side cropped avatar" User: type: "object" description: "A simplified representation of a user with core attributes." required: - "id" - "created_at" - "name" - "level" - "base_upload_limit" - "post_upload_count" - "post_update_count" - "note_update_count" - "is_banned" - "can_approve_posts" - "can_upload_free" - "level_string" properties: id: type: "integer" description: "The unique ID of the user" created_at: type: "string" format: "date-time" description: "The timestamp when the user account was created" name: type: "string" description: "The username of the user" level: type: "integer" description: "The user's access level (numerical)" base_upload_limit: type: "integer" description: "The base upload limit for the user" post_upload_count: type: "integer" description: "Number of posts uploaded by the user" post_update_count: type: "integer" description: "Number of post updates made by the user" note_update_count: type: "integer" description: "Number of note updates made by the user" is_banned: type: "boolean" description: "Whether the user is banned" can_approve_posts: type: "boolean" description: "Whether the user can approve posts" can_upload_free: type: "boolean" description: "Whether the user can upload without restrictions" level_string: type: "string" description: "The user's access level (textual description)" avatar_id: type: "integer" description: "The ID of the user's avatar image" is_verified: type: "boolean" description: "Whether the user has verified their email" has_cropped_avatar: type: "boolean" description: "Whether the user has a server-side cropped avatar" Ticket: type: "object" description: "A ticket object representing a user complaint or moderation issue." required: - "id" - "creator_id" - "reason" - "disp_id" - "qtype" - "status" - "created_at" - "updated_at" - "response" - "handler_id" properties: id: type: "integer" description: "The unique ID of the ticket" creator_id: type: "integer" description: "The ID of the user who created the ticket" reason: type: "string" description: "The reason for the ticket" disp_id: type: "integer" description: "The ID of the reported content associated with the ticket" qtype: $ref: "#/components/schemas/TicketQtype" status: $ref: "#/components/schemas/TicketStatus" created_at: type: "string" format: "date-time" description: "The time when the ticket was created" updated_at: type: "string" format: "date-time" description: "The last time the ticket was updated" response: type: "string" description: "The response to the ticket" handler_id: type: "integer" description: "The ID of the user handling the ticket" claimant_id: type: "integer" nullable: true description: "The ID of the claimant user" report_reason: type: "string" nullable: true description: "The post report reason for the ticket" accused_id: type: "integer" nullable: true description: "The ID of the accused user" Appeal: type: "object" description: | An appeal raised against a moderation action (currently only flag appeals). Field visibility depends on viewer permissions: users without view access do not receive `creator_id`, `accused_id`, `reason`, or `response`; non-staff users do not receive `claimant_id`. required: - "id" - "creator_id" - "disp_id" - "qtype" - "status" - "reason" - "response" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the appeal" creator_id: type: "integer" description: "The ID of the user who created the appeal" creator_ip_addr: type: "string" description: "The IP address from which the appeal was created (staff only)" disp_id: type: "integer" description: "The ID of the appealed record (e.g. a PostFlag ID when `qtype=flag`)" qtype: $ref: "#/components/schemas/AppealQtype" status: $ref: "#/components/schemas/AppealStatus" reason: type: "string" description: "The reason given for the appeal" response: type: "string" description: "The handler's response to the appeal" claimant_id: type: "integer" nullable: true description: "The ID of the staff member currently claiming the appeal" handler_id: type: "integer" nullable: true description: "The ID of the staff member who last updated the appeal" accused_id: type: "integer" nullable: true description: "The ID of the user the appeal is filed against (e.g. the flag creator for flag appeals)" created_at: type: "string" format: "date-time" description: "The time the appeal was created" updated_at: type: "string" format: "date-time" description: "The last time the appeal was updated" UserFeedback: type: "object" description: "A user feedback object representing a piece of feedback left by a user." required: - "id" - "user_id" - "creator_id" - "created_at" - "body" - "category" - "updated_at" - "updater_id" - "is_deleted" properties: id: type: "integer" description: "The unique ID of the user feedback" user_id: type: "integer" description: "The ID of the user who received the feedback" creator_id: type: "integer" description: "The ID of the user who created the feedback" created_at: type: "string" format: "date-time" description: "The time when the feedback was created" body: type: "string" description: "The body of the feedback, containing the details" category: $ref: "#/components/schemas/UserFeedbackCategory" updated_at: type: "string" format: "date-time" description: "The last time the feedback was updated" updater_id: type: "integer" description: "The ID of the user who last updated the feedback" is_deleted: type: "boolean" description: "Whether the feedback is deleted" Approval: type: "object" description: "A post approval object representing a user's approval of a post." required: - "id" - "user_id" - "post_id" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the approval" user_id: type: "integer" description: "The ID of the user who approved the post" post_id: type: "integer" description: "The ID of the approved post" created_at: type: "string" format: "date-time" description: "The timestamp when the approval was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the approval was last updated" Upload: type: "object" description: "An upload object representing a user's uploaded content." required: - "id" - "source" - "rating" - "uploader_id" - "status" - "created_at" - "updated_at" - "file_ext" - "file_size" - "image_width" - "image_height" - "uploader_name" properties: id: type: "integer" description: "The unique ID of the upload" source: type: "string" description: "The source URL of the upload, if provided" rating: $ref: "#/components/schemas/PostRating" uploader_id: type: "integer" description: "The ID of the user who uploaded the content" tag_string: type: "string" description: "The tags associated with the upload" status: type: "string" description: "The current status of the upload. May include details like \"duplicate: 12345\" or \"error: message\"" backtrace: type: "string" nullable: true description: "Any backtrace or error details if applicable" post_id: type: "integer" nullable: true description: "The ID of the post generated by this upload, if applicable" md5_confirmation: type: "string" nullable: true description: "The MD5 confirmation hash for the upload, if applicable" created_at: type: "string" format: "date-time" description: "The timestamp when the upload was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the upload was last updated" parent_id: type: "integer" nullable: true description: "The ID of the parent post, if applicable" md5: type: "string" description: "The MD5 hash of the file" file_ext: type: "string" description: "The file extension (e.g., jpg, png, webm)" file_size: type: "integer" description: "The size of the file in bytes" image_width: type: "integer" description: "The width of the uploaded image in pixels" image_height: type: "integer" description: "The height of the uploaded image in pixels" description: type: "string" description: "A description of the uploaded content" uploader_name: type: "string" description: "The username of the uploader" PostFlag: type: "object" description: "A post flag object representing a user's flag or deletion of a post." required: - "id" - "created_at" - "post_id" - "reason" - "creator_id" - "is_resolved" - "updated_at" - "is_deletion" - "type" properties: id: type: "integer" description: "The unique ID of the post flag" created_at: type: "string" format: "date-time" description: "The timestamp when the post flag was created" post_id: type: "integer" description: "The ID of the post that the flag is related to" reason: type: "string" description: "The reason for the flag or deletion request" creator_id: type: "integer" description: "The ID of the user who created the flag or deletion request" is_resolved: type: "boolean" description: "Whether the flag has been resolved" updated_at: type: "string" format: "date-time" description: "The timestamp when the post flag was last updated" is_deletion: type: "boolean" description: "Whether the flag is a deletion request" type: $ref: "#/components/schemas/PostFlagType" note: type: "string" nullable: true description: "Additional explanation regarding the flag" PostVersion: type: "object" description: "A version of a post, representing changes made to the post." required: - "id" - "post_id" - "tags" - "updater_id" - "updated_at" - "rating" - "parent_id" - "source" - "description" - "version" - "updater_name" properties: id: type: "integer" description: "The unique ID of the post version" post_id: type: "integer" description: "The ID of the associated post" tags: type: "string" description: "The tags associated with the post version" updater_id: type: "integer" description: "The ID of the user who updated the post" updated_at: type: "string" format: "date-time" description: "The timestamp when the post version was updated" rating: $ref: "#/components/schemas/PostRating" parent_id: type: "integer" nullable: true description: "The ID of the parent post, if applicable" source: type: "string" description: "The source URL associated with the post version" description: type: "string" description: "The description of the post version" reason: type: "string" nullable: true description: "The reason for the update, if applicable" locked_tags: type: "string" nullable: true description: "The locked tags associated with the post version" added_tags: type: "array" items: type: "string" description: "An array of tags added in this version" removed_tags: type: "array" items: type: "string" description: "An array of tags removed in this version" added_locked_tags: type: "array" items: type: "string" description: "An array of locked tags added in this version" removed_locked_tags: type: "array" items: type: "string" description: "An array of locked tags removed in this version" rating_changed: type: "boolean" description: "Whether the rating was changed in this version" parent_changed: type: "boolean" description: "Whether the parent ID was changed in this version" source_changed: type: "boolean" description: "Whether the source was changed in this version" description_changed: type: "boolean" description: "Whether the description was changed in this version" version: type: "integer" description: "The version number of the post" updater_name: type: "string" description: "The username of the user who updated the post version" is_hidden: type: "boolean" description: "Whether this version is hidden" PostReplacement: type: "object" description: "A post replacement object representing a file replacement request for a post." required: - "id" - "created_at" - "updated_at" - "post_id" - "creator_id" - "file_ext" - "file_size" - "image_height" - "image_width" - "md5" - "source" - "file_name" - "status" - "reason" properties: id: type: "integer" description: "The unique ID of the post replacement" created_at: type: "string" format: "date-time" description: "The timestamp when the replacement was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the replacement was last updated" post_id: type: "integer" description: "The ID of the post associated with the replacement" creator_id: type: "integer" description: "The ID of the user who created the replacement" approver_id: type: "integer" nullable: true description: "The ID of the user who approved the replacement, if applicable" file_ext: type: "string" description: "The file extension of the replacement (e.g., jpg, png, webm)" file_size: type: "integer" description: "The size of the replacement file in bytes" image_height: type: "integer" description: "The height of the replacement image in pixels" image_width: type: "integer" description: "The width of the replacement image in pixels" md5: type: "string" description: "The MD5 hash of the replacement file" source: type: "string" description: "The source URLs for the replacement, separated by newlines" file_name: type: "string" description: "The name of the replacement file" status: $ref: "#/components/schemas/PostReplacementStatus" reason: type: "string" description: "The reason for the replacement request" ModAction: type: "object" description: "A moderation action representing administrative actions taken on the platform." required: - "id" - "creator_id" - "created_at" - "updated_at" - "action" - "values" properties: id: type: "integer" description: "The unique ID of the moderation action" creator_id: type: "integer" description: "The ID of the user who performed the moderation action" created_at: type: "string" format: "date-time" description: "The timestamp when the moderation action was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the moderation action was last updated" action: $ref: "#/components/schemas/ModActionAction" values: $ref: "#/components/schemas/ModActionValues" BulkUpdateRequest: type: "object" required: - "id" - "user_id" - "script" - "status" - "created_at" - "updated_at" - "title" properties: id: type: "integer" description: "The unique ID of the bulk update request" user_id: type: "integer" description: "The ID of the user who created the request" forum_topic_id: type: "integer" description: "The ID of the forum topic associated with the request" script: type: "string" description: "The script content of the bulk update request" status: $ref: "#/components/schemas/BulkUpdateRequestStatus" created_at: type: "string" format: "date-time" description: "The timestamp when the request was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the request was last updated" approver_id: type: "integer" nullable: true description: "The ID of the user who approved the request, if applicable" forum_post_id: type: "integer" description: "The ID of the forum post associated with the request" title: type: "string" description: "The title of the bulk update request" TagAlias: type: "object" required: - "id" - "antecedent_name" - "consequent_name" - "status" - "created_at" - "updated_at" - "creator_id" properties: id: type: "integer" description: "The unique ID of the tag alias" antecedent_name: type: "string" description: "The name of the antecedent tag" consequent_name: type: "string" description: "The name of the consequent tag" status: $ref: "#/components/schemas/TagAliasStatus" created_at: type: "string" format: "date-time" description: "The timestamp when the tag alias was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the tag alias was last updated" reason: type: "string" description: "The reason for creating the tag alias" creator_id: type: "integer" description: "The ID of the user who created the tag alias" approver_id: type: "integer" nullable: true description: "The ID of the user who approved the tag alias, if applicable" forum_post_id: type: "integer" description: "The ID of the associated forum post" forum_topic_id: type: "integer" description: "The ID of the associated forum topic" post_count: type: "integer" description: "The number of posts associated with the tag alias" TagImplication: type: "object" required: - "id" - "antecedent_name" - "consequent_name" - "status" - "created_at" - "updated_at" - "creator_id" properties: id: type: "integer" description: "The unique ID of the tag implication" antecedent_name: type: "string" description: "The name of the antecedent tag" consequent_name: type: "string" description: "The name of the consequent tag" status: $ref: "#/components/schemas/TagImplicationStatus" created_at: type: "string" format: "date-time" description: "The timestamp when the tag implication was created" updated_at: type: "string" format: "date-time" description: "The timestamp when the tag implication was last updated" reason: type: "string" description: "The reason for creating the tag implication" creator_id: type: "integer" description: "The ID of the user who created the tag implication" approver_id: type: "integer" nullable: true description: "The ID of the user who approved the tag implication, if applicable" forum_post_id: type: "integer" description: "The ID of the associated forum post" forum_topic_id: type: "integer" description: "The ID of the associated forum topic" descendant_names: type: "array" items: type: "string" description: "A list of descendant tag names derived from this implication" PostEvent: type: "object" required: - "id" - "creator_id" - "post_id" - "action" - "extra_data" - "created_at" properties: id: type: "integer" description: "The unique ID of the post event" creator_id: type: "integer" description: "The ID of the user who performed the action" post_id: type: "integer" description: "The ID of the post that was affected" action: $ref: "#/components/schemas/PostEventAction" extra_data: $ref: "#/components/schemas/PostEventExtraData" created_at: type: "string" format: "date-time" description: "The timestamp when the event occurred" Artist: type: "object" required: - "id" - "name" - "creator_id" - "is_active" - "is_locked" - "other_names" - "group_name" - "linked_user_id" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the artist" name: type: "string" description: "The artist's tag name" creator_id: type: "integer" description: "The ID of the user who created the artist entry" is_active: type: "boolean" description: "Whether the artist is active" is_locked: type: "boolean" description: "Whether the artist page is locked for editing" other_names: type: "array" items: type: "string" description: "Alternative names for the artist" group_name: type: "string" description: "The name of the artist group or circle" linked_user_id: type: "integer" nullable: true description: "The ID of the linked user account" created_at: type: "string" format: "date-time" description: "The time when the artist was created" updated_at: type: "string" format: "date-time" description: "The last time the artist was updated" urls: type: "array" items: $ref: "#/components/schemas/ArtistUrl" description: "The artist's URLs" ArtistUrl: type: "object" properties: id: type: "integer" description: "The unique ID of the URL entry" artist_id: type: "integer" description: "The ID of the associated artist" url: type: "string" description: "The URL" normalized_url: type: "string" description: "The normalized form of the URL" is_active: type: "boolean" description: "Whether the URL is active" created_at: type: "string" format: "date-time" description: "The time when the URL was added" updated_at: type: "string" format: "date-time" description: "The last time the URL was updated" EditHistory: type: "object" required: - "id" - "versionable_id" - "versionable_type" - "version" - "body" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the edit history entry" versionable_id: type: "integer" description: "The ID of the edited item" versionable_type: $ref: "#/components/schemas/GetEditHistoryType" user_id: type: "integer" description: "The ID of the user who made the edit" body: type: "string" description: "The body content at this version" subject: type: "string" nullable: true description: "The subject at this version (for forum posts)" version: type: "integer" description: "The version number" ip_addr: type: "string" nullable: true description: "The IP address of the editor" created_at: type: "string" format: "date-time" description: "The time when this version was created" updated_at: type: "string" format: "date-time" description: "The last time this version was updated" Comment: type: "object" required: - "id" - "post_id" - "creator_id" - "body" - "score" - "created_at" - "updated_at" - "updater_id" - "do_not_bump_post" - "is_hidden" - "is_sticky" properties: id: type: "integer" description: "The unique ID of the comment" post_id: type: "integer" description: "The ID of the post this comment belongs to" creator_id: type: "integer" description: "The ID of the user who created the comment" body: type: "string" description: "The comment body text" score: type: "integer" description: "The comment score" created_at: type: "string" format: "date-time" description: "The time when the comment was created" updated_at: type: "string" format: "date-time" description: "The last time the comment was updated" updater_id: type: "integer" nullable: true description: "The ID of the user who last updated the comment" do_not_bump_post: type: "boolean" description: "Whether the comment should not bump the post" is_hidden: type: "boolean" description: "Whether the comment is hidden" is_sticky: type: "boolean" description: "Whether the comment is sticky" warning_type: type: "integer" nullable: true description: "The type of warning applied to the comment" warning_user_id: type: "integer" nullable: true description: "The ID of the user who applied the warning" creator_name: type: "string" description: "The username of the comment creator" updater_name: type: "string" nullable: true description: "The username of the last updater" Blip: type: "object" required: - "id" - "creator_id" - "body" - "is_hidden" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the blip" creator_id: type: "integer" description: "The ID of the user who created the blip" body: type: "string" description: "The blip body text" response_to: type: "integer" nullable: true description: "The ID of the parent blip if this is a response" is_hidden: type: "boolean" description: "Whether the blip is hidden" created_at: type: "string" format: "date-time" description: "The time when the blip was created" updated_at: type: "string" format: "date-time" description: "The last time the blip was updated" warning_type: type: "integer" nullable: true description: "The type of warning applied to the blip" warning_user_id: type: "integer" nullable: true description: "The ID of the user who applied the warning" updater_id: type: "integer" nullable: true description: "The ID of the user who last updated the blip" creator_name: type: "string" description: "The username of the blip creator" ForumPost: type: "object" required: - "id" - "topic_id" - "creator_id" - "updater_id" - "body" - "is_hidden" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the forum post" topic_id: type: "integer" description: "The ID of the forum topic this post belongs to" creator_id: type: "integer" description: "The ID of the user who created the post" updater_id: type: "integer" description: "The ID of the user who last updated the post" body: type: "string" description: "The forum post body text" is_hidden: type: "boolean" description: "Whether the forum post is hidden" created_at: type: "string" format: "date-time" description: "The time when the forum post was created" updated_at: type: "string" format: "date-time" description: "The last time the forum post was updated" warning_type: type: "integer" nullable: true description: "The type of warning applied to the post" warning_user_id: type: "integer" nullable: true description: "The ID of the user who applied the warning" creator_name: type: "string" description: "The username of the post creator" updater_name: type: "string" description: "The username of the last updater" ForumTopic: type: "object" required: - "id" - "creator_id" - "updater_id" - "title" - "response_count" - "is_sticky" - "is_locked" - "is_hidden" - "created_at" - "updated_at" - "category_id" properties: id: type: "integer" description: "The unique ID of the forum topic" creator_id: type: "integer" description: "The ID of the user who created the topic" updater_id: type: "integer" description: "The ID of the user who last updated the topic" title: type: "string" description: "The topic title" response_count: type: "integer" description: "The number of responses in the topic" is_sticky: type: "boolean" description: "Whether the topic is sticky" is_locked: type: "boolean" description: "Whether the topic is locked" is_hidden: type: "boolean" description: "Whether the topic is hidden" created_at: type: "string" format: "date-time" description: "The time when the topic was created" updated_at: type: "string" format: "date-time" description: "The last time the topic was updated" category_id: type: "integer" description: "The forum category ID" creator_name: type: "string" description: "The username of the topic creator" updater_name: type: "string" description: "The username of the last updater" CommentVote: type: "object" required: - "id" - "comment_id" - "user_id" - "score" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the comment vote" comment_id: type: "integer" description: "The ID of the comment that was voted on" user_id: type: "integer" description: "The ID of the user who voted" score: $ref: "#/components/schemas/CommentVoteScore" created_at: type: "string" format: "date-time" description: "The time when the vote was cast" updated_at: type: "string" format: "date-time" description: "The last time the vote was updated" ForumPostVote: type: "object" required: - "id" - "forum_post_id" - "creator_id" - "score" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the forum post vote" forum_post_id: type: "integer" description: "The ID of the forum post that was voted on" creator_id: type: "integer" description: "The ID of the user who voted" score: $ref: "#/components/schemas/CommentVoteScore" created_at: type: "string" format: "date-time" description: "The time when the vote was cast" updated_at: type: "string" format: "date-time" description: "The last time the vote was updated" creator_name: type: "string" description: "The username of the voter" Tag: type: "object" required: - "id" - "name" - "post_count" - "category" - "is_locked" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the tag" name: type: "string" description: "The name of the tag" post_count: type: "integer" description: "The number of posts with this tag" category: type: "integer" description: "The category ID of the tag" related_tags: type: "string" nullable: true description: "Space-separated related tags with counts" related_tags_updated_at: type: "string" format: "date-time" nullable: true description: "When related tags were last updated" is_locked: type: "boolean" description: "Whether the tag category is locked" created_at: type: "string" format: "date-time" description: "When the tag was created" updated_at: type: "string" format: "date-time" description: "When the tag was last updated" TagTypeVersion: type: "object" required: - "id" - "tag_id" - "old_type" - "new_type" - "is_locked" - "creator_id" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the tag type version" tag_id: type: "integer" description: "The ID of the tag that was changed" old_type: type: "integer" description: "The previous category ID" new_type: type: "integer" description: "The new category ID" is_locked: type: "boolean" description: "Whether the tag was locked at time of change" creator_id: type: "integer" description: "The ID of the user who made the change" created_at: type: "string" format: "date-time" description: "When the change was made" updated_at: type: "string" format: "date-time" description: "When the record was last updated" WikiPage: type: "object" required: - "id" - "creator_id" - "title" - "body" - "is_locked" - "is_deleted" - "other_names" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the wiki page" creator_id: type: "integer" description: "The ID of the user who created the wiki page" creator_name: type: "string" description: "The username of the creator" title: type: "string" description: "The title of the wiki page" body: type: "string" description: "The body content of the wiki page" is_locked: type: "boolean" description: "Whether the wiki page is locked" is_deleted: type: "boolean" description: "Whether the wiki page is deleted" other_names: type: "array" items: type: "string" description: "Alternative names for the wiki page" updater_id: type: "integer" nullable: true description: "The ID of the user who last updated the wiki page" parent: type: "string" nullable: true description: "The parent wiki page title for redirects" category_id: type: "integer" nullable: true description: "The tag category ID associated with the wiki page" created_at: type: "string" format: "date-time" description: "When the wiki page was created" updated_at: type: "string" format: "date-time" description: "When the wiki page was last updated" WikiPageVersion: type: "object" required: - "id" - "wiki_page_id" - "updater_id" - "title" - "body" - "is_locked" - "is_deleted" - "other_names" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the wiki page version" wiki_page_id: type: "integer" description: "The ID of the wiki page" updater_id: type: "integer" description: "The ID of the user who made this version" title: type: "string" description: "The title at this version" body: type: "string" description: "The body content at this version" is_locked: type: "boolean" description: "Whether the page was locked at this version" is_deleted: type: "boolean" description: "Whether the page was deleted at this version" other_names: type: "array" items: type: "string" description: "Alternative names at this version" reason: type: "string" nullable: true description: "The edit reason for this version" parent: type: "string" nullable: true description: "The parent wiki page title at this version" created_at: type: "string" format: "date-time" description: "When this version was created" updated_at: type: "string" format: "date-time" description: "When this version was last updated" Note: type: "object" required: - "id" - "creator_id" - "post_id" - "x" - "y" - "width" - "height" - "is_active" - "body" - "version" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the note" creator_id: type: "integer" description: "The ID of the user who created the note" creator_name: type: "string" description: "The username of the creator" post_id: type: "integer" description: "The ID of the post the note is on" x: type: "integer" description: "X coordinate of the note" y: type: "integer" description: "Y coordinate of the note" width: type: "integer" description: "Width of the note" height: type: "integer" description: "Height of the note" is_active: type: "boolean" description: "Whether the note is active" body: type: "string" description: "The body text of the note" version: type: "integer" description: "The version number of the note" created_at: type: "string" format: "date-time" description: "When the note was created" updated_at: type: "string" format: "date-time" description: "When the note was last updated" NoteVersion: type: "object" required: - "id" - "note_id" - "post_id" - "updater_id" - "x" - "y" - "width" - "height" - "is_active" - "body" - "version" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the note version" note_id: type: "integer" description: "The ID of the note" post_id: type: "integer" description: "The ID of the post the note is on" updater_id: type: "integer" description: "The ID of the user who made this version" x: type: "integer" description: "X coordinate at this version" y: type: "integer" description: "Y coordinate at this version" width: type: "integer" description: "Width at this version" height: type: "integer" description: "Height at this version" is_active: type: "boolean" description: "Whether the note was active at this version" body: type: "string" description: "The body text at this version" version: type: "integer" description: "The version number" created_at: type: "string" format: "date-time" description: "When this version was created" updated_at: type: "string" format: "date-time" description: "When this version was last updated" Pool: type: "object" required: - "id" - "name" - "creator_id" - "is_active" - "post_ids" - "category" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the pool" name: type: "string" description: "The name of the pool" creator_id: type: "integer" description: "The ID of the pool creator" creator_name: type: "string" description: "The username of the pool creator" description: type: "string" description: "The pool description" is_active: type: "boolean" description: "Whether the pool is active" post_ids: type: "array" items: type: "integer" description: "Ordered array of post IDs in the pool" post_count: type: "integer" description: "The number of posts in the pool" category: $ref: "#/components/schemas/PoolCategory" created_at: type: "string" format: "date-time" description: "When the pool was created" updated_at: type: "string" format: "date-time" description: "When the pool was last updated" PoolVersion: type: "object" required: - "id" - "pool_id" - "post_ids" - "added_post_ids" - "removed_post_ids" - "version" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the pool version" pool_id: type: "integer" description: "The ID of the pool" post_ids: type: "array" items: type: "integer" description: "The full ordered list of post IDs at this version" added_post_ids: type: "array" items: type: "integer" description: "Post IDs added in this version" removed_post_ids: type: "array" items: type: "integer" description: "Post IDs removed in this version" updater_id: type: "integer" description: "The ID of the user who made this version" description: type: "string" nullable: true description: "The pool description at this version" description_changed: type: "boolean" description: "Whether the description was changed in this version" name: type: "string" nullable: true description: "The pool name at this version" name_changed: type: "boolean" description: "Whether the name was changed in this version" is_active: type: "boolean" description: "Whether the pool was active at this version" category: type: "string" nullable: true description: "The pool category at this version" version: type: "integer" description: "The version number" created_at: type: "string" format: "date-time" description: "When this version was created" updated_at: type: "string" format: "date-time" description: "When this version was last updated" PostSet: type: "object" required: - "id" - "name" - "shortname" - "is_public" - "creator_id" - "post_ids" - "post_count" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the post set" name: type: "string" description: "The name of the post set" shortname: type: "string" description: "The short name of the post set" description: type: "string" description: "The post set description" is_public: type: "boolean" description: "Whether the post set is publicly visible" transfer_on_delete: type: "boolean" description: "Whether to transfer favorites on delete" creator_id: type: "integer" description: "The ID of the set creator" post_ids: type: "array" items: type: "integer" description: "Ordered array of post IDs in the set" post_count: type: "integer" description: "The number of posts in the set" created_at: type: "string" format: "date-time" description: "When the post set was created" updated_at: type: "string" format: "date-time" description: "When the post set was last updated" PostVote: type: "object" description: "A vote on a post." required: - "id" - "post_id" - "user_id" - "score" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the vote" post_id: type: "integer" description: "The ID of the voted post" user_id: type: "integer" description: "The ID of the voting user" score: type: "integer" description: "The vote score (1, 0, or -1)" created_at: type: "string" format: "date-time" description: "When the vote was cast" updated_at: type: "string" format: "date-time" description: "When the vote was last updated" PostDisapproval: type: "object" description: "A disapproval of a pending post by an approver." required: - "id" - "post_id" - "user_id" - "reason" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the disapproval" post_id: type: "integer" description: "The ID of the disapproved post" user_id: type: "integer" description: "The ID of the disapproving user" reason: $ref: "#/components/schemas/PostDisapprovalReason" message: type: "string" nullable: true description: "Optional message explaining the disapproval" created_at: type: "string" format: "date-time" description: "When the disapproval was created" updated_at: type: "string" format: "date-time" description: "When the disapproval was last updated" Dmail: type: "object" description: "A direct message between users." required: - "id" - "owner_id" - "from_id" - "to_id" - "title" - "body" - "is_read" - "is_deleted" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the DMail" owner_id: type: "integer" description: "The ID of the user who owns this copy of the DMail" from_id: type: "integer" description: "The ID of the sender" to_id: type: "integer" description: "The ID of the recipient" title: type: "string" description: "The subject line of the DMail" body: type: "string" description: "The body text of the DMail" is_read: type: "boolean" description: "Whether the DMail has been read" is_deleted: type: "boolean" description: "Whether the DMail has been deleted" to_name: type: "string" description: "The recipient's username" from_name: type: "string" description: "The sender's username" created_at: type: "string" format: "date-time" description: "When the DMail was created" updated_at: type: "string" format: "date-time" description: "When the DMail was last updated" ApiKey: type: "object" description: "An API key for authenticating API requests." required: - "id" - "user_id" - "name" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the API key" user_id: type: "integer" description: "The ID of the user who owns the key" name: type: "string" description: "The name of the API key" key: type: "string" description: "The API key token (only shown on creation)" created_at: type: "string" format: "date-time" description: "When the API key was created" updated_at: type: "string" format: "date-time" description: "When the API key was last updated" last_used_at: type: "string" format: "date-time" nullable: true description: "When the API key was last used" last_ip_address: type: "string" nullable: true description: "The last IP address that used this key" expires_at: type: "string" format: "date-time" nullable: true description: "When the API key expires" Ban: type: "object" description: "A user ban record." required: - "id" - "user_id" - "banner_id" - "reason" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the ban" user_id: type: "integer" description: "The ID of the banned user" banner_id: type: "integer" description: "The ID of the staff member who issued the ban" reason: type: "string" description: "The reason for the ban" expires_at: type: "string" format: "date-time" nullable: true description: "When the ban expires (null for permanent bans)" created_at: type: "string" format: "date-time" description: "When the ban was created" updated_at: type: "string" format: "date-time" description: "When the ban was last updated" UserNameChangeRequest: type: "object" description: "A request to change a user's name." required: - "id" - "user_id" - "original_name" - "desired_name" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the name change request" status: type: "string" description: "The status of the request" user_id: type: "integer" description: "The ID of the user requesting the change" approver_id: type: "integer" nullable: true description: "The ID of the approving moderator" original_name: type: "string" description: "The user's original name" desired_name: type: "string" description: "The requested new name" change_reason: type: "string" nullable: true description: "The reason for the name change" rejection_reason: type: "string" nullable: true description: "The reason for rejecting the request" created_at: type: "string" format: "date-time" description: "When the request was created" updated_at: type: "string" format: "date-time" description: "When the request was last updated" StaffNote: type: "object" description: "A staff-only note on a user." required: - "id" - "user_id" - "creator_id" - "body" - "is_deleted" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the staff note" user_id: type: "integer" description: "The ID of the user the note is about" creator_id: type: "integer" description: "The ID of the staff member who created the note" updater_id: type: "integer" description: "The ID of the staff member who last updated the note" body: type: "string" description: "The body text of the staff note" is_deleted: type: "boolean" description: "Whether the staff note has been deleted" created_at: type: "string" format: "date-time" description: "When the staff note was created" updated_at: type: "string" format: "date-time" description: "When the staff note was last updated" AvoidPosting: type: "object" description: "An avoid posting (Do Not Post) entry for an artist." required: - "id" - "creator_id" - "updater_id" - "artist_id" - "is_active" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the avoid posting entry" creator_id: type: "integer" description: "The ID of the user who created the entry" updater_id: type: "integer" description: "The ID of the user who last updated the entry" artist_id: type: "integer" description: "The ID of the associated artist" details: type: "string" description: "Details about the avoid posting entry" staff_notes: type: "string" description: "Staff-only notes (hidden from non-staff users)" is_active: type: "boolean" description: "Whether the entry is active" created_at: type: "string" format: "date-time" description: "When the entry was created" updated_at: type: "string" format: "date-time" description: "When the entry was last updated" AvoidPostingVersion: type: "object" description: "A version history entry for an avoid posting record." required: - "id" - "updater_id" - "avoid_posting_id" - "is_active" - "updated_at" properties: id: type: "integer" description: "The unique ID of the version" updater_id: type: "integer" description: "The ID of the user who made this version" avoid_posting_id: type: "integer" description: "The ID of the associated avoid posting entry" details: type: "string" description: "Details at this version" staff_notes: type: "string" description: "Staff notes at this version (hidden from non-janitors)" is_active: type: "boolean" description: "Whether the entry was active at this version" updated_at: type: "string" format: "date-time" description: "When this version was created" Takedown: type: "object" description: "A takedown request. Most fields are hidden from non-staff users." required: - "id" - "status" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the takedown" status: $ref: "#/components/schemas/TakedownStatus" approver_id: type: "integer" nullable: true description: "The ID of the approving user" reason_hidden: type: "boolean" description: "Whether the reason is hidden" post_count: type: "integer" description: "The number of posts in the takedown" created_at: type: "string" format: "date-time" description: "When the takedown was created" updated_at: type: "string" format: "date-time" description: "When the takedown was last updated" IpBan: type: "object" description: "An IP address ban." required: - "id" - "creator_id" - "ip_addr" - "reason" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the IP ban" creator_id: type: "integer" description: "The ID of the staff member who created the ban" ip_addr: type: "string" description: "The banned IP address or CIDR range" reason: type: "string" description: "The reason for the ban" created_at: type: "string" format: "date-time" description: "When the ban was created" updated_at: type: "string" format: "date-time" description: "When the ban was last updated" ArtistVersion: type: "object" description: "A version history entry for an artist." required: - "id" - "artist_id" - "name" - "updater_id" - "is_active" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the version" artist_id: type: "integer" description: "The ID of the artist" name: type: "string" description: "The artist's name at this version" updater_id: type: "integer" description: "The ID of the user who made this version" is_active: type: "boolean" description: "Whether the artist was active at this version" group_name: type: "string" description: "The artist's group name at this version" other_names: type: "array" items: type: "string" description: "The artist's other names at this version" urls: type: "array" items: type: "string" description: "The artist's URLs at this version" notes_changed: type: "boolean" nullable: true description: "Whether the artist's notes were changed in this version" created_at: type: "string" format: "date-time" description: "When this version was created" updated_at: type: "string" format: "date-time" description: "When this version was last updated" UploadWhitelist: type: "object" description: "An upload whitelist entry controlling which domains are allowed for uploads." required: - "id" - "allowed" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the whitelist entry" domain: type: "string" description: "The domain pattern" path: type: "string" description: "The path pattern" note: type: "string" nullable: true description: "Note about the whitelist entry" reason: type: "string" nullable: true description: "The reason for the entry" allowed: type: "boolean" description: "Whether uploads from this domain are allowed" hidden: type: "boolean" description: "Whether the entry is hidden" created_at: type: "string" format: "date-time" description: "When the entry was created" updated_at: type: "string" format: "date-time" description: "When the entry was last updated" EmailBlacklist: type: "object" description: "A blacklisted email domain." required: - "id" - "domain" - "creator_id" - "reason" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the blacklist entry" domain: type: "string" description: "The blacklisted email domain" creator_id: type: "integer" description: "The ID of the staff member who created the entry" reason: type: "string" description: "The reason for blacklisting" created_at: type: "string" format: "date-time" description: "When the entry was created" updated_at: type: "string" format: "date-time" description: "When the entry was last updated" Mascot: type: "object" description: "A site mascot." required: - "id" - "creator_id" - "display_name" - "md5" - "file_ext" - "background_color" - "foreground_color" - "artist_url" - "artist_name" - "active" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the mascot" creator_id: type: "integer" description: "The ID of the user who created the mascot" display_name: type: "string" description: "The display name of the mascot" md5: type: "string" description: "The MD5 hash of the mascot image" file_ext: type: "string" description: "The file extension of the mascot image" background_color: type: "string" description: "Background color (hex)" foreground_color: type: "string" description: "Foreground color (hex)" artist_url: type: "string" description: "URL to the artist's page" artist_name: type: "string" description: "Name of the artist" active: type: "boolean" description: "Whether the mascot is active" available_on: type: "array" items: type: "string" description: "Sites the mascot is available on" is_layered: type: "boolean" description: "Whether the mascot is layered" url_path: type: "string" description: "URL path to the mascot image" created_at: type: "string" format: "date-time" description: "When the mascot was created" updated_at: type: "string" format: "date-time" description: "When the mascot was last updated" HelpPage: type: "object" description: "A help page linking to a wiki page." required: - "id" - "name" - "wiki_page" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the help page" name: type: "string" description: "The unique name identifier for the help page" wiki_page: type: "string" description: "The wiki page title this help page links to" related: type: "string" description: "Comma-separated related help page names" title: type: "string" description: "The display title for the help page" created_at: type: "string" format: "date-time" description: "When the help page was created" updated_at: type: "string" format: "date-time" description: "When the help page was last updated" NewsUpdate: type: "object" description: "A news update displayed on the site." required: - "id" - "message" - "creator_id" - "updater_id" - "created_at" - "updated_at" properties: id: type: "integer" description: "The unique ID of the news update" message: type: "string" description: "The news message content" creator_id: type: "integer" description: "The ID of the user who created the update" updater_id: type: "integer" description: "The ID of the user who last updated it" created_at: type: "string" format: "date-time" description: "When the news update was created" updated_at: type: "string" format: "date-time" description: "When the news update was last updated" RelatedTag: type: "object" description: "Related tags for a given query." properties: query: type: "string" description: "The query tag" category: type: "integer" nullable: true description: "The category ID filter" tags: type: "array" items: type: "array" items: type: "string" description: "A pair of [tag_name, tag_category_id]" description: "Array of related tag pairs" wiki_page_tags: type: "array" items: type: "string" description: "Tags found on the wiki page" PostV2Files: type: "object" description: "File information for a v2 Post payload." properties: meta: $ref: "#/components/schemas/PostV2FilesMeta" original: $ref: "#/components/schemas/PostV2FilesOriginal" preview: $ref: "#/components/schemas/PostV2FilesSample" sample: $ref: "#/components/schemas/PostV2FilesSample" video: $ref: "#/components/schemas/PostV2FilesVideo" PostV2Stats: type: "object" properties: score: $ref: "#/components/schemas/PostV2StatsScore" fav_count: type: "integer" is_favorited: type: "boolean" comment_count: type: "integer" PostV2Flags: type: "object" properties: pending: type: "boolean" flagged: type: "boolean" note_locked: type: "boolean" status_locked: type: "boolean" rating_locked: type: "boolean" deleted: type: "boolean" PostV2Has: type: "object" properties: parent: type: "boolean" children: type: "boolean" active_children: type: "boolean" notes: type: "boolean" sample: type: "boolean" PostV2Relationships: type: "object" properties: parent_id: type: "integer" nullable: true children: type: "array" items: type: "integer" PostV2Base: type: "object" description: "Common fields shared by the v2 basic and extended Post formats." properties: id: type: "integer" created_at: type: "string" format: "date-time" updated_at: type: "string" format: "date-time" change_seq: type: "integer" files: $ref: "#/components/schemas/PostV2Files" uploader_id: type: "integer" uploader_name: type: "string" approver_id: type: "integer" nullable: true stats: $ref: "#/components/schemas/PostV2Stats" flags: $ref: "#/components/schemas/PostV2Flags" has: $ref: "#/components/schemas/PostV2Has" relationships: $ref: "#/components/schemas/PostV2Relationships" pools: type: "array" items: type: "integer" rating: $ref: "#/components/schemas/PostRating" locked_tags: type: "array" items: type: "string" sources: type: "array" items: type: "string" description: type: "string" PostV2Basic: description: "Basic v2 Post payload (`v2=true`, `mode` unset or `basic`). Tags are a flat array of strings." allOf: - $ref: "#/components/schemas/PostV2Base" - type: "object" properties: tags: type: "array" items: type: "string" description: "All tags on the post." PostV2Extended: description: "Extended v2 Post payload (`v2=true`, `mode=extended`). Tags are grouped by category name." allOf: - $ref: "#/components/schemas/PostV2Base" - type: "object" properties: tags: type: "object" description: "Tags keyed by category name (`general`, `species`, `character`, `copyright`, `artist`, `invalid`, `lore`, `meta`)." additionalProperties: type: "array" items: type: "string" PostV2Thumbnail: type: "object" description: "Compact thumbnail v2 Post payload (`v2=true`, `mode=thumbnail` or `thumbnails`)." properties: id: type: "integer" created_at: type: "string" format: "date-time" md5: type: "string" file_ext: type: "string" width: type: "integer" height: type: "integer" size: type: "integer" preview_url: type: "string" nullable: true preview_webp: type: "string" nullable: true sample_url: type: "string" nullable: true file_url: type: "string" nullable: true preview_width: type: "integer" preview_height: type: "integer" uploader_id: type: "integer" uploader: type: "string" score: type: "integer" fav_count: type: "integer" is_favorited: type: "boolean" comment_count: type: "integer" flags: type: "string" description: "Space-separated subset of \"pending\", \"flagged\", and \"deleted\"." pools: type: "string" description: "Space-separated list of pool IDs." rating: $ref: "#/components/schemas/PostRating" tags: type: "string" description: "Space-separated tag string." IqdbQuery: type: "object" description: "An IQDB similarity match result. The shape of `post` depends on the request's `v2` parameter." properties: post_id: type: "integer" description: "The ID of the matching post" score: type: "number" description: "The similarity score" post: oneOf: - $ref: "#/components/schemas/Post" - $ref: "#/components/schemas/PostV2Basic" description: "Basic v2 Post format when `v2=true`, legacy Post format otherwise." PostRating: type: "string" description: "The rating of the post (e.g., safe, questionable, explicit)" enum: - "s" - "q" - "e" FileExt: type: "string" description: "The file extension (e.g., jpg, png, webm)" enum: - "jpg" - "png" - "gif" - "webm" - "mp4" - "swf" - "apng" SampleAlternates: type: "object" description: "Alternate versions of the sample for video posts" properties: has: type: "boolean" description: "Whether alternate versions exist" original: $ref: "#/components/schemas/SampleAlternatesOriginal" variants: $ref: "#/components/schemas/SampleAlternatesVariants" samples: $ref: "#/components/schemas/SampleAlternatesSamples" SampleAlternatesOriginal: type: "object" description: "The original video version" properties: codec: type: "string" nullable: true fps: type: "integer" size: type: "integer" width: type: "integer" height: type: "integer" url: type: "string" nullable: true SampleAlternatesVariants: type: "object" description: "Transcoded video variants keyed by name" additionalProperties: type: "object" properties: codec: type: "string" url: type: "string" nullable: true width: type: "integer" height: type: "integer" SampleAlternatesSamples: type: "object" description: "Sample versions keyed by name" additionalProperties: type: "object" properties: url: type: "string" nullable: true width: type: "integer" height: type: "integer" TicketQtype: type: "string" enum: - "user" - "comment" - "forum" - "blip" - "wiki" - "pool" - "set" - "post" - "dmail" - "replacement" description: "The type of ticket (e.g., comment, user, post)" AppealQtype: type: "string" enum: - "flag" description: "The kind of appeal" AppealStatus: type: "string" enum: - "pending" - "partial" - "approved" description: "The current status of the appeal" TicketStatus: type: "string" enum: - "pending" - "partial" - "approved" description: "The current status of the ticket" UserFeedbackCategory: type: "string" enum: - "negative" - "positive" - "neutral" description: "The category of the feedback (e.g., negative, positive, neutral)" PostFlagType: type: "string" description: "The type of the flag (e.g., flag or deletion)" enum: - "flag" - "deletion" PostReplacementStatus: type: "string" description: "The current status of the replacement" enum: - "original" - "pending" - "rejected" - "approved" - "promoted" ModActionAction: type: "string" description: "The type of moderation action performed" enum: - "admin_user_delete" - "artist_page_rename" - "artist_page_lock" - "artist_page_unlock" - "artist_user_linked" - "artist_user_unlinked" - "avoid_posting_create" - "avoid_posting_update" - "avoid_posting_delete" - "avoid_posting_undelete" - "avoid_posting_destroy" - "staff_note_create" - "staff_note_update" - "staff_note_delete" - "staff_note_undelete" - "blip_delete" - "blip_hide" - "blip_unhide" - "blip_update" - "comment_delete" - "comment_hide" - "comment_unhide" - "comment_update" - "forum_category_create" - "forum_category_delete" - "forum_category_update" - "forum_post_delete" - "forum_post_hide" - "forum_post_unhide" - "forum_post_update" - "forum_topic_delete" - "forum_topic_hide" - "forum_topic_unhide" - "forum_topic_lock" - "forum_topic_unlock" - "forum_topic_stick" - "forum_topic_unstick" - "forum_topic_update" - "help_create" - "help_delete" - "help_update" - "ip_ban_create" - "ip_ban_delete" - "mascot_create" - "mascot_update" - "mascot_delete" - "pool_delete" - "report_reason_create" - "report_reason_delete" - "report_reason_update" - "set_update" - "set_delete" - "set_change_visibility" - "tag_destroy" - "tag_alias_create" - "tag_alias_update" - "tag_implication_create" - "tag_implication_update" - "ticket_claim" - "ticket_unclaim" - "ticket_update" - "upload_whitelist_create" - "upload_whitelist_update" - "upload_whitelist_delete" - "user_uploads_toggle" - "user_blacklist_changed" - "user_text_change" - "user_upload_limit_change" - "user_flags_change" - "user_level_change" - "user_name_change" - "user_delete" - "user_ban" - "user_ban_update" - "user_unban" - "user_feedback_create" - "user_feedback_update" - "user_feedback_delete" - "user_feedback_undelete" - "user_feedback_destroy" - "user_flush_favorites" - "wiki_page_rename" - "wiki_page_delete" - "wiki_page_lock" - "wiki_page_unlock" - "mass_update" - "nuke_tag" - "takedown_delete" - "takedown_process" - "post_version_hide" - "post_version_unhide" ModActionValues: type: "object" description: "Additional details or parameters related to the moderation action" additionalProperties: type: "string" BulkUpdateRequestStatus: type: "string" description: "The current status of the request" enum: - "pending" - "approved" - "rejected" TagAliasStatus: type: "string" description: "The current status of the tag alias" enum: - "active" - "pending" - "deleted" - "retired" - "processing" - "queued" TagImplicationStatus: type: "string" description: "The current status of the tag implication" enum: - "active" - "pending" - "deleted" - "retired" - "processing" - "queued" PostEventAction: type: "string" description: "The action that was performed on the post" enum: - "deleted" - "undeleted" - "approved" - "unapproved" - "flag_created" - "flag_removed" - "favorites_moved" - "favorites_received" - "rating_locked" - "rating_unlocked" - "status_locked" - "status_unlocked" - "note_locked" - "note_unlocked" - "comment_locked" - "comment_unlocked" - "comment_disabled" - "comment_enabled" - "replacement_accepted" - "replacement_rejected" - "replacement_promoted" - "replacement_deleted" - "expunged" - "changed_bg_color" - "replacement_penalty_changed" PostEventExtraData: type: "object" nullable: true description: "Additional contextual data about the event" additionalProperties: true CommentVoteScore: type: "integer" description: "The vote score (1 for upvote, -1 for downvote, 0 for locked)" enum: - -1 - 0 - 1 PoolCategory: type: "string" enum: - "series" - "collection" description: "The pool category" PostDisapprovalReason: type: "string" description: "The reason for disapproval" enum: - "borderline_quality" - "borderline_relevancy" - "other" TakedownStatus: type: "string" description: "The status of the takedown" enum: - "pending" - "approved" - "denied" - "partial" PostV2FilesMeta: type: "object" properties: md5: type: "string" ext: type: "string" size: type: "integer" duration: type: "number" nullable: true has_sample: type: "boolean" PostV2FilesOriginal: type: "object" properties: width: type: "integer" height: type: "integer" url: type: "string" nullable: true PostV2FilesSample: type: "object" properties: width: type: "integer" height: type: "integer" jpg: type: "string" nullable: true webp: type: "string" nullable: true PostV2FilesVideo: type: "object" description: "Only present for video posts." nullable: true PostV2StatsScore: type: "object" properties: up: type: "integer" down: type: "integer" total: type: "integer" GetUsersSearchOrder: type: "string" enum: - "date" - "name" - "post_upload_count" - "note_count" - "post_update_count" CreateUserBody: type: "object" required: - "user" properties: user: $ref: "#/components/schemas/CreateUserBodyUser" CreateUserBodyUser: type: "object" required: - "name" - "email" - "password" - "password_confirmation" properties: name: type: "string" description: "The desired username" email: type: "string" description: "The user's email address" password: type: "string" description: "The password for the account" password_confirmation: type: "string" description: "Password confirmation" UpdateUserBody: type: "object" required: - "user" properties: user: $ref: "#/components/schemas/UpdateUserBodyUser" UpdateUserBodyUser: type: "object" properties: comment_threshold: type: "integer" description: "Score threshold below which comments are hidden" default_image_size: type: "string" description: "Default image display size" favorite_tags: type: "string" description: "User's favorite tags" blacklisted_tags: type: "string" description: "Tags to blacklist" time_zone: type: "string" description: "User's time zone" per_page: type: "integer" description: "Number of items per page" custom_style: type: "string" description: "Custom CSS style" description_collapsed_initially: type: "boolean" description: "Whether post descriptions are collapsed by default" hide_comments: type: "boolean" description: "Whether to hide comments by default" receive_email_notifications: type: "boolean" description: "Whether to receive email notifications" enable_keyboard_navigation: type: "boolean" description: "Whether keyboard navigation is enabled" enable_privacy_mode: type: "boolean" description: "Whether privacy mode is enabled" disable_user_dmails: type: "boolean" description: "Whether to disable user DMails" blacklist_users: type: "boolean" description: "Whether to blacklist users" show_post_statistics: type: "boolean" description: "Whether to show post statistics" style_usernames: type: "boolean" description: "Whether to style usernames by level" show_hidden_comments: type: "boolean" description: "Whether to show hidden comments" enable_auto_complete: type: "boolean" description: "Whether auto-complete is enabled" enable_safe_mode: type: "boolean" description: "Whether safe mode is enabled" disable_responsive_mode: type: "boolean" description: "Whether responsive mode is disabled" profile_about: type: "string" description: "User's about me text" profile_artinfo: type: "string" description: "User's artist info text" avatar_id: type: "integer" description: "Post ID to use as avatar" password: type: "string" description: "New password" old_password: type: "string" description: "Current password (required when changing password)" password_confirmation: type: "string" description: "New password confirmation" CreateApiKeyBody: type: "object" required: - "api_key" properties: api_key: $ref: "#/components/schemas/CreateApiKeyBodyApiKey" CreateApiKeyBodyApiKey: type: "object" required: - "name" properties: name: type: "string" description: "A name for the API key" expires_at: type: "string" format: "date-time" description: "When the API key should expire" duration: type: "string" description: "Duration preset (e.g. \"30\", \"90\", \"never\", \"custom\")" GetBansSearchOrder: type: "string" enum: - "expires_at_desc" CreateStaffNoteBody: type: "object" required: - "staff_note" properties: staff_note: $ref: "#/components/schemas/CreateStaffNoteBodyStaffNote" CreateStaffNoteBodyStaffNote: type: "object" required: - "body" properties: body: type: "string" description: "The body text of the staff note" UpdateTicketBody: type: "object" properties: ticket[response]: type: "string" description: "The response to the ticket" ticket[status]: $ref: "#/components/schemas/TicketStatus" ticket[record_type]: type: "string" description: "The type of record to apply if the ticket content is warnable" ticket[send_update_dmail]: type: "boolean" description: "Whether to send a DMail notification about the update" force_claim: type: "boolean" description: "Force claiming the ticket even if already claimed by another user" GetAppealsSearchStatus: type: "string" enum: - "pending" - "pending_unclaimed" - "pending_claimed" - "partial" - "approved" GetTicketsSearchStatus: type: "string" enum: - "pending" - "pending_unclaimed" - "pending_claimed" - "partial" - "approved" CreateAppealBody: type: "object" required: - "appeal" properties: appeal: $ref: "#/components/schemas/CreateAppealBodyAppeal" CreateAppealBodyAppeal: type: "object" required: - "qtype" - "disp_id" - "reason" properties: qtype: $ref: "#/components/schemas/AppealQtype" disp_id: type: "integer" description: "The ID of the appealed record (e.g. a PostFlag ID for `qtype=flag`)" reason: type: "string" description: "The reason for the appeal" UpdateAppealBody: type: "object" properties: appeal[response]: type: "string" description: "The response to the appeal" appeal[status]: $ref: "#/components/schemas/AppealStatus" appeal[send_update_dmail]: type: "boolean" description: "Whether to send a DMail notification about the update" force_claim: type: "boolean" description: "Force claiming the appeal even if already claimed by another user" UpdateUserFeedbackBody: type: "object" properties: user_feedback: $ref: "#/components/schemas/UpdateUserFeedbackBodyUserFeedback" UpdateUserFeedbackBodyUserFeedback: type: "object" properties: body: type: "string" description: "New feedback body (DText supported)" category: $ref: "#/components/schemas/UserFeedbackCategory" send_update_dmail: type: "boolean" description: "Send DMail notification to the user about the update" GetUploadsSearchStatus: type: "string" enum: - "completed" - "processing" - "pending" - "duplicate" - "error" CreatePostFlagBody: type: "object" required: - "post_flag" properties: post_flag: $ref: "#/components/schemas/CreatePostFlagBodyPostFlag" CreatePostFlagBodyPostFlag: type: "object" required: - "post_id" - "reason_name" properties: post_id: type: "integer" description: "The ID of the post to flag" reason_name: type: "string" description: "The reason for flagging" parent_id: type: "integer" description: "The parent post ID (for inferior duplicates)" note: type: "string" description: "Additional explanation for the flag" GetPostVersionsSearchRatingChanged: type: "string" enum: - "any" - "s" - "q" - "e" GetPostVersionsSearchUploads: type: "string" enum: - "only" - "included" - "excluded" GetUserFeedbacksSearchDeleted: type: "string" enum: - "included" - "excluded" - "only" GetPostReplacementsSearchStatus: type: "string" enum: - "pending" - "rejected" - "approved" - "promoted" CreatePostReplacementBody: type: "object" required: - "post_id" properties: post_id: type: "integer" description: "The ID of the post to replace" post_replacement[replacement_url]: type: "string" description: "URL of the replacement file" post_replacement[replacement_file]: type: "string" format: "binary" description: "The replacement file to upload" post_replacement[reason]: type: "string" description: "Reason for the replacement" post_replacement[source]: type: "string" description: "Source URL for the replacement" post_replacement[as_pending]: type: "boolean" description: "Whether to upload as pending" GetModActionsSearchAction: type: "string" enum: - "artist_page_rename" - "artist_page_lock" - "artist_page_unlock" - "artist_user_linked" - "artist_user_unlinked" - "avoid_posting_create" - "avoid_posting_update" - "avoid_posting_delete" - "avoid_posting_undelete" - "avoid_posting_destroy" - "blip_delete" - "blip_hide" - "blip_unhide" - "blip_update" - "comment_delete" - "comment_hide" - "comment_unhide" - "comment_update" - "forum_category_create" - "forum_category_delete" - "forum_category_update" - "forum_post_delete" - "forum_post_hide" - "forum_post_unhide" - "forum_post_update" - "forum_topic_delete" - "forum_topic_hide" - "forum_topic_unhide" - "forum_topic_lock" - "forum_topic_unlock" - "forum_topic_stick" - "forum_topic_unstick" - "forum_topic_update" - "help_create" - "help_delete" - "help_update" - "ip_ban_create" - "ip_ban_delete" - "mascot_create" - "mascot_update" - "mascot_delete" - "pool_delete" - "report_reason_create" - "report_reason_delete" - "report_reason_update" - "set_update" - "set_delete" - "set_change_visibility" - "tag_alias_create" - "tag_alias_update" - "tag_implication_create" - "tag_implication_update" - "ticket_claim" - "ticket_unclaim" - "ticket_update" - "upload_whitelist_create" - "upload_whitelist_update" - "upload_whitelist_delete" - "user_blacklist_changed" - "user_text_change" - "user_upload_limit_change" - "user_flags_change" - "user_level_change" - "user_name_change" - "user_delete" - "user_ban" - "user_ban_update" - "user_unban" - "user_feedback_create" - "user_feedback_update" - "user_feedback_delete" - "user_feedback_undelete" - "user_feedback_destroy" - "wiki_page_rename" - "wiki_page_delete" - "wiki_page_lock" - "wiki_page_unlock" - "mass_update" - "nuke_tag" - "takedown_delete" - "takedown_process" GetBulkUpdateRequestsSearchOrder: type: "string" enum: - "status_desc" - "updated_at_desc" - "id_desc" - "id_asc" CreateBulkUpdateRequestBody: type: "object" required: - "bulk_update_request[script]" properties: bulk_update_request[title]: type: "string" description: "The title of the request" bulk_update_request[script]: type: "string" description: "The BUR script content" bulk_update_request[reason]: type: "string" description: "The reason for the request" bulk_update_request[forum_topic_id]: type: "integer" description: "The forum topic ID to link to" bulk_update_request[skip_forum]: type: "boolean" description: "Skip forum post creation (admin only)" UpdateBulkUpdateRequestBody: type: "object" properties: bulk_update_request[script]: type: "string" description: "The BUR script content" bulk_update_request[forum_topic_id]: type: "integer" description: "The forum topic ID to link to (admin only)" bulk_update_request[forum_post_id]: type: "integer" description: "The forum post ID to link to (admin only)" GetTagAliasesSearchStatus: type: "string" enum: - "Approved" - "Active" - "Pending" - "Deleted" - "Retired" - "Processing" - "Queued" GetTagAliasesSearchOrder: type: "string" enum: - "id_desc" - "id_asc" - "status" - "created_at" - "updated_at" - "name" - "tag_count" GetTagImplicationsSearchOrder: type: "string" enum: - "id_desc" - "id_asc" - "status" - "created_at" - "updated_at" - "name" - "tag_count" GetTagImplicationsSearchStatus: type: "string" enum: - "Approved" - "Active" - "Pending" - "Deleted" - "Retired" - "Processing" - "Queued" GetArtistsSearchOrder: type: "string" enum: - "name" - "updated_at" - "post_count" - "created_at" GetEditHistoriesSearchOrder: type: "string" enum: - "updated_at" - "updated_at_desc" - "id" - "id_desc" GetEditHistoryType: type: "string" enum: - "Comment" - "ForumPost" - "Blip" SearchCommentsGroupBy: type: "string" enum: - "post" CreateCommentBody: type: "object" required: - "comment" properties: comment: $ref: "#/components/schemas/CreateCommentBodyComment" CreateCommentBodyComment: type: "object" required: - "body" - "post_id" properties: body: type: "string" description: "The comment body text" post_id: type: "integer" description: "The ID of the post to comment on" do_not_bump_post: type: "boolean" description: "Whether to bump the post" is_sticky: type: "boolean" description: "Whether the comment is sticky (janitor only)" is_hidden: type: "boolean" description: "Whether the comment is hidden (moderator only)" UpdateCommentBody: type: "object" required: - "comment" properties: comment: $ref: "#/components/schemas/UpdateCommentBodyComment" UpdateCommentBodyComment: type: "object" properties: body: type: "string" description: "The comment body text" is_sticky: type: "boolean" description: "Whether the comment is sticky (janitor only)" is_hidden: type: "boolean" description: "Whether the comment is hidden (moderator only)" CreateCommentVoteBody: type: "object" required: - "score" properties: score: $ref: "#/components/schemas/CreatePostVoteBodyScore" no_unvote: type: "boolean" description: "If true, do not unvote when voting again with the same score" CreateBlipBody: type: "object" required: - "blip" properties: blip: $ref: "#/components/schemas/CreateBlipBodyBlip" CreateBlipBodyBlip: type: "object" required: - "body" properties: body: type: "string" description: "The blip body text" response_to: type: "integer" description: "The ID of the blip to respond to" UpdateBlipBody: type: "object" required: - "blip" properties: blip: $ref: "#/components/schemas/UpdateBlipBodyBlip" UpdateBlipBodyBlip: type: "object" properties: body: type: "string" description: "The blip body text" WarningBlipRecordType: type: "string" enum: - "warning" - "record" - "ban" - "unmark" CreateForumTopicBody: type: "object" required: - "forum_topic" properties: forum_topic: $ref: "#/components/schemas/CreateForumTopicBodyForumTopic" CreateForumTopicBodyForumTopic: type: "object" required: - "title" - "category_id" - "original_post_attributes" properties: title: type: "string" description: "The topic title" category_id: type: "integer" description: "The forum category ID" original_post_attributes: $ref: "#/components/schemas/CreateStaffNoteBodyStaffNote" is_sticky: type: "boolean" description: "Whether the topic is sticky (moderator only)" is_locked: type: "boolean" description: "Whether the topic is locked (moderator only)" UpdateForumTopicBody: type: "object" required: - "forum_topic" properties: forum_topic: $ref: "#/components/schemas/UpdateForumTopicBodyForumTopic" UpdateForumTopicBodyForumTopic: type: "object" properties: title: type: "string" description: "The topic title" category_id: type: "integer" description: "The forum category ID" original_post_attributes: $ref: "#/components/schemas/UpdateForumTopicBodyForumTopicOriginalPostAttributes" is_sticky: type: "boolean" description: "Whether the topic is sticky (moderator only)" is_locked: type: "boolean" description: "Whether the topic is locked (moderator only)" UpdateForumTopicBodyForumTopicOriginalPostAttributes: type: "object" properties: id: type: "integer" description: "The ID of the original post" body: type: "string" description: "The body text of the opening post" CreateForumPostBody: type: "object" required: - "forum_post" properties: forum_post: $ref: "#/components/schemas/CreateForumPostBodyForumPost" CreateForumPostBodyForumPost: type: "object" required: - "body" - "topic_id" properties: body: type: "string" description: "The forum post body text" topic_id: type: "integer" description: "The ID of the forum topic to post in" UpdateForumPostBody: type: "object" required: - "forum_post" properties: forum_post: $ref: "#/components/schemas/UpdateBlipBodyBlip" CreateForumPostVoteBody: type: "object" required: - "forum_post_vote" properties: forum_post_vote: $ref: "#/components/schemas/CreateForumPostVoteBodyForumPostVote" CreateForumPostVoteBodyForumPostVote: type: "object" required: - "score" properties: score: $ref: "#/components/schemas/CommentVoteScore" SearchTagsSearchOrder: type: "string" enum: - "name" - "date" - "similarity" - "id_asc" - "id_desc" UpdateTagBody: type: "object" required: - "tag" properties: tag: $ref: "#/components/schemas/UpdateTagBodyTag" UpdateTagBodyTag: type: "object" properties: category: type: "integer" description: "The category ID for the tag" is_locked: type: "boolean" description: "Whether the tag is locked (admin only)" PreviewTagsBody: type: "object" properties: tags: type: "string" description: "The tags string to preview" SearchWikiPagesSearchOrder: type: "string" enum: - "title" - "post_count" CreateWikiPageBody: type: "object" required: - "wiki_page" properties: wiki_page: $ref: "#/components/schemas/CreateWikiPageBodyWikiPage" CreateWikiPageBodyWikiPage: type: "object" required: - "title" - "body" properties: title: type: "string" description: "The title of the wiki page" body: type: "string" description: "The body content of the wiki page" category_id: type: "integer" description: "The tag category ID" edit_reason: type: "string" description: "The reason for the edit" parent: type: "string" description: "The parent wiki page title (privileged+ only)" is_locked: type: "boolean" description: "Whether the page is locked (janitor+ only)" is_deleted: type: "boolean" description: "Whether the page is deleted (janitor+ only)" UpdateWikiPageBody: type: "object" required: - "wiki_page" properties: wiki_page: $ref: "#/components/schemas/UpdateWikiPageBodyWikiPage" UpdateWikiPageBodyWikiPage: type: "object" properties: body: type: "string" description: "The body content of the wiki page" category_id: type: "integer" description: "The tag category ID" edit_reason: type: "string" description: "The reason for the edit" parent: type: "string" description: "The parent wiki page title (privileged+ only)" title: type: "string" description: "The title of the wiki page (janitor+ only)" is_locked: type: "boolean" description: "Whether the page is locked (janitor+ only)" is_deleted: type: "boolean" description: "Whether the page is deleted (janitor+ only)" CreateNoteBody: type: "object" required: - "note" properties: note: $ref: "#/components/schemas/CreateNoteBodyNote" CreateNoteBodyNote: type: "object" required: - "post_id" - "x" - "y" - "width" - "height" - "body" properties: post_id: type: "integer" description: "The ID of the post to attach the note to" x: type: "integer" description: "X coordinate of the note" y: type: "integer" description: "Y coordinate of the note" width: type: "integer" description: "Width of the note" height: type: "integer" description: "Height of the note" body: type: "string" description: "The body text of the note" html_id: type: "string" description: "HTML element ID for the note" UpdateNoteBody: type: "object" required: - "note" properties: note: $ref: "#/components/schemas/UpdateNoteBodyNote" UpdateNoteBodyNote: type: "object" properties: x: type: "integer" description: "X coordinate of the note" y: type: "integer" description: "Y coordinate of the note" width: type: "integer" description: "Width of the note" height: type: "integer" description: "Height of the note" body: type: "string" description: "The body text of the note" CreatePoolBody: type: "object" required: - "pool" properties: pool: $ref: "#/components/schemas/CreatePoolBodyPool" CreatePoolBodyPool: type: "object" required: - "name" properties: name: type: "string" description: type: "string" category: $ref: "#/components/schemas/PoolCategory" is_active: type: "boolean" post_ids: type: "array" items: type: "integer" UpdatePoolBody: type: "object" required: - "pool" properties: pool: $ref: "#/components/schemas/UpdatePoolBodyPool" UpdatePoolBodyPool: type: "object" properties: name: type: "string" description: type: "string" category: $ref: "#/components/schemas/PoolCategory" is_active: type: "boolean" post_ids: type: "array" items: type: "integer" AddPoolElementBody: type: "object" required: - "post_id" properties: pool_id: type: "integer" description: "The ID of the pool" pool_name: type: "string" description: "The name of the pool (alternative to pool_id)" post_id: type: "integer" description: "The ID of the post to add" SearchPostSetsSearchOrder: type: "string" enum: - "name" - "shortname" - "post_count" - "created_at" - "updated_at" CreatePostSetBody: type: "object" required: - "post_set" properties: post_set: $ref: "#/components/schemas/CreatePostSetBodyPostSet" CreatePostSetBodyPostSet: type: "object" required: - "name" - "shortname" properties: name: type: "string" shortname: type: "string" description: type: "string" is_public: type: "boolean" transfer_on_delete: type: "boolean" UpdatePostSetBody: type: "object" required: - "post_set" properties: post_set: $ref: "#/components/schemas/UpdatePostSetBodyPostSet" UpdatePostSetBodyPostSet: type: "object" properties: name: type: "string" shortname: type: "string" description: type: "string" is_public: type: "boolean" transfer_on_delete: type: "boolean" AddPostSetPostsBody: type: "object" required: - "post_ids" properties: post_ids: type: "array" items: type: "integer" description: "The IDs of posts to add" AddFavoriteBody: type: "object" required: - "post_id" properties: post_id: type: "integer" description: "The ID of the post to favorite" LockPostVotesBody: type: "object" required: - "ids" properties: ids: type: "string" description: "Comma-separated list of post vote IDs to lock" CreatePostVoteBody: type: "object" required: - "score" properties: score: $ref: "#/components/schemas/CreatePostVoteBodyScore" no_unvote: type: "boolean" description: "If true, do not remove an existing identical vote" CreatePostVoteBodyScore: type: "integer" description: "The vote score (1 for upvote, -1 for downvote)" enum: - 1 - -1 ResolvePostFlagApproval: type: "string" enum: - "approve" CreatePostDisapprovalBody: type: "object" required: - "post_disapproval" properties: post_disapproval: $ref: "#/components/schemas/CreatePostDisapprovalBodyPostDisapproval" CreatePostDisapprovalBodyPostDisapproval: type: "object" required: - "post_id" - "reason" properties: post_id: type: "integer" description: "The ID of the post to disapprove" reason: $ref: "#/components/schemas/PostDisapprovalReason" message: type: "string" description: "Optional message explaining the disapproval" ModeratorDeletePostBody: type: "object" required: - "reason" - "commit" properties: reason: type: "string" description: "The reason for deleting the post" commit: $ref: "#/components/schemas/ModeratorDeletePostBodyCommit" from_flag: type: "string" description: "Set if the deletion originates from a flag" copy_sources: type: "boolean" description: "Copy sources to the parent post" copy_tags: type: "boolean" description: "Copy tags to the parent post" move_favorites: type: "boolean" description: "Move favorites and post sets to the parent post" ModeratorDeletePostBodyCommit: type: "string" description: "Must be \"Delete\" to confirm deletion" enum: - "Delete" ModeratorExpungePostBody: type: "object" properties: reason: type: "string" description: "The reason for expunging the post" ModeratorMoveFavoritesBody: type: "object" required: - "commit" properties: commit: $ref: "#/components/schemas/ModeratorMoveFavoritesBodyCommit" ModeratorMoveFavoritesBodyCommit: type: "string" description: "Must be \"Submit\" to confirm the transfer" enum: - "Submit" GetAvoidPostingsSearchOrder: type: "string" enum: - "artist_name" - "artist_name_asc" - "artist_name_desc" - "created_at" - "updated_at" CreateAvoidPostingBody: type: "object" properties: avoid_posting[details]: type: "string" description: "Details about the avoid posting entry" avoid_posting[staff_notes]: type: "string" description: "Staff-only notes" avoid_posting[is_active]: type: "boolean" description: "Whether the entry is active" avoid_posting[artist_attributes][name]: type: "string" description: "The artist's name" avoid_posting[artist_attributes][other_names_string]: type: "string" description: "Other names for the artist (space-separated)" avoid_posting[artist_attributes][group_name]: type: "string" description: "The artist's group name" avoid_posting[artist_attributes][linked_user_id]: type: "integer" description: "The ID of the linked user" UpdateAvoidPostingBody: type: "object" properties: avoid_posting[details]: type: "string" description: "Details about the avoid posting entry" avoid_posting[staff_notes]: type: "string" description: "Staff-only notes" avoid_posting[is_active]: type: "boolean" description: "Whether the entry is active" GetTakedownsSearchOrder: type: "string" enum: - "status" - "post_count" UpdateTakedownBody: type: "object" properties: takedown[notes]: type: "string" description: "Staff notes for the takedown" takedown[reason_hidden]: type: "boolean" description: "Whether to hide the reason" takedown_posts: $ref: "#/components/schemas/UpdateTakedownBodyTakedownPosts" process_takedown: type: "boolean" description: "Whether to process the takedown" delete_reason: type: "string" description: "Reason for deleting posts" UpdateTakedownBodyTakedownPosts: type: "object" description: "Map of post IDs to keep/delete status" AddTakedownPostsByIdsBody: type: "object" properties: post_ids: type: "string" description: "Space-separated post IDs or URLs to add" AddTakedownPostsByTagsBody: type: "object" properties: post_tags: type: "string" description: "Tag query to find posts to add" CreateIpBanBody: type: "object" required: - "ip_ban[ip_addr]" - "ip_ban[reason]" properties: ip_ban[ip_addr]: type: "string" description: "The IP address or CIDR range to ban" ip_ban[reason]: type: "string" description: "The reason for the ban" GetArtistVersionsSearchOrder: type: "string" enum: - "name" GetUploadWhitelistsSearchOrder: type: "string" enum: - "domain" - "path" - "updated_at" - "created_at" CreateUploadWhitelistBody: type: "object" properties: upload_whitelist[allowed]: type: "boolean" description: "Whether uploads from this domain are allowed" upload_whitelist[domain]: type: "string" description: "The domain pattern" upload_whitelist[path]: type: "string" description: "The path pattern" upload_whitelist[reason]: type: "string" description: "The reason for the whitelist entry" upload_whitelist[note]: type: "string" description: "Note about the whitelist entry" upload_whitelist[hidden]: type: "boolean" description: "Whether the entry is hidden" GetPopularPostsScale: type: "string" enum: - "day" - "week" - "month" GetIqdbQueryV2: type: "string" enum: - "true" PostIqdbQueryBody: type: "object" properties: search[file]: type: "string" format: "binary" description: "An image file to find similar images for" search[url]: type: "string" description: "Find images similar to the image at this URL" search[post_id]: type: "integer" description: "Find images similar to this post" search[hash]: type: "string" description: "Find images similar to this perceptual hash" search[score_cutoff]: type: "number" description: "Minimum similarity score threshold" PostRelatedTagBulkBody: type: "object" properties: query: type: "string" description: "The tag query for bulk related tag lookup" category_id: type: "integer" description: "Filter by tag category ID" CreateDtextPreviewBody: type: "object" properties: body: type: "string" description: "The DText markup to render" allow_color: type: "boolean" description: "Whether to allow color tags" CreateMascotBody: type: "object" required: - "mascot[mascot_file]" - "mascot[display_name]" - "mascot[artist_url]" - "mascot[artist_name]" properties: mascot[mascot_file]: type: "string" format: "binary" description: "The mascot image file" mascot[display_name]: type: "string" description: "Display name for the mascot" mascot[background_color]: type: "string" description: "Background color (hex)" mascot[foreground_color]: type: "string" description: "Foreground color (hex)" mascot[is_layered]: type: "boolean" description: "Whether the mascot is layered" mascot[artist_url]: type: "string" description: "URL to the artist's page" mascot[artist_name]: type: "string" description: "Name of the artist" mascot[available_on_string]: type: "string" description: "Comma-separated list of sites the mascot is available on" mascot[active]: type: "boolean" description: "Whether the mascot is active" UpdateMascotBody: type: "object" properties: mascot[mascot_file]: type: "string" format: "binary" description: "The mascot image file" mascot[display_name]: type: "string" description: "Display name for the mascot" mascot[background_color]: type: "string" description: "Background color (hex)" mascot[foreground_color]: type: "string" description: "Foreground color (hex)" mascot[is_layered]: type: "boolean" description: "Whether the mascot is layered" mascot[artist_url]: type: "string" description: "URL to the artist's page" mascot[artist_name]: type: "string" description: "Name of the artist" mascot[available_on_string]: type: "string" description: "Comma-separated list of sites the mascot is available on" mascot[active]: type: "boolean" description: "Whether the mascot is active" CreateHelpPageBody: type: "object" required: - "help_page[name]" - "help_page[wiki_page]" properties: help_page[name]: type: "string" description: "The unique name identifier for the help page" help_page[wiki_page]: type: "string" description: "The wiki page title to link to" help_page[related]: type: "string" description: "Comma-separated related help page names" help_page[title]: type: "string" description: "The display title for the help page" UpdateHelpPageBody: type: "object" properties: help_page[name]: type: "string" description: "The unique name identifier for the help page" help_page[wiki_page]: type: "string" description: "The wiki page title to link to" help_page[related]: type: "string" description: "Comma-separated related help page names" help_page[title]: type: "string" description: "The display title for the help page" GetEmailBlacklistsSearchOrder: type: "string" enum: - "reason" - "domain" CreateEmailBlacklistBody: type: "object" required: - "email_blacklist[domain]" - "email_blacklist[reason]" properties: email_blacklist[domain]: type: "string" description: "The email domain to blacklist" email_blacklist[reason]: type: "string" description: "The reason for blacklisting"