NAV
shell go

Introduction

This is the API documentation for open source imageboard jschan.


In the data examples, arrays can contain more than one item however only one is included to reduce the size of this document.

In data parameters, note that data is always submitted as a strings, that is how urlencoded/multipart forms work. There is no concept of "types". "number" simply means a string only including numbers. For "boolean", any value with length > 0 = true, 0 length or missing = false.

Public Endpoints

Board list

curl "https://fatchan.org/boards.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getBoardsPublicOptions := &jschan.GetBoardsPublicOptions{
  Search:    "tech",
}
boards, err := client.GetBoardsPublic(ctx, getBoardsPublicOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", boards)

The above command returns JSON structured like this:

{
  "boards": [
    {
      "_id": "61a45ea2c5f3b57f31789cfc",
      "uri": "a",
      "sequence_value": 709261,
      "ips": 109,
      "pph": 25,
      "webring": true
      "path": "https://smuglo.li/a",
      "siteName": "Smug",
      "lastPostTimestamp": {
        "text": "12 minutes ago",
        "color": "#14d900"
      },
      "settings": {
        "sfw": false,
        "name": "Anime & Manga",
        "description": "Stay away from 3DPD"
      },
      "tags": [
        "anime",
        "manga"
      ]
    },
    {
      "_id": "b",
      "sequence_value": 320,
      "ips": 4,
      "pph": 0,
      "ppd": 5,
      "webring": false
      "lastPostTimestamp": {
        "text": "1 hour ago",
        "color": "#72d900"
      },
      "settings": {
        "name": "Random",
        "description": "Anything and everything",
        "sfw": false,
        "unlistedLocal": false
      },
      "tags": [
        "random",
        "b",
        "rand",
        "anything",
        "everything"
      ],
    },
  ],
  "page": 1,
  "maxPage": 1
}

Returns a list of boards, max 30 per page. Unlisted boards are not included in search results. Also return the current page and maximum page with the current search and sites parameters.

HTTP Request

GET https://fatchan.org/boards.json

Query Parameters

Parameter Default Description
search A string to search by board name and tags, including prefix matches.
sort popularity popularity sorts by a compound of (ips, pph, sequence_value), activity sorts by lastPostTimestamp.
direction desc desc or asc for descending or ascending sort order respectively.
local_first false If true, put local sites grouped before webring sites. Sort and direction for local and webring sites will be independent.
sites Sites to include by siteName, can be repeated to include multiple sites. Blank includes all sites.
page Page number. 30 per page. Blank is first page. Page numbering starts at 1. Included in all responses is maxPage.

Overboard index

curl "https://fatchan.org/overboard.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
overboardOptions := &jschan.GetOverboardOptions{
  IncludeDefault: true,
}
overboard, err := client.GetOverboardIndex(ctx, overboardOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", overboard.Threads)

The above command returns JSON structured like this:

{
  "threads": [
    {
      "_id": "619b5c90de842499502c366c",
      "date": "2021-11-22T09:02:08.852Z",
      "u": 1637571728852,
      "name": "Anon",
      "country": null,
      "board": "b",
      "tripcode": null,
      "capcode": null,
      "subject": "My music",
      "message": null,
      "messagehash": null,
      "nomarkup": null,
      "thread": null,
      "email": null,
      "spoiler": false,
      "banmessage": null,
      "userId": null,
      "files": [
        {
          "filename": "a631c506f8884d263a3cf79023399504d600b0ab3219b515ac1e658d746f5d38.mp4",
          "spoiler": null,
          "hash": "a631c506f8884d263a3cf79023399504d600b0ab3219b515ac1e658d746f5d38",
          "originalFilename": "the matrixx - black moon.mp4",
          "mimetype": "video/mp4",
          "size": 17745211,
          "extension": ".mp4",
          "sizeString": "16.9MB",
          "duration": 191.379,
          "durationString": "03:11",
          "thumbextension": ".jpg",
          "geometry": {
            "width": 640,
            "height": 368,
            "thumbwidth": 250,
            "thumbheight": 143
          },
          "geometryString": "640x368",
          "hasThumb": true
        }
      ],
      "quotes": [],
      "crossquotes": [],
      "backlinks": [],
      "replyposts": 3,
      "replyfiles": 7,
      "sticky": 0,
      "locked": 0,
      "bumplocked": 0,
      "cyclic": 0,
      "bumped": "2021-11-29T03:54:32.232Z",
      "postId": 309,
      "replies": [
        {
          "_id": "619b832b009b4a926fb37f36",
          "date": "2021-11-22T11:46:51.776Z",
          "u": 1637581611776,
          "name": "Anon",
          "country": null,
          "board": "b",
          "tripcode": null,
          "capcode": null,
          "subject": null,
          "message": "fuck dude those russians left as fast as they came",
          "messagehash": "NNRY6z0VURq58lfsJ80CXqSHR/fvtokjVmFT2lE5IkM=",
          "nomarkup": "fuck dude those russians left as fast as they came",
          "thread": 309,
          "email": null,
          "spoiler": false,
          "banmessage": null,
          "userId": null,
          "files": [
            {
              "filename": "421049b5beedb751c05be7f53f3a4bb781b8f03cd8fd6888293918deea9a9f64.jpg",
              "spoiler": null,
              "hash": "421049b5beedb751c05be7f53f3a4bb781b8f03cd8fd6888293918deea9a9f64",
              "originalFilename": "cover.jpg",
              "mimetype": "image/jpeg",
              "size": 1214658,
              "extension": ".jpg",
              "sizeString": "1.2MB",
              "thumbextension": ".jpg",
              "geometry": {
                "width": 1403,
                "height": 1400,
                "thumbwidth": 250,
                "thumbheight": 249
              },
              "geometryString": "1403x1400",
              "hasThumb": true
            }
          ],
          "quotes": [],
          "crossquotes": [],
          "backlinks": [],
          "postId": 310
        }
      ]
    }
  ]
}

Returns a list of threads with preview replies from multiple boards. Similar to board index pages.

HTTP Request

GET https://fatchan.org/overboard.json

Query Parameters

Parameter Default Description
include_default true Whether to include boards that are publicly listed and by default appear on the overboard. If not true and the add_boards parameter is empty, this will be ignored and default to true (otherwise you are asking for an overboard view of no boards).
add Additional boards to fetch threads from. Can be repeated for multiple boards.
rem Boards to remove from the default board list if include_detault is true. Can be repeated for multiple boards.

Overboard catalog

curl "https://fatchan.org/catalog.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
overboardOptions := &jschan.GetOverboardOptions{
  IncludeDefault: true,
}
overboard, err := client.GetOverboardCatalog(ctx, overboardOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", overboard.Threads)

The above command returns JSON structured like this:

{
  "threads": [
    {
      "_id": "619b5c90de842499502c366c",
      "date": "2021-11-22T09:02:08.852Z",
      "u": 1637571728852,
      "name": "Anon",
      "country": null,
      "board": "b",
      "tripcode": null,
      "capcode": null,
      "subject": "My music",
      "message": null,
      "messagehash": null,
      "nomarkup": null,
      "thread": null,
      "email": null,
      "spoiler": false,
      "banmessage": null,
      "userId": null,
      "files": [
        {
          "filename": "a631c506f8884d263a3cf79023399504d600b0ab3219b515ac1e658d746f5d38.mp4",
          "spoiler": null,
          "hash": "a631c506f8884d263a3cf79023399504d600b0ab3219b515ac1e658d746f5d38",
          "originalFilename": "the matrixx - black moon.mp4",
          "mimetype": "video/mp4",
          "size": 17745211,
          "extension": ".mp4",
          "sizeString": "16.9MB",
          "duration": 191.379,
          "durationString": "03:11",
          "thumbextension": ".jpg",
          "geometry": {
            "width": 640,
            "height": 368,
            "thumbwidth": 250,
            "thumbheight": 143
          },
          "geometryString": "640x368",
          "hasThumb": true
        }
      ],
      "quotes": [],
      "crossquotes": [],
      "backlinks": [],
      "replyposts": 3,
      "replyfiles": 7,
      "sticky": 0,
      "locked": 0,
      "bumplocked": 0,
      "cyclic": 0,
      "bumped": "2021-11-29T03:54:32.232Z",
      "postId": 309
    },
    {
      "_id": "60aabfd6fc57a0112f5dbdc4",
      "date": "2021-05-23T20:49:26.918Z",
      "u": 1621802966918,
      "name": "名無し",
      "country": null,
      "board": "lain",
      "tripcode": null,
      "capcode": null,
      "subject": "lain Fanart thread",
      "message": null,
      "messagehash": null,
      "nomarkup": null,
      "thread": null,
      "email": null,
      "spoiler": false,
      "banmessage": null,
      "userId": null,
      "files": [
        {
          "spoiler": null,
          "hash": "10e24a1eef06d36d29a30f60e4616ef8cea9050c8f1e13b80af75b01687ef1fa",
          "filename": "10e24a1eef06d36d29a30f60e4616ef8cea9050c8f1e13b80af75b01687ef1fa.jpg",
          "originalFilename": "10e24a1eef06d36d29a30f60e4616ef8cea9050c8f1e13b80af75b01687ef1fa.jpg",
          "mimetype": "image/jpeg",
          "size": 259561,
          "extension": ".jpg",
          "sizeString": "253.5KB",
          "thumbextension": ".jpg",
          "geometry": {
            "width": 1024,
            "height": 768,
            "thumbwidth": 250,
            "thumbheight": 187
          },
          "geometryString": "1024x768",
          "hasThumb": true
        }
      ],
      "quotes": [],
      "crossquotes": [],
      "backlinks": [],
      "replyposts": 42,
      "replyfiles": 119,
      "sticky": 0,
      "locked": 0,
      "bumplocked": 0,
      "cyclic": 0,
      "bumped": "2021-11-28T18:57:37.215Z",
      "postId": 362
    }
  ]
}

Returns a list of threads without replies from multiple boards. Similar to board catalog pages.

HTTP Request

GET https://fatchan.org/catalog.json

Query Parameters

Parameter Default Description
include_default true Whether to include boards that are publicly listed and by default appear on the overboard. If not true and the add_boards parameter is empty, this will be ignored and default to true (otherwise you are asking for an overboard view of no boards).
add Additional boards to fetch threads from. Can be repeated for multiple boards.
rem Boards to remove from the default board list if include_detault is true. Can be repeated for multiple boards.

Thread

curl "https://fatchan.org/t/thread/1329.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getThreadOptions := &jschan.GetThreadOptions{
  Board:    "t",
  ThreadId: 1329,
}
thread, err := client.GetThread(ctx, getThreadOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", thread)

The above command returns JSON structured like this:

{
  "_id": "614de00fdd671464b69b6fe0",
  "date": "2021-09-24T14:26:23.861Z",
  "u": 1632493583861,
  "name": "Anon",
  "country": {
    "code": "TOR",
    "name": "Tor Hidden Service"
  },
  "board": "t",
  "tripcode": null,
  "capcode": null,
  "subject": "Login and Board Abandonment",
  "message": "Tom,\r\nWhat are the criteria for a board becoming available for claim? My board hardly gets any traffic, so I do not often log in, but I still monitor it closely. Does this put it at risk of being given away or deleted? How often should one log in to maintain ownership of his board?\r\nThank you.",
  "messagehash": "s5Jm+bRGPlsMb78ROCTwEg0H7fAAtAhBlhd+yvdwbhE=",
  "nomarkup": "Tom,\r\nWhat are the criteria for a board becoming available for claim? My board hardly gets any traffic, so I do not often log in, but I still monitor it closely. Does this put it at risk of being given away or deleted? How often should one log in to maintain ownership of his board?\r\nThank you.",
  "thread": null,
  "email": "",
  "spoiler": false,
  "banmessage": null,
  "userId": "65fedc",
  "files": [],
  "quotes": [],
  "crossquotes": [],
  "backlinks": [
    {
      "_id": "614dfa85dd671464b69b6fe2",
      "postId": 1330
    }
  ],
  "replyposts": 5,
  "replyfiles": 0,
  "sticky": 0,
  "locked": 0,
  "bumplocked": 1,
  "cyclic": 0,
  "bumped": "2021-10-03T22:52:13.202Z",
  "postId": 1329,
  "replies": [
    {
      "_id": "614dfa85dd671464b69b6fe2",
      "date": "2021-09-24T16:19:17.465Z",
      "u": 1632500357465,
      "name": "Anon",
      "country": {
        "code": "AU",
        "name": "Australia"
      },
      "board": "t",
      "tripcode": null,
      "capcode": "## Admin",
      "subject": "",
      "message": "<a class=\"quote\" href=\"/t/thread/1329.html#1329\">&gt;&gt;1329</a> <small>(OP)</small> \r\nThere is no regular claims process, but I was considering a cleanup soon. There will be a newspost and global announcement with reasonable notice before any account deletion or board forfeiture takes place. Logging into your account in that instance would be warranted, because I can see the last activity date and will delete inactive accounts.",
      "messagehash": "jviA+n4rb3tYhSq2eonkuCZYzr/frpmwsDVv2N0XQUE=",
      "nomarkup": ">>1329\r\nThere is no regular claims process, but I was considering a cleanup soon. There will be a newspost and global announcement with reasonable notice before any account deletion or board forfeiture takes place. Logging into your account in that instance would be warranted, because I can see the last activity date and will delete inactive accounts.",
      "thread": 1329,
      "email": "",
      "spoiler": false,
      "banmessage": null,
      "userId": "b5d092",
      "files": [],
      "quotes": [
        {
          "_id": "614de00fdd671464b69b6fe0",
          "thread": 1329,
          "postId": 1329
        }
      ],
      "crossquotes": [],
      "backlinks": [
        {
          "_id": "614fb22e448d10f67a8d4dff",
          "postId": 1331
        },
        {
          "_id": "61538bd4dd671464b69b7034",
          "postId": 1339
        },
        {
          "_id": "615a341db33d7abaa5f90bb5",
          "postId": 1363
        }
      ],
      "postId": 1330
    }
  ]
]

Returns a thread with all replies.

HTTP Request

GET https://fatchan.org/{board}/thread/{threadId}.json

URL Parameters

Parameter Description
board The board URI for whatever board you want
threadId The thread number, which is the post number of the OP.

Board index pages

curl "https://fatchan.org/t/index.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getIndexOptions := &jschan.GetIndexOptions{
  Board: "t",
  Page:  1,
}
index, err := client.GetIndex(ctx, getIndexOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", index)

The above command returns JSON structured like this:

[
  {
    "_id": "6158e81eb33d7abaa5f90ba0",
    "date": "2021-10-02T23:15:42.675Z",
    "u": 1633216542675,
    "name": "Anon",
    "country": {
      "code": "AU",
      "name": "Australia"
    },
    "board": "t",
    "tripcode": null,
    "capcode": "## Admin",
    "subject": "Important Links",
    "message": "<span class=\"title\">Git repository &amp; issue tracker:</span> <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://gitgud.io/fatchan/jschan\">https://gitgud.io/fatchan/jschan</a>\nGo here to see the source code, report issues or ask relevant questions.\n\n<span class=\"title\">IRC:</span> <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://irc-web.fatpeople.lol\">https://irc-web.fatpeople.lol</a> (irc-web.fatpeople.lol port 6697 TLS on)\nJoin IRC to chat directly with staff and other users in a realtime format.\n\n<span class=\"title\">Test board:</span> <a class=\"quote\" href=\"/test/index.html\">&gt;&gt;&gt;/test/</a>\nTest things on the /test/ board rather than here or anywhere else.",
    "messagehash": "tkak9s72dCSv9XkocVNwceUfmtwqaTH8gL9bzcQxwP4=",
    "nomarkup": "==Git repository & issue tracker:== https://gitgud.io/fatchan/jschan\nGo here to see the source code, report issues or ask relevant questions.\n\n==IRC:== https://irc-web.fatpeople.lol (irc-web.fatpeople.lol port 6697 TLS on)\nJoin IRC to chat directly with staff and other users in a realtime format.\n\n==Test board:== >>>/test/\nTest things on the /test/ board rather than here or anywhere else.",
    "thread": null,
    "email": "",
    "spoiler": false,
    "banmessage": null,
    "userId": "307203",
    "files": [],
    "quotes": [],
    "crossquotes": [],
    "backlinks": [],
    "replyposts": 0,
    "replyfiles": 0,
    "sticky": 3,
    "locked": 1,
    "bumplocked": 0,
    "cyclic": 0,
    "bumped": "2021-10-02T23:15:42.675Z",
    "postId": 1360,
    "edited": {
      "username": "admin",
      "date": "2021-11-03T00:36:36.620Z"
    },
    "replies": []
  },
  {
    "_id": "614ba0e132f471fcdd2c7139",
    "date": "2021-09-22T21:32:17.737Z",
    "u": 1632346337737,
    "name": "Anon",
    "country": {
      "code": "AU",
      "name": "Australia"
    },
    "board": "t",
    "tripcode": null,
    "capcode": "## Admin",
    "subject": "Board Requests",
    "message": "1. <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"/rules.html\">Global rules</a>\r\n2. <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"/register.html\">Register an account</a> \r\n3. Post in this thread, format:\r\n<span class=\"code\">''Board URI:'' /example/\r\n''Board name:'' &lt;name of the board&gt;\r\n''Board description:'' &lt;25 words or less&gt;\r\n''I want it because:'' &lt;your pathetic excuse for wanting a board&gt;\r\n''My registered account username is:'' &lt;username&gt;\r\n''I have read and understand the global rules, and acknowledge the existence of the Israeli nuclear weapons program.''\r\n</span>\r\nEnjoy.",
    "messagehash": "J3Sg5W1b7iXYZQAofK+HFHvrpr8IpjOKEOMZvnMWB5I=",
    "nomarkup": "1. [Global rules](/rules.html)\r\n2. [Register an account](/register.html) \r\n3. Post in this thread, format:\r\n[code]plain\r\n''Board URI:'' /example/\r\n''Board name:'' <name of the board>\r\n''Board description:'' <25 words or less>\r\n''I want it because:'' <your pathetic excuse for wanting a board>\r\n''My registered account username is:'' <username>\r\n''I have read and understand the global rules, and acknowledge the existence of the Israeli nuclear weapons program.''\r\n[/code]\r\n\r\nEnjoy.",
    "thread": null,
    "email": "",
    "spoiler": false,
    "banmessage": null,
    "userId": "f63865",
    "files": [],
    "quotes": [],
    "crossquotes": [],
    "backlinks": [],
    "replyposts": 1,
    "replyfiles": 0,
    "sticky": 2,
    "locked": 0,
    "bumplocked": 0,
    "cyclic": 0,
    "bumped": "2021-11-14T14:09:39.353Z",
    "postId": 1325,
    "edited": {
      "username": "admin",
      "date": "2021-10-05T13:18:26.680Z"
    },
    "replies": [
      {
        "_id": "619118a39ca8261cc8311609",
        "date": "2021-11-14T14:09:39.353Z",
        "u": 1636898979353,
        "name": "Anon",
        "country": {
          "code": "LU",
          "name": "Luxembourg"
        },
        "board": "t",
        "tripcode": null,
        "capcode": null,
        "subject": "",
        "message": "<span class=\"bold\">Board URI:</span> /shy/\r\n<span class=\"bold\">Board name:</span> Shy Anonymous\r\n<span class=\"bold\">Board description:</span> Доска для застенчивых одиноких людей без сети социальных связей (в том числе своего пола), друзей, тян, с отсутствующими навыками НЕФОРМАЛЬНОГО общения. Обсуждение связанных с этим проблем.\r\n<span class=\"bold\">I want it because:</span> Because I can and want\r\n<span class=\"bold\">My registered account username is:</span> anonymous1234\r\n<span class=\"bold\">I have read and understand the global rules, and acknowledge the existence of the Israeli nuclear weapons program.</span>",
        "messagehash": "S3r9l9svoA/ebm4c7e9U1pOq6kW1WYsE1vc/9/BHZTg=",
        "nomarkup": "''Board URI:'' /shy/\r\n''Board name:'' Shy Anonymous\r\n''Board description:'' Доска для застенчивых одиноких людей без сети социальных связей (в том числе своего пола), друзей, тян, с отсутствующими навыками НЕФОРМАЛЬНОГО общения. Обсуждение связанных с этим проблем.\r\n''I want it because:'' Because I can and want\r\n''My registered account username is:'' anonymous1234\r\n''I have read and understand the global rules, and acknowledge the existence of the Israeli nuclear weapons program.''",
        "thread": 1325,
        "email": "",
        "spoiler": false,
        "banmessage": null,
        "userId": "c54e7d",
        "files": [],
        "quotes": [],
        "crossquotes": [],
        "backlinks": [],
        "postId": 1391
      }
    ]
  }
]

Returns a list of threads with preview replies from a page of a board.

HTTP Request

GET https://fatchan.org/{board}/{page}.json

URL Parameters

Parameter Description
board Board URI.
page index for page 1, or a number for subsequent pages.

Board catalog

curl "https://fatchan.org/t/catalog.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getCatalogOptions := &jschan.GetCatalogOptions{
  Board: "t",
}
catalog, err := client.GetCatalog(ctx, getCatalogOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", catalog)

The above command returns JSON structured like this:

[
  {
    "_id": "6158e81eb33d7abaa5f90ba0",
    "date": "2021-10-02T23:15:42.675Z",
    "u": 1633216542675,
    "name": "Anon",
    "country": {
      "code": "AU",
      "name": "Australia"
    },
    "board": "t",
    "tripcode": null,
    "capcode": "## Admin",
    "subject": "Important Links",
    "message": "<span class=\"title\">Git repository &amp; issue tracker:</span> <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://gitgud.io/fatchan/jschan\">https://gitgud.io/fatchan/jschan</a>\nGo here to see the source code, report issues or ask relevant questions.\n\n<span class=\"title\">IRC:</span> <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://irc-web.fatpeople.lol\">https://irc-web.fatpeople.lol</a> (irc-web.fatpeople.lol port 6697 TLS on)\nJoin IRC to chat directly with staff and other users in a realtime format.\n\n<span class=\"title\">Test board:</span> <a class=\"quote\" href=\"/test/index.html\">&gt;&gt;&gt;/test/</a>\nTest things on the /test/ board rather than here or anywhere else.",
    "messagehash": "tkak9s72dCSv9XkocVNwceUfmtwqaTH8gL9bzcQxwP4=",
    "nomarkup": "==Git repository & issue tracker:== https://gitgud.io/fatchan/jschan\nGo here to see the source code, report issues or ask relevant questions.\n\n==IRC:== https://irc-web.fatpeople.lol (irc-web.fatpeople.lol port 6697 TLS on)\nJoin IRC to chat directly with staff and other users in a realtime format.\n\n==Test board:== >>>/test/\nTest things on the /test/ board rather than here or anywhere else.",
    "thread": null,
    "email": "",
    "spoiler": false,
    "banmessage": null,
    "userId": "307203",
    "files": [],
    "quotes": [],
    "crossquotes": [],
    "backlinks": [],
    "replyposts": 0,
    "replyfiles": 0,
    "sticky": 3,
    "locked": 1,
    "bumplocked": 0,
    "cyclic": 0,
    "bumped": "2021-10-02T23:15:42.675Z",
    "postId": 1360,
    "edited": {
      "username": "admin",
      "date": "2021-11-03T00:36:36.620Z"
    }
  },
  {
    "_id": "614ba0e132f471fcdd2c7139",
    "date": "2021-09-22T21:32:17.737Z",
    "u": 1632346337737,
    "name": "Anon",
    "country": {
      "code": "AU",
      "name": "Australia"
    },
    "board": "t",
    "tripcode": null,
    "capcode": "## Admin",
    "subject": "Board Requests",
    "message": "1. <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"/rules.html\">Global rules</a>\r\n2. <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"/register.html\">Register an account</a> \r\n3. Post in this thread, format:\r\n<span class=\"code\">''Board URI:'' /example/\r\n''Board name:'' &lt;name of the board&gt;\r\n''Board description:'' &lt;25 words or less&gt;\r\n''I want it because:'' &lt;your pathetic excuse for wanting a board&gt;\r\n''My registered account username is:'' &lt;username&gt;\r\n''I have read and understand the global rules, and acknowledge the existence of the Israeli nuclear weapons program.''\r\n</span>\r\nEnjoy.",
    "messagehash": "J3Sg5W1b7iXYZQAofK+HFHvrpr8IpjOKEOMZvnMWB5I=",
    "nomarkup": "1. [Global rules](/rules.html)\r\n2. [Register an account](/register.html) \r\n3. Post in this thread, format:\r\n[code]plain\r\n''Board URI:'' /example/\r\n''Board name:'' <name of the board>\r\n''Board description:'' <25 words or less>\r\n''I want it because:'' <your pathetic excuse for wanting a board>\r\n''My registered account username is:'' <username>\r\n''I have read and understand the global rules, and acknowledge the existence of the Israeli nuclear weapons program.''\r\n[/code]\r\n\r\nEnjoy.",
    "thread": null,
    "email": "",
    "spoiler": false,
    "banmessage": null,
    "userId": "f63865",
    "files": [],
    "quotes": [],
    "crossquotes": [],
    "backlinks": [],
    "replyposts": 1,
    "replyfiles": 0,
    "sticky": 2,
    "locked": 0,
    "bumplocked": 0,
    "cyclic": 0,
    "bumped": "2021-11-14T14:09:39.353Z",
    "postId": 1325,
    "edited": {
      "username": "admin",
      "date": "2021-10-05T13:18:26.680Z"
    }
  }
]

Returns a list of all threads on a board.

HTTP Request

GET https://fatchan.org/{board}/catalog.json

URL Parameters

Parameter Description
board Board URI.

Board log list

curl "https://fatchan.org/t/logs.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getLogsListOptions := &jschan.GetLogsListOptions{
  Board: "t",
}
logs, err := client.GetLogsList(ctx, getLogsListOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", logs)

The above command returns JSON structured like this:

[
  {
    "date": {
      "year": 2022,
      "month": 8,
      "day": 13
    },
    "count": 3
  },
  {
    "date": {
      "year": 2022,
      "month": 8,
      "day": 12
    },
    "count": 1
  }
]

Returns a list of objects each containing a date (day, month, year) and number of log entries on that date.

HTTP Request

GET https://fatchan.org/{board}/logs.json

URL Parameters

Parameter Description
board Board URI.

Board log (day)

curl "https://fatchan.org/t/logs/8-12-2022.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getLogsOptions := &jschan.GetLogsOptions{
  Board: "t",
  Date: models.LogDate{
    Year: 2022,
    Month: 12,
    Day: 8,
  }
}
logs, err := client.GetLogs(ctx, getLogsOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", logs)

The above command returns JSON structured like this:

[
  {
    "_id": "62f5f3d1b0ffeb3e12205fa2",
    "showLinks": false,
    "postLinks": [
      {
        "postId": 143,
        "thread": 138,
        "board": "t"
      }
    ],
    "actions": [
      "Delete"
    ],
    "date": "2022-08-12T06:31:45.492Z",
    "showUser": false,
    "message": null,
    "user": null,
    "board": "t"
  },
  {
    "_id": "62f5f3c0b0ffeb3e12205fa1",
    "showLinks": true,
    "postLinks": [
      {
        "postId": 144,
        "thread": 138,
        "board": "t"
      }
    ],
    "actions": [
      "Unlink files"
    ],
    "date": "2022-08-12T06:31:28.084Z",
    "showUser": true,
    "message": null,
    "user": "admin",
    "board": "t"
  },
  {
    "_id": "62f5e88038f79a03efaee40c",
    "showLinks": true,
    "postLinks": [
      {
        "postId": 138,
        "thread": null,
        "board": "t"
      }
    ],
    "actions": [
      "Sticky"
    ],
    "date": "2022-08-12T05:43:28.800Z",
    "showUser": true,
    "message": null,
    "user": "admin",
    "board": "t"
  }
]

Returns a list of log entries for a board ona a particular date.

HTTP Request

GET https://fatchan.org/{board}/logs/{mm}-{dd}-{yyyy}.json

URL Parameters

Parameter Description
board Board URI.
mm Month of date to fetch log entries from, 01-12.
dd Day of date to fetch log entries from, 01-31.
yyyy Year of date to fetch log entries from, 0000-9999.

Board custom page

curl "https://fatchan.org/t/custompage/example.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getCustomPageOptions := &jschan.GetCustomPageOptions{
  Board: "t",
  CustomPage: "example",
}
custompage, err := client.GetCustomPage(ctx, getCustomPageOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", custompage)

The above command returns JSON structured like this:

{
  "board": "t",
  "page": "example",
  "title": "Example custompage",
  "message": {
    "raw": "Hello, world!\n>12345\n''wow!''",
    "markdown": "Hello, world!\n<span class=\"greentext\">&gt;12345</span>\n<span class=\"bold\">wow!</span>"
  },
  "date": "2022-08-25T11:47:32.073Z",
  "edited": null,
  "_id": "63076154f5e68d47ddd787c4"
}

Returns the data for a board custom page.

HTTP Request

GET https://fatchan.org/{board}/custompage/{page}.json

URL Parameters

Parameter Description
board Board URI.
name Name of the page (same as the name property).

Board banners

curl "https://fatchan.org/t/banners.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getBannersOptions := &jschan.GetBannersOptions{
  Board: "t",
}
banners, err := client.GetBanners(ctx, getBannersOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", banners)

The above command returns JSON structured like this:

[
  "efdff01e8310bd76f6561ea8f34ded9bca1a6ddff067fd9f024d39aad3ebf1ae.png",
  "41bcdcb558954073a45a5faac7ac38f0824108062b5d0236c5b4e891b5278553.jpg"
]

Returns a list of board banner file names. Full path of a banner is /banner/{board}/{filename}.

HTTP Request

GET https://fatchan.org/{board}/banners.json

URL Parameters

Parameter Description
board Board URI.

Board settings

curl "https://fatchan.org/t/settings.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
getSettingsOptions := &jschan.GetSettingsOptions{
  Board: "t",
}
settings, err := client.GetBanners(ctx, getSettingsOptions)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", settings)

The above command returns JSON structured like this:

{
  "customPages": [
    "example"
  ],
  "announcement": {
    "raw": ">lol!",
    "markdown": "<span class=\"greentext\">&gt;lol!</span>"
  },
  "allowedFileTypes": {
    "animatedImage": true,
    "image": true,
    "video": true,
    "audio": true,
    "other": true
  },
  "maxFiles": 5,
  "captchaMode": 0,
  "forceAnon": false,
  "sageOnlyEmail": false,
  "customFlags": false,
  "forceThreadMessage": false,
  "forceThreadFile": false,
  "forceThreadSubject": false,
  "disableReplySubject": false,
  "minThreadMessageLength": 0,
  "minReplyMessageLength": 0,
  "maxThreadMessageLength": 20000,
  "maxReplyMessageLength": 20000,
  "defaultName": "Anon"
}

Returns some publicly available board settings.

HTTP Request

GET https://fatchan.org/{board}/settings.json

URL Parameters

Parameter Description
board Board URI.

Global settings

curl "https://fatchan.org/settings.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
settings, err := client.GetGlobalSettings(ctx)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", settings)

The above command returns JSON structured like this:

{
  "captchaOptions": {
    "type": "text",
    "grid": {
      "size": 4,
      "question": "Select all the odd numbers."
    }
  }
}

Returns some publicly available global settings.

HTTP Request

GET https://fatchan.org/settings.json

Webring

curl "https://fatchan.org/webring.json"
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
webring, err := client.GetWebring(ctx)
if err != nil {
  fmt.Println(err)
  return
}
fmt.Printf("%+v", webring)

The above command returns JSON structured like this:

{
  "name": "fatchan",
  "url": "https://fatchan.org",
  "endpoint": "https://fatchan.org/webring.json",
  "logo": [
    "https://fatchan.org/favicon.ico"
  ],
  "following": [
    "https://anon.cafe/webring.json",
    ...
  ],
  "blacklist": [],
  "known": [
    "https://anon.cafe/webring.json",
    ...
  ],
  "boards": [
    {
      "uri": "t",
      "title": "Meta",
      "subtitle": "Fatchan Official",
      "path": "https://fatchan.org/t/",
      "postsPerHour": 0,
      "postsPerDay": 0,
      "totalPosts": 1410,
      "uniqueUsers": 0,
      "nsfw": false,
      "tags": [
        "meta",
        "t",
        "site",
        "discussion",
        "fatchan",
        "/t/",
        "/meta/",
        "jschan"
      ],
      "lastPostTimestamp": "2021-11-23T01:11:13.122Z"
    }
  ]
}

Returns webring information.

The webring is a system "enabling the collaborating with other imageboards to form a decentralized webring via a standardized schema."

See here for compatible implementations:

HTTP Request

GET https://fatchan.org/webring.json

Create thread/reply

# UNDER CONSTRUCTION...
ctx := context.Background()
client := jschan.NewClient("https://fatchan.org")
makePostOptions := &jschan.MakePostOptions{
  Board:        "test",
  Thread:       277,
  Name:         "Test",
  Message:      ">test",
  Email:        "sage",
  PostPassword: "123",
  Files:        []string{"./image.png"},
}
err := client.MakePost(ctx, makePostOptions)
if err != nil {
  fmt.Println(err)
  return
}

Make a new thread, or reply to an existing thread.

HTTP Request

POST https://fatchan.org/forms/board/{board}/post

Parameters

Parameter Type Description
thread number or null postId of the thread this post is replying to. If null, creates a new thread.
name string Name
message string Message
subject string Subject
email string Email, or special values such as 'sage'.
postpassword string Post password lets users action posts e.g. delete, spoiler, remove files after posting. It's useful to let anonymous users manage their own posts without requiring an account. Users can set it manually, or if they have JavaScript enabled one is randomly generated and stored in localstorage. If the post password is left empty, the post can only be actioned by staff. Staff can also action any post without needing the post password. The ability for anonymous users to action their posts can be disabled on a per-board level.
file file(s) One or more files, multipart form data.
spoiler array(string) Array of sha256 hash of files to be spoilered.
spoiler_all boolean Whether to spoiler all files.
strip_filename array(string) Array of sha256 hash of files to have filenames stripped.. The sha256 hash will be used instead. Note: the server will still receive the original filenames before stripping.
customflag string or null Name of custom flag to be used. If null, will use no flag unless the board also has geoip flags enabled, then it will use the geo flag.
captcha array(number) or string See Captcha/block bypass
signature string Signature output of a web3 eth personal_sign request with the content of the message parameter. Will add a signature and the recovered address to the bottom of the post.

Post actions (delete, report, etc)

# UNDER CONSTRUCTION...

Submit actions against posts e.g. report, spoiler, delete. Supports multiple posts in a single submission. Actions against OP such as delete or move will take replies with it. This endpoint does not require a session cookie or CSRF token like the staff variants, but having valid credentials will allow staff to bypass certain restrictions such as being able to delete posts when the board settings have "user post deletion" disabled. Anonymous users can submit parameters checkedposts, delete, unlink_file, spoiler, postpassword, report, global_report, report_reason and captcha. Multiple actions can be combined e.g. delete+ban. While there are no errors for submitting incompatible actions e.g. delete+report (you cannot report and delete a post simultaneously), the server will handle them in a sensible order, with delete taking precedence.

HTTP Request

POST https://fatchan.org/forms/board/{board}/actions

Parameters

Parameter Type Description
checkedposts array(number) Array of postId's to action against.
delete boolean Delete the selected posts.
spoiler boolean Spoiler all files in the selected posts.
unlink_file boolean Unlink files from the selected posts. If there are other copies of the file in other posts, or the global settings do not immediately prune unlinked files, the file may remain on disk.
postpassword string Post password lets users action posts e.g. delete, spoiler, remove files after posting. It's useful to let anonymous users manage their own posts without requiring an account. Users can set it manually, or if they have JavaScript enabled one is randomly generated and stored in localstorage. If the post password is left empty, the post can only be actioned by staff. Staff can also action any post without needing the post password. The ability for anonymous users to action their posts can be disabled on a per-board level.
report boolean Report the selected posts to board staff.
global_report boolean Report the selected posts to global staff.
report_reason string Reason for reporting, if report or global_report.
captcha array(number) or string See Captcha/block bypass

HTTP Request

POST https://fatchan.org/forms/board/{board}/actions

Staff Endpoints

The following endpoints are only available when properly authenticated and if your account has permission to access the respective pages.

Board staff - create thread/reply

# UNDER CONSTRUCTION...

Make a new thread, or reply to an existing thread. Staff endpoint does not require captcha completion, but requires a CSRF token and session cookie.

HTTP Request

POST https://fatchan.org/forms/board/{board}/modpost

Parameters

Parameter Type Description
_csrf string CSRF token
thread number or null postId of the thread this post is replying to. If null, creates a new thread.
name string Name
message string Message
subject string Subject
email string Email, or special values such as 'sage'.
postpassword string Post password lets users action posts e.g. delete, spoiler, remove files after posting. It's useful to let anonymous users manage their own posts without requiring an account. Users can set it manually, or if they have JavaScript enabled one is randomly generated and stored in localstorage. If the post password is left empty, the post can only be actioned by staff. Staff can also action any post without needing the post password. The ability for anonymous users to action their posts can be disabled on a per-board level.
file file(s) One or more files, multipart form data.
spoiler array(string) Array of sha256 hash of files to be spoilered.
spoiler_all boolean Whether to spoiler all files.
strip_filename array(string) Array of sha256 hash of files to have filenames stripped.. The sha256 hash will be used instead. Note: the server will still receive the original filenames before stripping.
customflag string or null Name of custom flag to be used. If null, will use no flag unless the board also has geoip flags enabled, then it will use the geo flag.

Board staff - post actions

# UNDER CONSTRUCTION...

Submit actions against posts e.g. report, spoiler, delete. Supports multiple posts in a single submission. Actions against OP such as delete or move will take replies with it. This endpoint requires a session cookie and CSRF token, allows staff to use additional actions, and bypass certain restrictions such as being able to delete posts when the board settings have "user post deletion" disabled. Multiple actions can be combined e.g. delete+ban. While there are no errors for submitting incompatible actions e.g. delete+report (you cannot report and delete a post simultaneously), the server will handle them in a sensible order, with delete taking precedence.

HTTP Request

POST https://fatchan.org/forms/board/{board}/modactions

Parameters

Parameter Type Description
_csrf string CSRF token
checkedposts array(number) Array of postId's to action against.
delete boolean Delete the selected posts.
spoiler boolean Spoiler all files in the selected posts.
unlink_file boolean Unlink files from the selected posts. If there are other copies of the file in other posts, or the global settings do not immediately prune unlinked files, the file may remain on disk.
delete_file boolean Forcefully delete files from the selected posts, ignoring other references or server settings for delayed file pruning.
postpassword string Post password lets users action posts e.g. delete, spoiler, remove files after posting. It's useful to let anonymous users manage their own posts without requiring an account. Users can set it manually, or if they have JavaScript enabled one is randomly generated and stored in localstorage. If the post password is left empty, the post can only be actioned by staff. Staff can also action any post without needing the post password. The ability for anonymous users to action their posts can be disabled on a per-board level.
report boolean Report the selected posts to board staff.
global_report boolean Report the selected posts to global staff.
report_reason string Reason for reporting, if report or global_report.
ban boolean Ban the ips for all selected posts from the board.
global_ban boolean Ban the ips for all selected posts globally.
ban_q boolean Ban a small ip range, /24 for ipv4 and /64 for ipv6.
ban_h boolean Ban a larger ip range, /16 for ipv4 and /48 for ipv6.
no_appeal boolean Removes the ability to appeal a ban.
preserve_post boolean Whether to preserve the post and show it in the ban page. If the server prunes files, the files may no longer exist.
hide_name boolean Whether the username of the staff should be hidden from public modlogs.
sticky number Set the sticky priority for a thread. Threads are sorted in descending order, with 0 being the default or not sticky.
lock boolean Toggles if a thread is locked, so no more repies are allowed from unauthenticated users.
bumplock boolean Toggles if a thread is bumplocked, so replies will no longer bump the thread.
cyclic boolean Toggles if a thread is cyclic, i.e. when it reaches thread limit earlier replies are deleted and replaced by new posts instead of locking the thread.
checkedreports array(string) Array of report ids, for report actions such as dismiss or report_ban.
edit boolean Whether to edit the selected post. Staff only. Must have only a single checkedposts.
ban_reason string Reason for banning if ban or global_ban.
log_message string Message to show in modlog explaining the reason for post actions.
ban_duration Time format string Time format string for how long until the ban expires.
report_ban boolean Whether to ban a reporter. Must submit the checkedpost and relevant checkedreports.
move boolean Whether to move selected posts to another thread.
move_to_thread The postId of the destination thread for moving.

Board staff - recent posts

curl -v 'https://fatchan.org/t/manage/recent.json' \
-H 'Cookie: connect.sid=s%REDACTED;'

The above command returns JSON structured like this:

[
  {
    "_id": "6182b5f2013eb3d1e8313300",
    "date": "2021-11-03T16:16:50.257Z",
    "u": 1635956210257,
    "name": "Anon",
    "country": {
      "code": "TOR",
      "name": "Tor Hidden Service"
    },
    "board": "t",
    "tripcode": null,
    "capcode": null,
    "subject": "",
    "message": "<a class=\"quote\" href=\"/t/thread/1376.html#1377\">&gt;&gt;1377</a>\r\nOh yeah. Did you change the default from iwakura to lain? Looks good.",
    "messagehash": "uD7zsFXapRsocZPJzUeroVsND9KvX4FQ0AmAl54FXxg=",
    "nomarkup": ">>1377\r\nOh yeah. Did you change the default from iwakura to lain? Looks good.",
    "thread": 1376,
    "email": "",
    "spoiler": false,
    "banmessage": null,
    "userId": "546403",
    "ip": {
      "raw": "redacted",
      "cloak": "redacted"
    },
    "files": [],
    "reports": [],
    "quotes": [
      {
        "_id": "61820031804c0bf6d2271026",
        "thread": 1376,
        "postId": 1377
      }
    ],
    "crossquotes": [],
    "backlinks": [
      {
        "_id": "6182ba0da5af18e5ee5b3f2b",
        "postId": 1382
      }
    ],
    "postId": 1381
  }
]

Returns a list of the most recent posts made on a specific board.

HTTP Request

GET https://fatchan.org/{board}/manage/recent.json

URL Parameters

Parameter Type Description
board string The board to fetch recent posts from.

Query Parameters

Parameter Default Description
page Page number. 30 per page. Blank is first page. Page numbering starts at 1.

Board staff - reports

curl -v 'https://fatchan.org/t/manage/reports.json' \
-H 'Cookie: connect.sid=s%REDACTED;' 

The above command returns JSON structured like this:

{
  "reports": [
    {
      "_id": "61a06777c3ba8becf5be6303",
      "date": "2021-11-26T04:49:59.832Z",
      "u": 1637902199832,
      "name": "Anon",
      "country": {
        "code": "TOR",
        "name": "Tor Hidden Service"
      },
      "board": "test",
      "tripcode": null,
      "capcode": null,
      "subject": "",
      "message": "test",
      "messagehash": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=",
      "nomarkup": "test",
      "thread": null,
      "email": "",
      "spoiler": false,
      "banmessage": null,
      "userId": "1e22fb",
      "ip": {
        "raw": "redacted",
        "cloak": "redacted"
      },
      "files": [],
      "reports": [
        {
          "id": "61a63249a2e147d7c0f382dd",
          "reason": "test",
          "date": "2021-11-30T14:16:41.780Z",
          "ip": {
            "cloak": "redacted"
          }
        }
      ],
      "quotes": [],
      "crossquotes": [],
      "backlinks": [],
      "replyposts": 0,
      "replyfiles": 0,
      "sticky": 0,
      "locked": 0,
      "bumplocked": 0,
      "cyclic": 0,
      "bumped": "2021-11-26T04:49:59.832Z",
      "postId": 224
    }
  ]
}

Returns a list of posts that were reported with the board reports attached.

HTTP Request

GET https://fatchan.org/{board}/manage/reports.json

Global staff - post actions

# UNDER CONSTRUCTION...

Submit actions against posts e.g. report, spoiler, delete. Supports multiple posts in a single submission. Actions against OP such as delete or move will take replies with it. This endpoint requires a session cookie and CSRF token, allows global staff to use additional actions, and bypass restrictions. Multiple actions can be combined e.g. delete+ban. While there are no errors for submitting incompatible actions e.g. delete+report (you cannot report and delete a post simultaneously), the server will handle them in a sensible order, with delete taking precedence. Certain actions such as "move" are not present compared to the board-specific endpoints because global actions can apply to posts from multiple different boards. Global actions use posts _id (mongo id) in the globalcheckedposts array instead of postIds because global actions can apply to posts from multiple different boards and cannot just reference postIds.

HTTP Request

POST https://fatchan.org/forms/global/actions

Parameters

Parameter Type Description
globalcheckedposts array(string) Array of post _ids to action against.
delete boolean Delete the selected posts.
spoiler boolean Spoiler all files in the selected posts.
unlink_file boolean Unlink files from the selected posts. If there are other copies of the file in other posts, or the global settings do not immediately prune unlinked files, the file may remain on disk.
delete_file boolean Forcefully delete files from the selected posts, ignoring other references or server settings for delayed file pruning.
global_report boolean Report the selected posts to global staff.
global_ban boolean Ban the ips for all selected posts globally.
ban_q boolean Ban a small ip range, /24 for ipv4 and /64 for ipv6.
ban_h boolean Ban a larger ip range, /16 for ipv4 and /48 for ipv6.
no_appeal boolean Removes the ability to appeal a ban.
preserve_post boolean Whether to preserve the post and show it in the ban page. If the server prunes files, the files may no longer exist.
hide_name boolean Whether the username of the staff should be hidden from public modlogs.
checkedreports array(string) Array of report ids, for report actions such as dismiss or report_ban.
edit boolean Whether to edit the selected post. Staff only. Must have only a single checkedposts.
ban_reason string Reason for banning if ban or global_ban.
log_message string Message to show in modlog explaining the reason for post actions.
ban_duration Time format string Time format string for how long until the ban expires.
report_ban boolean Whether to ban a reporter. Must submit the checkedpost and relevant checkedreports.
_csrf string CSRF token

Global staff - clear bypasses or login sessions

curl -v 'https://fatchan.org/forms/global/clear' -X POST \
-H 'Cookie: connect.sid=s%REDACTED;' \
--data "table=blockbypass" --data "confirm=1"

This endpoint allows you to delete all login sessions or block bypasses. Shares permissions with global manage settings (MANAGE_GLOBAL_SETTINGS permission).

HTTP Request

POST https://fatchan.org/forms/global/clear

Parameters

Parameter Type Description
table string 'sessions' or 'blockbypass', whether to clear login sessions or blockbypasses.
confirm string any value, set to confirm that you want to delete all sessions or blockbypasses
_csrf string CSRF token

Global staff - reports

curl -v 'https://fatchan.org/globalmanage/reports.json' \
-H 'Cookie: connect.sid=s%REDACTED;'

The above command returns JSON structured like this:

{
  "reports": [
    {
      "_id": "61a06777c3ba8becf5be6303",
      "date": "2021-11-26T04:49:59.832Z",
      "u": 1637902199832,
      "name": "Anon",
      "country": {
        "code": "TOR",
        "name": "Tor Hidden Service"
      },
      "board": "test",
      "tripcode": null,
      "capcode": null,
      "subject": "",
      "message": "test",
      "messagehash": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=",
      "nomarkup": "test",
      "thread": null,
      "email": "",
      "spoiler": false,
      "banmessage": null,
      "userId": "1e22fb",
      "ip": {
        "raw": "redacted",
        "cloak": "redacted"
      },
      "files": [],
      "globalreports": [
        {
          "id": "61a63249a2e147d7c0f382dd",
          "reason": "test",
          "date": "2021-11-30T14:16:41.780Z",
          "ip": {
            "cloak": "redacted"
          }
        }
      ],
      "quotes": [],
      "crossquotes": [],
      "backlinks": [],
      "replyposts": 0,
      "replyfiles": 0,
      "sticky": 0,
      "locked": 0,
      "bumplocked": 0,
      "cyclic": 0,
      "bumped": "2021-11-26T04:49:59.832Z",
      "postId": 224
    }
  ],
  "page": 1,
  "ip": null,
  "queryString": ""
}

Returns a list of posts that were globally reported with the global reports attached.

HTTP Request

GET https://fatchan.org/globalmanage/reports.json

Query Parameters

Parameter Default Description
page Page number. 30 per page. Blank is first page. Page numbering starts at 1.
ip Urlencoded IP address or cloak. Filters results to only posts made or reported by the IP.

Global staff - recent posts

curl -v 'https://fatchan.org/globalmanage/recent.json' \
-H 'Cookie: connect.sid=s%REDACTED;' 

The above command returns JSON structured like this:

[
  {
    "_id": "619c4cd4c3ba8becf5be62eb",
    "date": "2021-11-23T02:07:16.339Z",
    "u": 1637633236339,
    "name": "Anon",
    "country": null,
    "board": "b",
    "tripcode": null,
    "capcode": null,
    "subject": null,
    "message": "<a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://m.youtube.com/watch?v=Fiv7nteHZPY&amp;feature=emb_title\">https://m.youtube.com/watch?v=Fiv7nteHZPY&amp;feature=emb_title</a>\r\n\r\nPresenting, life of childe",
    "messagehash": "yzBCT0RFSk7PWwHipZdetIkymJc7HDbth2d5uVQFokk=",
    "nomarkup": "https://m.youtube.com/watch?v=Fiv7nteHZPY&feature=emb_title\r\n\r\nPresenting, life of childe",
    "thread": 109,
    "email": null,
    "spoiler": false,
    "banmessage": null,
    "userId": null,
    "ip": {
      "raw": "redacted",
      "cloak": "redacted"
    },
    "files": [],
    "globalreports": [],
    "quotes": [],
    "crossquotes": [],
    "backlinks": [],
    "postId": 311
  }
]

Returns a list of the most recent posts made across all boards.

HTTP Request

GET https://fatchan.org/globalmanage/recent.json

Query Parameters

Parameter Default Description
page Page number. 30 per page. Blank is first page. Page numbering starts at 1.

Global staff - board list

curl -v 'https://fatchan.org/globalmanage/boards.json' \
-H 'Cookie: connect.sid=s%REDACTED;' 

The above command returns JSON structured like this:

{
  "localBoards": [
    {
      "_id": "lain",
      "owner": "redacted",
      "tags": [
        "lain",
        "internet",
        "technology",
        "transhumanism",
        "anime",
        "manga",
        "japan"
      ],
      "sequence_value": 572,
      "pph": 0,
      "ppd": 2,
      "ips": 2,
      "lastPostTimestamp": {
        "text": "5 hours ago",
        "color": "#83d900"
      },
      "webring": false,
      "settings": {
        "moderators": [],
        "name": "serial experiments lain",
        "description": "ANIME / GAME / PRINT / SOFTWARE",
        "sfw": true,
        "unlistedLocal": false
      }
    },
    {
      "_id": "b",
      "owner": "redacted",
      "sequence_value": 323,
      "pph": 0,
      "ips": 2,
      "lastPostTimestamp": {
        "text": "27 minutes ago",
        "color": "#31d900"
      },
      "settings": {
        "moderators": [],
        "name": "Random",
        "description": "Where morons argue with baiting spammers",
        "sfw": false,
        "unlistedLocal": false
      },
      "ppd": 2,
      "tags": [
        "random",
        "b",
        "rand",
        "anything",
        "everything"
      ],
      "webring": false
    },
  ],
  "page": 1,
  "maxPage": 1
}

Returns a list of boards, 30 per page. Unlike the public endpoint it does not include webring boards, includes unlisted boards and shows whether a board is abandoned (has no owner). Can be filtered and sorted like the public board list.

HTTP Request

GET https://fatchan.org/globalmanage/boards.json

Query Parameters

Parameter Default Description
page Page number. 30 per page. Blank is first page. Page numbering starts at 1.
search A string to search by board name and tags, including prefix matches.
sort popularity popularity sorts by a compound of (ips, pph, sequence_value), activity sorts by lastPostTimestamp.
direction desc desc or asc for descending or ascending sort order respectively.
filter_unlisted false Filter to only unlisted boards.
filter_sfw false Filter to only sfw boards.
filter_abandoned false Filter to only abandoned boards.

Filters used in conjunction will AND together. That is, filter_unlited=true&filter_sfw=true will show only boards that are both unlisted and sfw.

Authentication

Register

curl -v 'https://fatchan.org/forms/register' -X POST \
-H 'Referer: https://fatchan.org/registration.html' -H 'x-using-xhr: true' \
--data "username=admin" --data "password=hunter2" --data "passwordconfirm=hunter2" --data "captcha=abc123"

# if the account is created successfully, 302 redirect to login.
...
< HTTP/2 302 
< location: /login.html
...

Registers a new account.

HTTP Request

POST https://fatchan.org/forms/register

Parameters

Parameter Type Description
username string Account username
password string Account password
passwordconfirm string Account password repeated
captcha array(number) or string See Captcha/block bypass
nonce string Optional, for web3 registration: the nonce fetched from the nonce endpoint
address string Optional, for web3 registration: eth address
signature string Optional, for web3 registration: web3 signature output of signing the nonce

Login

curl -v 'https://fatchan.org/forms/login' -X POST \
-H 'Referer: https://fatchan.org/login.html' -H 'x-using-xhr: true' \
--data "username=admin" --data "password=hunter2"

# if the password is correct, 302 response code and sets the 'connect.sid' cookie
...
< HTTP/2 302 
< location: /account.html
< set-cookie: connect.sid=s%REDACTED; Path=/; Expires=Wed, 01 Dec 2021 10:35:03 GMT; HttpOnly; Secure; SameSite=Strict
...

# or, for an incorrect password, a 403 and an error
...
< HTTP/2 403
...
{"title":"Forbidden","message":"Incorrect username or password","redirect":"/login.html?goto=%2Faccount.html"}

Login to an account to get a session cookie. The connect.sid cookie must be sent in requests to endpoints that require authentication. Expiry is rolling, so each time the session is used, the expiry is reset to 24 hours and this will be reflected in the expiry value in set-cookie headers.

HTTP Request

POST https://fatchan.org/forms/login

Parameters

Parameter Type Description
username string Account username
password string Account password
nonce string Optional, for web3 login: the nonce fetched from the nonce endpoint
address string Optional, for web3 login: eth address
signature string Optional, for web3 login: web3 signature output of signing the nonce

Logout

curl 'https://fatchan.org/forms/logout' -X POST \
-H 'Referer: https://fatchan.org/account.html' -H 'x-using-xhr: true' \
-H 'Cookie: connect.sid=s%REDACTED;'

Logs out and invalidate the connect.sid session cookie.

HTTP Request

POST https://fatchan.org/forms/logout

CSRF token

curl -v 'https://fatchan.org/csrf.json' \
-H 'Referer: https://fatchan.org/csrf.json' \
-H 'Cookie: connect.sid=s%REDACTED;'

# Returns a csrf token if the session cookie is valid.
...
< HTTP/2 200
...
{"token":"REDACTED"}

Returns a token used as an additional security field by some endpoints. For more information about CSRF (cross site request forgery), see https://owasp.org/www-community/attacks/csrf'

HTTP Request

GET https://fatchan.org/csrf.json

Captcha/block bypass

To solve a captcha when posting, or to separately solve a block bypass, submit the captchaid cookie and data captcha. Depending on captcha type, there are different options. The example requests below are for blockbypass endpoint, however the same captchaid cookie and captcha data should be submitted to the reporting and posting endpoint when captcha is enabled. If a form submission requires a block bypass and the form also requires a captcha, solving the captcha correctly will count as a block bypass, so it is not necessary to solve an additional block bypass captcha beforehand.


# Get a captchaid cookie
curl -v 'https://fatchan.org/captcha'

# returns 302 to the captcha image, and sets the cookie.
< HTTP/2 302
< set-cookie: captchaid=61b55e3e49e367be7c5a818c; Max-Age=300; Path=/; Expires=Sun, 12 Dec 2021 02:33:14 GMT; Secure; SameSite=Strict
< location: /captcha/61b55e3e49e367be7c5a818c.jpg
...

Web3 Nonce

curl -v 'https://fatchan.org/nonce/{address}.json' -X POST \
-H 'Referer: https://fatchan.org/login.html' \

# Returns json with the nonce
...
< HTTP/2 200 OK 
...
< {"nonce":"diPRlfjSVQs78DGE3YKcENb4pgRqB1Bdlv3RH/yiE6Y="}
...

Fetches a nonce used as part of the web3 login process.

### HTTP Request

`GET https://fatchan.org/nonce/{address}.json`

### URL Parameters

Parameter | Type | Description
--------- | ---- | -----------
address | string | Ethereum address e.g. 0x68b637f227953eeb081a3b591c218adbeaa4c489

### Captcha cookie

To solve a captcha, you need a `captchaid` cookie.

Visiting `/captcha` will set the captchaid cookie (if you do not already have one), and redirect you to the captcha image `/captcha/<captchaid>.jpg`.

The cookie is required to be submitted when solving the captcha as described in the next sections. Captcha id cookies are valid for ~5 minutes in a default jschan configuration.

### HTTP Request

`GET https://fatchan.org/captcha`

```shell
# Grid v1 captcha example
curl 'https://fatchan.org/forms/blockbypass' -X POST \
-H 'Referer: https://fatchan.org/bypass.html' -H 'x-using-xhr: true' \
-H 'Cookie: captchaid=61a60064a2e147d7c0f382d8' \
--data 'captcha=1' --data 'captcha=3' --data 'captcha=11'

# returns 200 and a bypassid cookie if correct
< HTTP/2 200
< set-cookie: bypassid=s%REDACTED; Max-Age=86400; Path=/; Expires=Wed, 01 Dec 2021 11:12:21 GMT; Secure; SameSite=Strict
{"title":"Success","message":"Completed block bypass, you may go back and make your post."}

Grid v1 captcha

Grid v1 captcha consists of a nxn (by default 4x4) square grid of characters, and a question text. The characters are separated into "correct" and "incorrect" character groups, with a minimum of at least one correct character in the grid. Follow the question text and select only the "correct" characters. The character groups and question text can be completely customised, so it is not possible to document exact instructions for each. The captcha may have image effects applied such as noise, edge detection and distortion.

The default grid v1 configuration of jschan is:

The grid positions start from 0 and go from left to right, top to bottom i.e:

0123
4567
891011
12131415

Example (the example request is for this image):

Question: "Select the solid/filled icons"

0123
4567
891011
12131415

The solution is 1, 3, 11.

Other examples:

Question: "Select the odd numbers"

0123
4567
891011
12131415

The solution is 1, 3, 4, 12, 13, 14.

HTTP Request

POST https://fatchan.org/forms/blockbypass

Parameters

Parameter Type Description
captcha array(number) One or more numbers for the correct grid square indexes.
# Grid v2 captcha example
curl 'https://fatchan.org/forms/blockbypass' -X POST \
-H 'Referer: https://fatchan.org/bypass.html' -H 'x-using-xhr: true' \
-H 'Cookie: captchaid=61a60064a2e147d7c0f382d8' \
--data 'captcha=2' --data 'captcha=6' --data 'captcha=11' --data 'captcha=14'

# returns 200 and a bypassid cookie if correct
< HTTP/2 200
< set-cookie: bypassid=s%REDACTED; Max-Age=86400; Path=/; Expires=Wed, 01 Dec 2021 11:12:21 GMT; Secure; SameSite=Strict
{"title":"Success","message":"Completed block bypass, you may go back and make your post."}

Grid v2 captcha

Grid v2 captcha consists of a nxn (by default 4x4) square grid of characters and arrows, and a question text. The characters are separated into "correct" and "incorrect" character groups, with one correct character in the grid. The rest of the grid will be incorrect characters and arrows. The objective is to select all arrows pointing at the "correct" character. The character groups (excluding arrows) and question text can be completely customised, so it is not possible to document exact instructions for each. The captcha may have image effects applied such as noise, edge detection and distortion. Grid v2 configuration is shared with v1.

The grid positions start from 0 and go from left to right, top to bottom i.e:

0123
4567
891011
12131415

Example (the example request is for this image):

0123
4567
891011
12131415

The solution is 2, 6, 11, 14.

HTTP Request

POST https://fatchan.org/forms/blockbypass

Parameters

Parameter Type Description
captcha array(number) One or more numbers for the correct grid square indexes.

# Text captcha example
curl 'https://fatchan.org/forms/blockbypass' -X POST \
-H 'Referer: https://fatchan.org/bypass.html' -H 'x-using-xhr: true' \
-H 'Cookie: captchaid=61a60064a2e147d7c0f382d8' \
--data 'captcha=bxw9yt'

# returns 200 and a bypassid cookie if correct
< HTTP/2 200 
< set-cookie: bypassid=s%REDACTED; Max-Age=86400; Path=/; Expires=Wed, 01 Dec 2021 11:12:21 GMT; Secure; SameSite=Strict
{"title":"Success","message":"Completed block bypass, you may go back and make your post."}

Text captcha

Text captcha is a simple 6 character captcha containing numbers and letters only. The captcha may have a different font, and image effects applied such as wave, noise, paint, strikethrough, and distortion.

Example (the example request is for this image):

Solution: bxw9yt.

Other examples:

Solution: 3dhm6f.

Solution: lcvpya.

Solution: xnkosc.

HTTP Request

POST https://fatchan.org/forms/blockbypass

Parameters

Parameter Type Description
captcha string The text shown in the image.

Objects & Properties

Board

Two example boards. The first a webring board, the second a local board.

{
  "_id": "61a45ea2c5f3b57f31789cfc",
  "uri": "a",
  "sequence_value": 709261,
  "ips": 109,
  "pph": 25,
  "webring": true
  "path": "https://smuglo.li/a",
  "siteName": "Smug",
  "lastPostTimestamp": {
    "text": "12 minutes ago",
    "color": "#14d900"
  },
  "settings": {
    "sfw": false,
    "name": "Anime & Manga",
    "description": "Stay away from 3DPD"
  },
  "tags": [
    "anime",
    "manga"
  ]
}
{
  "_id": "b",
  "sequence_value": 320,
  "ips": 4,
  "pph": 0,
  "ppd": 5,
  "webring": false
  "lastPostTimestamp": {
    "text": "1 hour ago",
    "color": "#72d900"
  },
  "settings": {
    "name": "Random",
    "description": "Anything and everything",
    "sfw": false,
    "unlistedLocal": false
  },
  "tags": [
    "random",
    "b",
    "rand",
    "anything",
    "everything"
  ],
},

Returned from boards endpoint and global staff boards endpoint. Can be a local board, or one fetched from a federated site through the "webring" system. Local and webring boards have slightly different data.

Parameters

Parameter Type Description
_id string The board URI if webring is false, otherwise a unique identifier for a webring board.
uri string The board URI if webring is true, otherwise not present.
sequence_value number The current highest post number.
ips number Number of IPs from active users. In webring false boards, represents the number of unique IPs that have posted in the last 24 hours. In webring true, implementations vary and the timeframe may be different.
pph number Number of posts made in the last hour.
ppd number Number of posts made in the last day. Not present in all webring implementations.
webring boolean Whether a board is a webring board, or a local board.
path string The URL of the board if webring true, otherwise not present.
siteName string The site name if webring true, otherwise not preesnt.
lastPostTimestamp object
lastPostTimestamp.text string Text representation of when the last post was made e.g. "13 minutes ago".
lastPostTimestamp.color string Text of a hexadecimal color code prefixed with # e.g. "#14d900".
settings object
settings.sfw boolean Whether the board is "safe for work".
settings.name string The board name.
settings.description string The board description.
settings.unlistedLocal boolean Whether the board is unlisted locally if webring false, otherwise not present. Always false on public boards endpoint.
settings.moderators array(string) List of usernames of moderators, only present in global staff board list.
owner string Board owner username, only present in global staff board list.
tags array(string) List of tags for the board.

Post

An example post

{
  "_id": "6158e81eb33d7abaa5f90ba0",
  "date": "2021-10-02T23:15:42.675Z",
  "u": 1633216542675,
  "name": "Anon",
  "country": {
    "code": "AU",
    "name": "Australia"
  },
  "ip": {
    "raw": "redacted",
    "cloak": "redacted"
  },
  "board": "t",
  "tripcode": null,
  "capcode": "## Admin",
  "subject": "Important Links",
  "message": "<span class=\"title\">Git repository &amp; issue tracker:</span> <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://gitgud.io/fatchan/jschan\">https://gitgud.io/fatchan/jschan</a>\nGo here to see the source code, report issues or ask relevant questions.\n\n<span class=\"title\">IRC:</span> <a rel=\"nofollow\" referrerpolicy=\"same-origin\" target=\"_blank\" href=\"https://irc-web.fatpeople.lol\">https://irc-web.fatpeople.lol</a> (irc-web.fatpeople.lol port 6697 TLS on)\nJoin IRC to chat directly with staff and other users in a realtime format.\n\n<span class=\"title\">Test board:</span> <a class=\"quote\" href=\"/test/index.html\">&gt;&gt;&gt;/test/</a>\nTest things on the /test/ board rather than here or anywhere else.",
  "messagehash": "tkak9s72dCSv9XkocVNwceUfmtwqaTH8gL9bzcQxwP4=",
  "nomarkup": "==Git repository & issue tracker:== https://gitgud.io/fatchan/jschan\nGo here to see the source code, report issues or ask relevant questions.\n\n==IRC:== https://irc-web.fatpeople.lol (irc-web.fatpeople.lol port 6697 TLS on)\nJoin IRC to chat directly with staff and other users in a realtime format.\n\n==Test board:== >>>/test/\nTest things on the /test/ board rather than here or anywhere else.",
  "thread": null,
  "email": "",
  "spoiler": false,
  "banmessage": null,
  "userId": "307203",
  "files": [],
  "quotes": [],
  "crossquotes": [],
  "backlinks": [],
  "replyposts": 0,
  "replyfiles": 0,
  "sticky": 3,
  "locked": 1,
  "bumplocked": 0,
  "cyclic": 0,
  "bumped": "2021-10-02T23:15:42.675Z",
  "postId": 1360,
  "edited": {
    "username": "admin",
    "date": "2021-11-03T00:36:36.620Z"
  },
  "replies": []
}

Returned from overboard endpoints, board endpoints, staff recent posts and staff reports endpoints. A post can be a thread of a reply. The thread being the first post under which replies are made. Threads include a few extra properties for things such as being "sticky". Where included (such as index pages and threads), replies are nested within the "replies" property of a thread.

Parameters

Parameter Type Description
_id string Unique identifier for the post.
date string The ISO format date string of when the post was made.
u string Unix timestamp format of when the post was made.
name string The poster name.
board string The board URI.
country object Geoip or custom flag information, if enabled on a board.
country.code string Custom flag name if country.custom is true. Otherwise ISO 2 character country code, or "T1" for Tor exit nodes, "TOR" for Tor .onion, "LOKI" for lokinet, or "XX" for unknown (no geoip information).
country.name string Custom flag name if country.custom is true. Otherwise the country name. "Europe" for unknown european country. "Unknown" when no geoip information is available. "Tor Exit Node" for Tor exit node. "Tor Hidden Service" for Tor .onion.
country.custom boolean Whether the flag is a board custom flag.
country.src string The filename of a board custom flag. The absolute path of the flag file is /flag/{board}/{country.src}.
ip object
ip.raw string IP (or ip.cloak if raw ips are not stored).
ip.cloak string Cloaked IP.
tripcode string or null The tripcode if one was used, otherwise null. Traditional ("insecure") tripcodes start with !, "secure" tripcodes use !!.
capcode string or null The staff capcode if one is used e.g. '## Admin'.
subject string The post subject.
message string HTML formatted message
nomarkup string Original message before HTML formatting.
messagehash string sha256 hash of nomarkup.
postId number The post number, increasing by 1 for each post.
thread number of null For threads, null. For replies, a number equal to the postId of the thread.
email string or null The poster email. Not necessarily an email, can be any string or special values like "sage" meaning the post will not bump a thread.
spoiler boolean Whether all files in a post are spoilered.
signature string or null Web3 eth personal_sign signature of signed message content.
address string or null Recovered ethereum address from web3 signature.
banmessage string or null The public ban message attached to a post, optionally set when a staff member bans the poster without deleting the post.
userId string or null The user ID which is a substring of a hash of poster IP + server side per-thread secret e.g. substring(hash(poster IP + thread secret)).
files array(File) Array of files, explained in the File subsection
quotes array(object) Array of quotes, posts within the same thread that this post mentions.
quotes[]._id string Corresponds to the _id property of a post.
quotes[].thread number Corresponds to the thread property of a post.
quotes[].postId number Corresponds to the postId property of a post.
crossquotes array(object) Array of crossquotes, posts in other threads on the same board that this post mentions.
crossquotes[]._id string Corresponds to the _id property of a post.
crossquotes[].thread number Corresponds to the thread property of a post.
crossquotes[].postId number Corresponds to the postId property of a post.
backlinks array(object) Array of backlinks, posts in the same thread that mention this post.
backlinks[]._id string Corresponds to the _id property of a post.
backlinks[].postId number Corresponds to the postId property of a post.
replyposts number Threads only, the number of replies to this post.
replyfiles number Threads only, the total number of files in all replie sto this post.
sticky number Threads only, The "sticky" priority of a thread. Higher number = higher priority and sorted earlier. 0 = Not sticky.
locked number Threads only, 0 = not locked, 1 = locked. Locked prevents non-staff from replying to the thread.
cyclic number Threads only, 0 = not cyclic, 1 = locked. Cyclic means earlier replies will be deleted to make room for new replies, instead of the thread reaching a bump limit and locking.
bumplocked number Threads only, 0 = not locked, 1 = locked. Bumplocked prevents the thread from being bumped when a reply is posted.
bumped string Threads only, the ISO format date string of when the thread was last bumped. Note, this is not equal to the date of the most recent reply because it could have used "sage" email, the thread may be bumplocked, or have reached the bump limit.
edited object Object with information about when the post was last edited.
edited.username string Username of the staff who edited the post.
edited.date string ISO format date string of when the post was edited.
replies array(Post) Array of replies (other non-thread posts). Only present in threads, or index pages with > 0 preview replies.
reports array(Report) Array of board reports. Only present when fetched from board staff endpoints.
globalreports array(Report) Array of global reports. Only present when fetched from global staff endpoints.

File

An example file

{
  "spoiler": null,
  "hash": "10e24a1eef06d36d29a30f60e4616ef8cea9050c8f1e13b80af75b01687ef1fa",
  "filename": "10e24a1eef06d36d29a30f60e4616ef8cea9050c8f1e13b80af75b01687ef1fa.jpg",
  "originalFilename": "10e24a1eef06d36d29a30f60e4616ef8cea9050c8f1e13b80af75b01687ef1fa.jpg",
  "mimetype": "image/jpeg",
  "size": 259561,
  "extension": ".jpg",
  "sizeString": "253.5KB",
  "thumbextension": ".jpg",
  "geometry": {
    "width": 1024,
    "height": 768,
    "thumbwidth": 250,
    "thumbheight": 187
  },
  "geometryString": "1024x768",
  "hasThumb": true
}

Files uploaded by users, in the files array of a Post object.

Parameter Type Description
spoiler boolean If the individual file is spoilered
hash string Sha256 hash of the file
filename string Filename (sha256sum + extension). Absolute path of files are /file/{filename}
originalFilename string The original filename (non hash) of the file when uploaded.
mimetype string Mimetype of the file e.g. "image/png" or "video/webm"
extension string The file extension with . e.g. ".jpg"
size number Size in bytes of the file
sizeString string Friendly string format of filesize, a number with up to 1 decimal place followed by the unit B, KB, MB, GB, TB.
duration number Floating point number, how many seconds a video or audio file is.
durationString string Friendly string format of duration, in hours:minutes:seconds format. Hours are the largest unit and can be a number larger than 99. Number in each segment are left padded with 0. Duration less than 60 seconds will have 00: prefixed. Will not show 00: for hours. e.g. 35 seconds = 00:35, 1 minute 25 seconds = 01:35, 1 hour 35 minutes = 01:35:00
thumbextension string The file extension of the thumbnail with . e.g. ".jpg". Can be different from extension due to thumbnails using different format.
geometry object Object containing information about file and thumbnail dimensions.
geometry.width string Width in pixels of the file.
geometry.height string Height in pixels of the file.
geometry.thumbwidth string Width in pixels of the thumbnail.
geometry.thumbheight string Height in pixels of the thumbnail.
geometryString string Friendly string format of the file geometry as {width}x{height}.
hasThumb boolean Whether the file has a thumbnail.
attachment boolean Whether the file is an "attachment" type, a file that is not an image, video or audio.

Report

An example report

{
  "id": "61a5d504ed285eccf2909dee",
  "reason": "spam",
  "date": "2021-11-30T07:38:44.971Z",
  "ip": {
    "raw": "redacted",
    "cloak": "redacted"
  }
}
Parameter Type Description
id string Unique identifier of the report.
reason string Report reason entered by the reporter.
date string ISO format date string when the report was made.
ip object
ip.raw string IP (or ip.cloak if raw ips are not stored).
ip.cloak string Cloaked IP.

Webring.json

Example webring.json data

{
  "name": "fatchan",
  "url": "https://fatchan.org",
  "endpoint": "https://fatchan.org/webring.json",
  "logo": [
    "https://fatchan.org/favicon.ico"
  ],
  "following": [
    "https://anon.cafe/webring.json",
    ...
  ],
  "blacklist": [],
  "known": [
    "https://anon.cafe/webring.json",
    ...
  ],
  "boards": [
  ]
}

Webring.json data.

Parameter Type Description
name string The name of this site.
url string The primary url of this site.
endpoint string The url of the webring.json file. Typically {url}/webring.json
logo array(string) Array of URLs to logo images to use.
following array(string) Array of URLs of other sites endpoint to follow.
known array(string) Array of known endpoints found through crawling, starting from endpoints in following.
blacklist array(string) Array of hostnames to blacklist and not crawl.
boards array(Webring Board) Array of webring-listed board on this site in webring format.

Webring.json board

Example webring.json board

{
  "uri": "t",
  "title": "Meta",
  "subtitle": "Fatchan Official",
  "path": "https://fatchan.org/t/",
  "postsPerHour": 0,
  "postsPerDay": 0,
  "totalPosts": 1410,
  "uniqueUsers": 0,
  "nsfw": false,
  "tags": [
    "meta",
    "t",
    "site",
    "discussion",
    "fatchan",
    "/t/",
    "/meta/",
    "jschan"
  ],
  "lastPostTimestamp": "2021-11-23T01:11:13.122Z"
}

A board from webring.json.

Parameter Type Description
uri string The uri of the board on this site.
title string The board title/name.
subtitle string The board subtitle.
path string Full URL of the board.
postsPerHour number Number of posts made per hour on this board.
postsPerDay number Number of posts made per day on this board.
totalPosts number The total number of posts ever made on this board.
uniqueUsers number The number of unique user IP/IDs that have posted on this board in the past 24 hours.
nsfw boolean Whether the board is nsfw (not safe for work).
tags array(string) List of tags for the board.
lastPostTimeStamp string ISO format date string of when the last post was made on the board.

Miscellaneous

Time format string

Some moderation interfaces, for example the ban duration when moderating posts, or the ban duration for post filtering use a shorthand for times/length. This format supports years, months, weeks, days, hours, minutes and seconds. An input of "3mo" would mean 3 months and "1y2mo3w4d5h6m7s" would mean 1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes and 7 seconds. Units of time should be in descending order, so "2w1mo" is invalid. However you may use "6w" for example to input 6 weeks, and are not required to use "1mo2w".

Errors

The jschan API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
403 Forbidden -- You are not logged in, or do not have permission to access the requested resource.
404 Not Found -- The specified resource could not be found.
405 Method Not Allowed -- You tried to access a resource with an invalid method.
429 Too Many Requests -- You're sending too many requests too quickly.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.