This article assumes some familiarity with HTTP in general and RESTful APIs in particular (background).

Simplified Example: Transmission Owner Sends Forecast with curl

If a Transmission Owner is their own Ratings Provider, they must regularly send a Ratings Forecast to their Transmission Provider. TROLIE provides the patchRatingForecastProposal operation for this purpose.

Assume the Transmission Owner creates a file called input.json containing their forecast. An example of the required format for the file is given below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{
  "proposal-header" : {
    "source": {
      "last-updated": "2025-10-31T15:05:43.044267100-07:00",
      "provider": "UTILITY-A",
      "origin-id": "5aeacb25-9b65-4738-8a00-ac10afa63640"
    },
    "begins": "2025-11-01T01:00:00-05:00",
    "default-emergency-durations": [
      {
        "name": "lte",
        "duration-minutes": 240
      },
      {
        "name": "ste",
        "duration-minutes": 30
      },
      {
        "name": "dal",
        "duration-minutes": 15
      }
    ],
    "power-system-resources": [
      { "resource-id": "8badf00d",
        "alternate-identifiers": [
          {"name": "segmentX", "authority": "TO-NERC-ID"},
          {"name": "LINE1 SEG-X", "authority": "RC-NERC-ID", "mrid": "8badf00d"}
        ]
      }
    ]
  },
  "ratings": [
    {
      "resource-id": "8badf00d",
      "periods": [
        {
          "period-start": "2025-11-01T01:00:00-05:00",
          "period-end": "2025-11-01T02:00:00-05:00",
          "continuous-operating-limit": {
            "mva": 160
          },
          "emergency-operating-limits": [
            {
              "duration-name": "lte",
              "limit": {
                "mva": 165
              }
            },
            {
              "duration-name": "ste",
              "limit": {
                "mva": 170
              }
            },
            {
              "duration-name": "dal",
              "limit": {
                "mva": 170
              }
            }
          ]
        },
        {
          "period-start": "2025-11-01T01:00:00-06:00",
          "period-end": "2025-11-02T02:00:00-06:00",
          "continuous-operating-limit": {
            "mva": 160
          },
          "emergency-operating-limits": [
            {
              "duration-name": "lte",
              "limit": {
                "mva": 165
              }
            },
            {
              "duration-name": "ste",
              "limit": {
                "mva": 170
              }
            },
            {
              "duration-name": "dal",
              "limit": {
                "mva": 170
              }
            }
          ]
        }
      ]
    }
  ]
}

This example also illustrates handling the fall Daylight Savings transition in the Central timezone. The format is one of TROLIE’s supported media types named application/vnd.trolie.rating-forecast-proposal.v1+json.

Pushing input.json to TROLIE with curl

Given the above input.json, run the following command to send it to the TROLIE server:

1
2
3
4
5
6
curl -d @input.json \
-X PATCH \
-H "Content-Type: application/vnd.trolie.rating-forecast-proposal.v1+json" \
-H "Accept: application/vnd.trolie.rating-forecast-proposal-status.v1+json"
-o output.json \
"https://trolie.example.com/rating-proposals/forecast"

If this submission is successful, output.json will contain the contents of the response from TROLIE. The format of the response is defined by another TROLIE media type: application/vnd.trolie.rating-forecast-proposal-status.v1+json. An example of this response format is given below:

1
2
3
4
5
6
7
8
9
10
11
12
{
  "source": {
    "provider": "UTILITY-A",
    "last-updated": "2023-07-12T15:05:43.044267100-07:00",
    "origin-id": "5aeacb25-9b65-4738-8a00-ac10afa63640"
  },
  "incomplete-obligation-count": 0,
  "incomplete-obligations": [],
  "invalid-proposal-count": 0,
  "proposal-validation-errors": []
}

Invalid Forecasts for Individual Resources Should be Tolerated

The TROLIE spec supports allowing some individual resource forecasts to be invalid without rejecting the entire proposal. A specific example will help illustrate the idea. Suppose the Ratings Provider submits a Forecast Proposal for two resources–8badf00d and d34dc0d3. Further suppose that there’s nothing wrong at all with the d34dc0d3 forecast, but the 8badf00d forecast is missing an hour, with everything else about the request being valid. In this case TROLIE should a return response like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
HTTP/1.1 202 Accepted
Content-Type: application/vnd.trolie.rating-forecast-proposal-status.v1+json
Server: trolie.example.com
Date: Wed, 29 Feb 2024 12:03:20 GMT
ETag: "123e4567e89b12d3a456426614174000"
X-Rate-Limit-Limit: 100
X-Rate-Limit-Remaining: 97
X-Rate-Limit-Reset: 3400


{
  "source": {
    "provider": "UTILITY-A",
    "last-updated": "2023-07-12T15:05:43.044267100-07:00",
    "origin-id": "5aeacb25-9b65-4738-8a00-ac10afa63640"
  },
  "begins": "2025-11-01T01:00:00-05:00",
  "incomplete-obligation-count": 1,
  "incomplete-obligations": [
      { "resource-id": "8badf00d",
        "alternate-identifiers": [
          {"name": "segmentX", "authority": "TO-NERC-ID"},
          {"name": "LINE1 SEG-X", "authority": "RC-NERC-ID", "mrid": "8badf00d"}
        ]
      }
  ],
  "invalid-proposal-count": 1,
  "proposal-validation-errors": [
    {
      "message": "The `resource-forecast-proposal` for `8badf00d` is incomplete.",
      "resource-id": "8badf00d"
    }
  ]
}

Client Errors are Not Acceptable

Bear in mind the proposal must always be on-time. Moreover, there are other client errors that are not tolerated, including:

  • Malformed requests, i.e., the JSON provided is not valid according to the media type schema.
  • Unprocessable content error: when the Forecast Proposal is well-formed, but the units provided in any of the forecasts are invalid.
  • Unprocessable content error: when none of the individual resource Forecast Proposals are valid, but the request is otherwise well-formed.

Additional client errors are identified in the patchRatingForecastProposal spec.

Clients Should Check the incomplete-obligation-count

The flip-side of this accommodative approach is that clients will not receive an error response when one of their resource forecasts is invalid, so the spec defines incomplete-obligation-count:

The number of facilities for this provider whose Ratings Obligation has not been met in this forecast window. This number may be larger than the size of incomplete-facilities, since the latter has a pre-defined upper bound for performance and application security reasons.

The Ratings Provider should check that this value is zero when they believe they have completed their submission process.

Multiple Submissions per Forecast Window

In every Forecast Window, a new area-wide Forecast Proposal is created on the TROLIE server of the Clearinghouse Provider. Each Ratings Provider then PATCHes the area-wide proposal with the forecasts for their respective Ratings Obligations. Any unmet Ratings Obligations will result in the Clearinghouse Provider using an appropriate Recourse Rating for those unmet obligations.

For Ratings Providers with a natural split in their Ratings Obligations, e.g., geographic or control areas, the PATCH semantics afford the ability to submit multiple Forecast Proposals containing just proposals for the relevant resources, if they choose to do so. This affordance can also be leveraged to split a large proposal into one or more parts in cases where that is advantageous from a performance or reliable delivery perspective.

There are two supported media types for a Real-Time Ratings proposals.

application/vnd.trolie.rating-forecast-proposal.v1+json allows the Ratings Provider to combine different limit types, such as apparent-power (MVA) and current (MW), in a single proposal.

application/vnd.trolie.rating-forecast-proposal-slim.v1+json for proposals that only require a single limit type, e.g., apparent-power. Clients MUST specify that limit-type as a media type parameter. For example,

1
2
PATCH /ratings-proposals/forecast HTTP/1.1
Content-Type: application/vnd.trolie.rating-forecast-proposal-slim.v1+json; limit-type=apparent-power

Note that this format is much more concise but requires significant care in serialization/deserialization. For details, see Using Slim Media Types.

Jointly-Owned Facilities

In a jointly-owned facility there may be one or more Ratings Providers for a given facility. This is expected to be fairly typical on seams. From a submittal perspective, this is inconsequential: Each Ratings Provider simply submits their own Forecast Proposal for Ratings Obligation using the appropriate resource-id. As with all resource-id uses, the TROLIE spec is agnostic as to which kind of Power System Resource is nominated by the identifier, but it will typically be a Segment in the case of a Jointly-Owned Facility with multiple Ratings Providers.