What's this CRUD do?

Lets people grab stats and attributes like an author's games list or a list of their game scenes (only on games set to public, of course).

It also allows for managing games remotely – this would allow a third-party editor to update your game once you give the system your Game API Key or create new games on your account with your Creation API Key.

There's absolutely no reason to share your Developer API Key or ask a member for their Developer API Key.

All EasyAPI transactions are logged for security. Abuse of the EasyAPI will lead to the banning of the offending user account and/or blocking of the offending IP address from access.

GET Stuff

This is how you steal stuff from dashingdon.com.


Output Options

JSON

The default return format is a JSON object. Note that slashes are not escaped.

CSV

Comma-separated values with a header row can be returned by appending ?csv to the request URL.

XML

Nope.


GET Metadata

GET /easy/meta

Get yourself some metadata. You'll need to pass your Developer API Key as the Username using Basic Authorization.

Requires:
  1. [DEVKEY] – Developer API Key
Returns:
  1. members – # of total members
  2. games – # of total games
  3. public – # of public games
  4. downloadable – # of downloadable games
Example (HTTP): [DEVKEY] Must Be Base64 Encoded
GET /easy/meta HTTP/1.1
Host: dashingdon.com
Authorization: Basic [DEVKEY]
Cache-Control: no-cache
Example (PHP cURL):
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashingdon.com/easy/meta",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Basic [DEVKEY]", //[DEVKEY] Must Be Base64 Encoded
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Example (NodeJS):
var http = require("https");
var options = {
"method": "GET",
"hostname": "dashingdon.com",
"port": null,
"path": "/easy/meta",
"headers": {
"authorization": "Basic [DEVKEY]", //[DEVKEY] Must Be Base64 Encoded
"cache-control": "no-cache"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
Result:
{"authors":941,"games":780,"public":203,"downloadable":7}
Appending ?csv will format this output as CSV.

GET Authors

GET /easy/authors

Get a list of authors with at least one published public game. You'll need to pass your Developer API Key as the Username using Basic Authorization.

Requires:
  1. [DEVKEY] – Developer API Key
Returns:
  1. id – ID of the Author
  2. name – Author nickname
Result:
{
	"0": {
		"id": "EdRbko",
		"name": "dashingdon"
	},
	"1": {
		"id": "gg95eE",
		"name": "anotherauthor"
	},
	"2": {
		"id": "bb81Aa",
		"name": "yetanotherauthor"
	}
}

You may also append the author nickname to the GET URL to request that particular author's ID:

GET /easy/authors/dashingdon

{"id":"EdRbko","name":"dashingdon"}
Appending ?csv will format this output as CSV.

GET Games by Author ID

GET /easy/authors/[AUTHORID]/games

Retrieve the list of public games by an author. Last Update may be 'null' for JSON and 'NULL' for CSV if the author has never used the update feature. The URL Slug is a sanitized, hypenated version of the Title and it is the name of the directory holding the game files.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [AUTHORID] – Author's ID
Returns:
  • For each public game:

    1. id Game ID
    2. title Title
    3. slug URL Slug
    4. desc Description
    5. update Last Update (YYYY-MM-DD)
Result (JSON):
{
	"0": {
		"id": 2,
		"title": "The Burden",
		"slug": "the-burden",
		"desc": "Unarmed and unarmored...",
		"update": null
	},
	"1": {
		"id": 738,
		"title": "Phobia",
		"slug": "phobia",
		"desc": "Inspired by Obsidian With great fear comes great power.",
		"update": null
	}
}
Result (CSV):
"id","title","slug","desc","update"
"2","The Burden","the-burden","Unarmed and unarmored...","NULL"
"738","Phobia","phobia","Inspired by Obsidian With great fear comes great power.","NULL"

Game URL

All public games can be accessed via the 'short URL' method. Therefore, you can create URLs for each of the returned games by using https://dashingdon.com/go/[GAMEID] where [GAMEID] is the first returned value for each entry. For example, above we can see 2 is the Game ID for 'The Burden' so we can access it thusly:

https://dashingdon.com/go/2

By design, private games cannot be accessed via the short URL method.

If you prefer to use the long URL instead (weirdo), you can do so by using https://dashingdon.com/play/[AUTHOR]/[URLSLUG] where [AUTHOR] is the author's name and [URLSLUG] is the 'safe' version of the Title used for the name of the game's directory. Therefore, in this instance:

https://dashingdon.com/play/dashingdon/the-burden

The long URL above may be 'broken' on older games – a temporary remedy (until the game is updated) is to append /mygame/ to the end of the long URL.


GET Full Game Info

GET /easy/games/[GAMEID]

The meat and potatoes. The whole kit and caboodle. The cat's pajamas. Actually, no, not that last one. That's something different.

Requires:
  1. [DEVKEY] – Developer API Key Base64 Encoded
  2. [GAMEKEY] – Game API Key
Returns:
  1. title – Game Title
  2. author – Author
  3. slug – URL Slug
  4. desc – Description
  5. feedback – Feedback URL
  6. update – Last Update (possible null)
  7. stylesheet – Stylesheet (0 to 9)
  8. saveplugin – Save Plugin (0 for no or 1 for yes)
  9. usecompiled – Use Compiled (0 for no or 1 for yes)
  10. scenes – Scenes
    • For each scene:

      1. filename – Text File Name (no .txt extention)
      2. size – File Size (in Bytes, Kilobytes, Megabytes, or Gigabytes)
      3. update – Last Modified (server time) (Y-m-d H:i:s)
Result:
{
	"title": "The Burden",
	"author": "dashingdon",
	"slug": "the-burden",
	"desc": "Unarmed and unarmored...",
	"feedback": "https://forum.choiceofgames.com/t/the-burden-yet-another-typical-fantasy-adventure/",
	"update": null,
	"stylesheet": "2",
	"saveplugin": "0",
	"usecompiled": "0",
	"scenes": {
		"0": {
			"filename": "00_introduction",
			"size": "4K",
			"update": "2016-09-12 00:38:05"
		},
		"16": {
			"filename": "variables",
			"size": "1K",
			"update": "2016-09-12 00:38:05"
		}
	}
}
Again, appending ?csv will format this output as CSV.

GET Scenes by Game ID

GET /easy/games/[GAMEID]/scenes

Retrieve the list of scenes for a public game. This is a lesser payload that I would ask you to use if you don't need the full game info but are working with a game's scenes.

The filename will not have the '.txt.' extension as that is absolute for scene files. Size will be rounded up to a full number in Bytes, Kilobytes, Megabytes, or Gigabytes as designed by B, K, M, and G respectively. Last Update is the file modified server datetime presented as YEAR[4]-MONTH[2]-DAY[2] HOUR[2]:MINUTE[2]:SECONDS[2] / (Y-m-d H:i:s) in 24-hour notation.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [GAMEKEY] – Game API Key
Returns:
  • For each scene:

    1. filename – Name of the File
    2. size – File Size
    3. update – Last Update
Result:
{
	"0": {
		"filename": "00_introduction",
		"size": "4K",
		"update": "2016-09-12 00:38:05"
	},
	"1": {
		"filename": "01_flashback",
		"size": "9K",
		"update": "2016-09-12 00:38:05"
	},
	"15": {
		"filename": "sub_moniker",
		"size": "710B",
		"update": "2016-09-12 00:38:05"
	},
	"16": {
		"filename": "variables",
		"size": "1K",
		"update": "2016-09-12 00:38:05"
	}
}
Again, appending ?csv will format this output as CSV.

GET Scene Content by Game ID & File Name

GET /easy/games/[GAMEID]/scenes/[FILENAME]

Retrieve the full text contents of a scene file of a public game. The return format will be UTF-8 encoded plain text with preservation of tabs and spaces.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [GAMEKEY] – Game API Key
  3. [FILENAME] – Name of the Scene File without .txt extension
Result:
*TITLE The Burden
*AUTHOR Dashing Don
*SCENE_LIST
	startup
	00_introduction
	01_flashback
	02_flashforward
	03_outbound

The crabby old wizard bursts into your barren room with a scowl on his face.
He is every bit as decrepit and unwelcoming as the tower where you've lived for the past six years.

"We're going to help the duchess!" he shouts. "Get your lantern. Be quick, now!"

You walk behind the ambling wizard, your lantern squeaking as it sways from the handle in your fist
and your sandals trampling the tall, wet grass under your feet. You can't recall having any other possessions.

This heaviness in your stomach, this lightness in your head: the feeling grows stronger as you
approach the town of your birth. The town that had long ago forgotten you...

*FINISH

POST/PUT Stuff

POSTs and PUTs can be used for both Create and Update requests. Generally, POST expects a file while PUT expects the payload in the body of the request.


POST Game

POST /easy/games/new

Create a new game on the dashingdon.com system.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [CREATEKEY] – Creation API Key (this is unique to each member's account)
  3. title – [TITLE] Name of the New Game (must be unique to the author)
Optional:
  1. desc – [DESC] Short Description (assumed none)
  2. public – [PUBLIC] Either 1 for public game or 0 for private game (assumed 0)
  3. stylesheet – Which stylesheet? 0 to 9
  4. saveplugin – Using the save plugin? 0 for no and 1 for yes
  5. usecompiled – Using a compiled HTML file? 0 for no and 1 for yes
  6. downloadable – Can compiled HTML be downloaded? 0 for no and 1 for yes
  7. feedback – The URL or email address for game feedback
Returns:
  • 201 Created – On Success
  • 401 Unauthorized – Authentication Failed
  • 409 Conflict – Game (with that exact title!) Exists
Example (PHP cURL):
$username = '[DEVKEY]';
$password = '[CREATEKEY]';
$ch = curl_init();
$data = array(
	'title' => '[TITLE]',
	'description' => '[DESC]',
	'public' => '[PUBLIC]'
);
curl_setopt($ch, CURLOPT_URL, 'https://dashingdon.com/easy/games');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
Result (JSON):

The [GAMEKEY] of the created game will be returned so that you can further manage that game through your system.

{"gamekey":"[GAMEKEY]"}

PUT Game

PUT /easy/games/new

Create a new game on the dashingdon.com system using PUT.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [CREATEKEY] – Creation API Key (this is unique to each member)
  3. title – [TITLE] Name of the New Game (must be unique to the author)
Optional:
  1. desc – Short Description (assumed none)
  2. public – Either 1 for public game or 0 for private game (assumed 0)
  3. stylesheet – Which stylesheet? 0 to 9
  4. saveplugin – Using the save plugin? 0 for no and 1 for yes
  5. usecompiled – Using a compiled HTML file? 0 for no and 1 for yes
  6. downloadable – Can compiled HTML be downloaded? 0 for no and 1 for yes
  7. feedback – The URL or email address for game feedback
Returns:
  • 201 Created – On Success
  • 401 Unauthorized – Authentication Failed
  • 409 Conflict – Game (with that exact title!) Exists
Example (JSON):
{
	"title":"thistitle",
	"public":"no",
	"desc":"The short description.",
	"stylesheet":9,
	"saveplugin":1,
	"usecompiled":0,
	"downloadable":0,
	"feedback":"http://thisfeedbackurl.dot/coolgame/"
}
Result (JSON):

The [GAMEKEY] of the created game will be returned so that you can further manage that game through your system.

{"gamekey":"[GAMEKEY]"}

POST Scene

POST /easy/games/[GAMEID]/scenes

Create or update a scene for a game using a POSTed file.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [GAMEKEY] – Game API Key
  3. [SCENENAME] – Name of the Scene File without .txt extention
  4. file – Scene .txt (UTF-8) File (will be renamed to [SCENENAME])
Returns:
  • 200 OK – On Successful Update
  • 201 Created – On Successful Create
  • 401 Unauthorized – Authentication Failed
  • 403 Forbidden – No API Access to Game OR File Is Not a Text File
  • 413 Request Entity Too Large – File Exceeds Max Size Allowed
Example (PHP cURL):
$username = '[DEVKEY]';
$password = '[GAMEKEY]';
$filepath = $_FILES['file']['tmp_name'];
$filename = $_FILES['file']['name'];
$data = array(
	'scenename' => '[SCENENAME]',
	'file' => "@$filepath",
	'filename' =>$filename
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://dashingdon.com/easy/games/[GAMEID]/scenes');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_exec($ch);
curl_close($ch);
Some PHP cURL Options for [DEVKEY] and [GAMEKEY]
  • Provide your Developer API Key and the Game API Key within the request URL:
  • https://[DEVKEY]:[CREATEKEY]@dashingdon.com/easy/games/[GAMEID]/scenes
  • Provide your Developer API Key and the Game API Key within the CURLOPT_USERPWD parameter:
  • curl_setopt($ch, CURLOPT_USERPWD, "[DEVKEY]:[CREATEKEY]");
  • Provide your Developer API Key and the Game API Key Base64 Encoded in the CURLOPT_HTTPHEADER parameter:
  • curl_setopt($ch, CURLOPT_HTTPHEADER, "authorization: Basic [BASE64([DEVKEY]:[GAMEKEY])]");
Result:
{"location": "https://dashingdon.com/play/[AUTHORNAME]/[GAMENAME]/mygame/scenes/[SCENENAME].txt"}

PUT Scene

PUT /easy/games/[GAMEID]/scenes/[SCENENAME]

Create or update an existing scene .txt file in a game's directory using PUT. The body of the PUT request must contain the content of the file in raw text.

Requires:
  1. [DEVKEY] – Developer API Key
  2. [GAMEKEY] – Game API Key
  3. [SCENENAME] – Name of the Scene File without .txt extention
  4. [BODY] – The Raw Text Contents of the Scene
Returns:
  • 200 OK – On Successful Update
  • 201 Created – On Successful Create
  • 401 Unauthorized – Authentication Failed
  • 413 Request Entity Too Large – Content Exceeds Max Size Allowed
Example (PHP cURL):
$username = '[DEVKEY]';
$password = '[GAMEKEY]';
$data = "...*FAKE_CHOICE\r\n\t#I've grown\r\n\t\t*set distinction \"taller\"\r\n\t#I didn't even..."
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://dashingdon.com/easy/games/[GAMEID]/scenes/[SCENENAME]');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_exec($ch);
curl_close($ch);
Example (NodeJS):
var http = require("https");
var options = {
  "method": "PUT",
  "hostname": "dashingdon.com",
  "port": null,
  "path": "/easy/games/[GAMEID]/scenes/[SCENENAME]",
  "headers": {
    "authorization": "Basic [BASE64([DEVKEY]:[GAMEKEY])]",
    "cache-control": "no-cache"
  }
};
var req = http.request(options, function (res) {
  var chunks = [];
  res.on("data", function (chunk) {
    chunks.push(chunk);
  });
  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});
req.write("...He turns and sprints to the tower.\r\n\r\n\t#\"Um… what do you plan on doing with my ${bet} if you win...");
req.end();
Result:
{"location": "https://dashingdon.com/play/[AUTHORNAME]/[GAMENAME]/mygame/scenes/[SCENENAME].txt"}