forio Toggle navigation

Model Variable API

The Variable API allows you to view and update the values of model variables for particular runs.

Depending on the language in which you have written your model, the variables may need to be exposed (e.g. export for a Julia model) in the model file in order to be called through the API. See Writing your Model).

Runs are stored both in memory on the Epicenter servers and in the Epicenter backend database. See more information on run persistence.

Variables are queued for persisting from memory to the database if a method from the model is called (using the Operation API), AND that method includes an explicit save of the variables (record for a Julia, Python, or R model).

The frequency of the queue processing is approximately every 30 seconds.

See more about writing Epicenter-friendly

The Variable API supports the following methods:

See also some additional notes on:

GET: Reading Details about Variables in this Model Run

You can retrieve the current value of any variable exposed by a model using the Variable API GET method.

Reading One Variable from One Run


Method: GET

URI: /model/variable/{run id}/{variable name}

Headers: Authorization: Bearer{access token}

Return Status: 200 (successful response), 400 (invalid variable, run in memory, Vensim model), 404 (invalid variable and run in database, or invalid run id)

Return Body: The variable value


Example:

curl -G \
    'https://api.forio.com/model/variable/668aaf1f-0006-4aef-bdc5-f287e50f444f/sample_string' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

Example Response:

"Hello World"

Notes:

  • When the run id is explicitly part of the URI, the variables are retrieved from memory if available, meaning all exposed variables may be included in the response. If the run is not in memory, the variables are retrieved from the database, meaning only variables that have explicitly been saved (e.g. for Julia models, variables that are recorded during a method that has been called on the model) are retrieved.
  • The variable name can include hard-coded array indices (name[1]) or object fields (name.field) if desired. Array indices are 1-based.
  • For arrayed variables in Vensim models, the time step is the last index. (Note that for arrayed constants in Vensim models, there is no time index.)



Reading One Variable from Many Runs


Method: GET

URI: /model/variable/;id={run id};id={run id}/{variable name}

Headers: Authorization: Bearer{access token}

Return Status: 200 (successful response), 404 (invalid variable)

Return Body: An array of objects, each one including the run id and variable value.


Example:

curl -G \
    'https://api.forio.com/model/variable/;id=668aaf1f-0006-4aef-bdc5-f287e50f444f;id=cdb0f424-20ba-445a-a4bd-6738010b5d71/sample_string' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

Example Response:

[ 
    { "run": "668aaf1f-0006-4aef-bdc5-f287e50f444f", 
      "variables": "Hello World" 
    }, 
    { "run": "cdb0f424-20ba-445a-a4bd-6738010b5d71", 
      "variables": "Goodbye World"
    } 
]

Notes:

  • When the run ids as listed in matrix parameters, the variables are retrieved from the database, meaning only variables that have explicitly been saved (e.g. for Julia models, variables that are recorded during a method that has been called on the model) are retrieved.
  • The variable name can include hard-coded array indices (name[1]) or object fields (name.field) if desired. Array indices are 1-based.
  • For arrayed variables in Vensim models, the time step is the last index. (Note that for arrayed constants in Vensim models, there is no time index.)



Reading Many Variables from One Run


Method: GET

URI: /model/variable/{run id}?name={variable name}&name={variable name}

Headers: Authorization: Bearer{access token}

Return Status: 200 (successful response), 400 (invalid variables, run in memory, Vensim model), 404 (invalid variables and run in database, or invalid run id)

Return Body: JSON object with each variable name and value.


Example:

curl -G \
    'https://api.forio.com/model/variable/668aaf1f-0006-4aef-bdc5-f287e50f444f?name=sample_string&name=sample_int' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

Example Response:

{ 
    "sample_string": "Hello World", 
    "sample_int": 10 
}

Notes:

  • When the run id is explicitly part of the URI, the variables are retrieved from memory if available, meaning all exposed variables may be included in the response. If the run is not in memory, the variables are retrieved from the database, meaning only variables that have explicitly been saved (e.g. for Julia models, variables that are recorded during a method that has been called on the model) are retrieved.
  • The variable name can include hard-coded array indices (name[1]) or object fields (name.field) if desired. Array indices are 1-based.
  • For arrayed variables in Vensim models, the time step is the last index. (Note that for arrayed constants in Vensim models, there is no time index.)



Reading Many Variables from Many Runs


Method: GET

URI: /model/variable/;id={run id};id={run id}/?name={variable name}&name={variable name}

Headers: Authorization: Bearer{access token}

Return Status: 200 (successful response), 404 (invalid variables)

Return Body: An array of JSON objects, each one including the run id and an object with all of the variable names and values.


Example:

curl -G \
    'https://api.forio.com/model/variable/;id=668aaf1f-0006-4aef-bdc5-f287e50f444f;id=cdb0f424-20ba-445a-a4bd-6738010b5d71/?name=sample_string&name=sample_int' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'

Example Response:

[ 
    { "run": "668aaf1f-0006-4aef-bdc5-f287e50f444f", 
      "variables": { 
          "sample_string": "Hello_World", 
          "sample_int": 10 
      } 
    }, 
    { "run": "cdb0f424-20ba-445a-a4bd-6738010b5d71", 
      "variables": { 
          "sample_string": "Goodbye_World", 
          "sample_int": 15 
      } 
    } 
]

Notes:

  • When the run ids as listed in matrix parameters, the variables are retrieved from the database, meaning only variables that have explicitly been saved (e.g. for Julia models, variables that are recorded during a method that has been called on the model) are retrieved.
  • The variable name can include hard-coded array indices (name[1]) or object fields (name.field) if desired. Array indices are 1-based.
  • For arrayed variables in Vensim models, the time step is the last index. (Note that for arrayed constants in Vensim models, there is no time index.)



PATCH: Updating the Values of Variables in this Model Run

You can update the current value of any variable exposed by a model using the Variable API PATCH method.

Runs must be in memory in order for you to update variables or call operations on them. (See more information on run persistence.) Runs are automatically replayed when you attempt to update a model variable. (If needed, you can change this behavior in your model context file.)

Updating the Value of a Variable


Method: PATCH

URI: /model/variable/{run id}

Headers: Content-Type: application/json, Authorization: Bearer{access token}

Body: JSON object with variable name and new value, e.g. { "fieldName1": "fieldValue1", "fieldName2": "fieldValue2"}.

Return Status: 200 (successful response)

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


Example:

curl -X PATCH \
    'https://api.forio.com/model/variable/668aaf1f-0006-4aef-bdc5-f287e50f444f' 
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{"sample_string": "Hello Again", "sample_array[2]": 10}'

Example Response:

{
    "sample_string": "Hello Again", 
    "sample_array[2]": 10
}

Notes:

  • The variable name can include hard-coded array indices (name[1]) or object dereferences (name.field) if desired. Array indices are 1-based.
  • 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, the time step is the 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).

Working with Array Variables

When working with array variables, the variable name can include hard-coded array indices (foo[1]). Array indices are 1-based.

  • For GET requests, use the parameter format name=varName[subscript1][subscript2][...]
  • For PATCH requests, use the parameter format {"varName[subscript1][subscript2][...]" : <value or array of values>}
  • For arrayed variables in Vensim models, the time step is the last index: varName[step, subscriptN].
  • For arrayed constants in Vensim models, there is no time index.

For example, suppose you have the three-dimensional array variable sales[product, region, channel], where

  • product: apple, orange, banana
  • region: north, south
  • channel: club, grocery, farmersmarket

You can specify zero, one, two, or three dimensions in your request.

No dimensions specified. When specifying no dimensions (that is, just using the name of the variable), the response is the complete three dimensional array.

Using name=sales in your GET request returns:

[   
    [ [18, 17, 16], [15, 14, 13] ],
    [ [12, 11, 10], [9, 8, 7] ],    
    [ [6, 5, 4], [3, 2, 1] ]
]

One dimension specified. When specifying one dimension, the response is a two dimensional array. The data retrieved depends on which dimension you specify in the request.

Using name=sales[1] retrieves the region and channel values for the first product (apple), returning a two dimensional array:

[ [18, 17, 16], 
  [15, 14, 13] ]

Two dimensions specified. When specifying two dimensions, the response is an array (the third dimension). The data retrieved depends on which dimensions you specify in the request.

Using name=sales[1][1] or name=sales[1][1] retrieves all the channel values for the first product (apple) and first region (north), returning an array:

[18, 17, 16] 

Three dimensions specified. When specifying three dimensions, the response is a scalar.

Using name=sales[1][1][2] retrieves the specific value:

17

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/variable


Example:

curl -X OPTIONS 'https://api.forio.com/model/variable'

Error Reporting from Model APIs

The Model APIs — and the APIs built on top of them in the Epicenter stack, such as the Run API — all use the same format for reporting errors from the model.

These are errors because of a problem with a variable or operation. General errors with API usage, such as making a call without appropriate permissions, simply return the appropriate HTTP status code. See each of the Model APIs for specifics.

Errors Messages from the Model

Errors messages generated by the model include:

  • status, the HTTP Status Code
  • runId, the unique identifier of this run
  • errors, an array of the errors

Each element of the errors array includes:

  • The specific error that caused the problem with the model. This is one of:
    • invalid_name
    • cannot_set_parameter
    • internal_model_error
    • internal_worker_error
    • file_not_found
  • A name with more information about what triggered the specific error. This varies based on the language of your model. For example, for Vensim models this is the name of the variable or operation; for Python models this is the Python language error.
  • A message with more information about how the error occurred.

Example

For example, the following API request to update variables (using a Vensim model):

curl -X PATCH \
    'https://api.forio.com/model/variable/e2bf7868-f20e-42a9-8119-8adeb5f5f751' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
    --data '{ "Price": 200, "Bad Var": 35 }'

generates this error message from the model:

{
    "status": 400,
    "runId": "e2bf7868-f20e-42a9-8119-8adeb5f5f751",
    "errors": [
        {
            "error": "invalid_name",
            "message": "Invalid variable name: Bad Var.",
            "name": "Bad Var"
        }
    ]
}

IMPORTANT: Note that for multi-part API requests, part of the request may be completed even if another part of the request returns an error. In the example above, the variable Price is updated, even though the attempt to update the variable Bad Var causes a model error.