rotur
Talk to rotur.dev from OSL: sign in, read the feed, post, manage groups and storage, listen in realtime, and sign and encrypt messages.
import "std:rotur"std:rotur is a client for the rotur.dev API. Almost everything the website does is a method here: accounts, posts, friends, groups, the economy, key-value storage, signing and encryption, and a realtime socket for presence and rooms.
Calls talk to the network, so most examples on this page compile but don't run in the browser. Run them on your machine. A few helpers that work offline run right here.
A client#
rotur.new(token) makes a client. With no token (or "") it is anonymous and can call public endpoints:
import "std:rotur"
auto rotur_client = rotur.new()
auto feed = rotur_client.posts().list({limit: 3}).unwrap()
for post in feed (
log post
)Every API method returns a result. The response is the API's own JSON, so keys keep the names rotur.dev uses. Errors have a kind you can match on: NotFoundError (404), PermissionError (no token, or refused), ValueError (a rejected request), StateError (conflicts and rate limits), TimeoutError and NetworkError.
Signing in#
The first time, client.login() runs the device flow. It prints a code, you approve it on rotur.dev, and the token is saved where the rotur command line tool keeps it. After that rotur.load() finds it again. A program asks only once:
import "std:rotur"
*rotur.Client client = rotur.load().unwrap()
if !client.hasToken() (
client.login().unwrap()
)
log "signed in as " ++ client.username().unwrap()ROTUR_TOKEN in the environment also works, and is checked first. To skip the saved file, build the client with rotur.new(token).
Check who you are#
client.whoami() asks the API what the token is allowed to do:
import "std:rotur"
*rotur.Client client = rotur.load().unwrap()
auto me = client.whoami().unwrap()
log me.username me.token_typeA call that needs a token without one fails with PermissionError, which you can handle:
import "std:rotur"
auto client = rotur.new()
auto attempt = client.posts().create("hello")
if attempt.isErr() (
log attempt.unwrapErr().kind
)rotur.new() with no token calls client.posts().list(). What happens?
Posts and people#
Each area of the API is a group of methods on the client: posts(), friends(), following(), groups(), profiles(), notifications(), storage() and more. They read like the website:
import "std:rotur"
*rotur.Client client = rotur.load().unwrap()
auto post = client.posts().create("Hello from OSL", {profileOnly: true}).unwrap()
client.posts().like(post.id).unwrap()
client.posts().reply(post.id, "A reply").unwrap()
log client.profiles().userExists("mist").unwrap()
for name in ["a", "b"] (
client.following().follow(name).unwrap()
)posts().find(query) searches, posts().popular() is the front page, and groups() has methods for creating, inviting, roles, bans and events.
Storage#
Your account has a small key-value store per application id. It is how a program remembers things across machines:
import "std:rotur"
*rotur.Client client = rotur.load().unwrap()
auto store = client.storage()
store.set("my-app", "theme", "dark").unwrap()
log store.value("my-app", "theme").unwrap()
store.delete("my-app", "theme").unwrap()Endpoints without a method#
client.request(method, path, options) calls any endpoint the client has no method for, with query and body options. The token goes only to the client's own host:
import "std:rotur"
auto client = rotur.new()
auto limits = client.request("GET", "/limits").unwrap()
log limitsRealtime#
client.socket() is a websocket connection to rotur. start() connects and authenticates, join enters rooms, and on(event, handler) listens. Handlers run on background threads:
import "std:rotur"
import "std:thread"
*rotur.Client client = rotur.load().unwrap()
auto socket = client.socket()
socket.on("gmsg", def(any message) ( log message ))
socket.start().unwrap()
socket.join(["lobby"]).unwrap()
socket.broadcast("lobby", {hello: "world"}).unwrap()
thread.sleep(60000)
socket.stop()Offline helpers#
These work without a network. rotur.avatarURL, bannerURL, backgroundURL and overlayURL build the image addresses for a user, and version busts the cache when a picture changes:
import "std:rotur"
log rotur.avatarURL("mist", {version: "2"})rotur.canonical(value) writes a value as canonical JSON: keys sorted, no spaces. Those bytes are what rotur signatures are made over, so two sides get the same bytes from the same data:
import "std:rotur"
log rotur.canonical({b: 1, a: [1, 2], c: "x"})rotur.generateKey() makes an Ed25519 key pair as JWK objects, and rotur.signWith(seed, content) and rotur.verifyWith(publicKey, content, signature) sign and check. For a signed-in client, client.signing() signs content as you, encrypts to another user, and decrypts what was sent to you.
import "std:rotur"
auto pair = rotur.generateKey().unwrap()
log pair.algorithmSame bytes
Two programs describe the same data with keys in different orders. Print true if rotur.canonical gives the same text for both.
true
API reference#
410 members, generated from the std:rotur source of OSL 9.3.0.
Functions
rotur.avatarURL(string username, object? options) stringavatarURL is the profile picture of username on avatars.rotur.dev. Options: version (string appended as ?v= so a changed picture isn't served from cache).
rotur.backgroundURL(string username, object? options) stringbackgroundURL is the profile background video of username. Options as for avatarURL.
rotur.bannerURL(string username, object? options) stringbannerURL is the profile banner of username. Options as for avatarURL.
rotur.canonical(any value) stringcanonical serialises value as canonical JSON (sorted object keys, numbers as JavaScript prints them), the bytes rotur signatures are made over.
rotur.configPath() result<string, error>configPath is the rotur CLI config file (~/.config/rotur/config.json) that load, loadToken, logout and client.saveToken share with the rotur CLI. Fails with IOError when the home directory is unknown.
rotur.generateKey() result<{algorithm: string, private_key_jwk: object, public_key_jwk: object}, error>generateKey makes a new Ed25519 key pair, returned as {private_key_jwk, public_key_jwk, algorithm}. Fails with RuntimeError when the system has no randomness.
rotur.load() result<*rotur.Client, error>load builds a client from the saved token (see loadToken). Without one the client is anonymous; check client.hasToken(). Fails like loadToken.
rotur.loadToken() result<string?, error>loadToken returns the saved token: the ROTUR_TOKEN environment variable, else the token in the rotur CLI config file, else null. Fails with IOError or ParseError when the config file exists but can't be read.
rotur.login(any ...timeoutSecs) *rotur.ClientDeprecated. Deprecated: use client.login(options?) on rotur.new() instead.
login runs the device flow and returns the signed-in client, or null.
rotur.logout() result<unit, error>logout removes the saved token and username from the rotur CLI config file. Fails with IOError or ParseError when the file can't be updated.
rotur.new(any ...token) *rotur.Clientnew builds a client: new(token?). Pass a rotur account token, or nothing (or "") for an anonymous client that can only call public endpoints.
Every API method returns result<T, error> whose message carries the API's own error text. The kinds are NotFoundError for a missing resource (HTTP 404), PermissionError when the client has no token or the API refuses the request (401, 402, 403), ValueError for other rejected requests (4xx), StateError for conflicts and rate limits (409, 429), TimeoutError, NetworkError when the API can't be reached (and for 502 and 503), and RuntimeError for anything else. Response objects keep the API's own keys. Throws TypeError when token isn't a string.
rotur.overlayURL(string username, object? options) stringoverlayURL is the avatar overlay of username. Options as for avatarURL.
rotur.savedToken() stringDeprecated. Deprecated: use rotur.loadToken() instead, which returns null when there is no token.
savedToken returns the saved token, or "" when there is none.
rotur.signWith(string seed, any content) result<string, error>signWith signs content's canonical JSON with an Ed25519 seed given as base64url (the private JWK's "d") and returns the base64url signature. Fails with ValueError when seed isn't a 32-byte base64url seed.
rotur.verifyWith(string publicKey, any content, string signature) result<boolean, error>verifyWith reports whether signature is a valid Ed25519 signature of content's canonical JSON for publicKey (base64url, the JWK's "x"). A well-formed signature that doesn't match is false. Fails with ValueError when publicKey or signature isn't well-formed base64url of the right size.
*rotur.Client
client.accounts() *rotur.Accountsaccounts registers accounts and handles password resets.
client.ai() *rotur.Aiai talks to the rotur AI.
client.avatars() *rotur.Avatarsavatars uploads and removes profile pictures, banners and overlays.
client.baseUrl(string url) *rotur.ClientDeprecated. Deprecated: use client.useBaseURL(url) instead.
baseUrl points the client at another API root and returns the client.
client.cosmetics() *rotur.Cosmeticscosmetics browses, buys and equips profile cosmetics.
client.delete(string path, any ...body) resultDeprecated. Deprecated: use client.request("DELETE", path, {body}) instead.
delete calls DELETE path with an optional body; it needs a token.
client.emojis() *rotur.Emojisemojis manages custom emojis.
client.files() *rotur.Filesfiles reads and writes the account's cloud files.
client.following() *rotur.Followingfollowing follows users and lists followers.
client.friends() *rotur.Friendsfriends manages friends and friend requests.
client.get(string path, object? options) resultDeprecated. Deprecated: use client.request("GET", path, {query}) instead.
get calls GET path with optional query params.
client.gifts() *rotur.Giftsgifts creates and claims credit gifts.
client.groups() *rotur.Groupsgroups manages groups, members, roles, events and products.
client.hasToken() booleanhasToken reports whether the client has a token. It doesn't ask the API whether the token is valid; whoami does that.
client.items() *rotur.Itemsitems manages tradeable items.
client.keys() *rotur.Keyskeys manages purchasable access keys.
client.link() *rotur.Linklink drives the rotur.dev/link device sign-in flow step by step.
client.loggedIn() booleanDeprecated. Deprecated: use client.hasToken() instead.
loggedIn reports whether the client has a token.
client.login(object? options) result<unit, error>login signs the client in with the rotur.dev/link device flow: it requests a code, shows it, waits for the user to approve it on rotur.dev and then uses the new token. Options: timeout (ms, default 180000), save (boolean, default true: also store the token like saveToken), onCode (function called with the code and the approval URL; without it the instructions are printed). Fails with TimeoutError when nobody approves the code in time, and with the usual API errors.
client.me() *rotur.Meme is the signed-in account: profile data, credits, blocks, notes, billing.
client.notifications() *rotur.Notificationsnotifications reads, marks and sends notifications.
client.patch(string path, any ...body) resultDeprecated. Deprecated: use client.request("PATCH", path, {body}) instead.
patch calls PATCH path with an optional body; it needs a token.
client.pets() *rotur.Petspets browses, buys and equips pets.
client.post(string path, any ...body) resultDeprecated. Deprecated: use client.request("POST", path, {body}) instead.
post calls POST path with an optional body.
client.posts() *rotur.Postsposts creates, reads and reacts to posts.
client.profiles() *rotur.Profilesprofiles reads public profiles.
client.push() *rotur.Pushpush manages web push devices and sends push notifications.
client.put(string path, any ...body) resultDeprecated. Deprecated: use client.request("PUT", path, {body}) instead.
put calls PUT path with an optional body; it needs a token.
client.request(string method, string path, object? options) result<any, error>request calls any API endpoint the client has no method for. method is an HTTP method and path is relative to baseURL ("/limits") or a full URL. Options: query (object of query parameters), body (a string is sent as text/plain, anything else as JSON). Returns the decoded JSON response, or the text when it isn't JSON. The token is sent only to the scheme and host of the client's base URL, never with a full URL to anywhere else.
client.save(any ...username) booleanDeprecated. Deprecated: use client.saveToken(options?) instead.
save stores the token (and optional username) in the config file and reports whether that worked.
client.saveToken(object? options) result<unit, error>saveToken stores the client's token in the rotur CLI config file so rotur.load() and the rotur CLI pick it up. Options: username (string, saved alongside). Fails with StateError when the client has no token, and IOError or ParseError when the file can't be written.
client.sessions() *rotur.Sessionssessions starts and ends usage sessions.
client.setToken(string token) *rotur.ClientDeprecated. Deprecated: use client.useToken(token) instead.
setToken replaces the token and returns the client.
client.signing() *rotur.Signingsigning signs, verifies, encrypts and decrypts with rotur identity keys.
client.socket() *rotur.Socketsocket is the client's realtime connection for presence, rooms, live account keys and activities. Each client has one; call start() on it.
client.stats() *rotur.Statsstats reads public platform statistics.
client.status() *rotur.Statusstatus reads and sets live status.
client.storage() *rotur.Storagestorage reads and writes per-app key/value storage.
client.systems() *rotur.Systemssystems manages registered systems and their badges.
client.token() stringDeprecated. Deprecated: tokens are write-only; use client.hasToken() to check for one.
token returns the client's token.
client.tokens() *rotur.Tokenstokens manages sub-tokens with limited permissions.
client.trust() *rotur.Trusttrust reads trust scores and verifies users.
client.useBaseURL(string url)useBaseURL points the client at another API root instead of https://api.rotur.dev/v2, such as a test server ("http://127.0.0.1:8080/v2"). A trailing slash is dropped.
client.useToken(string token)useToken makes the client send token from now on, replacing any previous one; "" makes it anonymous. The token is write-only: nothing returns it.
client.username() result<string, error>username is the account name the token belongs to. Fails with PermissionError when the client has no token or the API rejects it.
client.validators() *rotur.Validatorsvalidators generates and checks validator tokens for third-party sign-in.
client.whoami() result<object, error>whoami checks the token with the API and returns {auth, username, token_type, permissions}.
*rotur.Me
me.abilities() result<object, error>abilities returns what the client's token is allowed to do. Needs a token.
me.acceptTOS() result<object, error>acceptTOS accepts the current terms of service. Needs a token.
me.badgePreferences() result<object, error>badgePreferences returns {preferences, badges}: how the account's badges are shown. Needs a token.
me.badges() result<object, error>badges returns {badge_names}, the badges the account has. Needs a token.
me.benefits() result<object, error>benefits returns {benefits, subscription} for the account's tier. Needs a token.
me.billing() result<object, error>billing returns the account's billing status. Needs a token.
me.billingPortal() result<object, error>billingPortal returns a billing portal session (with its URL). Needs a token.
me.block(string username) result<object, error>block blocks username. Needs a token.
me.blocked() result<object, error>blocked returns {blocked}, the usernames the account blocks. Needs a token.
me.changePassword(string current, string next) result<object, error>changePassword changes the account password. Fails with PermissionError when current is wrong. Needs a token.
me.checkAuth() resultDeprecated. Deprecated: use client.whoami() instead.
checkAuth checks the token.
me.checkout(string lookupKey) result<object, error>checkout starts buying the subscription lookupKey and returns the checkout session (with its URL). Needs a token.
me.claimDaily() result<object, error>claimDaily claims the daily credit reward. Fails with StateError or ValueError (as the API reports it) when it was already claimed. Needs a token.
me.claimTime() result<object, error>claimTime returns {wait_time}, how long until the daily reward can be claimed again, as the API reports it. Needs a token.
me.deleteAccount(string username) resultDeprecated. Deprecated: use client.profiles().delete(username) instead.
deleteAccount deletes the signed-in account.
me.deleteKey(string key) result<object, error>deleteKey removes one key from the account data. Needs a token.
me.deleteNote(string username) result<object, error>deleteNote removes the note about username. Needs a token.
me.get() result<object, error>get returns the signed-in account's data object, including sys.* keys such as sys.currency. Needs a token.
me.note(string username, string content) result<object, error>note saves a private note about username, replacing any earlier one. Needs a token.
me.notes() result<object, error>notes returns {notes}, an object of username to note. Needs a token.
me.outgoing() resultDeprecated. Deprecated: use client.friends().outgoing() instead.
outgoing returns the outgoing friend requests.
me.pay(string to, number amount, object? options) result<object, error>pay sends amount credits to the user to. Options: note (string shown to the receiver). Needs a token.
me.refreshToken(string password) result<object, error>refreshToken asks for a new token, returned as {token}, and needs the account password. The old token stops working; the client keeps using it until you pass the new one to useToken. Fails with ValueError when password is empty and PermissionError when it is wrong. Needs a token.
me.requests() resultDeprecated. Deprecated: use client.friends().requests() instead.
requests returns the incoming friend requests.
me.resendVerification() result<object, error>resendVerification sends the verification email again. Needs a token.
me.subscription() result<{active: boolean, next_billing: number, tier: string}, error>subscription returns {active, tier, next_billing} for the account; an account without one is {active: false, tier: "Free", next_billing: 0}. next_billing is unix milliseconds. Needs a token.
me.transactions() result<array, error>transactions returns the account's credit transactions, newest first as the API stores them. Needs a token.
me.transfer(string to, number amount, any ...note) resultDeprecated. Deprecated: use client.me().pay(to, amount, {note}) instead.
transfer sends credits with an optional note.
me.unblock(string username) result<object, error>unblock unblocks username. Needs a token.
me.update(string key, any value) result<object, error>update sets one key of the account data and returns the API's answer. Needs a token.
me.updateBadgePreferences(object preferences) result<object, error>updateBadgePreferences replaces the badge display preferences and returns {preferences, badges}. Needs a token.
*rotur.Posts
posts.bookmark(string id) result<object, error>bookmark bookmarks the post id. Needs a token.
posts.bookmarks() result<array, error>bookmarks returns the bookmarked posts. Needs a token.
posts.castVote(string id, int option) result<object, error>castVote votes for option (1 for the first) in the poll on post id, replacing an earlier vote, and returns {poll}. Throws ValueError when option is below 1. Needs a token.
posts.create(string content, object? options) result<object, error>create publishes a post and returns it (or the scheduled post). Options: attachment (string URL), attachments (array of URLs), profileOnly (boolean, keep it off the public feed), os (string, a registered system to tag), poll (array of 2-6 option strings), scheduledFor (unix ms to publish at). The older spellings profile_only and scheduled_for, and attachments as one comma-separated string, still work. Fails with ValueError when the API rejects the content. Needs a token.
Deprecated option profile_only: pass profileOnly instead. Deprecated option scheduled_for: pass scheduledFor instead.
posts.delete(string id) result<object, error>delete deletes the post id. Needs a token.
posts.edit(string id, string content) result<object, error>edit replaces the text of the post id. Needs a token.
posts.feed(any ...args) resultDeprecated. Deprecated: use client.posts().list({limit, offset}) instead.
feed returns the public feed: feed(limit?, offset?).
posts.find(string query, object? options) result<array, error>find searches posts for query. Options: limit (1-20, default 20). Public.
posts.following(object? options) result<array, error>following returns recent posts from accounts the user follows. Options: limit (default 100). Needs a token.
posts.followingFeed(any ...limit) resultDeprecated. Deprecated: use client.posts().following({limit}) instead.
followingFeed returns posts from followed accounts: followingFeed(limit?).
posts.get(string id) result<object, error>get returns the post id. Fails with NotFoundError when it doesn't exist. Public.
posts.like(string id) result<object, error>like likes the post id. Needs a token.
posts.limits() result<object, error>limits returns the posting limits for each subscription tier. Public.
posts.list(object? options) result<array, error>list returns the public feed, newest first. Options: limit (1-100, default 100), offset (posts to skip, default 0). Public.
posts.pin(string id) result<object, error>pin pins the post id to the account's profile. Needs a token.
posts.popular(object? options) result<array, error>popular returns the most liked recent posts. Options: limit (default 50), period (ms to look back, default 86400000 = 24 hours, counted in whole hours). Public.
posts.reply(string id, string content) result<object, error>reply replies to the post id and returns the reply. Needs a token.
posts.repost(string id) result<object, error>repost reposts the post id and returns the new post. Needs a token.
posts.scheduled() result<array, error>scheduled returns the account's scheduled posts. Needs a token.
posts.search(string query, any ...limit) resultDeprecated. Deprecated: use client.posts().find(query, {limit}) instead.
search searches posts: search(query, limit?).
posts.top(any ...args) resultDeprecated. Deprecated: use client.posts().popular({limit, period}) instead, with period in ms.
top returns the top posts: top(limit?, hours?).
posts.unbookmark(string id) result<object, error>unbookmark removes the bookmark on post id. Needs a token.
posts.unlike(string id) result<object, error>unlike removes the like on post id. Needs a token.
posts.unpin(string id) result<object, error>unpin unpins the post id. Needs a token.
posts.view(string id) result<object, error>view counts a view of the post id and returns {views}. Needs a token.
posts.viewMany(array ids) result<object, error>viewMany counts a view of each post id and returns {views}, an object of id to view count. Needs a token.
*rotur.Friends
friends.accept(string username) result<object, error>accept accepts the friend request from username. Needs a token.
friends.cancel(string username) result<object, error>cancel withdraws the friend request sent to username. Needs a token.
friends.list() result<object, error>list returns {friends}, the account's friends. Needs a token.
friends.outgoing() result<object, error>outgoing returns the friend requests the account sent, as {requests_out}. Needs a token.
friends.reject(string username) result<object, error>reject rejects the friend request from username. Needs a token.
friends.remove(string username) result<object, error>remove unfriends username. Needs a token.
friends.request(string username) result<object, error>request sends a friend request to username. Needs a token.
friends.requests() result<object, error>requests returns the incoming friend requests, as {requests}. Needs a token.
*rotur.Following
following.follow(string username) result<object, error>follow follows username. Needs a token.
following.followers(string username) result<object, error>followers returns who follows username. Public.
following.following(string username) result<object, error>following returns who username follows. Public.
following.unfollow(string username) result<object, error>unfollow stops following username. Needs a token.
*rotur.Notifications
notifications.clear() result<object, error>clear deletes every notification. Needs a token.
notifications.create(string target, string kind, object? options) result<object, error>create sends a notification of type kind to the user target. Options: actor (string), data (object), platform (string), platformData (object; the older platform_data still works). Needs a token.
Deprecated option platform_data: pass platformData instead.
notifications.delete(string id) result<object, error>delete deletes the notification id. Needs a token.
notifications.list(any ...afterDays) resultDeprecated. Deprecated: use client.notifications().recent({period}) instead, with period in ms.
list returns notifications from the last afterDays days (default 30).
notifications.markRead(any ...ids) resultDeprecated. Deprecated: use client.notifications().readMany(ids) or readAll() instead.
markRead marks the given ids read, or every notification without ids.
notifications.read(string id) result<object, error>read marks the notification id read. Needs a token.
notifications.readAll() result<object, error>readAll marks every notification read. Needs a token.
notifications.readMany(array ids) result<object, error>readMany marks the notifications with these ids read. Needs a token.
notifications.recent(object? options) result<array, error>recent returns the account's notifications, newest first. Options: period (ms to look back, default 30 days, counted in whole days). Needs a token.
*rotur.Keys
keys.addUser(string id, string user) result<object, error>addUser gives the key id to user. Needs a token.
keys.buy(string id) result<object, error>buy buys the key id. Needs a token.
keys.cancel(string id) result<object, error>cancel cancels the subscription to the key id. Needs a token.
keys.check(string username, string key) result<object, error>check reports whether username holds key, as the API's answer object. Public.
keys.create(string name, object? options) result<object, error>create makes a new key called name. Options: description (string), price (credits), subscription (boolean), frequency (number), period (string such as "month"). Needs a token.
keys.delete(string id) result<object, error>delete deletes the key id. Needs a token.
keys.get(string id) result<object, error>get returns the key id. Public.
keys.mine() result<array, error>mine returns the keys the account owns. Needs a token.
keys.removeUser(string id, string user) result<object, error>removeUser removes user from the key id. Needs a token.
keys.rename(string id, string name) result<object, error>rename renames the key id. Needs a token.
keys.revoke(string id, string user) result<object, error>revoke takes the key id away from user. Needs a token.
keys.update(string id, string key, any data) result<object, error>update sets one field of the key id. Needs a token.
*rotur.Items
items.buy(string name) result<object, error>buy buys the item name. Needs a token.
items.create(object item) result<object, error>create makes a new item from its fields (name, description, price, ...) and returns it. Needs a token.
items.delete(string name) result<object, error>delete deletes the item name. Needs a token.
items.forSale(object? options) result<array, error>forSale returns items listed for sale. Options: limit (default 50). Public.
items.get(string name) result<object, error>get returns the item name. Public.
items.list(string username) result<array, error>list returns the items username owns. Public.
items.sell(string name) result<object, error>sell lists the item name for sale. Needs a token.
items.selling(any ...limit) resultDeprecated. Deprecated: use client.items().forSale({limit}) instead.
selling returns items for sale: selling(limit?).
items.setPrice(string name, number price) result<object, error>setPrice sets the price of the item name in credits. Needs a token.
items.stopSelling(string name) result<object, error>stopSelling takes the item name off sale. Needs a token.
items.transfer(string name, string username) result<object, error>transfer gives the item name to username. Needs a token.
items.update(string name, any data) result<object, error>update replaces the data of the item name and returns the item. Needs a token.
*rotur.Gifts
gifts.cancel(string id) result<object, error>cancel cancels the account's unclaimed gift id. Needs a token.
gifts.claim(string code) result<object, error>claim claims the gift code. Needs a token.
gifts.create(number amount, object? options) result<object, error>create makes a claimable gift of amount credits and returns it with its code. Options: note (string), expiresIn (ms until it expires, counted in whole hours). Deprecated: expiresInHrs and expires_in_hrs still take hours. Needs a token.
Deprecated option expiresInHrs: pass expiresIn (milliseconds) instead. Deprecated option expires_in_hrs: pass expiresIn (milliseconds) instead.
gifts.get(string code) result<object, error>get returns {gift} for the gift code. Public.
gifts.mine() result<object, error>mine returns {gifts, count}, the gifts the account made. Needs a token.
*rotur.Tokens
tokens.active() result<object, error>active returns {tokens, total}, the sub-tokens that still work. Needs a token.
tokens.activity(string id) result<object, error>activity returns the recent use of the sub-token id. Needs a token.
tokens.create(string name, array permissions, object? options) result<object, error>create makes a sub-token called name with the given permission strings and returns it, including the token itself. Options: expiresIn (ms, counted in whole hours), origin (string), description (string), websites (array of strings). Deprecated: expiresInHrs and expires_in_hrs still take hours. Needs a token.
Deprecated option expiresInHrs: pass expiresIn (milliseconds) instead. Deprecated option expires_in_hrs: pass expiresIn (milliseconds) instead.
tokens.delete(string id) result<object, error>delete deletes the sub-token id. Needs a token.
tokens.get(string id) result<object, error>get returns the sub-token id. Needs a token.
tokens.list() result<object, error>list returns {tokens, total}, every sub-token. Needs a token.
tokens.permissions() result<object, error>permissions returns the permissions a sub-token can have. Public.
tokens.rename(string id, string name) result<object, error>rename renames the sub-token id. Needs a token.
tokens.revoke(string id) result<object, error>revoke stops the sub-token id from working. Needs a token.
tokens.update(string id, object changes) result<object, error>update changes fields of the sub-token id (the API's field names). Needs a token.
*rotur.Groups
groups.acceptInvite(string tag, string inviteID) result<object, error>acceptInvite accepts the invite inviteID to the group tag. Needs a token.
groups.acceptJoinRequest(string tag, string requestID) result<object, error>acceptJoinRequest lets the requester of requestID in. Needs a token.
groups.announce(string tag, string title, string body, object? options) result<object, error>announce posts an announcement to the group tag and returns it. Options: pingMembers (boolean, notify every member). Needs a token.
groups.announcements(string tag) result<array, error>announcements returns the announcements of the group tag. Public.
groups.askToJoin(string tag, object? options) result<object, error>askToJoin asks to join the group tag. Options: message (string for the group's admins). Needs a token.
groups.assignRole(string tag, string userID, string roleID) result<object, error>assignRole gives the member userID the role roleID. Needs a token.
groups.ban(string tag, string userID, any ...reason) resultDeprecated. Deprecated: use client.groups().banMember(tag, userID, {reason}) instead.
ban bans a member: ban(tag, userID, reason?).
groups.banMember(string tag, string userID, object? options) result<object, error>banMember bans userID from the group tag. Options: reason (string). Needs a token.
groups.bans(string tag) result<array, error>bans returns the bans of the group tag. Needs a token.
groups.cancelProductSubscription(string tag, string productID) result<object, error>cancelProductSubscription cancels the subscription to productID. Needs a token.
groups.checkBan(string tag, string userID) result<object, error>checkBan returns the ban record of userID, as the API's answer object. Needs a token.
groups.create(string tag, string name, object? options) result<object, error>create makes a group with the short tag and display name and returns it. Options: description (string), iconURL (string), bannerURL (string), public (boolean), joinPolicy (string such as "open" or "request"). The older spellings icon_url, iconUrl, banner_url, bannerUrl and join_policy still work. Needs a token.
Deprecated option icon_url: pass iconURL instead. Deprecated option iconUrl: pass iconURL instead. Deprecated option banner_url: pass bannerURL instead. Deprecated option bannerUrl: pass bannerURL instead. Deprecated option join_policy: pass joinPolicy instead.
groups.createAnnouncement(string tag, string title, string body, any ...pingMembers) resultDeprecated. Deprecated: use client.groups().announce(tag, title, body, {pingMembers}) instead.
createAnnouncement posts an announcement: createAnnouncement(tag, title, body, pingMembers?).
groups.createEvent(string tag, object event) result<object, error>createEvent creates an event in the group tag from its fields (the API's field names) and returns it. Needs a token.
groups.createProduct(string tag, object product) result<object, error>createProduct adds a product to the group tag. product has name, description, priceCredits, roleID, subscription, frequency and period (the API's snake_case names are accepted too). Needs a token.
groups.createRole(string tag, object role) result<object, error>createRole creates a role in the group tag from its fields and returns it. Needs a token.
groups.declineInvite(string tag, string inviteID) result<object, error>declineInvite declines the invite inviteID. Needs a token.
groups.declineJoinRequest(string tag, string requestID) result<object, error>declineJoinRequest turns down the join request requestID. Needs a token.
groups.delete(string tag) result<object, error>delete deletes the group tag. Needs a token.
groups.deleteAnnouncement(string tag, string id) result<object, error>deleteAnnouncement deletes the announcement id of the group tag. Needs a token.
groups.deleteEvent(string tag, string eventID) result<object, error>deleteEvent deletes the event eventID. Needs a token.
groups.deleteProduct(string tag, string productID) result<object, error>deleteProduct deletes the product productID. Needs a token.
groups.deleteRole(string tag, string roleID) result<object, error>deleteRole deletes the role roleID. Needs a token.
groups.disrepresent(string tag) result<object, error>disrepresent stops showing the group tag on the profile. Needs a token.
groups.events(string tag) result<array, error>events returns the events of the group tag. Needs a token.
groups.get(string tag) result<object, error>get returns the group tag. Needs a token.
groups.invite(string tag, string username) result<object, error>invite invites username to the group tag. Needs a token.
groups.invites(string tag) result<array, error>invites returns the pending invites of the group tag. Needs a token.
groups.join(string tag) result<object, error>join joins the open group tag. Needs a token.
groups.joinRequests(string tag) result<array, error>joinRequests returns the pending join requests of the group tag. Needs a token.
groups.kick(string tag, string userID) result<object, error>kick removes the member userID from the group tag. Needs a token.
groups.leave(string tag) result<object, error>leave leaves the group tag. Needs a token.
groups.memberInfo(string tag, string userID) result<object, error>memberInfo returns the membership of userID in the group tag. Needs a token.
groups.members(string tag, object? options) result<object, error>members returns a page of the members of the group tag. Options: page (1-based, default 1), perPage (number; the older per_page still works), search (string). Needs a token.
Deprecated option per_page: pass perPage instead.
groups.mine() result<array, error>mine returns the groups the account is in. Needs a token.
groups.muteAnnouncements(string tag) result<object, error>muteAnnouncements stops announcement notifications from the group tag. Needs a token.
groups.myInvites() result<array, error>myInvites returns the group invites the account received. Needs a token.
groups.myProductSubscriptions() result<array, error>myProductSubscriptions returns the account's group product subscriptions. Needs a token.
groups.popular(object? options) result<array, error>popular returns the largest public groups. Options: limit (default 10). Public.
groups.productOwnership(string tag, string productID, string username) result<object, error>productOwnership reports whether username owns productID, as the API's answer object. Public.
groups.products(string tag) result<array, error>products returns the products the group tag sells. Needs a token.
groups.purchaseProduct(string tag, string productID) result<object, error>purchaseProduct buys the product productID. Needs a token.
groups.removeRole(string tag, string userID, string roleID) result<object, error>removeRole takes the role roleID from the member userID. Needs a token.
groups.report(string tag) result<object, error>report reports the group tag to moderators. Needs a token.
groups.represent(string tag) result<object, error>represent shows the group tag on the account's profile. Needs a token.
groups.requestJoin(string tag, any ...message) resultDeprecated. Deprecated: use client.groups().askToJoin(tag, {message}) instead.
requestJoin asks to join a group: requestJoin(tag, message?).
groups.revokeInvite(string tag, string inviteID) result<object, error>revokeInvite withdraws the invite inviteID. Needs a token.
groups.roles(string tag) result<array, error>roles returns the roles of the group tag. Needs a token.
groups.search(string query) result<array, error>search returns groups matching query. Needs a token.
groups.sendTip(string tag, number amount, any ...note) resultDeprecated. Deprecated: use client.groups().tip(tag, amount, {note}) instead.
sendTip tips a group: sendTip(tag, amount, note?).
groups.tip(string tag, number amount, object? options) result<object, error>tip sends amount credits to the group tag. Options: note (string). Needs a token.
groups.tipWithdrawals(string tag, object? options) result<array, error>tipWithdrawals returns past tip withdrawals of the group tag. Options: limit (default 20). Needs a token.
groups.tips(string tag) result<array, error>tips returns the tips the group tag received. Needs a token.
groups.top(any ...limit) resultDeprecated. Deprecated: use client.groups().popular({limit}) instead.
top returns the largest groups: top(limit?).
groups.transferOwnership(string tag, string userID) result<object, error>transferOwnership makes userID the owner of the group tag. Needs a token.
groups.unban(string tag, string userID) result<object, error>unban lifts the ban on userID. Needs a token.
groups.update(string tag, object updates) result<object, error>update changes fields of the group tag (the API's field names). Needs a token.
groups.updateEvent(string tag, string eventID, object updates) result<object, error>updateEvent changes fields of the event eventID. Needs a token.
groups.updateRole(string tag, string roleID, object updates) result<object, error>updateRole changes fields of the role roleID. Needs a token.
groups.userBenefits(string tag, string userID) result<array, error>userBenefits returns the benefit names the member userID has. Needs a token.
groups.userPermissions(string tag, string userID) result<array, error>userPermissions returns the permission names the member userID has. Needs a token.
groups.userRoles(string tag, string userID) result<array, error>userRoles returns the roles the member userID has. Needs a token.
groups.withdrawTip(string tag, number amount) result<object, error>withdrawTip withdraws amount tipped credits from the group tag. Needs a token.
groups.withdrawals(string tag, any ...limit) resultDeprecated. Deprecated: use client.groups().tipWithdrawals(tag, {limit}) instead.
withdrawals returns tip withdrawals: withdrawals(tag, limit?).
*rotur.Stats
stats.economy() result<object, error>economy returns credit economy statistics. Public.
stats.followers(any ...max) resultDeprecated. Deprecated: use client.stats().topFollowed({limit}) instead.
followers returns the most followed accounts: followers(max?).
stats.mostGained(any ...max) resultDeprecated. Deprecated: use client.stats().topEarners({limit}) instead.
mostGained returns the top earners: mostGained(max?).
stats.postActivity(object? options) result<object, error>postActivity returns posting activity as {days, total, buckets}. Options: period (ms to look back, default 7 days, counted in whole days). Public.
stats.posts(any ...days) resultDeprecated. Deprecated: use client.stats().postActivity({period}) instead, with period in ms.
posts returns posting activity: posts(days?).
stats.systems() result<object, error>systems returns an object of system name to account count. Public.
stats.topEarners(object? options) result<array, error>topEarners returns the accounts that gained the most credits, as [{user, earned}]. Options: limit (default 10). Public.
stats.topFollowed(object? options) result<array, error>topFollowed returns the most followed accounts, as [{username, follower_count}]. Options: limit (default 10). Public.
stats.users() result<object, error>users returns account statistics. Public.
*rotur.Status
status.get(string username) result<object, error>get returns the live status of username. Public.
status.setLive(object status) result<object, error>setLive publishes the account's live status from its fields (the API's field names). Needs a token.
*rotur.Validators
validators.generate(string key) result<object, error>generate returns {validator}, a one-time proof of the account for the service identified by key. Needs a token.
validators.validate(string validator, string key) result<object, error>validate checks a validator another client generated for key and returns the API's answer (whether it is valid and for which user). Public.
*rotur.Link
link.code() result<string, error>code requests a fresh device link code for the user to approve. Public.
link.getCode() resultDeprecated. Deprecated: use client.link().code() instead.
getCode requests a link code as {code}.
link.linkCode(string code) result<object, error>linkCode approves code as the signed-in account, signing in the device that shows it. Needs a token.
link.linkedUser(string code) result<object, error>linkedUser returns {linked, token?} for code: the token appears once the user approved it. Public.
link.status(string code) result<object, error>status returns {status} for code. Public.
link.url(string code) stringurl is the page where the user approves code.
link.wait(string code, any ...timeoutSecs) stringDeprecated. Deprecated: use client.link().waitForToken(code, {timeout}) instead, with timeout in ms.
wait polls until code is approved and returns the token, or "" on timeout.
link.waitForToken(string code, object? options) result<string, error>waitForToken polls until code is approved, makes the client use the new token and returns it. Options: timeout (ms, default 120000). Fails with TimeoutError when nobody approves the code in time.
*rotur.Cosmetics
cosmetics.backgroundURL(string id) stringbackgroundURL is the background video of the cosmetic id.
cosmetics.equip(string id) result<object, error>equip wears the cosmetic id. Needs a token.
cosmetics.forUser(string username) result<object, error>forUser returns the cosmetics username wears. Public.
cosmetics.forUsers(array usernames) result<object, error>forUsers returns the cosmetics several users wear. Public.
cosmetics.get(string id) result<object, error>get returns the cosmetic id. Public.
cosmetics.gift(string id, string to, any ...note) resultDeprecated. Deprecated: use client.cosmetics().give(id, to, {note}) instead.
gift gifts a cosmetic: gift(id, to, note?).
cosmetics.gifts() result<object, error>gifts returns {received, sent}, the account's cosmetic gifts. Needs a token.
cosmetics.give(string id, string to, object? options) result<object, error>give gifts the cosmetic id to the user to. Options: note (string). Needs a token.
cosmetics.mine() result<object, error>mine returns the cosmetics the account owns. Needs a token.
cosmetics.overlayURL(string id) stringoverlayURL is the animated overlay image of the cosmetic id.
cosmetics.purchase(string id) result<object, error>purchase buys the cosmetic id. Needs a token.
cosmetics.shop(object? options) result<object, error>shop returns the cosmetics catalog. Options: type (string), featured (boolean), search (string), sort (string), limit (number), offset (number). Public.
cosmetics.unequip(string kind) result<object, error>unequip takes off the cosmetic of type kind. Needs a token.
*rotur.Push
push.addDevice(object device) result<object, error>addDevice registers a web push subscription. device has endpoint, p256dh, auth, source and fingerprint (all strings). Needs a token.
push.allowSender(string username, string source) result<object, error>allowSender lets username push to the account for source. Needs a token.
push.allowedSenders() result<object, error>allowedSenders returns, per source, who may push to the account. Needs a token.
push.check(string source, string fingerprint) result<object, error>check reports whether a device is registered for source, as the API's answer object. Needs a token.
push.deleteDevice(string deviceID) result<object, error>deleteDevice unregisters the device deviceID. Needs a token.
push.endpoints() result<object, error>endpoints returns {endpoints, count}, the registered devices. Needs a token.
push.log() result<object, error>log returns {log, count}, recently sent pushes. Needs a token.
push.notifiableUsers(string source) result<object, error>notifiableUsers returns {source, users}, who allows pushes from source. Needs a token.
push.register(string endpoint, string p256dh, string auth, any ...rest) resultDeprecated. Deprecated: use client.push().addDevice({endpoint, p256dh, auth, source, fingerprint}) instead.
register registers a push device: register(endpoint, p256dh, auth, source, fingerprint).
push.removeSender(string username, string source) result<object, error>removeSender stops username pushing to the account for source. Needs a token.
push.send(string username, string source, object? options) result<object, error>send pushes a notification for source to username. Options: title (string), body (string), data (object). Needs a token.
push.sendMany(array users, string source, object? options) result<object, error>sendMany pushes a notification for source to every username in users. Options as for send. Needs a token.
push.vapidKeys() result<object, error>vapidKeys returns {public_key, subject} for web push subscriptions. Public.
*rotur.Files
files.all() result<array, error>all returns every file entry with its contents. Needs a token.
files.byPath(string path) result<object, error>byPath returns the file at path. Fails with NotFoundError when it doesn't exist. Needs a token.
files.byUUID(string uuid) result<object, error>byUUID returns the file uuid. Fails with NotFoundError when it doesn't exist. Needs a token.
files.byUUIDs(array uuids) result<array, error>byUUIDs returns the files with these uuids. Needs a token.
files.deleteAll() result<object, error>deleteAll deletes every file. Needs a token.
files.getByPath(string path) resultDeprecated. Deprecated: use client.files().byPath(path) instead.
getByPath returns one file.
files.getByUUID(string uuid) resultDeprecated. Deprecated: use client.files().byUUID(uuid) instead.
getByUUID returns one file.
files.index() result<array, error>index returns every file entry without contents. Needs a token.
files.pathIndex() result<object, error>pathIndex returns an object of path to file uuid. Needs a token.
files.stats(array uuids) result<object, error>stats returns {stats} for the files with these uuids. Needs a token.
files.upload(object files) result<object, error>upload writes files, an upload request in the API's format. Needs a token.
files.usage() result<object, error>usage returns the storage used by files and the quota, in bytes. Needs a token.
*rotur.Profiles
profiles.avatarUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.avatarURL(username, {version}) instead.
avatarUrl is a profile picture URL: avatarUrl(username, cache?).
profiles.backgroundUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.backgroundURL(username, {version}) instead.
backgroundUrl is a background URL: backgroundUrl(username, cache?).
profiles.bannerUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.bannerURL(username, {version}) instead.
bannerUrl is a banner URL: bannerUrl(username, cache?).
profiles.delete(string username) result<object, error>delete deletes the signed-in account, which must be username. Needs a token.
profiles.exists(string username) resultDeprecated. Deprecated: use client.profiles().userExists(username) instead, which returns a boolean.
exists returns {exists} for username.
profiles.get(string username, any ...includePosts) resultDeprecated. Deprecated: use client.profiles().lookup(username, {includePosts}) instead.
get returns a profile: get(username, includePosts?).
profiles.lookup(string username, object? options) result<object, error>lookup returns the public profile of username. Options: includePosts (boolean, default true). Fails with NotFoundError when there is no such user. Public.
profiles.overlayUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.overlayURL(username, {version}) instead.
overlayUrl is an overlay URL: overlayUrl(username, cache?).
profiles.supporters() result<array, error>supporters returns the accounts with a paid subscription, as [{username, subscription}]. Public.
profiles.userExists(string username) result<boolean, error>userExists reports whether an account called username exists. Public.
*rotur.Storage
storage.clear(string id) result<object, error>clear removes every key of the app id and returns {id, cleared}. Needs a token.
storage.clearAll() result<object, error>clearAll removes every app's stored data. Needs a token.
storage.delete(string id, string key) result<object, error>delete removes key from the app id and returns {id, data}. Needs a token.
storage.get(string id) result<object, error>get returns {id, data}, every key stored under the app id. Needs a token.
storage.getKey(string id, string key) resultDeprecated. Deprecated: use client.storage().value(id, key) instead.
getKey returns one stored value.
storage.list() result<object, error>list returns {ids, usage, max}: every app id with stored data, and the usage and quota in bytes. Needs a token.
storage.set(string id, string key, any value) result<object, error>set stores value under key for the app id and returns {id, data}. Needs a token.
storage.usage() result<object, error>usage returns {usage, max} in bytes. Needs a token.
storage.value(string id, string key) result<any, error>value returns one key stored under the app id, or null when it isn't set. Needs a token.
*rotur.Signing
signing.compact(object envelope) result<string, error>compact turns an envelope into one "rotur_enc_v1." string, the form the rotur CLI prints. Fails with ValueError when envelope can't be encoded.
signing.currentKey(string username) result<object, error>currentKey returns the current public key record of username. Public.
signing.decrypt(any envelope) result<any, error>decrypt opens an envelope addressed to the signed-in account and returns its content. envelope is the object encrypt returns or the string compact returns. Fails with ParseError for a malformed or tampered envelope, UnsupportedError for an unknown version or algorithm, and ValueError when the envelope is for another key. Throws TypeError when envelope is neither an object nor a string. Needs a token.
signing.encrypt(object recipient, any content) result<{algorithm: string, ciphertext: string, ephemeral_public_key: string, iv: string, recipient_id: string, recipient_key_id: string, salt: string, version: number}, error>encrypt encrypts content (any JSON value) for the key recipient {user_id, key_id, username?} and returns the envelope {version, algorithm, recipient_id, recipient_key_id, ephemeral_public_key, salt, iv, ciphertext}. Fails with NotFoundError for an unknown key and ValueError when username doesn't own it.
signing.encryptFor(string username, any content) result<{algorithm: string, ciphertext: string, ephemeral_public_key: string, iv: string, recipient_id: string, recipient_key_id: string, salt: string, version: number}, error>encryptFor encrypts content for the current key of username; see encrypt.
signing.identity() result<{algorithm: string, key_id: string, public_key_jwk: object, user_id: string, username: string}, error>identity returns the public half of the signed-in account's identity key, {user_id, username, key_id, algorithm, public_key_jwk}. The private key never leaves the client. Needs a token.
signing.key() resultDeprecated. Deprecated: use client.signing().identity() instead, which never exposes the private key.
key returns the signed-in account's identity key record, private key included.
signing.lookupKey(string userID, string keyID, object? options) result<object, error>lookupKey returns the public key record keyID of the user userID, from a shared cache when possible. Options: refresh (boolean, skip the cache). Fails with NotFoundError when the key doesn't exist.
signing.publicKey(string userID, string keyID, any ...refresh) resultDeprecated. Deprecated: use client.signing().lookupKey(userID, keyID, {refresh}) instead.
publicKey returns a user's public key record: publicKey(userID, keyID, refresh?).
signing.rotate() result<object, error>rotate replaces the account's identity key; signatures made with the old key stay verifiable. Needs a token.
signing.sign(any content) result<{author_id: string, key_id: string, signature: string}, error>sign signs content's canonical JSON with the account's identity key and returns the proof {author_id, key_id, signature}. When the signed content must contain the author id, pass a function: it receives the id and returns the content to sign. Needs a token.
signing.verify(object proof, any content) result<boolean, error>verify reports whether proof {author_id, key_id, signature, username?} is a valid signature of content by that author. A malformed proof, an unknown key, a username that doesn't own the key or a wrong signature is false. Fails only when the author's key can't be fetched (NetworkError and the like).
*rotur.Avatars
avatars.backgroundUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.backgroundURL(username, {version}) instead.
backgroundUrl is a background URL: backgroundUrl(username, cache?).
avatars.bannerUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.bannerURL(username, {version}) instead.
bannerUrl is a banner URL: bannerUrl(username, cache?).
avatars.overlayUrl(string username, any ...cache) stringDeprecated. Deprecated: use rotur.overlayURL(username, {version}) instead.
overlayUrl is an overlay URL: overlayUrl(username, cache?).
avatars.removeBackground() result<object, error>removeBackground removes the profile background. Needs a token.
avatars.removeBanner() result<object, error>removeBanner removes the profile banner. Needs a token.
avatars.removeOverlay() result<object, error>removeOverlay removes the avatar overlay. Needs a token.
avatars.uploadAvatar(string image) result<object, error>uploadAvatar sets the profile picture from image, a data URL or base64 string. Uploads go to avatars.rotur.dev, or to the host of the client's base URL when useBaseURL changed it. Needs a token.
avatars.uploadBanner(string image) result<object, error>uploadBanner sets the profile banner from image, a data URL or base64 string. Needs a token.
avatars.url(string username, any ...cache) stringDeprecated. Deprecated: use rotur.avatarURL(username, {version}) instead.
url is a profile picture URL: url(username, cache?).
*rotur.Emojis
emojis.add(string id, string name) result<object, error>add saves someone else's emoji id to the account under name. Needs a token.
emojis.delete(string id) result<object, error>delete deletes the account's own emoji id. Needs a token.
emojis.mine() result<object, error>mine returns the account's uploaded and saved emojis. Needs a token.
emojis.unsave(string id) result<object, error>unsave removes a saved emoji id from the account. Needs a token.
emojis.upload(string name, string image) result<object, error>upload adds a custom emoji called name from image, a data URL or base64 string. Needs a token.
emojis.url(string id) stringurl is the image of the emoji id.
*rotur.Trust
trust.score(string username) result<object, error>score returns the trust score of username. Needs a token.
trust.verify(object? options) result<object, error>verify checks a user against trust requirements and returns the API's verdict. Options: username, userID, accountToken (strings), minScore (number), requiredStanding (string), maxRisk (number). The API's snake_case names (user_id, account_token, min_score, required_standing, max_risk) and userId still work. Needs a token.
Deprecated option user_id: pass userID instead. Deprecated option userId: pass userID instead. Deprecated option account_token: pass accountToken instead. Deprecated option min_score: pass minScore instead. Deprecated option required_standing: pass requiredStanding instead. Deprecated option max_risk: pass maxRisk instead.
*rotur.Accounts
accounts.bannedCheck(array usernames) result<object, error>bannedCheck returns {banned}, which of these usernames are banned. Public.
accounts.deletedCheck(array ids) result<object, error>deletedCheck reports which of these user ids belong to deleted accounts. Public.
accounts.register(object account) result<object, error>register creates an account from its fields (username, password, email, ... as the API names them) and returns it. Public.
accounts.requestPasswordReset(string email) result<object, error>requestPasswordReset emails a password reset link to email. Public.
accounts.resetPassword(string token, string newPassword) result<object, error>resetPassword sets a new password with the token from the reset email. Public.
accounts.verifyEmail(string token) result<object, error>verifyEmail confirms an email address with the token from the email. Public.
*rotur.Sessions
sessions.current() result<object, error>current returns the current usage session. Needs a token.
sessions.end() result<unit, error>end ends the current usage session. Needs a token.
sessions.start() result<object, error>start starts a usage session. Needs a token.
*rotur.Ai
ai.ask(string content, object? options) result<string, error>ask sends one prompt to the rotur AI and returns its reply text. Options: user (string, who is asking), model (string). Needs a token.
ai.chat(array history, object? options) result<any, error>chat continues a conversation. history is an array of {role, content}. Returns the reply text, or with returnHistory the whole conversation as an array of {role, content}. Options: user (string), model (string), returnHistory (boolean). Needs a token.
Deprecated option return_history: pass returnHistory instead.
*rotur.Pets
pets.catalog() result<object, error>catalog returns the pets for sale, as {pets}. Public.
pets.equip(string id) result<any, error>equip shows the pet id on the profile. Needs a token.
pets.mine() result<any, error>mine returns the account's pets as the API reports them. Needs a token.
pets.profile(string username) result<any, error>profile returns the pets username shows, as the API reports them. Public.
pets.purchase(string id) result<any, error>purchase buys the pet id. Needs a token.
pets.unequip() result<any, error>unequip stops showing a pet. Needs a token.
*rotur.Systems
systems.badges(string system) result<object, error>badges returns {badges}, the badges system defines. Public.
systems.createBadge(string system, object definition) result<object, error>createBadge defines a badge for system from definition (the API's field names) and returns it. Needs a token.
systems.deleteBadge(string system, string badge) result<object, error>deleteBadge deletes badge. Needs a token.
systems.list() result<object, error>list returns the registered systems, as an object of name to system. Public.
systems.revokeBadge(string system, string badge, string username) result<object, error>revokeBadge takes badge away from username. Needs a token.
systems.setBadgeProgress(string system, string badge, string username, any ...progress) resultDeprecated. Deprecated: use client.systems().updateBadgeProgress(system, badge, {username: progress}) instead.
setBadgeProgress sets one user's badge progress: setBadgeProgress(system, badge, username, progress).
systems.update(string system, string key, any value) result<object, error>update sets one field of the system you own. Needs a token.
systems.updateBadge(string system, string badge, object definition) result<object, error>updateBadge replaces the definition of badge. Needs a token.
systems.updateBadgeProgress(string system, string badge, object progress) result<object, error>updateBadgeProgress sets users' progress on badge of system. progress is an object of username to a number of 0 or more; tiers unlock at the thresholds the badge defines. Returns an object of username to the API's {grant, badge}. Stops at the first failure. Throws TypeError for a progress value that isn't a number. Needs a token.
systems.users(string system) result<array, error>users returns the usernames registered on system. Needs a token.
*rotur.Socket
socket.addActivity(object activity) result<unit, error>addActivity shows an activity on the profile. activity needs an id and may have title, application, status, image and media (the API's fields). Fails with StateError when the socket isn't connected.
socket.broadcast(string room, any value, object? options) result<unit, error>broadcast sends value to everyone in room, delivered as a "gmsg" message. Options: listener (string echoed back to match replies). Fails with StateError when the socket isn't connected.
socket.connect() booleanDeprecated. Deprecated: use socket.start(options?) instead, which fails with a typed error.
connect opens the socket and reports whether it became ready within 10 seconds; without a token it prints why and returns false.
socket.connected() booleanDeprecated. Deprecated: use socket.isConnected() instead.
connected reports whether the socket is connected and ready.
socket.getKey(string key) anyDeprecated. Deprecated: use socket.key(key) instead.
getKey returns one live account key.
socket.isConnected() booleanisConnected reports whether the socket is connected and authenticated.
socket.join(any ...rooms) result<unit, error>join joins one or more rooms by name (strings, or arrays of strings). The server answers with a join_ok message per room. Fails with StateError when the socket isn't connected.
socket.key(string key) anykey returns the live value of one account key, kept current by key_update messages, or null when it isn't set.
socket.keys() objectkeys returns every live account key as an object.
socket.leave(any ...rooms) result<unit, error>leave leaves one or more rooms; see join.
socket.listRooms() result<unit, error>listRooms asks the server for the joined rooms; the answer arrives as a "rooms" message. Fails with StateError when the socket isn't connected.
socket.off(string event, any handler)off removes a handler added with on(event, handler).
socket.on(string event, any handler)on adds handler for event: a server command such as "ready", "join_ok", "gmsg", "pmsg" or "key_update", "close" when the connection drops, or "*" for every message. The handler receives the message object. Handlers run on background threads; a throw is printed and the socket keeps running.
socket.removeActivity(string id) result<unit, error>removeActivity removes the activity id. Fails with StateError when the socket isn't connected.
socket.roomState(string room) result<unit, error>roomState asks for the members of room; the answer arrives as a "room_state" message. Fails with StateError when the socket isn't connected.
socket.rooms() arrayrooms lists the rooms the socket has joined.
socket.send(object packet) result<unit, error>send sends a raw message object to the server. Fails with StateError when the socket isn't connected.
socket.sendGroupMessage(string room, any val, any ...listener) booleanDeprecated. Deprecated: use socket.broadcast(room, value, {listener}) instead.
sendGroupMessage broadcasts to a room and reports whether it was sent.
socket.sendPrivate(string room, string to, any value, object? options) result<unit, error>sendPrivate sends value to one member of room (username or user id), delivered as a "pmsg" message. Options as for broadcast.
socket.sendPrivateMessage(string room, string to, any val, any ...listener) booleanDeprecated. Deprecated: use socket.sendPrivate(room, to, value, {listener}) instead.
sendPrivateMessage messages one room member and reports whether it was sent.
socket.setListening(string application, object media, object? options) result<unit, error>setListening shows music from application on the profile. media has title, artist, album, start and end (unix ms). Options: title (string, default "Listening to <application>"). Fails with StateError when the socket isn't connected.
socket.setMusic(string application, object media, any ...title) booleanDeprecated. Deprecated: use socket.setListening(application, media, {title}) instead.
setMusic shows music on the profile and reports whether it was sent.
socket.setPlaying(string application, object? options) result<unit, error>setPlaying shows "playing application" on the profile. Options: title (string, default application), status (string), url (string), image (string). Fails with StateError when the socket isn't connected.
socket.setStatus(string status, any ...presence) booleanDeprecated. Deprecated: use socket.updateStatus(status, {presence}) instead.
setStatus sets the status text and reports whether it was sent.
socket.setURL(string url)setURL changes the websocket address used by the next start().
socket.socketUrl(string url) *rotur.SocketDeprecated. Deprecated: use socket.setURL(url) instead.
socketUrl sets the websocket address and returns the socket.
socket.start(object? options) result<unit, error>start opens the socket, authenticates with the client's token and waits until the server says it is ready. Joined rooms are rejoined after a reconnect. Already connected is a no-op. Options: timeout (ms, default 10000). Fails with PermissionError when the client has no token or the server refuses it, NetworkError when the server can't be reached and TimeoutError when it doesn't answer in time.
socket.stop()stop closes the socket and forgets joined rooms and keys. start() can open it again. Stopping twice is a no-op.
socket.updateStatus(string status, object? options) result<unit, error>updateStatus sets the account's status text. Options: presence (string such as "online", "idle" or "dnd"). Fails with StateError when the socket isn't connected.
socket.url() stringurl is the websocket address the socket connects to.
socket.userID() string?userID is the signed-in account's id, or null before the socket is ready.
socket.username() string?username is the signed-in account's name, or null before the socket is ready.