{{ settings.application.app_name }}

{{ settings.application.title }}

API Version {{ settings.api.version }}

API Documentation!

The KDM API at http://api.thewatcher.io is a RESTful API for campaign/settlement management in "Monster" by Kingdom Death.

The API is a fan-created and fan-maintained project that is not supported by, affiliated with or otherwise authorized by Kingdom Death.

GitHub | Twitter | Official development blog

PUBLIC ROUTES

These routes DO NOT require authentication. Use them to construct dashboard, "create new whatever" type views and to look up game asset data that does not belong to any user.

RouteMethodsComment/Note
/campaign POST

Accepts a "name" or "handle" parameter included in the body of the request (which should be JSON) and returns a JSON representation of the campaign:

{"name": "People of the Lantern"}

...gets you something like this:

{"handle": "people_of_the_lantern","milestones": ["first_child", "first_death", "pop_15", "innovations_5", "game_over" ], "saviors": "1.3.1", "name": "People of the Lantern", "default": true, "principles": ["new_life", "death", "society", "conviction"], "always_available": { "location": ["Lantern Hoard"], "innovation": ["Language"]},"nemesis_monsters": [ "butcher", "kings_man","the_hand","watcher"],"quarries": [ "white_lion","screaming_antelope","phoenix", "beast_of_sorrow", "great_golden_cat", "mad_steed", "golden_eyed_king"],"type": "campaign_definition"}

NB: this also works with handles, e.g.:

{"handle": "people_of_the_stars"}
/login POST

The KD:M API uses JSON Web Tokens (https://jwt.io) to manage user sessions and user authentication.

POST to this route with JSON containing user credentials in the body of the request to get a token:

Authorization: {"username": "demo@kdm-manager.com", "password": "l33th4x0r"}

...if your credential checks out, you get a token and the the the user's ID (see below for working with users) back. Easy!

/monster POST

Accepts a "name" or "handle" parameter (via JSON) and returns a JSON representation of a monster type game asset. For example, POSTing to /monster with JSON such as this:

{"name": "White Lion Lvl. 1"}

...returns JSON like this:

{"comment": "Lvl. 1", "handle": "white_lion", "name": "White Lion", "level": 1, "levels": 3, "sort_order": 0, "type": "quarry"}

Or, with a handle:

{"handle": "manhunter"}

...you get:

{"handle": "manhunter", "name": "Manhunter", "levels": 4, "sort_order": 103, "type": "nemesis", "selectable": false, "misspellings": ["THE MANHUNTER", "MAN HUNTER"]}
/new_settlement GET Returns JSON representing available options for creating a new settlement, including expansions, pre-fab survivors, etc. Also includes subtitle/description elements. Use this to make "create new settlement" type views.
/settings.json GET Not strictly a part of the API, but sometimes useful. Hit this route to download an attachement of settings.cfg as JSON.
/settings GET Retrieve settings.cfg as JSON
/world GET Retrieve a JSON representation of aggregate/world stats.
PRIVATE ROUTES

Private routes require an Authorization header including a JWT token.

(See the documentation above for more info on how to POST user credentials to the /login route to get a token.)

Generally speaking, when you access any private route, you want your headers to look like this when using private routes:

{ 'content-type': 'application/json', 'Authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6...' }

Finally, keep in mind that tokens are extremely short-lived, so you should be prepared to refresh them frequently. See the section below on 'Authorization Token Management' for more info on checking/refreshing tokens.

RouteMethodsComment/Note
Authorization Token Management: once you've got an authorization token, you can work with it using these routes. Most failures from these routes are reported back as 401's, since they concern authorization.
/authorization/check GET,POST GET or POST to this endpoint to determine if your Authorization header is still valid or if it has expired.
/authorization/refresh POST

Use the standard 'Authorization' header and POST an empty request to this route to recieve a new Auth token based on the previous one.

On the back end, this route reads the incoming 'Authorization' header and, even if the JWT token is expired, will check the 'login' and 'password' (hash) keys: if they check out, you get a 200 and a brand new token.

Finally, the KDM API does NOT use refresh tokens (it just feels like overkill, you know?).

Create Assets: To create new assets (survivor, settlement), POST JSON containing appropriate params to the /new/<asset_type> route. Invalid or unrecognized params will be ignored!
/new/settlement POST

Use 'handle' values from the /new_settlement route (see above) as params, like this:

{"campaign": "people_of_the_lantern", "expansions": ["dung_beetle_knight", "lion_god"], "survivors": ["adam", "anna"], "name": "Chicago", "special": ["create_first_story_survivors"]}

NB: if successful, this route returns a serialized version of the new settlement, including its OID, as JSON.

/new/survivor POST Coming Soon!
User Routes: all routes for working directly with a user follow a /user/<action>/<settlement_id> convention. These routes are private and require authentication.
/user/get/<user_id> GET Retrieve a serialized version of the user who owns <user_id>, to include some additional usage and meta facts about that user.
/user/set/<user_id> POST, OPTIONS

This route supports the assignment of user-specified key/value attributes to the user object.

To set an attribute, include JSON in the body of the request that indicates the key/value to set.

Supported attribute keys include:
keyvalue
current_settlement OID of an existing,non-removed settlement.
Use multiple key/value pairs to set multiple attributes in a single request, e.g. {"current_settlement": $oid, "current_session": $oid}

Important! This route does not support the assignment of arbitrary keys and will completely fail any request that includes unsupported keys!

Settlement Routes: all routes for working directly with a settlement follow a /settlement/<action>/<settlement_id> convention. These routes are private and require authentication.
/settlement/get/<settlement_id> GET Retrieve a serialized version of the settlement associated with <settlement_id> (to include all related user and game assets, including survivors).
/settlement/get_event_log/<settlement_id> GET Retrieve all settlement event log entries (in a giant hunk of JSON).
/settlement/get_innovation_deck/<settlement_id> GET Retrieve the settlement's current innovation deck (as an array).
/settlement/set/<settlement_id> POST Not implemented! Coming soon!
/settlement/add_expansions/<settlement_id> POST Add expansions to a settlement by POSTing a list of expansion handles. The body of your post should be a JSON-style list: ['beta_challenge_scenarios','dragon_king']

Note that this route not only updates the settlement sheet, but also adds/removes timeline events, updates the settlement's available game assets (e.g. items, locations, etc.).

/settlement/rm_expansions/<settlement_id> POST Remove expansions from a settlement by POSTing a list of expansion handles. The body of your post should be a JSON-style list: ['manhunter','gorm','spidicules']

Note that this route not only updates the settlement sheet, but also adds/removes timeline events, updates the settlement's available game assets (e.g. items, locations, etc.).

Important! We're all adults here, and the KDM API will not stop you from removing expansion handles for expansions that are required by your settlement's campaign. If you want to prevent users from doing this, that's got to be part of your UI/UX considerations.

/settlement/set_current_quarry/<settlement_id> POST

This route sets the settlement's 'current_quarry' attribute, which is the monster that the settlement's Departing Survivors are currently hunting.

POST some simple JSON containing a monster name (do not use handles for this):

{'current_quarry': 'White Lion Lvl 2'}

...or, the monster is unique:

{'current_quarry': 'Watcher'}

Important! You're typically going to want to pull monster names from the settlements' game_assets -> defeated_monsters list (which is a list of monster names created for the settlement based on expansion content, etc.)

/settlement/add_timeline_event/<settlement_id> POST

Adding a timeline event to a settlement's timeline requires a fairly specific bit of JSON. To add, for example, a settlement event, you need to post JSON that looks like this:

{'type': 'settlement_event', 'ly': 3, 'handle': 'core_haunted', 'name': 'Haunted', 'user_login': 'dev@kdm-manager.com'}

Event names, types, handles, etc. can be found in the settlement's game_assets -> events (which is a dictionary of settlement and story events).

Adding showdown type events works similarly:

{'type': 'showdown_event', 'name': 'White Lion Lvl 1', 'ly': 4, 'user_login': 'user@whatever.com'}

...or, for a special showdown:

{'type': 'special_showdown', 'name': 'Watcher', 'ly': 20, 'user_login': 'qa@kdm-manager.com'}

Here is a list of accepted event 'type' values:

  • showdown_event
  • special_showdown
  • nemesis_encounter
  • settlement_event
  • story_event
Important! Events without handles may be added, which means that you may absolutely add an event that does not come from the settlement's game_assets -> events. Events with neither a name nor a handle may not be added, however.

/settlement/rm_timeline_event/<settlement_id> POST

Works just like the add_timeline_event method, except in reverse. POST some JSON describing a timeline event that exists on the settlement's timeline to remove it:

{'type': 'settlement_event', 'ly': 3, 'handle': 'core_haunted', 'name': 'Haunted', 'user_login': 'dev@kdm-manager.com'}

Since the add_timeline_event method allows for events without handle attributes (i.e. since it will accept JSON with a name and no handle), events may be removed using only their name and Lantern Year ('ly' ) attribute:

{'type': 'nemesis_encounter', 'name': 'Butcher Lvl 1', 'ly': 4, 'user_login': 'user@whatever.com'}
/settlement/add_innovation/<settlement_id> POST

POST an Innovation handle to this route to add it to the settlement's Innovations:

{'handle': 'hovel'}

...or:

{'handle': 'mastery_club'}

Innovation handles may be found in the settlement's game_assets -> innovations element, which is a dictionary/hash of innovations where the keys are handles.

/settlement/rm_innovation/<settlement_id> POST

This is basically the reverse of add_innovation and works nearly identically. POST a JSON representation of an Innovation handle to remove it from the settlement's list:

{'handle': 'mastery_club'}
/settlement/set_innovation_level/<settlement_id> POST

For Innovations that have a level (e.g. the Slenderman's 'Dark Water Research'), you may set the Innovation's level by posting the handle of the innovation and the level:

{'handle': 'dark_water_research', 'level': 2}
/settlement/add_settlement_note/<settlement_id> POST Documentation coming soon!
/settlement/rm_settlement_note/<settlement_id> POST Documentation coming soon!
Survivor Routes: all routes for working directly with an individual survivor follow a /settlement/<action>/<settlement_id> convention. Like settlement routes, these routes are private and require authentication.
/settlement/get/<survivor_id> GET Retrieve a serialized version of the survivor.