Docs Releases Log in

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:

  1. 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.
  2. Send the bytes there. That request goes to the file store, not to this API, and must not carry the bearer token.
  3. 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.