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 /
- GET /current_match
- GET /users/:user_id
- GET /matches
- GET /matches/:match_id
- GET /matches/:match_id/log
- GET /songs
- GET /balance_transactions
- GET /balance_rankings
- GET /balance_rankings/:ranking_id
- GET /overall_balance_ranking
- GET /modbotlog
- GET /username_to_id/:username
- GET /cursor/:token
- POST /cursor/:token
- DELETE /cursor/:token
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.
- The key is
user_id
and not the lowercased username. Although rare, name changes can happen, and therefore TPP identifies users by their id everywhere. See the/username_to_id
endpoint if you need help getting auser_id
.
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
.
- This resource is paginated
- Can be filtered by:
id
,stage
- Can be sorted by:
id
- Supports creating cursors
Generated example:
[
{
coming soon
}
]
GET /matches/:match_id¶
Returns a (finished) match.
- Our API only provides matches after Nov 18th 2021. Matches prior to that date are unavailable.
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.
- This resource is paginated
- Can be filtered by:
id
,game_id
,types
- Can be sorted by:
id
,volume
,last_played_at
,last_bid_at
,ends
- Supports creating cursors
- Because this endpoint is rather new and still missing quite some data (e.g. only
game_id
, and no further game information), it is very likely to change in the near future.
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.
- This resource is paginated
- Can be filtered by:
user
,type
- Can be sorted by:
id
,timestamp
- Supports creating cursors
- This endpoint only works when authorized, and only shows the authorized user's transactions!
Generated example:
Error
GET /balance_rankings¶
Returns all SmashCash bet rankings.
- This resource is paginated
- Can be filtered by:
id
, - Can be sorted by:
id
,timestamp
, - Supports creating cursors
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.
- This resource is paginated
- Can be filtered by:
balance
- Can be sorted by:
id
,balance
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.
- This resource is paginated
- Can be filtered by:
id
,user
,rule
- Can be sorted by:
id
,ts
- Supports creating cursors
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.
- We use the same user ids as glimesh. Due to glimesh's name change feature, a user may change their username, but their user id will always remain unchanged.
- If the user is on glimesh, but isn't recorded in our database (never visisted our stream?), this endpoint returns
null
.
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:
sort
specifies which key the data gets sorted by. Prepend with a-
to sort descending, otherwise it is ascending. Default is always-id
. You can sort by multiple keys, e.g.sort=-id&sort=created_at
. Each resource lists the fields it can be sorted by.skip
specifies how many entries get initially skipped. Default is0
.limit
specifies how many entries get returned. Default is20
, and the current maximum you can set it to is1000
.
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:
- as the GET-parameter
oauth_token
, or - as the HTTP-Header
OAuth-Token
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."
}