Old School Ops

The OSO API

Using the site from a program with an API key - the forum, reactions, comments, messages, your profile, bug reports and ideas.

Every game · updated 2026-10-09
On this page

The OSO API is how a program uses this site. It authenticates with a key, never a cookie, and lives under /api/v1/. Anything you can do on the forum, on profiles and in your messages, a key can do too, and nothing more.

This is the API for oldschoolops.com. A game server's own control panel has a separate one, described in GameCP API.

Getting a Key

Account, then API keys. A key is shown once and stored only as a hash, so there is no way to look it up again. Keys expire after a year unless you say otherwise.

A key acts as you. Your groups, your staff level, any restriction a moderator has placed on your account and whether each part of the site is open are all checked on every request, exactly as they are when you use the site in a browser, rather than fixed when the key was made. So a key never sees a board your account cannot see, and it stops posting the moment your account cannot post.

A key cannot change your password, email address, name or two-factor setting, and cannot manage your sessions or other keys. Those need you, in a browser.

Using It

Send the key as a header, never in a URL: query strings end up in server logs, in Referer headers and in your shell history. Requests with a body send JSON.

curl -H "Authorization: Bearer oso_..." https://oldschoolops.com/api/v1/forum
curl -H "Authorization: Bearer oso_..." -H "Content-Type: application/json" \
     -d '{"body": "Thanks, that fixed it."}' \
     https://oldschoolops.com/api/v1/forum/threads/some-thread-12/posts

If you have registered but not yet confirmed your email address, a key can read but not write, the same as the site.

Endpoints

You

Method and pathWhat it does
GET /api/v1/meWho the key acts as: name, groups, permissions and which parts of the site are open to you.
GET /api/v1/account/profileYour profile and appearance settings, with the titles and name styles you may pick.
POST /api/v1/account/profileChange any of title, bio, location, website, accent, preset, wall_open, timezone, title_key, name_style, watch_on_reply, watch_on_create. Fields you leave out are kept.
GET /api/v1/account/notificationsWhich events reach you on the site and by email.
POST /api/v1/account/notifications{"events": {"forum.reply": {"email": false}}}. Events you leave out are kept; events that cannot be switched off are refused.
GET /api/v1/notificationsYour notifications and unread count.
POST /api/v1/notifications/{id}/readMark one read.
POST /api/v1/notifications/read-allMark them all read.

The forum

Method and pathWhat it does
GET /api/v1/forumEvery board you can see, by section, with unread state.
GET /api/v1/forum/feedThreads across every board you can see, most recently active first. page.
GET /api/v1/forum/searchThreads matching q.
GET /api/v1/forum/boards/{slug}One board's threads and subforums. page, tag. Marks the board read, as opening it does.
GET /api/v1/forum/threads/{slug}One page of a thread: every post with its reactions and who reacted. page. Counts as a view, exactly as opening the thread does.
GET /api/v1/forum/posts/{id}One post.
POST /api/v1/forum/boards/{slug}/threadsStart a thread: title, body, optional tag.
POST /api/v1/forum/threads/{slug}/postsReply: body, and reply_to with a post id to answer that post.
POST /api/v1/forum/posts/{id}/editChange a post's body. Your own, or any on a board you moderate.
POST /api/v1/forum/posts/{id}/deleteRemove a post, with a reason. Removing the opening post removes the thread.
POST /api/v1/forum/threads/{slug}/watch{"watching": true} or false.
POST /api/v1/forum/read-allMark the whole forum read.

Post bodies come back as the text that was written, in the same markup you post with. A removed post comes back with removed: true and no body, unless you moderate that board.

Reactions and comments

These work on anything that takes them. kind is one of forum_post, forum_thread, profile, comment, bug, idea, changelog, news, and ref is its id. An idea's may be given as IDEA-12. A reaction on an idea is not a vote.

Method and pathWhat it does
GET /api/v1/reactionskind, ref: the tally and who reacted, most recent first.
POST /api/v1/reactionskind, ref, emoji: toggle your reaction.
GET /api/v1/commentskind, ref: the comments, each with its reactions.
POST /api/v1/commentskind, ref, body.
POST /api/v1/comments/{id}/editChange your own comment's body.
POST /api/v1/comments/{id}/deleteRemove your own comment, with an optional reason.

People and messages

Method and pathWhat it does
GET /api/v1/membersThe newest members.
GET /api/v1/profiles/{name}A profile, its awards and titles, and the comments on its wall.
POST /api/v1/profiles/{name}/commentsWrite on a wall: body.
GET /api/v1/messagesYour conversations, newest first, with unread counts.
GET /api/v1/messages/{name}The latest hundred messages with one person. Marks them read, as opening the conversation does.
POST /api/v1/messages/{name}Send a message: body.

Bug reports

Method and pathWhat it does
GET /api/v1/bugsRecent reports. Optional status, game and page.
GET /api/v1/bugs/{ref}One report; comments=1 adds its comments.
GET /api/v1/bugs/similarWhether something has been reported already, without filing anything.
POST /api/v1/bugsFile a report.
GET /api/v1/bugs/mineThe reports you filed. Optional game.
GET /api/v1/bugs/componentsWhat the report form offers, and which games have a tracker.
POST /api/v1/bugs/{ref}/me-tooAdd what you saw to an existing report instead of filing a duplicate.

similar before POST is the half of de-duplication that stops a duplicate existing at all: it answers "has this been reported" without writing a row. A report against GoMMO Client names the game it was playing in tool_game, as the report form asks. Staff accounts can also move, reply to, assign and note reports; the routes are listed on the API keys page.

Ideas

{ref} is the idea's id as the site shows it, such as IDEA-12.

Method and pathWhat it does
GET /api/v1/ideasIdeas, newest page first. Optional tag, status, sort (top, new or updated) and page.
GET /api/v1/ideas/searchIdeas matching q, by their words or an IDEA- id. Search before you suggest.
GET /api/v1/ideas/{ref}One idea with the team's response; comments=1 adds its comments.
POST /api/v1/ideasSuggest an idea: tag (a game, a tool or site), title, body, optional why.
POST /api/v1/ideas/{ref}/commentsComment on an idea: body.

Votes are cast on the website only. A key can read the vote count and whether you have voted, but POST /api/v1/ideas/{ref}/vote answers 403: sign in on the site to vote. Staff accounts can also move an idea and write the team's response; those routes are on the API keys page.

Responses

Field names are a contract. Timestamps are RFC 3339 in UTC. A post looks like this:

{
  "id": 4127,
  "thread": "pit-bosses-never-healed-311",
  "ordinal": 3,
  "author": {"id": 18, "name": "Somebody"},
  "body": "Same here, on **every** boss.",
  "reply_to": 4120,
  "created_at": "2026-10-01T09:12:00Z",
  "reactions": [{"emoji": "like", "count": 2, "mine": true, "by": "Someone Else"}],
  "reactors": [{"name": "Someone Else", "emoji": "like"}, {"name": "You", "emoji": "like"}],
  "can_edit": false,
  "url": "https://oldschoolops.com/forum/t/pit-bosses-never-healed-311?page=1#p3"
}

Errors

Every error is JSON with an error message.

StatusMeans
400The request is missing something, or a value is not one the site accepts
401No key, or the key was not accepted
403Your account may not do that: a locked thread, a closed wall, a restriction on your account
404No such thing, or nothing your account can see
422Refused as a repeat of something already posted
429Too many requests

Something your account cannot see answers 404, the same as something that does not exist. A rejected key returns 401 whether it is unknown, revoked or expired.

Revoking

Account, then API keys, then Revoke. It stops working immediately.

Connected Apps

GoMMO Manager and GoMMO Studio sign in without a key you copy: each opens /connect/manager or /connect/studio in your browser, you approve it once, and the site hands the app its own key through a loopback redirect with PKCE. A GoMMO Studio key files reports about GoMMO Studio only. That key acts as you like any other, lapses like a browser sign-in (14 days idle, 90 days at most), and is listed under Account, then Connected apps, where Disconnect withdraws it.

Something here wrong?

Out of date, incomplete, or assuming something it should not. Documentation errors are bugs, and this one arrives tagged and pointed at this page.

Top xp sources

How xp works
Loading…

Open the full search page