Model Run API
The Model Run API provides create, read, update, and delete (CRUD) capabilities for runs of a project.
A particular interaction with a project is a "run": a collection of interactions with the project and its model. Every time you want to interact with a project, you need to create a new run.
The Model Run API supports the following HTTP methods:
- POST: Creating a new run in this project
- GET: Reading details about the runs in this project
- PATCH: Updating run data
- HEAD: Retrieving the headers for a run
- DELETE: Removing a run from this project
- OPTIONS: View reference information about the API
Working with runs also requires some knowledge about how runs are stored. See more information on run persistence.
POST: Creating a New Run for this Project
Use the Run API POST
method to create a new run.
Creating a New Run
Method: POST
URI: /model/run/
Headers: Content-Type: application/json
, Authorization: Bearer
{access token}
Body: JSON object containing the account, project, and model name, e.g. { "account": "acme-simulations", "project", "supply-chain-game", "model": "supplyModel.jl"}
Return Status: 200
(successful response)
Return Body: The record (JSON object) for the run just created.
Example:
curl -X POST \
'https://api.forio.com/model/run' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"account": "acme-simulations", "project": "supply-chain-game", "model": "supplyModel.jl"}'
Example Response:
{
"id": "95efbb60-c015-43af-a0e9-47286c45c95c",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-01-13T21:38:39.499Z",
"created": "2014-01-13T21:38:39.499Z"
}
Notes:
- The
account
is the Account ID. This is the Team ID (for team projects) or User ID (for personal projects). - The
project
is the Project ID. - The
model
is the name of the one file in the project that explicitly exposes variables and methods in order for the the Variable and Operation APIs, respectively, to have access to them. (Note that this file name is case-sensitive. See Writing your Model.) The following additional fields are optional in the request:
- Optional: The
user
object is optional. If supplied, it must contain the user'sid
and optionally can include the associateduserName
,firstName
, andlastName
. The default value is the user associated with user access token in the header; this parameter is only effective if you are using the project access token. - Optional: The
scope
object, including thegroup
,role
, andtrackingKey
fields, is optional. Typically you use this if your project includes end users and groups, or if you want to track all runs associated with a particular user (even if that user is "anonymous," that is, your project access is public). For example, thescope
should always be passed in if this run belongs to an end user of your project. However, sometimes during development or testing you may want to make a run for yourself (your own user), rather than an end user.* For the `group`, pass in the `name` of any `local` group. * For the `role`, valid values are `standard` or `facilitator`. * For the `trackingKey`, pass in a string of your choosing.
- Optional: The
files
object, if and only if you are using a Vensim model and you have additional data to pass in to your model. (Note that you'll also need to add this samefiles
object to your Vensim Model Context file.) Within thefiles
object, list name : value pairs. Each name can be any designation you like (for example:data
orfile1
). Each value is name of the file to load. This file must be in your project's Model folder. For example:"files": {"data": "myData.xlsx"}
or"files": {"file1": "myFirstFile.xlsx", "file2": "mySecondFile.xlsx"}
. (See a complete example in How To: Use External Data in Vensim.)
- Optional: The
The
created
andlastModified
fields are in ISO 8601 format.- The
saved
andinitialized
fields are simply flags in the run record. You can set them as needed; their values are not tied to run creation or run persistence.
Performance Optimization for Creating a New Run
Sometimes you know that you will be creating the same kind of run — a run with the same account
, project
, and model
— many times. In this case, you can use a variant of the Model Run API POST
method to help optimize performance and speed up the creation of the new run: you can create a new run based on an existing run. This request is valid both for existing runs that are currently in memory and for existing runs that are currently only in the database. (See more information on run persistence.)
Creating a New Run Using an Existing Run ("Reset")
Method: POST
URI: /model/run/
{original run id}
Headers: Content-Type: application/json
, Authorization: Bearer
{access token}
Body: {}
Return Status: 200
(successful response)
Return Body: The record (JSON object) for the run just created.
Example:
curl -X POST \
'https://api.forio.com/model/run/95efbb60-c015-43af-a0e9-47286c45c95c' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{}'
Example Response:
{
"id": "176a79f8-953a-4bb9-88e4-ea4b748e1edb",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-01-13T21:38:39.499Z",
"created": "2014-01-13T21:38:39.499Z"
}
Notes:
This request:
- Removes the original run id (the run id in the URI) from the server session cache if the original run id is in memory.
- Calls a reset function, if your model subscribes to one (for example, see details for Python or R).
- Creates a new run (returned in the response), reusing the existing model session on the Epicenter backend server to do so.
- Note that relevant, existing run properties are copied from the original run to the new run. For example,
scope
is copied, butsaved
andinitialized
have their values set as for a new run created throughPOST /model/run
.
- Note that relevant, existing run properties are copied from the original run to the new run. For example,
Optionally, you can pass in any of the same fields you pass in when creating a new run from scratch. For example, if you want to have the run in a different group, pass in {"scope": {"group": "newGroup"}}
instead of {}
in the body of this request.
GET: Reading Details about the Runs in this Project
You can retrieve properties about any run using the Run API GET
method.
Retrieve One Run, from Memory if Available
Method: GET
URI: /model/run/
{run id}
Headers: Authorization: Bearer
{access token}
Return Status: 200
(successful response)
Return Body: The record (JSON object) for the run.
Example:
curl -G \
'https://api.forio.com/model/run/930e0426-9fcd-45c0-97c9-5baef2cddf2d' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Example Response:
{
"id": "930e0426-9fcd-45c0-97c9-5baef2cddf2d",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-01-13T21:38:39.499Z",
"created": "2014-01-13T21:38:39.499Z"
}
Notes:
- The run is retrieved from memory if available. If the run is not in memory, it is retrieved from the database.
Retrieve One or More Runs, from Database
Method: GET
URI: /model/run/?
{filter, sort}
Headers: Authorization: Bearer
{access token}
Return Status: 200
(successful response)
Return Body: An array of JSON objects with the run records matching the filter.
Example:
curl -G \
'https://api.forio.com/model/run/?id=930e0426-9fcd-45c0-97c9-5baef2cddf2d' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Example Response:
[
{
"id": "930e0426-9fcd-45c0-97c9-5baef2cddf2d",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-01-13T21:38:39.499Z",
"created": "2014-01-13T21:38:39.499Z"
}
]
Notes:
- All runs are retrieved from the database.
- The {filter} in the URI is a set of query parameters, and takes the format:
?field1=value1&field2=value2
. Fields available for filtering include:id
: The run id.account
: The account id. This is the "Team ID" (for team projects) or "User ID" (for personal projects).project
: The project id.model
: The file name of the model.saved
: Flag in every run record. (Not releated to whether the run is persisted in the database.)scope.worldId
: The id of the world for which this run was created.scope.trackingKey
: The identifier for this set of runs (passed in during run creation).
- The {sort} in the URI can also include a query parameter indicating the field by which to sort the runs before they are returned, and the direction of the sort. This takes the format:
?sort=field1&direction=dir
.- Fields available for sorting include
project
,account
,model
,lastModified
,created
. - If the
sort
parameter is not specified, the default sort is bylastModified
, descending (most recently modified returned first). - The
direction
indicates whether to sort the runs ascending (asc
) or descending (desc
) before they are returned. The default direction isdesc
.
- Fields available for sorting include
- Optionally, you can add the query parameter
?include=active
to your request. Then, the response includes theactive
field of the run record. This istrue
for runs that are currently in memory andfalse
for runs that are only in the database.
Paging: Retrieving Many Records at Once
When you use the GET
method for an API, your request may return many records at once.
The default page size is 100 (for most APIs) or 1000 (for the Data API). You can limit the number of records returned by adding the Range
header.
Method: GET
URI: Any Epicenter API call
Headers: Range: records
{i}-
{j}
Return Status:
200
: Successfully retrieved all records206
: Successfully retrieved the partially complete response, for example if you request records 0-20 and there are 35 records416
: No records are found in a given search range (e.g.Range: records 10-15
when there are only 8 records)
Response Headers:
Whether or not you add the Range
header to your request, the response header contains:
Content-Range: records i-j/k
where
i
is the index of the first record returnedj
is the index of the last record returnedk
is the total number of records in the result set, or*
if that number is computationally infeasible (for example, because you are querying across multiple projects)
For example, Content-Range: records 0-9/57
or Content-Range: records 20-29/*
.
Response Body: An array of records. The array includes only those records indicated in the Content-Range
header.
Example:
curl -G \
'https://api.forio.com/v2/EpicenterAPI' \
--header 'Range: records i-j'
Notes:
If no records are returned, the response body is empty.
If you leave off the start index, this is considered an implied start index of 0 rather than an invalid range. The response header includes status code of
200
or206
depending on the ending index.This use of the
Range
header is part of the RFC 2616 (see details in Section 14.16 and 14.35).
Using POST to Retrieve Many Records at Once
Sometimes when you would like to use the GET
method for an API, your request may require a very long URI, for example: https://api.forio.com/v2/user?id=0b31ee58-6cef-488c-9825-19469376b70c&id=0f97e39b-4d45-475e-b710-8a6459db24cf&id=...
.
For these situations, Epicenter APIs support the option of using a POST
method with additional parameters in place of the GET
method.
Method: POST
URI:
- Any Epicenter API call that supports
GET
with query parameters - Followed by
?_method=GET
Headers:
- Authorization header as required by the Epicenter API in question (e.g.
Authorization: Bearer
{project access token}) Content-Type: application/json
Body: JSON object describing the query. For example:
{"id": ["0b31ee58-6cef-488c-9825-19469376b70c", "0f97e39b-4d45-475e-b710-8a6459db24cf"]}
Return Status:
200
: Successfully retrieved records
Return Body: Array of records (JSON objects) returned by the query.
Example:
curl -X POST 'https://api.forio.com/v2/user?_method=GET' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"id": ["0b31ee58-6cef-488c-9825-19469376b70c", "0f97e39b-4d45-475e-b710-8a6459db24cf"]}'
Notes:
- While using
POST
and query parameter?_method=GET
to retrieve many records at once is available in all Epicenter APIs, it is generally most useful in the User, Member, and Model Run APIs because of the frequency of doing longer queries with those APIs.
PATCH: Updating Run Data
You can update a minimal amount of run data using the Model Run API PATCH
method.
Updating Run Data
Method: PATCH
URI: /model/run/
{run id}
Headers: Content-Type: application/json
, Authorization: Bearer
{access token}
Body: JSON object, e.g. { "dataField": "dataValue" }
.
Return Status: 200
(successful response), 400
(invalid account id, project id, or invalid syntax)
Return Body: The updated data.
Example:
curl -X PATCH \
'https://api.forio.com/model/run/3575dd84-272f-4ffe-ad64-46d1d621da0a' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"saved": true}'
Example Response:
{ "saved": true }
Notes:
- Currently you can only update the
saved
property. This is a flag in every run record. (Not releated to whether the run is persisted in the database.)
HEAD: Retrieving the Headers for a Run
You can retrieve metadata about a run using the Model Run API HEAD
method.
Retrieving Metadata about the Run Record
Method: HEAD
URI: /model/run/
{run id}
Headers: Authorization: Bearer
{access token}
Return Status: 200
(successful response)
Example:
curl -X HEAD
'https://api.forio.com/model/run/1b7a6246-28a5-4e73-8382-7948e39f7d93'
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Example Response:
Only headers are returned.
Notes:
This request allows you to retrieve information written in response headers, including server information and resource last modified information, without having to retrieve all the data associated with a
GET
request.In particular, this is useful for verifying whether you are retrieving the run from memory or from the database:
- The
Pragma
field in the response header is present and set topersistent
if this run is persisted in the Epicenter backend database. - The
Pragma
field is not present in the response header if the run is only in memory on the Epicenter servers.
- The
DELETE: Removing a Run from this Project
If you no longer need a particular run, you can remove it from the current session using the Run API DELETE
method.
Removing a Run from this Project
Method: DELETE
URI: /model/run/
{run id}
Headers: Authorization: Bearer
{access token}
Return Status: 200
(successful response)
Return Body: The deleted run record.
Example:
curl -X DELETE \
'https://api.forio.com/model/run/bc895b37-6247-41c6-9e65-fa06745f39cf'
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Example Response:
{
"id": "bc895b37-6247-41c6-9e65-fa06745f39cf",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-01-13T21:38:39.499Z",
"created": "2014-01-13T21:38:39.499Z"
}
Notes:
- IMPORTANT: Note that this request only removes the run from memory on the Epicenter servers; it does not remove the run from the Epicenter backend database. See more information on run persistence.
Removing Multiple Runs from this Project
Method: DELETE
URI: /model/run?id=
{run id1}&id=
{run id2}
Headers: Authorization: Bearer
{access token}
Return Status: 200
(successful response)
Return Body: An array of the deleted run records.
Example:
curl -X DELETE \
'https://api.forio.com/model/run/id=f641048c-5801-4014-871e-da597162f527&id=b49ccb5e-5e58-4303-aea9-6325cf874056'
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Example Response:
[
{
"id": "f641048c-5801-4014-871e-da597162f527",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-06-18T23:07:40.545Z",
"created": "2014-06-18T23:07:40.545Z"
},
{
"id": "b49ccb5e-5e58-4303-aea9-6325cf874056",
"model": "supplyModel.jl",
"account": "acme-simulations",
"project": "supply-chain-game",
"saved": false,
"initialized": false,
"user": {
"id": "20a3e46f-e8cf-490c-b6be-fbe40341a477",
"userName": "testUser",
"firstName": "",
"lastName": ""
},
"lastModified": "2014-06-17T23:07:56.088Z",
"created": "2014-06-17T23:07:56.088Z"
}
]
Notes:
- IMPORTANT: Note that this request only removes the run from memory on the Epicenter servers; it does not remove the run from the Epicenter backend database. See more information on run persistence.
OPTIONS: View Reference Information about the API
For any Epicenter API, use the OPTIONS
method to view reference information on properties and arguments of that API.
View Reference Information about the API
Method: OPTIONS
URI: /model/run
Example:
curl -X OPTIONS 'https://api.forio.com/model/run'