forio Toggle navigation

Run API

The Run API is a RESTful API that collects common tasks around creating and updating runs, variables, and data in one endpoint.

It provides largely the same functionality as the lower-level Data API and Model APIs, but organized around particular user interactions with the project ("runs").

The Run API supports the following methods:

The Run API operates on the following resources / data structures:

POST

You can use the POST request to create new runs and to call model operations on existing runs.

Create a New Run


Method: POST

URI:

  • /v2/run/{account id}/{project id}

Headers:

Body: JSON object with the required fields:

  • model: The primary model file.
  • For a complete list of fields, see details on the run record.

Return Status:

  • 200: Successfully created run
  • 400: Invalid request (e.g. invalid account or project)
  • 500: Server error while starting the run (e.g. syntax errors in the model)

Return Body:

The new run record (JSON object) just created.


Example:

curl -X POST \
    'https://api.forio.com/v2/run/acme/supply-chain-game' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"model": "model.py"}'

Example Response:

{
    "morphology": "MANY",
    "id": "000001539d43a51db44159ddb1a354e484df",
    "user": {
        "firstName": "j",
        "lastName": "smith",
        "id": "233ef9a8-af8e-41ad-84ba-9a21097f6f55",
        "userName": "jsmith@acme.com",
        "email": "jsmith@acme.com"
    },
    "model": "model.py",
    "scope": null,
    "ephemeral": null,
    "created": "2016-03-22T17:17:46.092Z",
    "initialized": true,
    "active": true,
    "project": "supply-chain-game",
    "lastModified": "2016-03-22T17:17:46.092Z",
    "account": "acme",
    "files": null,
    "variables": null,
    "saved": false
}

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).
  • See the error record for more information on how to interpret possible errors.

Call an Operation for One Run


Method: POST

URI:

  • /v2/run/{account id}/{project id}/{run id}/operations/{name of operation}

Headers:

Body: JSON object with the required fields:

  • arguments: An array of the arguments for the operation.
  • For a complete list of fields, see details on the operation record.

Return Status:

  • 200: Successfully called operation
  • 400: Invalid request

Return Body:

JSON object with the name of the operation, the arguments passed in, and the result (return value) of the operation, if any. For a complete list of fields, see the operation record.


Example:

curl -X POST \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001539d43a51db44159ddb1a354e48506/operations/estimate' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"arguments": [ "input string", 25, true ]}'

Example Response:

{
    "name": "estimate",
    "arguments": [ "input string", 25, true ],
    "result": 20.44
}

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).
  • General errors with API usage, such as making a call without appropriate permissions, simply return the appropriate HTTP status code. Specific errors because of a problem with the model operation itself return a complete error record.

PATCH

You can use the PATCH request to update the values of run data or model variables associated with the run.

Important: You can update run data at any time. However:

  • You can only update model variables (that is, variables associated with the run) if the run is in memory. Runs are automatically replayed (and so brought back into memory) when you PATCH a variable.
  • For Vensim, you can only update model variables in the current time step.
  • In general, the preferred way to update model variables is to call a method from the model and have the method persist the variables (using the record() statement if your model is in Julia, in Python, or in R).

Update Run Data


Method: PATCH

URI:

  • /v2/run/{account id}/{project id}/{run id}

Headers:

Body: JSON object with fields (names / values) you want to update. For a complete list of fields, see details on the run record.

Return Status:

  • 200: Successfully updated run
  • 400: Invalid request

Return Body:

JSON object with the updated data.


Example:

curl -X PATCH \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001539d43a51db44159ddb1a354e48506' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"saved": true }'

Example Response:

{
    "saved: true
}

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).
  • Any data that you pass in here is added to the run data. That is, your request body can include both fields that are already part of the run record, and fields that are not initially part of the run record, e.g. {"saved": true, "scenario": "A", "level": "basic"}.

Update Variables for One Run


Method: PATCH

URI:

  • /v2/run/{account id}/{project id}/{run id}/variables

Headers:

Body: JSON object whose fields are variable names and whose values are the updated variable values, e.g. { "fieldName1": "fieldValue1", "fieldName2": "fieldValue2"}.

Return Status:

  • 200: Successful response, variables updated
  • 400: Invalid variable

Return Body:

A JSON array with the variables updated and their current (newly updated) values.


Example:

curl -X PATCH \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001539d43a51db44159ddb1a354e48506/variables' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"sample_int": 16, "sample_dict[\"day\"]": "tuesday", "sample_array[1]": 300}'

Example Response:

{
    "sample_int": 16,
    "sample_dict[\"day\"]": "tuesday",
    "sample_array[1]": 304
}

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).
  • The variable names may include hard-coded array indices (name[index]) or object fields (name.field) if desired. Array indices are modeling-language dependent.
  • If the variable is in a separate scope, that scope must be included in the variable name in the URI (myModule.sample_string).
  • The body of the requst must be valid JSON. Therefore, for boolean variables in Python models,
    • You can use boolean values directly: { "sample_bool": true }.
    • You can use the Python convention for boolean values only if you pass the string value: { "sample_bool": "True" }.
  • For arrayed variables in Vensim models, by default the time step is the last index (name[index, time step]). Use the model context file to specify whether the time step is the first or last index. (Note that for arrayed constants in Vensim models, there is no time index.)
  • For Vensim "LOOKUP" variables, the Epicenter format is an array. Each array element is itself an array with two elements: the x-y pairs from the original Vensim variable. When using the PATCH method, update the entire Epicenter representation (replace all values); you can change the number of ordered pairs if desired. For example:
    • Original Vensim LOOKUP represenation: [(2000,0)-(2010,2)],(2000,1),(2005,.5),(2010,1)
    • Epicenter representation: [ [2000,1], [2005,.5], [2010,1] ]
  • For Vensim models, variables designated as "CONSTANT" or "LOOKUP" variables can only be changed at the start of the simulation run (before the Vensim startGame operation is called).
  • For additional examples of working with complex variables (e.g. multidimensional arrays, lists, dicts, etc.), see the specific language pages:
  • Alternatively, you can include the "variables" specifically in the request body, rather than the URI. For example:

      curl -X PATCH \
          'https://api.forio.com/v2/run/acme/supply-chain-game/3575dd84-272f-4ffe-ad64-46d1d621da0a' \
          --header 'Content-Type:application/json' \
          --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
          --data '{"variables": {"sample_int": 20, "sample_string": "hello again"}}'
    

    Then the response is:

      {
          "variables": { 
              "sample_int": 20,
              "sample_string": "hello again"
          }
      }
    

GET

Retrieve One Run


Method: GET

URI:

  • /v2/run/{account id}/{project id}/{run id}

Headers:

Body: None

Return Status:

  • 200: Successful response
  • 400: Invalid request

Return Body:

The run record (JSON object) for this run.


Example:

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001533965543534cd21a606beb8feb9d6' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

{
    "morphology": "MANY",
    "id": "000001539d43a51db44159ddb1a354e484df",
    "user": {
        "firstName": "j",
        "lastName": "smith",
        "id": "233ef9a8-af8e-41ad-84ba-9a21097f6f55",
        "userName": "jsmith@acme.com"
    },
    "model": "model.py",
    "scope": null,
    "created": "2016-03-22T17:17:46.092Z",
    "initialized": true,
    "active": true,
    "project": "supply-chain-game",
    "lastModified": "2016-03-22T17:17:46.092Z",
    "account": "acme",
    "files": null,
    "saved": false
}

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).
  • 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

When you retrieve runs using filters and sorts, all runs are retrieved from the database.


Method: GET

URI:

  • /v2/run/{account id}/{project id}/{filter, sort}

URI Optional Parameters:

  • The {filter} is a set of matrix parameters, and takes the format: ;field1=value1;field2=value2.

    Fields available for filtering include: id, model, saved, scope.worldId.

  • The {sort} is a query parameter indicating the field by which to sort the runs before they are returned, and a second query parameter with the direction of the sort. This takes the format: ?sort=field1&direction=dir.

    Fields available for sorting include: model, created, lastModified. The default is lastModified.

    The direction can be asc (ascending) or desc (descending). The default is desc.

  • See more information on the run record for a complete description of these fields.

Headers:

  • Authorization: Bearer{access token}

  • (Optional) Range: records {i}-{j}

    • Depending on your filter, this request may return many run records. The default page size is 100. You can limit the number of records returned by adding the Range header.

Body: None

Return Status:

  • 200: Successful response
  • 206: Successfully retrieved the partially complete response (for example if you request records 0-20 with the Range header and there are 35 records)
  • 400: Invalid request
  • 416: No records are found in a given search range (for example if you request records 10-15 with the Range header and there are only 8 records)

Return Body:

An array of JSON objects with the run records matching the filter. If you have specified a Range header in the request, or if your request returns more than 100 run records, this may not be all of the run records matching your filter. The array includes only those records indicated in the Content-Range header.


Example:

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/;saved=true?sort=lastModified&direction=asc' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response:

[
    {
        "morphology": "MANY",
        "id": "000001539d43a51db44159ddb1a354e484df",
        "user": {
            "firstName": "j",
            "lastName": "smith",
            "id": "233ef9a8-af8e-41ad-84ba-9a21097f6f55",
            "userName": "jsmith@acme.com"
        },
        "model": "model.py",
        "scope": null,
        "created": "2016-03-22T17:17:46.092Z",
        "initialized": true,
        "active": true,
        "project": "supply-chain-game",
        "lastModified": "2016-03-22T17:17:46.092Z",
        "account": "acme",
        "files": null,
        "saved": true
    },
    ... // other run records matching the filter, if any
        // ordered by lastModified, ascending
]

Notes:

  • All runs are retrieved from the database.
  • If the sort parameter is not specified in the URI, the default sort is by lastModified.
  • If the direction parameter is not specified in the URI, the default direction is desc.

  • 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 returned, j is the index of the last record returned, and k is the total number of records in the result set, or * if that number is computationally infeasible (for instance, because you are querying across multiple projects).

    For example, Content-Range: records 0-9/57 or Content-Range: records 20-29/*.

    If no records are returned, the response body is empty and the Content-Range header in the response is

      Content-Range: records -/0
    

    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 or 206 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).

Retrieve Variables as Part of Each Run Record

You can use either the GET request for one run or the GET request for many runs and append ?include= to also return specific model variables in the body of the run record.


Method: GET

URI:

  • /v2/run/{account id}/{project id}/{run id or filter}?include={comma-separated list of variable names}

Headers:

  • Authorization: Bearer{access token}

  • (Optional) Range: records {i}-{j}

    • Depending on your filter, this request may return many records. The default page size is 100. You can limit the number of records returned by adding the Range header.

Body: None

Return Status:

  • 200: Successful response
  • 206: Successfully retrieved the partially complete response (for example if you request records 0-20 with the Range header and there are 35 records)
  • 400: Invalid request
    • If you ask for both a valid and an invalid variable name, the response is 400. For example, ?include=sample_int,bad_variable and ?include=bad_variable both return 400.
  • 416: No records are found in a given search range (for example if you request records 10-15 with the Range header and there are only 8 records)

Return Body:

  • If the URI includes a run id directly, the response is the run record, with the named variables also included.
  • If the URI includes a filter (even if the filter is simply ;id=myRunId), the response is an array of such run records.
    • In the case of filtering only, if you have specified a Range header in the request, or if your request returns more than 100 run records, the response may not be all of the run records matching your filter. The response includes only those records indicated in the Content-Range header.
  • See the run record for more information on specific fields returned.

Example (single run id):

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001539d43a51db44159ddb1a354e48542?include=sample_dict,sample_int,sample_array[2]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response (single run id):

{
    "morphology": "MANY",
    "id": "000001539d43a51db44159ddb1a354e48542",
    "user": {
        "firstName": "j",
        "lastName": "smith",
        "id": "233ef9a8-af8e-41ad-84ba-9a21097f6f55",
        "userName": "jsmith@acme.com"
    },
    "model": "model.py",
    "variables": {
        "sample_array[2]": 6,
        "sample_int": 16,
        "sample_dict": {
            "day": "tuesday",
            "month": 2
        }
    },
    "scope": null,
    "created": "2016-03-22T18:00:14.059Z",
    "initialized": true,
    "active": false,
    "project": "supply-chain-game",
    "lastModified": "2016-03-22T18:00:14.059Z",
    "account": "acme",
    "files": null,
    "saved": true
}

Example (filter):

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/;saved=true?include=sample_dict,sample_int,sample_array' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response (filter):

[
    {
        "morphology": "MANY",
        "id": "000001539d43a51db44159ddb1a354e48542",
        "user": {
            "firstName": "j",
            "lastName": "smith",
            "id": "233ef9a8-af8e-41ad-84ba-9a21097f6f55",
            "userName": "jsmith@acme.com"
        },
        "model": "model.py",
        "variables": {
            "sample_array": [
                2,
                4,
                6,
                8
            ],
            "sample_int": 16,
            "sample_dict": {
                "day": "tuesday",
                "month": 2
            }
        },
        "scope": null,
        "created": "2016-03-22T18:00:14.059Z",
        "initialized": true,
        "active": false,
        "project": "supply-chain-game",
        "lastModified": "2016-03-22T18:00:14.059Z",
        "account": "acme",
        "files": null,
        "saved": true
    },
    ... // other run records matching the filter, if any
]

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).

  • When using a single run id in the URI,

    • The run is retrieved from memory if available. If the run is not in memory, it is retrieved from the database.
    • If the run is in memory, the variables in the response includes all (requested) variables. However, if the run is only in the database, the variables only includes (requested) variables that have been explicitly saved. (Variables are saved to the database using Epicenter.record() or similar, see Writing your model.)
    • The variable name may include hard-coded array indices (name[index]) or object fields (name.field) if desired. Array indices are modeling-language dependent.
  • When using a filter in the URI,

    • When reading from many runs, all information is pulled from the database, regardless of whether the run is also currently in memory. As a consequence, only variables that have been explicitly saved to the database are available for query using this method. (Variables are saved to the database using Epicenter.record() or similar, see Writing your model.)
    • The variable name may NOT include hard-coded array indices (name[index]) or object fields (name.field); only the complete variable is available when you are reading from many runs.
  • There are three different variations that you can use to specify a particular variable name in the URI. The following expressions all add sample_int to the variables in the response body:

    • ?include=sample_int
    • ?include=variables.sample_int
    • ?include=.sample_int
  • If the variable is in a separate scope, that scope must be included in the variable name in the URI (myModule.sample_string).

Retrieve Only Variables

You can use either the GET request for one run or the GET request for many runs and append /variables/?include= to return an object with specific model variables request (or an array of such objects).


Method: GET

URI:

  • /v2/run/{account id}/{project id}/{run id or filter}/variables/?include={comma-separated list of variable names}

Headers:

  • Authorization: Bearer{access token}

  • (Optional) Range: records {i}-{j}

    • Depending on your filter, this request may return many records. The default page size is 100. You can limit the number of records returned by adding the Range header.

Body: None

Return Status:

  • 200: Successful response
  • 206: Successfully retrieved the partially complete response (for example if you request records 0-20 with the Range header and there are 35 records)
  • 400: Invalid request
    • If you ask for both a valid and an invalid variable name, the response is 400. For example, /variables/?include=sample_int,bad_variable and /variables/?include=bad_variable both return 400.
  • 416: No records are found in a given search range (for example if you request records 10-15 with the Range header and there are only 8 records)

Return Body:

  • If the URI includes a run id directly, the response is an object whose fields are the requested variables.
  • If the URI includes a filter (even if the filter is simply ;id=myRunId), the response is an array of such objects, one object for each run.
    • In the case of filtering only, if you have specified a Range header in the request, or if your request returns more than 100 runs, this array may not contain objects for all runs matching your filter. The array includes only objects for those runs indicated in the Content-Range header.

Example (single run id):

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001539d43a51db44159ddb1a354e48542/variables/?include=sample_dict,sample_int,sample_array[2]' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response (single run id):

{
    "sample_array[2]": 6,
    "sample_int": 16,
    "sample_dict": {
        "day": "tuesday",
        "month": 2
    }
}

Example (filter):

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/;saved=true/variables/?include=sample_dict,sample_int,sample_array' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response (filter):

[
    {
        "sample_array": [
            2,
            4,
            6,
            8
        ],
        "sample_int": 10,
        "sample_dict": {
            "day": "monday",
            "month": 2
        }
    },
    ... // other run records matching the filter, if any
]

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).

  • When using a single run id in the URI,

    • The run is retrieved from memory if available. If the run is not in memory, it is retrieved from the database.
    • If the run is in memory, the object in the response includes all (requested) variables. However, if the run is only in the database, the object only includes (requested) variables that have been explicitly saved. (Variables are saved to the database using Epicenter.record() or similar, see Writing your model.)
    • The variable name may include hard-coded array indices (name[index]) or object fields (name.field) if desired. Array indices are modeling-language dependent.
  • When using a filter in the URI,

    • When reading from many runs, all information is pulled from the database, regardless of whether the run is also currently in memory. As a consequence, only variables that have been explicitly saved to the database are available for query using this method. (Variables are saved to the database using Epicenter.record() or similar, see Writing your model.)
    • The variable name may NOT include hard-coded array indices (name[index]) or object fields (name.field); only the complete variable is available when you are reading from many runs.
  • There are three different variations that you can use to specify a particular variable name in the URI. The following expressions all add sample_int to the object in the response body:

    • /variables/?include=sample_int
    • /variables/?include=variables.sample_int
    • /variables/?include=.sample_int
  • If the variable is in a separate scope, that scope must be included in the variable name in the URI (myModule.sample_string).

Retrieve a Single, Dereferenced Variable Value from One or More Runs

You can use either the GET request for one run or the GET request for many runs and append /variables/varName to return the dereferenced value of that variable (or an array of such values).


Method: GET

URI:

  • /v2/run/{account id}/{project id}/{run id or filter}/variables/{variable name}

Headers:

  • Authorization: Bearer{access token}

  • (Optional) Range: records {i}-{j}

    • Depending on your filter, this request may return many records. The default page size is 100. You can limit the number of records returned by adding the Range header.

Body: None

Return Status:

  • 200: Successful response
  • 206: Successfully retrieved the partially complete response (for example if you request records 0-20 with the Range header and there are 35 records)
  • 400: Invalid request
    • If you ask for both a valid and an invalid variable name, the response is 400. For example, ?include=sample_int,bad_variable and ?include=bad_variable both return 400.
  • 416: No records are found in a given search range (for example if you request records 10-15 with the Range header and there are only 8 records)

Return Body:

  • If the URI includes a run id directly, the response is the value of the variable.
  • If the URI includes a filter (even if the filter is simply ;id=myRunId), the response is an array of such values, one value for each run.
    • In the case of filtering only, if you have specified a Range header in the request, or if your request returns more than 100 runs, this array may not contain variable values for all runs matching your filter. The array includes only values for those runs indicated in the Content-Range header.

Example (single run id):

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/000001539d43a51db44159ddb1a354e48542/variables/sample_int' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response (single run id):

16

Example (filter):

curl -G \
    'https://api.forio.com/v2/run/acme/supply-chain-game/;saved=true/variables/sample_int' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \

Example Response (filter):

[
    16,
    ... // other variable values for runs matching the filter, if any
]

Notes:

  • In the URI, the Account ID is the Team ID (for team projects) or User ID (for personal projects).

  • When using a single run id in the URI,

    • The run is retrieved from memory if available. If the run is not in memory, it is retrieved from the database. In this case, the requested variable must have been explicitly saved. (Variables are saved to the database using Epicenter.record() or similar, see Writing your model.)
    • The variable name may include hard-coded array indices (name[index]) or object fields (name.field) if desired. Array indices are modeling-language dependent.
  • When using a filter in the URI,

    • When reading from many runs, all information is pulled from the database, regardless of whether the run is also currently in memory. As a consequence, only variables that have been explicitly saved to the database are available for query using this method. (Variables are saved to the database using Epicenter.record() or similar, see Writing your model.)
    • The variable name may NOT include hard-coded array indices (name[index]) or object fields (name.field); only the complete variable is available when you are reading from many runs.
  • If the variable is in a separate scope, that scope must be included in the variable name in the URI (myModule.sample_string).

Data Structure

The Run API operates on the Run, Operation, and Error record data structures. It also returns data structures containing variable names and values.

Run Record

The Run record describes the run.

Field Required? Description
id yes The identifier of the run. Always included in a response; should not be included as part of a POST request to create a run.
account yes The Account ID of the account for which the run is created. This is the Team ID (for team projects) or User ID (for personal projects). Required when creating a run and always included in a response.
project yes The Project ID of the project for which the run is created. Required when creating a run and always included in a response.
model yes The name of the primary model file. This is the one file in the project where model execution should begin, and that explicitly exposes variables and operations. Required when creating a run and always included in a response.
user no Information about the user that created the run, including id, userName, firstName, lastName. If the access token used to create the run was a user access token, the user information is included; if it was a project access token, the user information is null.
scope no A description of where the run is available. Typically you use this if your project includes end users and groups; for example, the scope should always be passed in if this run belongs to an end user of your project.
  • group: The name of any local group in the project.
  • role: The role of the end user with access to this run: standard or facilitator.
  • worldId: For multiplayer games, the identifier of the world in which this run was created.
  • trackingKey: A string identifier, so you can easily group runs together. This is most common when you have a public project, but want to track all runs associated with a particular user.
created yes When the run record was created, in ISO 8601 format. Always included in a response; should not be included as part of creating a run.
lastModified yes When the run record was most recently updated, in ISO 8601 format. Always included in a response; should not be included as part of creating a run.
files no Only relevant for Vensim models. If you are using a Vensim model and you have additional data to pass in to your model, pass a files object that includes name : value pairs. (Note that you'll also need to add this same files object to your Vensim Model Context file.) Each name can be any designation you like. 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.
active yes This field is true if the run is currently in memory, and false if the run is only in the database. (See more on run persistence.) Always included in a response; should not be included as part of creating a run.
saved no A flag in the run record, set to false when the run is created. You can set this field as needed; its value is not tied to run creation or run persistence.
initialized no A flag in the run record, set to true when the run is created. You can set this field as needed; its value is not tied to run creation or run persistence.
morphology no Read only and internal use only.


Example Run Record

An example Run record returned as a response to a creating a run:

{
    "user": {
        "id": "d730a1b5-5451-4627-b16d-f3a7ed63f039",
        "userName": "jsmith@acme.com",
        "firstName": "j",
        "lastName": "smith"
    },
    "files": null,
    "morphology": "MANY",
    "created": "2016-03-07T21:29:04.244Z",
    "lastModified": "2016-03-07T21:29:04.244Z",
    "id": "000001533965543534cd21a606beb8feb9c7",
    "account": "acme",
    "project": "supply-chain-game",
    "model": "model.py",
    "saved": false,
    "active": true,
    "initialized": true,
    "scope": null
}

Operation Record

The POST request to call an operation takes an operation record with the arguments of the operation. It returns the operation record with details on the operation called, including name, arguments, and result.

Field Required? Description
name no The name of the model operation called. This is required in the URI of the POST request but is not included in the request body. It is always present in the response.
arguments no An array of arguments to the operation called. If the operation does not take any arguments, you can either omit the arguments field, or pass an empty array. It is present in the response only if arguments were passed in to the operation. Each argument can be of any type (including JSON objects), as long as there is a corresponding operation in the model.
result no The return value from the operation. This is not included in the POST request; it may be present in the response. If there is no return value, this field is not included. Note that the return value may or may not also be stored in a model variable, depending on the operation.


Example Operation Record

An example operation record returned as a response to a POST request:

{
    "name": "runmodel",
    "arguments": [ "input string", 25, true ],
    "result": 20.44
}

Error Record

The POST request for the Run API may return an error, for example because of a problem creating a run or calling an operation.

Error on Run Creation: 400 Invalid Request

When the POST request cannot be completed because of a problem with the request body, the response is a 400 error.

Field Required? Description
fault yes The kind of fault, if available.
type yes Kind of error, if available.
run_id yes The identifier of the run, if it was created.
message yes The specific error message.
error yes Boolean, set to true for all errors.


Example: 400 Error Record

{
    "fault": null,
    "type": "model_not_found",
    "run_id": "000001533965543534cd21a606beb8fec3a0",
    "message": "Could not locate model(/opt/forio/files/projects/acme/supply-chain-game2/model/model.py)",
    "error": true
}

Error on Run Creation: 500 Server Error

When the POST request cannot be completed because of a problem with the model, the response is a 500 error.

Field Required? Description
cause yes Specific cause, if available.
context yes Additional detail, if available.
trace yes The stack trace of the error, in the
information yes Additional detail, if available.
type yes Kind of error, if available.
message yes The specific error message, as provided by the environment listed in type.
native yes Internal use only.


Example: 500 Error Record

{
    "cause": null,
    "context": null,
    "trace": [
        {
            "type": "python",
            "function": "__execute__",
            "file": "/usr/local/lib/python3.4/dist-packages/epicenter-py3.5.egg/epicenter/worker/python/python_worker.py",
            "line": 61
        }
    ],
    "information": null,
    "type": "python",
    "message": "SyntaxError: invalid syntax (model.py, line 7)",
    "native": null
}

Error on Model Operation: 400 Bad Request

Field Required? Description
run_id yes The unique identifier of the run.
name yes The name of the operation called. This is from the POST request.
arguments no The arguments of the operation called. This is from the POST request.
message yes A summary of how the error occurred. This will typically contain enough information to allow you to correct the error.
error yes Boolean; set to true when an error is returned.
type yes An identifier with more information about what triggered the specific error.
fault no An object with additional specifics of how the error occurred, if available. This may include the fields:
  • cause: Exact cause, if known; amount of information available dependent on the modeling language and the nature of the error. Typically includes type, function, file, and line.
  • context: Additional context, if known; amount of information available dependent on the modeling language and the nature of the error.
  • trace: A stack trace, if available, presented as an array. Each element of the array includes type, function, file, and line.
  • information: An object summarizing the class (from the Epicenter backend implementation) and value of the error. Information from the value object, including type, runId, key, and detail, may populate the top-level record fields type, run_id, name, and arguments respectively.
  • native: Not populated for model errors; returned as null.
  • type: Where the error occured.
  • message: A summary of how the error occurred.


Example Error Record

An example error record returned as a response to a POST request to call an operation that caused a model error:

{
    "type": "invalid_proc",
    "run_id": "00000152c3df8b67a362e3d5ee96365d95f3",
    "message": "TypeError: setRiskAssignedTo() missing 1 required positional argument: 'index'",
    "name": "setRiskAssignedTo",
    "arguments": "[\"TR-01\"]",
    "error": true,

    "fault": {
        "cause": null,
        "context": null,
        "trace": [
            {
                "type": "python",
                "function": "run",
                "file": "/usr/local/lib/python3.4/dist-packages/epicenter-py3.5.egg/epicenter/worker/worker_thread.py",
                "line": 41
            },
            ... 
        ],
        "information": {
            "class": "com.forio.epicenter.bedrock.utility.json.exception.GridErrorImplication",
            "value": {
                "type": "proc",
                "runId": "00000152c3df8b67a362e3d5ee96365d95f3",
                "key": "setRiskAssignedTo",
                "detail": "[\"TR-01\"]"
            }
        },
        "type": "python",
        "message": "TypeError: setRiskAssignedTo() missing 1 required positional argument: 'index'",
        "native": null
    }
}