Get Reading Forecast for Groups


This method provides the mechanism for computing group-level forecasts. It returns the same data provided by the single student forecasting function, but at an aggregate level.

In addition to this, it returns a predicted mean ability for the group as well as an associated uncertainty measure. It also returns for the population the percentage of students that are expected to fall into each of the cut levels (performance levels), as well as a standard error associated with each level.


POST /api/forecast/reading/group


Parameter Type Description
studentData Array Data for each student is in a 3 item array which consists of:
  • priorAbility
  • priorUncertainty
  • elapsedDays
testUncertainty Number Uncertainty of the difficulty of the test that student performance is to be forecasted for. MetaMetrics sends this information in spreadsheet format.
cutLevels Array An array of performance levels based on expected future ability levels, measured in Lexile or Quantile. MetaMetrics sends this information in spreadsheet format.


An array is returned. Each item in this array will be a struct containing forecast data for each student passed in the method call (in the order the students were passed) and group results.

Parameter Type Parameter
students Array

This contains each student’s forecasting outcomes:

  • ability

    The student’s forecasted ability estimate.

  • Uncertainty

    Uncertainty associated with the student’s forecasted ability estimate.

  • Probabilities

    The probabilities that the student will fall into each of the performance bands, as defined by the cutLevels.

group Array

This contains the group forecasting outcomes:

  • groupAbility

    The student or group's forecasted ability estimate.

  • groupUncertainty

    Uncertainty associated with the ability estimate.

  • groupProportionPerLevel

    The predicted proportion of the group that will fall into the corresponding cutLevels.

  • groupStderrPerLevel

    The standard error of the predictions of each corresponding cutLevels.

apiVersion String
The current version number for the API.
  • groupStderrPerLevel The standard error of the predictions of each corresponding cutLevels.
framework String Either Lexile or Quantile; framework used to produce the measure.

Code Example

The following show an example of the request followed by an example of the response. The Python example is written for use with Python 3 and above.

import java.util.List;
import java.util.ArrayList;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;

import org.json.JSONObject;
import org.json.JSONArray;

public class GroupForecastReading {
    public static void main (String[] args) {
        try {
            // Authorization
            String baseURL = "";
            String clientId = "your_client_id";
            String clientSecret = "your_client_secret";
            HttpClient client = HttpClientBuilder.create().build();
            HttpPost authPost = new HttpPost(baseURL + "/authToken");
            JSONObject jsonInput = new JSONObject();
            jsonInput.put("clientId", clientId);
            jsonInput.put("clientSecret", clientSecret);
            StringEntity input = new StringEntity(jsonInput.toString());
            authPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
            HttpResponse response = client.execute(authPost); 
            StringBuilder stringBuilder = new StringBuilder();
            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line;
            while ((line = rd.readLine()) != null) 
            JSONObject json = new JSONObject(stringBuilder.toString());
            String token = json.getString("accessToken");
            Integer expires = json.getInt("expiresIn");

            // Group Forecast Reading example
            HttpPost postForm = new HttpPost(baseURL + "/api/forecast/reading/group");

            JSONObject postData = new JSONObject();
            postData.put("testUncertainty", 50.5);
            JSONArray cutLevels = new JSONArray();
            postData.put("cutLevels", cutLevels);

            JSONArray studentData = new JSONArray();
            JSONObject student1 = new JSONObject();
            student1.put("priorAbility", 950);
            student1.put("priorUncertainty", 61);
            student1.put("elapsedDays", 45);

            JSONObject student2 = new JSONObject();
            student2.put("priorAbility", 450);
            student2.put("priorUncertainty", 78);
            student2.put("elapsedDays", 37);

            postData.put("studentData", studentData);

            StringEntity formInput = new StringEntity(postData.toString());
            postForm.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token);
            postForm.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
            response = client.execute(postForm); 
            stringBuilder = new StringBuilder();

            rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            while ((line = rd.readLine()) != null) 
            JSONObject output = new JSONObject(stringBuilder.toString());
            JSONObject forecastData = output.getJSONObject("forecasts");
            // begin group output
            JSONObject group = forecastData.getJSONObject("group");
            Double groupAbility = group.getDouble("groupAbility");
            Double groupUncertainty = group.getDouble("groupUncertainty");

            List<Double> groupPopulationPercentPerLevel = new ArrayList<>();
            JSONArray groupPctPerLevelJSON = group.getJSONArray("GroupProportionPerLevel");
            for(int i = 0; i < groupPctPerLevelJSON.length(); i++) {

            List<Double> groupStderrPerLevel = new ArrayList<>();
            JSONArray groupStderrPerLevelJSON = group.getJSONArray("groupStderrPerLevel");
            for(int i = 0; i < groupStderrPerLevelJSON.length(); i++) {
            // end group output

            // begin student output
            JSONArray students = forecastData.getJSONArray("students");
            for(int i = 0; i < students.length(); i++) {
                // individual student data
                JSONObject student = students.getJSONObject(i);
                Double ability = student.getDouble("ability");
                Double uncertainty = student.getDouble("uncertainty");

                List<Double> probabilities = new ArrayList<>();
                JSONArray probabilitiesJSON = student.getJSONArray("probabilities");
                for(int j = 0; j < probabilitiesJSON.length(); j++) {
            // end student output

            String framework = output.getString("framework");
            String apiVersion = output.getString("apiVersion");
        } catch(IOException e) {
# /authToken

import requests
import json

base_url = ""
client_id = "your_client_id"  # replace with your provided client ID
client_secret = "your_client_secret"  # replace with your provided client secret
response =
    data={"clientId": client_id, "clientSecret": client_secret},
access_token = response.json()["accessToken"]  # use in Authorization header

# use these headers to make requests
headers = {
    "Authorization": f"Bearer {access_token}",
    "Content-Type": "application/json",

# /api/forecast/reading/group

# 1) Basic Example
data = {
    "studentData": [
        {"priorAbility": 950, "priorUncertainty": 61, "elapsedDays": 45},
        {"priorAbility": 450, "priorUncertainty": 78, "elapsedDays": 37},
    "testUncertainty": 50.5,
    "cutLevels": [367.5, 785.5],
response =
    f"{base_url}/api/forecast/reading/group", headers=headers, json=data
# returns
# {
#    "forecast": {
#       "students": [{
#           "ability": <float>,
#           "uncertainty": <float>,
#           "probabilities": <list:float>
#       }],
#       "group": {
#           "groupAbility": <float>,
#           "groupUncertainty": <float>,
#           "GroupProportionPerLevel": <list:float>,
#           "groupStderrPerLevel": <list:float>
#       }
#    }
#    "framework": ["lexile" or "quantile"]
#    "apiVersion": <string>
# }