SmashBets.tv API

See also API Changelog.

You must connect to the API via a secure connection (https://).

API Endpoints

All endpoints can return HTML (text/html) JSON (application/json), and msgpack (application/msgpack) by setting the Accept HTTP-Header to the appropriate mime type. It defaults to JSON if the Accept-Header isn't set. The API's root is /api. The following locations are all relative to that url.

All simple requests (GET, POST) support CORS. CORS-support for all other methods will be added if someone shows me an example of that being useful for this API. There is no support for JSONP.

Index

GET /

Returns what information glimesh associates with the submitted oauth token. Use this endpoint to test if your oauth setup works. It isn't ratelimited.

{
    "authorization": {
        "created_at": "2017-01-24T06:09:08Z",
        "scopes": [],
        "updated_at": "2017-01-24T06:09:08Z"
    },
    "client_id": "qfc39j0dq8ahwf56yodig7654",
    "user_id": "12345678",
    "user_name": "test",
    "valid": true
}

If you are not considered authenticated, the response will simply be:

null

GET /current_match

Returns the match currently running.

This endpoint has a ratelimiting cost of 10.

Note: A 404 means there currently is no match

Note: the switching field is represented by a string. It used to be a simple boolean (true = switching, false = no switching), but since more fine-grained switch policies were introduced, it's a string now. Old matches still have the boolean though.

{
coming soon
}

Do not access this resource more often than needed! The data returned only changes once per new match, and eventually after the match started. To retrieve data for already finished matches, use the /match endpoints.

GET /users/:user_id

Returns a user.

Generated example:

{
    "id": "99999881",
    "name": "Theponylove",
    "name_lower": "theponylove",
    "balance": 1000,
    "balance_bet_rank": null,
    "subscriber": false,
}

GET /matches

Returns all (finished) matches. See notes on /matches/:match_id.

Generated example:

[
    {
        coming soon
    }
]

GET /matches/:match_id

Returns a (finished) match.

Generated example:

{
    coming soon
}

GET /matches/:match_id/log

Returns the matchlog for a match. feed can be empty.
Keep in mind that for bets there can be multiple entries per user (for example if that user increased their bet)

Generated example:

{
    coming soon
}

GET /songs

Returns all songs in the music database.

Generated example:

[
    {
        "ends": null,
        "game_id": "pachislot_ryu_ga_gotoku_of_the_end",
        "id": "\u9f8d\u304c\u5982\u304f_rush_default_bgm",
        "last_bid_at": null,
        "last_played_at": "2021-08-07 16:26:24.613000",
        "title": "\u9f8d\u304c\u5982\u304f RUSH Default BGM",
        "types": [
            "battle"
        ],
        "volume": 1.0
    }
]

GET /balance_transactions

Returns all balance transactions in the database.

Generated example:

Error

GET /balance_rankings

Returns all SmashCash bet rankings.

Generated example:

[
    {
        "id": 186869.0,
        "timestamp": "2021-09-10 06:45:35.766000"
    }
]

GET /balance_rankings/:ranking_id

Returns ranks of a SmashCash bet ranking.

Generated example:

[
    {
        "balance": 87785,
        "rank": 1,
        "user_id": "146113319"
    },
    {
        "balance": 40791,
        "rank": 2,
        "user_id": "49257792"
    },
    {
        "balance": 35989,
        "rank": 3,
        "user_id": "57351763"
    }
]

GET /modbotlog

Returns the modbot log.

Generated example:

[
    {
        "id": "613a7d5eca0772524789abd0",
        "reason": "excessive usage of emotes/emojis",
        "rule": "emote",
        "ts": "2021-09-09 21:32:14.255000",
        "user": "58125459"
    }
]

GET /username_to_id/:username

Returns the user id of the user associated with the specified username.

Example:

"37115530"

GET /cursor/:token

Returns information on a previously created cursor. Returns 410 Gone if the cursor expired. After that, or if the cursor did not exist in the first place, 404 Not Found is returned. Also see Pagination.

count is the total amount of entries the cursor matches (skip and limit are not taken into account).

Example:

{
    "count": 120
}

POST /cursor/:token

Continues to consume the cursor, returning more entries. Ignores any query-parameters except limit. Also see Pagination.

DELETE /cursor/:token

Closes a cursor, even before it is exhausted. Call this endpoint if you did not fully exhaust your cursor. Also see Pagination. This endpoint is not ratelimited.

Pagination

Some resources are paginated (as in they don't return the whole dataset at once). You can control what slice of the data gets returned with these GET-parameters:

Example: To get "page 2" of the 50 oldest entries (50-100), you would use the query-parameters sort=id&skip=50&limit=50.

Filtering

Each paginated resource lists the fields it can be filtered by. To filter a field, add the query-parameter filter:field=value, where field is the name of the field to filter, and value is the value that field has to be equal to (case sensitive for strings).

Example: To get all badges by the user 24393817, you would use the query-parameter filter:user=24393817 on /badges.

The value may be empty, e.g. ?filter:foo=&filter:bar=baz, which gets interpreted as null. Certain fields may be assigned default values after the filter is applied.

If the field is of list type, separate multiple elements with a comma. The filter will return all documents where the value of the field is an array that contains all the specified elements.

Example: To get all matches containing the defiance and rngod gimmicks, use the query-parameter filter:base_gimmicks=defiance,rngod on /matches.

Cursors

If you need to read lots of paginated data, navigating through the data with the skip query-parameter is quite error-prone, as the underlying data can change between the individual requests. For these cases, you can make one request to get a token representing a cursor, which you can exhaust over multiple requests and get a consistent view of memory.

To create a cursor, pass the query-parameter create_cursor=true to any paginated endpoint that supports creating cursors. Doing this will cause that endpoint to return a token. An eventual limit parameter will get ignored. The other pagination parameters will be incorporated into the cursor. Use the /cursor endpoints described above to use the cursor.

Cursors are deleted after 120 seconds of inactivity. In addition, each IP address may only have up to 5 cursors open at once. Creating additional cursors will automatically delete the one last accessed longest ago. If this is not the desired behavior, make sure you delete unused cursors with the DELETE /cursor/:token endpoint.

Ratelimiting

Every request on the API costs 1 point if not specified otherwise. Those points reset back to 3600 after an hour. The ratelimiting is IP-based, and if you try to go over your hourly budget, you will receive a 429 Too Many Requests error.

Be aware that the ratelimiting costs of specific endpoints will probably get tweaked in the future. To inform you about your current ratelimiting status, each request's response will contain these HTTP-Headers:

X-Ratelimit-Limit: 3600
X-Ratelimit-Remaining: 3473
X-Ratelimit-Reset: 2017-01-24T06:30:30.199000

If your requests are authenticated (see Authentication), and your authenticated Glimesh username is white-listed, you are exempted from any ratelimits. To get white-listed, contact an administrator of SmashBets (preferably jfarre20).

Authentication

To authenticate your API access, every request needs to have a glimesh OAuth token supplied. This token doesn't need to have any scopes (permissions) and is used to retrieve the client's glimesh username. The token can be submitted in 2 ways:

The first is only recommended for testing purposes, as your token can show up in weblogs. Additionally, when logged in to this website, you do not need to submit a token for GET requests, which is convenient for testing the API in a browser. When logged in, you can view your token at /show_oauth_token.

Errors

400 Bad Request

When the request was somehow invalid. Besides generally malformed requests, this can have various causes. Like not using https where https is required or providing invalid parameters.

{
    "message": "Message further describing why the request was invalid"
}

403 Forbidden

When no or no valid OAuth token was submitted, or the authenticated user doesn't have access rights.

{
    "message": "Message further describing the cause"
}

404 Not Found

The resource does not currently exist or the server is unwilling to disclose it at this moment.

{
    "message": "Message further describing why the resource was not found"
}

410 Gone

The resource at this location does no longer exist and will not return. Is sent once for remotely closed cursors, followed by subsequent 404 errors.

{
    "message": "Message further describing what is no longer available and why"
}

429 Too Many Requests

You hit the rate limit by issuing too many requests. See Ratelimiting

{
    "message": "Rate limit exceeded. Please try again later."
}