JSON manifest

An intelligence plugin uses an input JSON manifest file. But before you can get your initial JSON manifest you need to prepare the initial dataset first. That can be done by doing a POST to https://www.stormly.com/api/developer/initial_dataset/0_sec, using two headers: X-Project-Key and X-Dataset-Key.

The last part of the url can be 0_sec, latest or 95_pct, corresponding to the Initial dataset moment from the "Creating an empty plugin" section. When you run a plugin in production this is done all done automatically, but in local development mode you need to run a few of those steps manually.

To prepare the initial dataset, here is an example using curl:

curl -X "POST" "https://www.stormly.com/api/developer/initial_dataset/0_sec" \
-H 'X-Project-Key: abcd12345' \
-H 'X-Dataset-Key: abcdefghjklm12346789'

To get your initial JSON manifest make a GET request to https://www.stormly.com/api/developer/get_manifest/initial. You will get a status message in case the dataset is still being prepared. For example with curl:

curl "https://www.stormly.com/api/developer/get_manifest/initial" \
-H 'X-Project-Key: abcd12345' \
-H 'X-Dataset-Key: abcdefghjklm12346789'

Below you'll find JSON manifest could look like:

{
"stage": "initial",
"dataUrls": {
"initial": "https://data.stormly.com/api/plugin/query_dataset/abcdef123456"
},
"downloadUrls": {
"initial": "https://s3.eu-central-1.amazonaws.com/storage.stormly.com/abcd/1234"
},
"getUploadUrls": {
"initial": "https://www.stormly.com/api/developer/upload_url/abcd/1234"
},
"inputData": {},
"inputParams": {
"max_items": 4.0
}
"metadata": {
"datasets": {
"initial": {
"fullDatasetSize": 54203,
"moment": {
"type": "since",
"seconds": 0
}
}
},
"goal": {
"action": "event",
"event": "payment_completed",
"times": 1,
"human": "did Payment completed at least 1 time",
"type": "categorical"
},
"features": {
"feature_acaa2cf5d": {
"name": "Did event Play song",
"type": "categorical",
"nativeType": "boolean",
"moment": "dynamic",
"details": {
"propertyType": "event",
"value": "play_song"
}
},
"feature_3c11322c9": {
"name": "Did event Sign up",
"type": "categorical",
"nativeType": "boolean",
"moment": "dynamic",
"details": {
"propertyType": "event",
"value": "sign_up"
}
},
"feature_7f88703f1": {
"name": "Country",
"type": "categorical",
"nativeType": "string",
"moment": "static",
"details": {
"propertyType": "userProperty",
"value": {
"type": "text",
"name": "initial_country",
"value": "u_col_initial_country"
}
}
},
"feature_2fe4e4093": {
"name": "Campaign source",
"type": "categorical",
"nativeType": "string",
"moment": "static",
"details": {
"propertyType": "userProperty",
"value": {
"type": "text",
"name": "initial_campaign_source",
"value": "u_col_initial_campaign_source"
}
}
},
"feature_440572d3d": {
"name": "Device model",
"type": "categorical",
"nativeType": "string",
"moment": "static",
"details": {
"propertyType": "userProperty",
"value": {
"type": "text",
"name": "initial_device_model",
"value": "u_col_initial_device_model"
}
}
}
}
}
}

The stage indicates the current stage of the plugin run. As mentioned before, a plugin can have one or more stages. The first stage is always the initial one. In case your initial stage requests more stages, stage will be the name of the stage you've specified. More on that later in the Multiple stages section.

The object under inputParams maps 1-to-1 with any simple plugin input variables earlier.
If an optional plugin question is not assigned by the end-user, it will not be in the inputParams in the JSON manifest at all, so be sure to always check if the key exists.
Note that any numeric values will always be represented as float, so make to sure cast to integer when you pass it on to other libraries that expect integer input only.

The dataUrls can be called as-is, and returns a JSON containing all data for the dataset. Each dataset has an unique key, and for the initial stage the dataset is always called initial. But just as we can request more processing stages, we can also request more datasets if needed. So in any additional stages that may run, the dataUrls object will be supplied with datasets that were requested for that stage. More on this in the Multiple stages section.

The downloadUrls and getUploadUrls are useful when you have multiple stages, and you need to persist some objects that need to be retrieved in later stages. This can also be necessary when your plugin can be deployed, which means you will usually need to download the trained model from an earlier stage. More on this in the Persisting data between stages section.

The inputData object is used to describe any available additional input data in the form of specific events and its property that was interacted with, per user. For example a recommender plugin needs the product SKU id that was viewed by the users, so we can make recommendations based on this property. We'd then have an array of view_item events with the value of its sku_id property, timestamp and event id, for each user in the dataset. See the Events input data for more details.

Finally we have metadata — and object describing mainly three things. First there is datasets, where we can for each dataset key the size of the dataset (= number of users in dataset). Next there is goal describing what conversion goal the user picked, of which the human field is most used as you generally use it to present it to the end-user together with visualizations so its clear what the end-results are for. In case the plugin has No goal, the goal field is null. Finally we have features, which will be described in the next section.