API
Files
Every call names a bucket, and a game client's key reaches the game's buckets
through their files action. What a caller may then do is decided folder by
folder, by the rules you set. A key holding the
bucket's admin action is let through all of them.
No file's contents pass through these calls. Uploading is three steps:
POST /api/bkt/<bucket_id>/upload/with the path and exact size. The answer says where to send the bytes: a method, a URL and the headers to send.- Send the bytes there. That request goes to the file store, not to this API, and must not carry the bearer token.
POST /api/bkt/<bucket_id>/upload/<upload_id>/complete/. Only now is there a file.
Downloading is two: GET /api/bkt/<bucket_id>/download/ answers with a link,
good for about a minute, and the bytes are fetched from that.
A caller is not told whether a path it may not touch exists: being refused by a folder's rules and naming something that is not there are the same 404.
| Endpoint | Methods |
|---|---|
/api/gm/<game_id>/buckets/ |
GET |
/api/bkt/<bucket_id>/ |
GET |
/api/bkt/<bucket_id>/ls/ |
GET |
/api/bkt/<bucket_id>/dir/ |
POST DELETE |
/api/bkt/<bucket_id>/dir/rules/ |
GET PUT |
/api/bkt/<bucket_id>/upload/ |
POST |
/api/bkt/<bucket_id>/upload/<upload_id>/complete/ |
POST |
/api/bkt/<bucket_id>/download/ |
GET |
/api/bkt/<bucket_id>/file/ |
GET DELETE |
/api/files/local/<token>/ |
GET PUT |
Objects
Shapes that more than one endpoint answers with. Fields marked as the tenant's appear only in answers to your own server's calls.
Bucket
Bucket {
id: string,
name: string,
game: string, // the game's id
bytes_used: int,
files: int, // how many files it holds
max_bytes: int,
max_files: int,
player_max_bytes: int, // what one player may hold in it
player_max_files: int,
max_file_bytes: int, // the largest one file may be
monthly_download_bytes: int, // the most that may be downloaded in a month
downloaded_this_month: int,
}
Folder
Folder {
path: string, // such as "/saves/", always ending in "/"
name: string,
creator: string | null, // the player who made it; null for the tenant
created: string, // ISO datetime
// Only from the rules endpoints:
rules: { [rule]: level }, // a level for each of the seven rules
child_rules: { [rule]: level } | null,
}
File
File {
id: string, // stays the same when the file is overwritten
path: string, // such as "/saves/slot1.json"
name: string,
size: int, // bytes
content_type: string,
sha256: string | null, // hex, when the uploader gave one
creator: string | null, // the player who made it; null for the tenant
created: string, // ISO datetime
updated: string, // ISO datetime
}
/api/gm/<game_id>/buckets/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | The game's buckets. | gm:<game_id>:buckets |
Yes |
GET
Answers:
{ buckets: [{ id: string, name: string }] }
/api/bkt/<bucket_id>/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | The bucket's limits and how full it is. | bkt:<bucket_id>:details |
Yes |
GET
Answers a Bucket.
/api/bkt/<bucket_id>/ls/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | ?path=/saves/ What is in a folder. |
bkt:<bucket_id>:files |
Yes |
Folders and files are governed by separate rules, so a caller may be shown
one and not the other; folders or files is then null rather than
empty. Where files may be listed by their folder's creator only, any other
player who may create files there is shown just the files they made. limit and offset page
through both.
GET
Answers:
{
path: string, // the folder listed
folders: [Folder] | null, // null when the caller may not list them
folder_count: int | null,
files: [File] | null, // null when the caller may not list them
file_count: int | null,
offset: int,
limit: int,
}
/api/bkt/<bucket_id>/dir/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| POST | {path} Make a folder. |
bkt:<bucket_id>:files |
Yes |
| DELETE | ?path=&recursive=1 Remove one. |
bkt:<bucket_id>:configure |
No |
Making a folder is governed by the mkdir rule of the folder it goes
in, and the new folder starts with the rules that folder lays down for its
children. Removing one is the tenant's alone.
POST
Answers 201 with the new Folder.
DELETE
Answers:
{ deleted: string } // the folder's path
/api/bkt/<bucket_id>/dir/rules/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | ?path= A folder's rules. |
bkt:<bucket_id>:configure |
No |
| PUT | {path, rules, child_rules, apply_to_existing} |
bkt:<bucket_id>:configure |
No |
rules names a level for each of the seven actions. child_rules is
the same for folders made inside this one, or null for them to start with
a copy of rules. apply_to_existing also resets every folder
already under this one.
GET
Answers the Folder, with its rules and child_rules.
PUT
Answers the Folder, with its new rules and child_rules.
/api/bkt/<bucket_id>/upload/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| POST | {path, size, content_type, sha256} |
bkt:<bucket_id>:files |
Yes |
Step one of an upload. size is the exact number of bytes that will be
sent; the link that comes back accepts that many and no other. sha256,
in hex, is optional, and when given the file store checks the bytes
against it.
POST
Answers 201 with where to send the bytes:
{
upload_id: string, // for upload/<upload_id>/complete/
method: "PUT",
url: string, // send the bytes here, without the bearer token
headers: { [name]: string }, // send these headers with them
expires_in: int, // seconds the link works for
}
/api/bkt/<bucket_id>/upload/<upload_id>/complete/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| POST | Step three. | bkt:<bucket_id>:files |
Yes |
POST
Answers the new File.
/api/bkt/<bucket_id>/download/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | ?path= A link to fetch a file from. |
bkt:<bucket_id>:files |
Yes |
GET
Answers:
File & {
url: string, // fetch the bytes here, without the bearer token
expires_in: int, // seconds the link works for
}
/api/bkt/<bucket_id>/file/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | ?path= What is known about a file. |
bkt:<bucket_id>:files |
Yes |
| DELETE | ?path= Remove it. |
bkt:<bucket_id>:files |
Yes |
GET
Answers the File.
DELETE
Answers:
{ deleted: string } // the file's path
/api/files/local/<token>/
| Method | What it does | Permission | Game client |
|---|---|---|---|
| GET | Fetch the bytes of a download. | None | Yes |
| PUT | Send the bytes of an upload. | None | Yes |
GET
Answers the file's bytes, as an attachment.
PUT
Answers, once the bytes are stored:
{}
This page is generated from Scoreboat's source code, so it always matches the version you are reading it on.