tstor/daemons/kemono/client/spec.json
royalcat 585f317478
Some checks failed
docker / build-docker (push) Failing after 34s
daemons separation
2024-11-24 20:32:26 +03:00

2079 lines
No EOL
102 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"openapi": "3.0.1",
"info": {
"title": "Kemono API",
"version": "1.0.0"
},
"contact": {
"email": "contact@kemono.party"
},
"servers": [
{
"url": "https://kemono.su/api/v1"
},
{
"url": "https://coomer.su/api/v1"
}
],
"tags": [
{
"name": "Posts",
"description": "Version one"
},
{
"name": "Creators"
},
{
"name": "Comments"
},
{
"name": "Post Flagging",
"description": "Flag post for re-import"
},
{
"name": "Discord"
},
{
"name": "Favorites"
},
{
"name": "File Search"
},
{
"name": "Misc"
}
],
"paths": {
"/creators.txt": {
"get": {
"tags": [
"Posts"
],
"summary": "List All Creators",
"description": "List all creators with details. I blame DDG for .txt.",
"responses": {
"200": {
"description": "List of all creators",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"favorited": {
"type": "integer",
"description": "The number of times this creator has been favorited"
},
"id": {
"type": "string",
"description": "The ID of the creator"
},
"indexed": {
"type": "number",
"description": "Timestamp when the creator was indexed, Unix time as integer"
},
"name": {
"type": "string",
"description": "The name of the creator"
},
"service": {
"type": "string",
"description": "The service for the creator"
},
"updated": {
"type": "number",
"description": "Timestamp when the creator was last updated, Unix time as integer"
}
}
}
},
"example": [
{
"favorited": 1,
"id": "21101760",
"indexed": 1672534800,
"name": "RAIGYO",
"service": "fanbox",
"updated": 1672534800
}
]
}
}
}
}
}
},
"/posts": {
"get": {
"tags": [
"Posts"
],
"summary": "List recent posts",
"description": "List of recently imported posts",
"parameters": [
{
"name": "q",
"in": "query",
"description": "Search query",
"schema": {
"type": "string",
"minLength": 3
}
},
{
"name": "o",
"in": "query",
"description": "Result offset, stepping of 50 is enforced",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "List of recently added posts",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"user": {
"type": "string"
},
"service": {
"type": "string"
},
"title": {
"type": "string"
},
"content": {
"type": "string"
},
"embed": {
"type": "object"
},
"shared_file": {
"type": "boolean"
},
"added": {
"type": "string",
"format": "date-time"
},
"published": {
"type": "string",
"format": "date-time"
},
"edited": {
"type": "string",
"format": "date-time"
},
"file": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
}
}
}
},
"example": [
{
"id": "1836570",
"user": "6570768",
"service": "fanbox",
"title": "今日はFANBOXを始まりました",
"content": "<p>みなさんこんにちは、影おじです。</p><p>先週のように、FANBOXを始まりに決定しました</p><p>そしてFANBOXの更新内容について、アンケートのみなさん</p><p>ありがとうございました!</p><p><br/></p><p>では更新内容の詳しいことはこちらです↓</p><p>毎回の絵、元も差分がありませんの場合、ボナスとして差分イラストを支援者の皆様にプレゼント。</p><p>もとも差分があれば、ボナスとしてヌード差分イラストを支援者の皆様にプレゼント。</p><p><br/></p><p>これから、仕事以外の時間、できる限り勤勉な更新したいと思います!</p><p>どうぞよろしくお願いいたします!</p>",
"embed": {},
"shared_file": false,
"added": "2021-03-30T18:00:05.973913",
"published": "2021-01-24T17:54:38",
"edited": "2021-01-24T18:46:15",
"file": {
"name": "a99d9674-5490-400e-acca-4bed99590699.jpg",
"path": "/5c/98/5c984d1f62f0990a0891d8fa359aecdff6ac1e26ac165ba7bb7f31cc99e7a674.jpg"
},
"attachments": []
},
{
"id": "1836649",
"user": "6570768",
"service": "fanbox",
"title": "忍ちゃん 脇コキ差分",
"content": "",
"embed": {},
"shared_file": false,
"added": "2021-03-30T17:59:57.815397",
"published": "2021-01-24T18:23:12",
"edited": "2023-01-04T14:45:19",
"file": {
"name": "4c5615f9-be74-4fa7-b88d-168fd37a2824.jpg",
"path": "/d0/3c/d03c893927521536646619f5fb33426aa4b82dc12869865d6d666932755d9acd.jpg"
},
"attachments": [
{
"name": "9cc982e4-1d94-4a1a-ac62-3dddd29f881c.png",
"path": "/d7/4d/d74d1727f2c3fcf7a7cc2d244d677d93b4cc562a56904765e4e708523b34fb4c.png"
},
{
"name": "ab0e17d7-52e5-42c2-925b-5cfdb451df0c.png",
"path": "/1b/67/1b677a8c0525e386bf2b2f013e36e29e4033feb2308798e4e5e3780da6c0e815.png"
}
]
}
]
}
}
}
}
}
},
"/{service}/user/{creator_id}/profile": {
"get": {
"summary": "Get a creator",
"tags": [
"Creators"
],
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the creator is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Creator details retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The ID of the creator"
},
"public_id": {
"type": "string",
"nullable": true,
"description": "The public ID of the creator"
},
"service": {
"type": "string",
"description": "The service where the creator is located"
},
"name": {
"type": "string",
"description": "The creator's display name"
},
"indexed": {
"type": "string",
"format": "date-time",
"description": "The time the creator was last indexed"
},
"updated": {
"type": "string",
"format": "date-time",
"description": "The time the creator was last updated"
}
}
}
}
}
},
"404": {
"description": "The creator could not be found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "The error message",
"enum": [
"Creator not found."
]
}
}
}
}
}
}
}
}
},
"/{service}/user/{creator_id}": {
"get": {
"summary": "Get a list of creator posts",
"tags": [
"Posts"
],
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the post is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "q",
"in": "query",
"description": "Search query",
"schema": {
"type": "string",
"minLength": 3
}
},
{
"name": "o",
"in": "query",
"description": "Result offset, stepping of 50 is enforced",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Post details retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"user": {
"type": "string"
},
"service": {
"type": "string"
},
"title": {
"type": "string"
},
"content": {
"type": "string"
},
"embed": {
"type": "object"
},
"shared_file": {
"type": "boolean"
},
"added": {
"type": "string",
"format": "date-time"
},
"published": {
"type": "string",
"format": "date-time"
},
"edited": {
"type": "string",
"format": "date-time"
},
"file": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
}
}
}
},
"example": [
{
"id": "1836570",
"user": "6570768",
"service": "fanbox",
"title": "今日はFANBOXを始まりました",
"content": "<p>みなさんこんにちは、影おじです。</p><p>先週のように、FANBOXを始まりに決定しました</p><p>そしてFANBOXの更新内容について、アンケートのみなさん</p><p>ありがとうございました!</p><p><br/></p><p>では更新内容の詳しいことはこちらです↓</p><p>毎回の絵、元も差分がありませんの場合、ボナスとして差分イラストを支援者の皆様にプレゼント。</p><p>もとも差分があれば、ボナスとしてヌード差分イラストを支援者の皆様にプレゼント。</p><p><br/></p><p>これから、仕事以外の時間、できる限り勤勉な更新したいと思います!</p><p>どうぞよろしくお願いいたします!</p>",
"embed": {},
"shared_file": false,
"added": "2021-03-30T18:00:05.973913",
"published": "2021-01-24T17:54:38",
"edited": "2021-01-24T18:46:15",
"file": {
"name": "a99d9674-5490-400e-acca-4bed99590699.jpg",
"path": "/5c/98/5c984d1f62f0990a0891d8fa359aecdff6ac1e26ac165ba7bb7f31cc99e7a674.jpg"
},
"attachments": []
},
{
"id": "1836649",
"user": "6570768",
"service": "fanbox",
"title": "忍ちゃん 脇コキ差分",
"content": "",
"embed": {},
"shared_file": false,
"added": "2021-03-30T17:59:57.815397",
"published": "2021-01-24T18:23:12",
"edited": "2023-01-04T14:45:19",
"file": {
"name": "4c5615f9-be74-4fa7-b88d-168fd37a2824.jpg",
"path": "/d0/3c/d03c893927521536646619f5fb33426aa4b82dc12869865d6d666932755d9acd.jpg"
},
"attachments": [
{
"name": "9cc982e4-1d94-4a1a-ac62-3dddd29f881c.png",
"path": "/d7/4d/d74d1727f2c3fcf7a7cc2d244d677d93b4cc562a56904765e4e708523b34fb4c.png"
},
{
"name": "ab0e17d7-52e5-42c2-925b-5cfdb451df0c.png",
"path": "/1b/67/1b677a8c0525e386bf2b2f013e36e29e4033feb2308798e4e5e3780da6c0e815.png"
}
]
}
]
}
}
},
"400": {
"description": "Offset provided which is not a multiple of 50"
},
"404": {
"description": "The creator could not be found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "The error message",
"enum": [
"Creator not found."
]
}
}
}
}
}
}
}
}
},
"/{service}/user/{creator_id}/announcements": {
"get": {
"summary": "Get creator announcements",
"tags": [
"Posts"
],
"parameters": [
{
"name": "service",
"in": "path",
"required": true,
"description": "The service name",
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"required": true,
"description": "The creator's ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"service": {
"type": "string"
},
"user_id": {
"type": "string"
},
"hash": {
"type": "string",
"description": "sha256"
},
"content": {
"type": "string"
},
"added": {
"type": "string",
"format": "date-time",
"description": "isoformat UTC"
}
}
}
},
"example": [
{
"service": "patreon",
"user_id": "8693043",
"hash": "820b7397c7f75efb13c4a8aa5d4aacfbb200749f3e1cec16e9f2951d158be8c2",
"content": "Hey guys, thank you so much for your support, that means a lot to me!",
"added": "2023-01-31T05:16:15.462035"
}
]
}
}
},
"404": {
"description": "Artist not found"
}
}
}
},
"/{service}/user/{creator_id}/fancards": {
"get": {
"summary": "Get fancards by creator, fanbox only",
"tags": [
"Posts"
],
"parameters": [
{
"name": "service",
"in": "path",
"required": true,
"description": "The service name, has to be \"fanbox\"",
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"required": true,
"description": "The creator's ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"user_id": {
"type": "string"
},
"file_id": {
"type": "integer"
},
"hash": {
"type": "string"
},
"mtime": {
"type": "string",
"format": "date-time"
},
"ctime": {
"type": "string",
"format": "date-time"
},
"mime": {
"type": "string"
},
"ext": {
"type": "string"
},
"added": {
"type": "string",
"format": "date-time"
},
"size": {
"type": "integer"
},
"ihash": {
"type": "string"
}
}
}
},
"example": [
{
"id": 108058645,
"user_id": "3316400",
"file_id": 108058645,
"hash": "727bf3f0d774a98c80cf6c76c3fb0e049522b88eb7f02c8d3fc59bae20439fcf",
"mtime": "2023-05-23T15:09:43.941195",
"ctime": "2023-05-23T15:09:43.941195",
"mime": "image/jpeg",
"ext": ".jpg",
"added": "2023-05-23T15:09:43.960578",
"size": 339710,
"ihash": null
},
{
"id": 103286760,
"user_id": "3316400",
"file_id": 103286760,
"hash": "8b0d0f1be38efab9306b32c7b14b74ddd92a2513026c859a280fe737980a467d",
"mtime": "2023-04-26T14:16:53.205183",
"ctime": "2023-04-26T14:16:53.205183",
"mime": "image/jpeg",
"ext": ".jpg",
"added": "2023-04-26T14:16:53.289143",
"size": 339764,
"ihash": null
}
]
}
}
},
"404": {
"description": "Artist not found"
}
}
}
},
"/{service}/user/{creator_id}/links": {
"get": {
"summary": "Get a creator's linked accounts",
"tags": [
"Creators"
],
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the creator is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Linked accounts retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The ID of the creator"
},
"public_id": {
"type": "string",
"nullable": true,
"description": "The public ID of the creator"
},
"service": {
"type": "string",
"description": "The service where the creator is located"
},
"name": {
"type": "string",
"description": "The creator's display name"
},
"indexed": {
"type": "string",
"format": "date-time",
"description": "The time the creator was last indexed"
},
"updated": {
"type": "string",
"format": "date-time",
"description": "The time the creator was last updated"
}
}
}
}
}
}
},
"404": {
"description": "The creator could not be found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "The error message",
"enum": [
"Creator not found."
]
}
}
}
}
}
}
}
}
},
"/{service}/user/{creator_id}/post/{post_id}": {
"get": {
"summary": "Get a specific post",
"tags": [
"Posts"
],
"parameters": [
{
"name": "service",
"in": "path",
"required": true,
"description": "The service name",
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"required": true,
"description": "The creator's ID",
"schema": {
"type": "string"
}
},
{
"name": "post_id",
"in": "path",
"required": true,
"description": "The post ID",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"user": {
"type": "string"
},
"service": {
"type": "string"
},
"title": {
"type": "string"
},
"content": {
"type": "string"
},
"embed": {
"type": "object"
},
"shared_file": {
"type": "boolean"
},
"added": {
"type": "string",
"format": "date-time"
},
"published": {
"type": "string",
"format": "date-time"
},
"edited": {
"type": "string",
"format": "date-time"
},
"file": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
},
"next": {
"type": "string"
},
"prev": {
"type": "string"
}
}
},
"example": {
"id": "1836570",
"user": "6570768",
"service": "fanbox",
"title": "今日はFANBOXを始まりました",
"content": "<p>みなさんこんにちは、影おじです。</p><p>先週のように、FANBOXを始まりに決定しました</p><p>そしてFANBOXの更新内容について、アンケートのみなさん</p><p>ありがとうございました!</p><p><br/></p><p>では更新内容の詳しいことはこちらです↓</p><p>毎回の絵、元も差分がありませんの場合、ボナスとして差分イラストを支援者の皆様にプレゼント。</p><p>もとも差分があれば、ボナスとしてヌード差分イラストを支援者の皆様にプレゼント。</p><p><br/></p><p>これから、仕事以外の時間、できる限り勤勉な更新したいと思います!</p><p>どうぞよろしくお願いいたします!</p>",
"embed": {},
"shared_file": false,
"added": "2021-03-30T18:00:05.973913",
"published": "2021-01-24T17:54:38",
"edited": "2021-01-24T18:46:15",
"file": {
"name": "a99d9674-5490-400e-acca-4bed99590699.jpg",
"path": "/5c/98/5c984d1f62f0990a0891d8fa359aecdff6ac1e26ac165ba7bb7f31cc99e7a674.jpg"
},
"attachments": [],
"next": null,
"prev": "1836649"
}
}
}
},
"404": {
"description": "Post not found"
}
}
}
},
"/discord/channel/{channel_id}": {
"get": {
"tags": [
"Discord"
],
"summary": "Get Discord channel posts by offset",
"parameters": [
{
"name": "channel_id",
"in": "path",
"description": "ID of the Discord channel",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "o",
"in": "query",
"description": "Result offset, stepping of 150 is enforced",
"schema": {
"type": "integer"
}
}
],
"responses": {
"200": {
"description": "Discord channel found",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"author": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"avatar": {
"type": "string"
},
"username": {
"type": "string"
},
"public_flags": {
"type": "integer"
},
"discriminator": {
"type": "string"
}
}
},
"server": {
"type": "string"
},
"channel": {
"type": "string"
},
"content": {
"type": "string"
},
"added": {
"type": "string",
"format": "date-time"
},
"published": {
"type": "string",
"format": "date-time"
},
"edited": {
"type": "string",
"format": "date-time"
},
"embeds": {
"type": "array",
"items": {}
},
"mentions": {
"type": "array",
"items": {}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
}
}
}
},
"example": [
{
"id": "942909658610413578",
"author": {
"id": "421590382300889088",
"avatar": "0956f3dc18eba7da9daedc4e50fb96d0",
"username": "Merry",
"public_flags": 0,
"discriminator": "7849"
},
"server": "455285536341491714",
"channel": "455287420959850496",
"content": "@everyone Happy Valentines Day! 💜✨",
"added": "2022-02-15T01:26:12.708959",
"published": "2022-02-14T22:26:21.027000",
"edited": null,
"embeds": [],
"mentions": [],
"attachments": []
},
{
"id": "942909571947712594",
"author": {
"id": "421590382300889088",
"avatar": "0956f3dc18eba7da9daedc4e50fb96d0",
"username": "Merry",
"public_flags": 0,
"discriminator": "7849"
},
"server": "455285536341491714",
"channel": "455287420959850496",
"content": "",
"added": "2022-02-15T01:26:13.006228",
"published": "2022-02-14T22:26:00.365000",
"edited": null,
"embeds": [],
"mentions": [],
"attachments": [
{
"name": "sofa_03.png",
"path": "/3b/4e/3b4ed5aabdd85b26fbbc3ee9b0e5649df69167efe26b5abc24cc2a1159f446d4.png"
}
]
}
]
}
}
},
"404": {
"description": "Discord channel not found"
}
}
}
},
"/discord/channel/lookup/{discord_server}": {
"get": {
"tags": [
"Discord"
],
"summary": "Lookup Discord channels",
"parameters": [
{
"name": "discord_server",
"in": "path",
"description": "Discord Server ID",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Discord channels found",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
},
"example": [
{
"id": "455285536341491716",
"name": "news"
},
{
"id": "455287420959850496",
"name": "nyarla-lewds"
}
]
}
}
},
"404": {
"description": "Discord server not found"
}
}
}
},
"/account/favorites": {
"get": {
"tags": [
"Favorites"
],
"security": [
{
"cookieAuth": []
}
],
"summary": "List Account Favorites",
"description": "List account favorites (posts or creators) for the authenticated user (cookie session)",
"parameters": [
{
"name": "type",
"in": "query",
"description": "Type of favorites to list (post or creator (artist) )",
"schema": {
"type": "string",
"enum": [
"post",
"artist"
]
}
}
],
"responses": {
"200": {
"description": "List of account favorites",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"faved_seq": {
"type": "integer",
"description": "The sequence number of the favorite"
},
"id": {
"type": "string",
"description": "The ID of the favorite (post or creator)"
},
"indexed": {
"type": "string",
"description": "Timestamp when the creator was indexed isoformat"
},
"last_imported": {
"type": "string",
"description": "Timestamp when the creator was last imported"
},
"name": {
"type": "string",
"description": "The name of the creator"
},
"service": {
"type": "string",
"description": "The service where the creator is located"
},
"updated": {
"type": "string",
"description": "Timestamp when the creator was last updated"
}
}
}
}
}
}
},
"401": {
"$ref": "#/components/responses/401"
}
}
}
},
"/favorites/post/{service}/{creator_id}/{post_id}": {
"post": {
"tags": [
"Favorites"
],
"security": [
{
"cookieAuth": []
}
],
"summary": "Add Favorite Post",
"description": "Add a post to the user's favorite posts",
"parameters": [
{
"name": "service",
"in": "path",
"description": "Service of the post",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "post_id",
"in": "path",
"description": "The ID of the post",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Favorite post added successfully",
"content": {}
},
"302": {
"description": "Redirect to login if not authenticated",
"content": {}
},
"401": {
"$ref": "#/components/responses/401"
}
}
},
"delete": {
"tags": [
"Favorites"
],
"security": [
{
"cookieAuth": []
}
],
"summary": "Remove Favorite Post",
"description": "Remove a post from the user's favorite posts",
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the post is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "post_id",
"in": "path",
"description": "The ID of the post",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Unfavorite post removed successfully",
"content": {}
},
"302": {
"description": "Redirect to login if not authenticated",
"content": {}
},
"401": {
"$ref": "#/components/responses/401"
}
}
}
},
"/favorites/creator/{service}/{creator_id}": {
"post": {
"tags": [
"Favorites"
],
"security": [
{
"cookieAuth": []
}
],
"summary": "Add Favorite creator",
"description": "Add an creator to the user's favorite creators",
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the creator is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Favorite creator added successfully",
"content": {}
},
"302": {
"description": "Redirect to login if not authenticated",
"content": {}
},
"401": {
"$ref": "#/components/responses/401"
}
}
},
"delete": {
"tags": [
"Favorites"
],
"security": [
{
"cookieAuth": []
}
],
"summary": "Remove Favorite Creator",
"description": "Remove an creator from the user's favorite creators",
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the creator is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Favorite creator removed successfully",
"content": {}
},
"302": {
"description": "Redirect to login if not authenticated",
"content": {}
},
"401": {
"$ref": "#/components/responses/401"
}
}
}
},
"/search_hash/{file_hash}": {
"get": {
"tags": [
"File Search"
],
"summary": "Lookup file by hash",
"parameters": [
{
"name": "file_hash",
"in": "path",
"required": true,
"description": "SHA-2 / SHA-256",
"schema": {
"type": "string",
"format": "hex",
"minLength": 64,
"maxLength": 64
}
}
],
"responses": {
"200": {
"description": "File found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"hash": {
"type": "string"
},
"mtime": {
"type": "string",
"format": "date-time"
},
"ctime": {
"type": "string",
"format": "date-time"
},
"mime": {
"type": "string"
},
"ext": {
"type": "string"
},
"added": {
"type": "string",
"format": "date-time"
},
"size": {
"type": "integer"
},
"ihash": {
"type": "string"
},
"posts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"file_id": {
"type": "integer"
},
"id": {
"type": "string"
},
"user": {
"type": "string"
},
"service": {
"type": "string"
},
"title": {
"type": "string"
},
"substring": {
"type": "string"
},
"published": {
"type": "string",
"format": "date-time"
},
"file": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
}
}
}
},
"discord_posts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"file_id": {
"type": "integer"
},
"id": {
"type": "string"
},
"server": {
"type": "string"
},
"channel": {
"type": "string"
},
"substring": {
"type": "string"
},
"published": {
"type": "string",
"format": "date-time"
},
"embeds": {
"type": "array",
"items": {}
},
"mentions": {
"type": "array",
"items": {}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
}
}
}
}
}
},
"example": {
"id": 40694581,
"hash": "b926020cf035af45a1351e0a7e2c983ebcc93b4c751998321a6593a98277cdeb",
"mtime": "2021-12-04T07:16:09.385539",
"ctime": "2021-12-04T07:16:09.385539",
"mime": "image/png",
"ext": ".png",
"added": "2021-12-04T07:16:09.443016",
"size": 10869921,
"ihash": null,
"posts": [
{
"file_id": 108400151,
"id": "5956097",
"user": "21101760",
"service": "fanbox",
"title": "Loli Bae",
"substring": "Thank you for your continued support!\nいつも支援ありがとうご",
"published": "2023-05-14T00:00:00",
"file": {
"name": "8f183dac-470d-4587-9657-23efe8890a7b.jpg",
"path": "/e5/1f/e51fc831dfdac7a21cc650ad46af59340e35e2a051aed8c1e65633592f4dc11c.jpg"
},
"attachments": [
{
"name": "b644eb9c-cffa-400e-9bd6-40cccb2331ba.png",
"path": "/5e/b3/5eb3197668ac23bd7c473d3c750334eb206b060c610e4ac5fa1a9370fd1314d9.png"
},
{
"name": "17f295ba-a9f2-4034-aafc-bf74904ec144.png",
"path": "/88/ad/88ad2ba77c89e4d7a9dbe1f9531ba3e3077a82aee2b61efa29fda122ebe1b516.png"
}
]
}
],
"discord_posts": [
{
"file_id": 40694581,
"id": "769704201495904286",
"server": "455285536341491714",
"channel": "769703874356445216",
"substring": "",
"published": "2020-10-24T23:29:42.049",
"embeds": [],
"mentions": [],
"attachments": [
{
"name": "3.png",
"path": "/b9/26/b926020cf035af45a1351e0a7e2c983ebcc93b4c751998321a6593a98277cdeb.png"
}
]
}
]
}
}
}
},
"404": {
"description": "File not found"
}
}
}
},
"/{service}/user/{creator_id}/post/{post}/flag": {
"post": {
"tags": [
"Post Flagging"
],
"summary": "Flag a post",
"parameters": [
{
"name": "service",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "post",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"201": {
"description": "Flagged successfully",
"content": {}
},
"409": {
"description": "Already flagged",
"content": {}
}
}
},
"get": {
"tags": [
"Post Flagging"
],
"summary": "Check if a Post is flagged",
"description": "Check if a Post is flagged",
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the post is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The creator of the post",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "post",
"in": "path",
"description": "The ID of the post to flag",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The post is flagged",
"content": {}
},
"404": {
"description": "The post has no flag",
"content": {}
}
}
}
},
"/{service}/user/{creator_id}/post/{post_id}/revisions": {
"get": {
"tags": [
"Posts"
],
"summary": "List a Post's Revisions",
"description": "List revisions of a specific post by service, creator_id, and post_id",
"parameters": [
{
"name": "service",
"in": "path",
"description": "The service where the post is located",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The ID of the creator",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "post_id",
"in": "path",
"description": "The ID of the post",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of post revisions",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"revision_id": {
"type": "integer"
},
"id": {
"type": "string"
},
"user": {
"type": "string"
},
"service": {
"type": "string"
},
"title": {
"type": "string"
},
"content": {
"type": "string"
},
"embed": {
"type": "object"
},
"shared_file": {
"type": "boolean"
},
"added": {
"type": "string",
"format": "date-time"
},
"published": {
"type": "string",
"format": "date-time"
},
"edited": {
"type": "string",
"format": "date-time"
},
"file": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
}
}
}
}
}
}
},
"example": [
{
"revision_id": 8059287,
"id": "1836570",
"user": "6570768",
"service": "fanbox",
"title": "今日はFANBOXを始まりました",
"content": "<p>みなさんこんにちは、影おじです。</p><p>先週のように、FANBOXを始まりに決定しました</p><p>そしてFANBOXの更新内容について、アンケートのみなさん</p><p>ありがとうございました!</p><p><br/></p><p>では更新内容の詳しいことはこちらです↓</p><p>毎回の絵、元も差分がありませんの場合、ボナスとして差分イラストを支援者の皆様にプレゼント。</p><p>もとも差分があれば、ボナスとしてヌード差分イラストを支援者の皆様にプレゼント。</p><p><br/></p><p>これから、仕事以外の時間、できる限り勤勉な更新したいと思います!</p><p>どうぞよろしくお願いいたします!</p>",
"embed": {},
"shared_file": false,
"added": "2023-09-19T13:19:57.416086",
"published": "2021-01-24T17:54:38",
"edited": "2021-01-24T18:46:15",
"file": {
"name": "8c2be0fd-a130-4afb-9314-80f2501d94f7.jpg",
"path": "/5c/98/5c984d1f62f0990a0891d8fa359aecdff6ac1e26ac165ba7bb7f31cc99e7a674.jpg"
},
"attachments": [
{
"name": "attachment1.jpg",
"path": "/attachments/attachment1.jpg"
},
{
"name": "attachment2.jpg",
"path": "/attachments/attachment2.jpg"
}
]
},
{
"revision_id": 6770513,
"id": "1836570",
"user": "6570768",
"service": "fanbox",
"title": "今日はFANBOXを始まりました",
"content": "<p>みなさんこんにちは、影おじです。</p><p>先週のように、FANBOXを始まりに決定しました</p><p>そしてFANBOXの更新内容について、アンケートのみなさん</p><p>ありがとうございました!</p><p><br/></p><p>では更新内容の詳しいことはこちらです↓</p><p>毎回の絵、元も差分がありませんの場合、ボナスとして差分イラストを支援者の皆様にプレゼント。</p><p>もとも差分があれば、ボナスとしてヌード差分イラストを支援者の皆様にプレゼント。</p><p><br/></p><p>これから、仕事以外の時間、できる限り勤勉な更新したいと思います!</p><p>どうぞよろしくお願いいたします!</p>",
"embed": {},
"shared_file": false,
"added": "2023-07-28T23:51:25.477291",
"published": "2021-01-24T17:54:38",
"edited": "2021-01-24T18:46:15",
"file": {
"name": "0d133e49-a2d4-4733-9044-dd57e25b1fce.jpg",
"path": "/5c/98/5c984d1f62f0990a0891d8fa359aecdff6ac1e26ac165ba7bb7f31cc99e7a674.jpg"
},
"attachments": [
{
"name": "attachment3.jpg",
"path": "/attachments/attachment3.jpg"
},
{
"name": "attachment4.jpg",
"path": "/attachments/attachment4.jpg"
}
]
}
]
}
}
},
"404": {
"description": "Post not found"
}
}
}
},
"/{service}/user/{creator_id}/post/{post_id}/comments": {
"get": {
"tags": [
"Comments"
],
"summary": "List a post's comments",
"description": "List comments for a specific post by service, creator_id, and post_id.",
"parameters": [
{
"name": "service",
"in": "path",
"description": "The post's service.",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "creator_id",
"in": "path",
"description": "The service ID of the post's creator.",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "post_id",
"in": "path",
"description": "The service ID of the post.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List of post comments.",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"parent_id": {
"type": "string",
"nullable": true
},
"commenter": {
"type": "string"
},
"content": {
"type": "string"
},
"published": {
"type": "string",
"format": "date-time"
},
"revisions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"content": {
"type": "string"
},
"added": {
"type": "string",
"format": "date-time"
}
}
}
}
}
}
},
"example": [
{
"id": "121508687",
"parent_id": null,
"commenter": "84534108",
"content": "YOU DREW MORE YAYYYY",
"published": "2023-11-05T20:17:47.635000",
"revisions": [
{
"id": 1,
"content": "YOU DREW MORE YAYYYY2222222",
"added": "2023-11-14T03:09:12.275975"
}
]
}
]
}
}
},
"404": {
"description": "No comments found."
}
}
}
},
"/app_version": {
"get": {
"tags": [
"Misc"
],
"summary": "Git Commit Hash",
"description": "Show current App commit hash",
"responses": {
"200": {
"description": "Commit Hash",
"content": {
"text/plain": {
"schema": {
"type": "string",
"format": "hex",
"minLength": 40,
"maxLength": 40,
"example": "3b9cd5fab1d35316436968fe85c90ff2de0cdca0"
}
}
}
}
}
}
}
},
"components": {
"securitySchemes": {
"cookieAuth": {
"description": "Session key that can be found in cookies after a successful login",
"type": "apiKey",
"in": "cookie",
"name": "session"
}
},
"responses": {
"401": {
"description": "Unauthorized",
"content": {}
}
}
}
}