Skip to content

API Docs

Adam S edited this page Oct 14, 2020 · 11 revisions

WIP, DO NOT USE ANYTHING ON THIS PAGE (I have no idea what I'm doing)

How the API Works

Sending Messages

  • All commands are sent via websockets to the server. Websockets is used instead of a REST API to save on overhead.
  • The only way to access the API is with a API Key and API Secret. They can be generated by an API Key with the admin permission.
  • Every command takes the form of a JSON object with at least 3 keys:
    • "key"(string): Your API Key. This is so the server doesn't have to keep a list of connected clients.
    • "command"(string): The name of the command you want to execute.
    • "hmac"(string): The hex string of the HMAC-SHA256 digest of the sorted, minified message. Example:
import hmac, json

api_key = "YOUR_API_KEY" # You can get both of these from the keyinfo command, or having someone with the admin permission look it up for you.
api_secret = "YOUR_API_SECRET" 

commandDict = {'key': api_key, 'command': "ping"} # This list will also include parameters when you are using commands that need them.
message = json.dumps(commandDict, sort_keys=True, separators=(',', ':'))
digest = hmac.hexdigest(bytes.fromhex(api_secret), command, 'sha256')
commandDict['hmac'] = digest
finalCommand = json.dumps(commandDict, separators=(',', ':')) # You don't need to sort or minify responses sent to the server, but minifying will save on message size.
# Send to the server via websocket...
  • Some commands will require parameters, which should be added before digesting.

Receiving Messages

Whenever a command is sent, the server will send a JSON message with the following keys:

  • timestamp(int): The number of seconds since January 1st, 1970 when the message was sent.
  • success(bool): If the request was successful.
  • error(string): Only exists if success if false. Contains the error code that explains why the request failed.
  • data(dict): The response data.

Errors

The following are errors any command can throw. Certain commands may have their own errors, which are listed in the command description.

  • "INVALID_AUTH_ERROR": The API Key that was used does not exist, or the API secret that was used is incorrect.
  • "INVALID_COMMAND_ERROR": The command you tried to use didn't exist.
  • "PERMISSION_DENIED_ERROR": The command you tried to send requires permissions your API key does not have.
  • "MISSING_PARAMETERS_ERROR": The command you tried to send didn't have all of the required parameters.
  • "INVALID_PARAMETERS_ERROR": The command you tried to send had parameters that didn't exist.
  • "SERVER_ERROR": The server failed to execute the command for an unknown reason. Please contact an admin for more info.
  • "DB_ERROR": The server failed to talk to the database for an unknown reason. Please contact an admin for more info.

The Player Object

The player object is a JSON dictionary with the following keys:

  • "id"(int): The user's bobux ID. This isn't useful for much except for internally identifying the user.
  • "steam"(string|null): The user's steam ID.
  • "discord"(string|null): The user's discord ID.
  • "bobux"(int): The amount of bobux a user has currently.
  • "bobuxtotal"(int): The total amount of bobux this user has ever had. This value will become important if a spending system is added.

The Key Object

The key object is a JSON dictionary with the following keys:

  • "key"(string): A UUID string representing the API key.
  • "secret"(string): A hex string representing the API secret.
  • "permissions"(int): A byte representing the permissions the API key has.
  • "created"(int): The number of seconds since January 1st, 1970 when the key was created.

Permissions

Every key has a permission value, which is a byte with certain bits as 1. Here is a list of all permissions:

Read

  • Location: Bit 0
  • Permissions: Read Bobux values of players given an ID. Also get top n Bobux holders.

Write

  • Location: Bit 1
  • Permissions: Set the Bobux value of players given an ID.

Account

  • Location: Bit 2
  • Permissions: Create new users, and associate users with IDs.

Admin

  • Location: Bit 3
  • Permissions: Use the websocket SQLite interface, create and destroy key/secret pairs, and change existing keys' permission levels.

Other bits are reserved for future use and must be set to 0.

Commands that Don't Need Permissions

"ping"

This command has the server respond without any data. You could use it to test if your API Key is working or not.

Required Parameters

  • "command": "ping"

Response Data

None.

"info"

Returns the version of the server software the server is running.

Required Parameters

  • "command": "info"

Response Data

  • "version"(string): The version of BobuxServer the server is running.

"keyinfo"

Returns info about the API key currently in use.

Required Parameters

  • "command": "keyinfo"

Response Data

  • "key"(dict): A key object representing the key currently in use.

"replacekey"

Deletes any key that sends this command, and creates a new one with the same permissions. If the request fails, no data is changed.

Required Parameters

  • "command": "replacekey"

Response Data

  • "key"(dict): A key object representing the new key. It is important to store this, otherwise you will be locked out of the API.

"deletekey"

Deletes any key that sends this command. This action cannot be undone.

Required Parameters

  • "command": "deletekey"

Response Data

None.

Commands that Require the Read Permission

"getplayer"

Gets a player by their steam, discord, or bobux ID.

Required Parameters

  • "command": "getplayer"
  • "id"(string, int): The steam, discord, or bobux ID of a player. Sending an int may only be used with bobux IDs. Sending a string defaults to a steam ID.

Optional Parameters

  • "discord"(bool): Required only when "id" is a string and is referring to a discord ID instead of a steam ID.

Response Data

  • "player"(dict): Contains the player object with the specified ID.

"topplayers"

Returns the top n players of the server in groups of x.

Required Parameters

  • "command": "toppplayers"
  • "amount"(int): Amount of players to return on one page.
  • "page"(int): Page number to return. If "amount"*"page" is greater than the total number of people on the server, the last page will be returned.

Response Data

  • "count"(int): Number of players returned. This will normally be equal to "amount", except when asking for more people than the server has.
  • "players"(dict): A list of player objects sorted in decreasing order by how many bobux they have.

Commands that Require the Write Permission

"setbobux"

Modifies the amount of bobux a user has.

Required Parameters

  • "command": "setbobux"
  • "id"(int): The bobux ID of the person whose bobux you want to modify.
  • "amount"(int): The amount of bobux to set, add, or subtract.

Optional Parameters

  • "operation"(int, 0-2): The operation to perform. 0 is set, 1 is add, and 2 is subtract. Defaults to 0.

Response Data

  • "player"(dict): Contains the player object of the user whose bobux was edited.

Commands that Require the Account Permission

"createaccount"

Creates a new player account with a bobux ID, and either a Steam or Discord ID.

Required Parameters

  • "command": "createaccount"
  • "id"(string): The Steam or Discord ID of the user to create the account with.

Optional Parameters

  • "discord"(bool): If true, indicates that "id" is a Discord ID.

Response Data

  • "player"(dict): The player object of the account that was just created.

"linkaccount"

Associates a Steam account with a Discord account and vice versa.

Required Parameters

  • "command": "linkaccount"
  • "userid"(int): The bobux ID of the player whose account to link.
  • "newid"(string): The new ID to link. Specifying what kind isn't needed, because an account must always have one.

Response Data

  • "player"(dict): The player object whose account was account was just linked.

Commands that Require the Admin Permission

"sendsql"

Sends a single SQLite command and returns the response. This input isn't sanitized, so it's very easy to destroy the database using this command.

Required Parameters

  • "command": "sendsql"
  • "sql"(string): The SQLite command to send.

Response Data

  • "rows"(list): A list of rows returned by the database.

"createkey"

Creates a new API key.

Required Parameters

  • "command": "createkey"
  • "permissions"(int): A byte representing the permissions that the new API key will have.

Response Data

  • "key"(dict): A key object representing the key that was just created.

"editpermissions"

Changes the permissions of an existing API key.

Required Parameters

  • "command": "editpermissions"
  • "key"(string): The API key whose permissions you want to change.
  • "permissions"(int): A byte representing the permissions that the API key will have.

Response Data

  • "key"(dict): A key object representing the key that was just changed.

"deletekey"

Deletes an existing API key.

Required Parameters

  • "command": "deletekey"
  • "key"(string): The API key you want to delete.

Response Data

None.

Notes

  • connect via websockets
  • authentication consists of name, secret key (both probably random value from 0 to 2^256-1), use HMAC-SHA256 to verify key
  • permission levels:
    • read: get stuff about users
    • write: set bobux values
    • account: be able to write to steam/discord ids, create new users
    • admin: execute raw sqlite, create new api tokens

read commands

  • get player by bobux id
  • get player by steam id
  • get player by discord id
  • return top x players

write commands

  • set bobux by bobux id (maybe steam/discord too)

account commands

  • set steam id by discord id
  • set discord id by steam id
  • create new user with discord id
  • create new user with steam id

admin commands

  • send raw sqlite
  • create new api token
  • destroy other people's api tokens
  • change permission levels