HF API Documentation - SIM-2015410 - Apr 21, 2017
Hack Forums API
Documentation
Today we celebrate the 10th Anniversary of Hack Forums! As has been rumoured about in the past few weeks, in honour of 10 years of HF, we now have an API! The features are currently only available to UB3R members, while R3KT members will often be given early access to new features for beta testing.
The API has been currently READ ONLY, to ensure everything is working correctly. More active abilities such as posting replies to threads and replying to PMs will be added with time.
The current features are:- User info (GET /user/:id)
- Multiple users info (GET /users/:ids)
- Forum navigation (GET /category/:id)
- Forum info (GET /forum/:id)
- Thread info (GET /thread/:id)
- Post info (GET /post/:id)
- Private message info (GET /pm/:id)
- List of PMs in inbox and other pm boxes (GET /pmbox/:id or GET /inbox)
- Group info (GET /group/:id)
Every request must be accompanied by your personal API KEY, which is entered in the username field of the HTTP Basic authentication header.
The version number of the API can be obtained with the following call:
https://hackforums.net/api/v1/?version
Getting your API key- First things first, you need to generate an API key to use the API. R3kt members can do this by visiting this page here:
You API key will be a random 32 character string of numbers and letters, and is case sensitive. You can view it any time on the key page so you don't need to write it down or back it up. But it is important that you DON'T SHARE YOUR KEY WITH ANYONE. Anyone with your key will be able to read your PMs, and eventually reply and post as you on the forum.
You can also delete your key on this page (do this immediately if you accidentally share your key with someone, etc.) and then generate a new key. Goes without saying, but keys are still logged and doing this will not bypass the hourly call limit, so abusing the key generation feature (e.g. for vanity keys or something similar) will result in a ban.
Finally, using this page you can lock your key to the specific IP address it was created with. In v2 we may allow ranges of IPs to be whitelisted but this is currently unavailable. This is for use with, for example, a static IP server you are using to read data from the API, for security purposes. Once locked, the only way to unlock the key is to delete it and create a new one.
The apikey page also displays a QR code of your key for easy use with mobile apps.
If you are a developer and wish to apply for a developer key (including 3x higher rate limits), please apply directly to Omni.
Authentication- If you visit an API URI in your browser, you will be prompted to authenticate as in this screenshot (this is with chrome, other browsers are similar):
![[Image: nM77koZ.png]](https://imgur.com/nM77koZ.png)
Copy your API key into the username field of the prompt, leaving the password field blank, and click Log In.
Your browser will cache your key for a while so you won't be prompted every single call.
When using the API in code, use the following header:
Authorization: Basic XXXXXX
Replace XXXXXX with base64 encoded username:password
Username is the key, password is empty
(Jul 6, 2017 05:06 AM)xadamxk Wrote: Jquery has a fancy little call for passing the params that I never knew about xD
Code $.ajax({
type: "GET",
url: "https://"+siteAPI+"/api/v1/user/"+sender,
dataType: 'json',
async: false,
username: apikey,
password: "",
success: function (data){
// Username of sender
senderUsername = data.result.username;
}
});
The Output- Before we get into the details below, this section is just a brief overview of what the results from API calls look like, just for those of you who have never used JSON or an API like this before. An example result will be:
Code {"success":true,
"message":"",
"result":{"key":"value",
"something":0,
}
}
This output is called JSON, which stands for JavaScript Object Notation, but basically you can just know that each piece of data has a name and then a value. In the example above we see that "success" has the value true, which means the request succeeded. Then we see there is no message (empty quotes), message is used when success is false to say what went wrong. Then finally "result" contains the actual info, again separated into keys (names) and values. In a specific case, the name might be "username" and the value might be "MeshCollider". Your code can read this data in, most languages have some sort of library for parsing JSON data.
Messages are mostly self-explanatory, for example you might get INVALID_PID which means the post ID you entered was invalid (if the post doesn't exist/you don't have permission to see it), MAX_HOURLY_CALLS_EXCEEDED which means you have made too many API calls in the last hour and need to chill out a bit, INVALID_API_KEY which means you copied your key wrong or forgot it completely, and UNIMPLEMENTED_API_METHOD which means the API couldn't understand what you were asking it to do, you probably spelt the method wrong.
User Profiles (/user/:id)- This API method provides all the basic info about a user, such as username, number of posts, groups, avatar url, usertitle, online time, registration date, last online time, and reputation.
A request would look like this:
Code https://hackforums.net/api/v1/user/2015410
This will return the info for the user with UID=2015410, i.e. ME!
PHP Code
<?php { success: true, message: "", result: { username: "MeshCollider", postnum: 6544, avatar: "./uploads/avatars/avatar_2015410.png?dateline=1490393676", avatartype: "upload", usergroup: 28, additionalgroups: [ 55, 36, 39, 42, 62 ], usertitle: "Transcendent", timeonline: 8310653, regdate: 1382072872, lastactive: 1499296240, reputation: 692 } }
Forum Navigation (/category/:id)- This API method allows you to get basic forum info such as name and description for displaying in a manner similar to index.php does. When given a forum id, it will give this info along with the basic info of all direct child forums as well.
A list of top level forums is obtained with /category/0 or just /category (equivalent).
A request would look like this:
Code https://hackforums.net/api/v1/category/1
This will return the info for the forum with ID 1, which is Hack Forums Official Information category, containing the RANF subforum.
PHP Code
<?php { success: true, message: "", result: { name: "Hack Forums Official Information", description: "", type: "c", parent: 0, ficon: "shim.gif", children: [ { fid: 2, name: "Rules, Announcements, News, and Feedback", description: "This is where site rules and important announcements about the site are made. Please read carefully before you join. Also you can leave us feedback or ask site questions here.", type: "f", ficon: "rules-news-announcements.png" } ] } }
Post (/post/:id)- This API method grabs a specific post from the forum (as long as you have permission to view the thread it is in and as long as the post isn't junked). All you need to provide is the post ID, and it will give you the thread ID it is in, the parent post ID (OP), the forum ID the thread is in, the subject of the post (Usually "RE: thread title"), the user ID of the poster, the unix timestamp of when it was posted and edited (and by whom it was edited), and of course, the message in the post itself.
A request would look like this:
Code https://hackforums.net/api/v1/post/55230422
PHP Code
<?php { success: true, message: "", result: { tid: 5470739, parent: 53175820, fid: 162, subject: "*", uid: 3077324, dateline: 1498792772, message: "<span style="font-weight: bold;"><span style="color: #00e4ff;">Briefly describe the event: </span></span> <a href="https://hackforums.net/member.php?action=profile&uid=63387" target="_blank"><span style="color: #000000;"><span style="font-weight: bold;">BLACK SHADOW</span></span></a> GOT CLOSEEDD <span style="font-weight: bold;"><span style="color: #00e4ff;">Any important links: </span></span> <a href="https://hackforums.net/member.php?action=profile&uid=63387" target="_blank">https://hackforums.net/member.php?action...&uid=63387</a>", edituid: 0, edittime: 0 } }
This will return the info for the post with ID 55230422.
You will notice that by default, the MyCode in the post you request will be parsed into HTML by the API. You can turn this off if you would prefer to get the MyCode directly, by adding ?raw to the end of your request:
Code https://hackforums.net/api/v1/post/55230422?raw
PHP Code
<?php { success: true, message: "", result: { tid: 5470739, parent: 53175820, fid: 162, subject: "*", uid: 3077324, dateline: 1498792772, message: "[b][color=#00e4ff]Briefly describe the event: [/color][/b] [url=https://hackforums.net/member.php?action=profile&uid=63387][color=#000000][b]BLACK SHADOW[/b][/color][/url] GOT CLOSEEDD [b][color=#00e4ff]Any important links: [/color][/b] https://hackforums.net/member.php?action=profile&uid=63387", edituid: 0, edittime: 0 } }
Thread (/thread/:id)- This method let's you get some info about a specific thread. All you need is the thread ID. You will get the thread subject, poster, forum ID, whether it is closed or not, the number of replies, the date it was posted, the ID of the first post, and a comma separated list of post IDs that are the replies. You will also get the message content and info about each of the posts in that thread. Each request will give you 1 page of replies (10 post IDs), so you have to include a page parameter to choose which page of replies you get.
Again, the raw parameter can be included, as well as a page parameter for the next 10 posts:
Code https://hackforums.net/api/v1/thread/5494141?raw&page=3
If you get an INVALID_TID message, it could be because the thread doesn't exist or because it is in a forum you aren't allowed to access.
PHP Code
<?php { success: true, message: "", result: { subject: "I need YOU to reply to this thread.", user: 2504443, fid: 336, closed: true, numreplies: 42, dateline: 1481774674, firstpost: 53444715, postdata: [ { pid: 53461817, parent: 53444750, subject: "*", uid: 1356224, dateline: 1481914288, message: "[quote='BRΞNDΞN' pid='53444750' dateline='1481774953'] We're working to change that, lad. The reason it is dead is because HF stopped caring. If HF began to care again, and we all put effort in, it will come back. [/quote] You joined this year..", edituid: 0, edittime: 0 }, { pid: 53462608, parent: 53446829, subject: "*", uid: 2033319, dateline: 1481919041, message: "[quote='TheChiеf' pid='53446829' dateline='1481795656'] Your signature describes your state of mind when you made this post. [/quote] Is it bad that I had to go look at my signature", edituid: 0, edittime: 0 }, { pid: 53465259, parent: 53444715, subject: "*", uid: 2504443, dateline: 1481935497, message: "5 pages.. nice. That'll do it, thank you!", edituid: 0, edittime: 0 } ] } }
Forum (/forum/:id)- This method grabs the info about a specific forum, provided by the fid parameter, and includes the name, description parent forum ID, a list of thread IDs in the forum (as well as an array of thread details for each thread), and the type of the forum ("c" for category, "f" for forum, e.g. Hack Forums Official Information is a category but Rules, Announcements, News and Feedback is a forum).
The page parameter is used in the same way as for the TID call, there are 20 thread IDs per page in a forum.
Sample call:
Code https://hackforums.net/api/v1/forum/375
PHP Code
<?php { success: true, message: "", result: { name: "HF API", description: "This is for development and coding of apps and software that utilize the HF API.", type: "f", parent: 151, threaddata: [ { tid: 5662721, sticky: true, subject: "HF API v1 Beta", user: 1, closed: false, numreplies: 23, dateline: 1499281975, lastpost: 1499295855 }, { tid: 5627415, sticky: false, subject: "HF PM Notifications | First HF APP | Android", user: 1999047, closed: false, numreplies: 41, dateline: 1495302484, lastpost: 1499281417 },
... snip ....
{ tid: 5611829, sticky: false, subject: "Client Keys", user: 63823, closed: true, numreplies: 11, dateline: 1493561691, lastpost: 1493609100 } ] } }
Private Message (/pm/:id)- The private message ID (pmid) is required for this call, and you will get the sender, recipient, subject, message content, date and folder of the PM back.
Sample call:
Code https://hackforums.net/api/v1/pm/78288591
Reading a PM using the API is the same as via the website, and will show as "read" in a users PM tracking.
PHP Code
<?php { success: true, message: "", result: { to: 2015410, from: 1, subject: "Re: API", message: "[quote='MeshCollider']-snip-[/quote] Hit me up asap.", dateline: 1499280513, folder: 1 } }
Private Message Inbox (/pmbox/:id or /inbox)- This request simply requires you to set inbox in the request, and include a page parameter just like the thread and forum IDs. There are 20 PMs per page of the inbox.
The results of this call are slightly different to the earlier results. In this case, you will get a list of PM IDs of the PMs in your inbox, but you will also get some basic info about each PM in this list, namely the subject, sender, read status and date, to allow you to see which PMs have are read/unread without having to open them.
Sample call:
Code https://hackforums.net/api/v1/pmbox/1
PHP Code
<?php { success: true, message: "", result: [ { pmid: 78288591, subject: "Re: API", sender: 1, recipient: 2015410, status: 3, dateline: 1499280513 }, { pmid: 78287171, subject: "HF API", sender: 1660622, recipient: 2015410, status: 1, dateline: 1499274164 }, ... snip ...
{ pmid: 78194714, subject: "Mesh", sender: 458073, recipient: 2015410, status: 3, dateline: 1498686176 } ] }
Group (/group/:id)- Pass this the Group ID of the group you want, and it will return the name, description, type of group (1 = core mybb group like admins and staff, 2 = ub3r/l33t/3p1c/writ3rs/etc, 4 = usergroups like Red Lions, Equilibrium, etc.), userbar, and UIDs of the group leaders.
Sample call:
Code https://hackforums.net/api/v1/group/36
PHP Code
<?php { success: true, message: "", result: { name: "Red Lions", type: 4, description: "This is nokia2mon2's special group that he controls.", userbar: "{theme}/groupimages/{lang}/red-lion.jpg", owner: 80618, leaders: [ 370510 ] } }
Multiple Users Info (/users/:ids)- This method is used for grabbing multiple users' data at once, and takes up to 20 user IDs, listing the info for each user provided. This is designed to be used with thread displaying, to get usernames, avatars, etc. for display.
Sample call:
Code https://hackforums.net/api/v1/users/1,2015410
PHP Code
<?php { uids: [ { uid: 1, success: true, message: "", result: { username: "Omniscient", postnum: 38443, avatar: "./uploads/avatars/avatar_1.gif?dateline=1489528978", avatartype: "upload", usergroup: 4, additionalgroups: [ 0 ], usertitle: "All-Time HQ Leader", timeonline: 55788439, regdate: 1177194113, lastactive: 1499298655, reputation: 406 } }, { uid: 2015410, success: true, message: "", result: { username: "MeshCollider", postnum: 6544, avatar: "./uploads/avatars/avatar_2015410.png?dateline=1490393676", avatartype: "upload", usergroup: 28, additionalgroups: [ 55, 36, 39, 42, 62 ], usertitle: "Transcendent", timeonline: 8313231, regdate: 1382072872, lastactive: 1499298818, reputation: 692 } } ] }
Changelog- Changelog v1.1
- Key length increased to 32 characters
- Correct datatypes are now used for various output, for example integers for IDs and booleans for thread closed status
- QR codes of the keys are now shown on apikey.php
- Keys can now be deleted via apikey.php
- Keys can now be locked to the specific IP address they were created by via apikey.php
- Keys are now passed using HTTP Basic Auth in the username field rather than as a get url parameter
- Formatting of the UIDs method has changed to an array of objects instead of indexed by UIDs (as requested by the member QoL)
- Various bug fixes (for example fixing the output of group leader IDs on the gid method)
- Use the more common RESTful format of URIs, with versioning
- Rate limits increased to 240 / hour
- Opened access to Ub3r
Changelog 13 July 17:- /user endpoint defaults to owner of key if no uid is supplied
- Unix timestamps have been replaced by ISO formatted date strings where applicable
- Number of threads in forum is added to /forum method for pagination
- Added usernames to some more calls
- Added display group to user method
- Added better failure message for /users method if some don't exist but some do.
- Added new header with number of calls remaining
- Prevented redirect forums from being accessed normally
- Small bugfixes
Changelog v1.2- Added RAW / html output for private messages same as posts
- Added an optional ?include=header parameter to all calls which allows you to get the current number of unread PMs at the same time ( example: /api/v1/user/1?include=header )
- Added usernames to all remaining methods which return UIDs
- Added count of PMs and PMbox name to the /pmbox method BREAKING
- Added a /user/:id/threads method and /user/:id/posts method to get user threads and posts respectively
- Added a /groups method which returns all groups, or /groups/:ids which takes a CSV list of group IDs
- Added thread prefixes to thread and forum method
- Added an /avatar/:uid method which returns base64 encoded avatar of user, if uploaded to HF (or in HFs image gallery). Group userbars and ficons are coming soon.
The API was coded by MeshCollider with the invaluable assistance of Zach and the wise feedback of Omni
Credit to iHydra for the logo
* - QoL - Jul 9, 2017
What is the max hourly call limit? I thought it was 100, but I can't remember where I saw that.
Also, is it a rolling hour, or does it reset on the hour?
Edit: I found in one of Omni's posts that it's 100 calls/hour. I would still like to know whether that's a rolling hour or a reset on the hour.
* - Katarina Du Couteau - Jul 9, 2017
I wish I were a R3KT so I could use the features D:
* - QoL - Jul 9, 2017
(Jul 9, 2017 12:29 PM)Katarina Du Couteau Wrote: I wish I were a R3KT so I could use the features D:
FYI, Ub3rs no have access to this since yesterday.
* - Aerith - Jul 9, 2017
(Jul 9, 2017 12:29 PM)Katarina Du Couteau Wrote: I wish I were a R3KT so I could use the features D:
HF API is available for ub3r members. Omniscient released this yesterday.
* - Katarina Du Couteau - Jul 9, 2017
(Jul 9, 2017 12:30 PM)QoL Wrote: FYI, Ub3rs no have access to this since yesterday.
(Jul 9, 2017 12:30 PM)Aerith Wrote: HF API is available for ub3r members. Omniscient released this yesterday.
Oooh nice, so when are the first apps coming out?
* - QoL - Jul 9, 2017
(Jul 9, 2017 12:34 PM)Katarina Du Couteau Wrote: Oooh nice, so when are the first apps coming out?
I believe Vitani released an app for PM notifications. It just queries your inbox every x minutes and notifies you. I can't remember if he updated it to work with the new API format though.
I'm working on a fully fledged application and that should be out soon. It is a lot of work.
* - SIM-2223238 - Jul 9, 2017
Ah, was waiting for the documentation. Thanks!
* - Khamul - Jul 9, 2017
(Jul 9, 2017 12:36 PM)QoL Wrote: I'm working on a fully fledged application and that should be out soon. It is a lot of work.
Yeah. In fairness though we can't really make great apps until write access has been released and the call limit has been increased. Having said that I am working on (I'm sure others are too) the backend so that once these features are in place it won't take much effort to make use of them.
* - QoL - Jul 9, 2017
(Jul 9, 2017 01:52 PM)ɴᴀᴢɢᴜʟ Wrote: Yeah. In fairness though we can't really make great apps until write access has been released and the call limit has been increased. Having said that I am working on (I'm sure others are too) the backend so that once these features are in place it won't take much effort to make use of them.
I agree. Once I finish all of the features that have currently been released, I'm basically going to have to just sit on my hands and wait for write functionality.
* - sdk - Jul 9, 2017
(Jul 9, 2017 01:52 PM)ɴᴀᴢɢᴜʟ Wrote: Yeah. In fairness though we can't really make great apps until write access has been released and the call limit has been increased. Having said that I am working on (I'm sure others are too) the backend so that once these features are in place it won't take much effort to make use of them.
What is the current rate limit? Cache bb
(Jul 9, 2017 01:56 PM)QoL Wrote: I agree. Once I finish all of the features that have currently been released, I'm basically going to have to just sit on my hands and wait for write functionality.
I have to sit on my hands till I get the 30$ for uber lol
* - QoL - Jul 9, 2017
(Jul 9, 2017 02:00 PM)sdk Wrote: What is the current rate limit? Cache bb
I found in one of Omni's posts that it's 100 calls/hour. I would still like to know whether that's a rolling hour or a reset on the hour.
* - sdk - Jul 9, 2017
(Jul 9, 2017 02:03 PM)QoL Wrote: I found in one of Omni's posts that it's 100 calls/hour. I would still like to know whether that's a rolling hour or a reset on the hour.
Most likely rolling from when your first call is, that's a little low but not totally unheard of, caching will be the key I guess, im just making a design till I can get Uber
* - QoL - Jul 9, 2017
(Jul 9, 2017 02:10 PM)sdk Wrote: Most likely rolling from when your first call is, that's a little low but not totally unheard of, caching will be the key I guess, im just making a design till I can get Uber
This is what I assume it would be. I have gotten a limit reached error and tried again before the hour changes and did successfully get a response, so this is probably it.
* - Omniscient - Jul 9, 2017
Quote:. I would still like to know whether that's a rolling hour or a reset on the hour.
Should be a rolling hour. And it's max of 240 right now which is one call every 15 seconds.
If you're a developer and wish to get a Dev token please LMK. Dev tokens allow for 720 which is one every 5 seconds.
Quote: I'm basically going to have to just sit on my hands and wait for write functionality.
Not necessarily. We can give you examples of working queries and output. Might even be a good thing for all devs to have some beta testing functions. I'll speak to Mesh about it.
|