Risk Category Hazard Scoring

Calculate category-level hazard scores

Overview

Climate on Demand hazard modeling enables organizations to evaluate the potential risk to their facilities posed by multiple risk categories. Facilities may be modeled at either that category level (high-level) or at the subcategory level, which evaluates and scores risk indicators within each risk category. This endpoint returns data at the risk category level. It provides risk category scores for one or more facilities specified in a request.

Risk categories include Floods, Heat Stress, Hurricanes & Typhoons, Sea Level Rise, Water Stress, Wildfires, and Earthquakes.

Hazard modeling returns two hazard-scoring metrics:

  • A risk score is a measurement of a facility's exposure to a risk category due to climate change. For each risk category, the risk score returns a value (0-100) that measures the projected frequency and severity of future catastrophe events.
  • A risk level is an assessment of a category risk to a facility that is based on its risk score. One of none, low, medium, high, or red flag. Risk levels enable you to easily compare the relative exposure of facilities across multiple risk categories.

In this tutorial, we will review the process for hazard modeling a facility at the category level. We will review key request parameters to understand how these parameters determine the results calculated. Finally, we will review the hazard scores returned. This process is described using sample code in cURL and Python.

Step 1: Calculate risk category scores

The Calculate risk category scores calculates the financial impact of climate change for one or more facilities.

curl --request POST \
     --url https://{host}/AppsServices/api/v1/score-facilities/jobs \
     --header 'Authorization: XXXXXXXXXX' \
     --header 'accept: application/json' \
     --header 'content-type: application/json'

The request body defines an object with two required parameters: m, which specifies the methodology version and facilities, which defines an array of objects.

If a value of 2023.1 is specified for the m (methodology) parameter in a request, the th (time horizon) parameter and s (scenario) parameter are also required.

{
    "m": "2022.1",
    "facilities": [{
        "id": "1",
        "name": "newark office",
        "activity": "office",
        "street1": "7575 gateway blvd., suite 300",
        "city": "newark",
        "state": "ca",
        "postal_code": "94560",
        "country": "united states",
        "latitude": 37.5412000000,
        "longitude": -122.060610000
    }] 
}

This operation currently supports three versions of the Hazard Scoring Methodology: 2023.1, 2023.2, and 2023.3. To learn more about Hazard Scoring methodologies, see Climate on Demand API Endpoints.

If the latitude and longitude parameters are not specified, the Climate on Demand API attempts to geocode the address.

📷

RECOMMENDATION

Moody's RMS recommends that you carefully review geocoding results before running additional requests for the same facilities.

If successful, initiates a workflow job and returns a 200 response includes the job ID and job status (IN PROGRESS, FINISHED, FAILED):

{ 
    "job_id": 1676
}

Once the job is FINISHED, you can retrieve category scores for the specified facilities.

Step 2: Get results

The Get results by job returns the risk data calculated by a specific job.

curl --request GET \
     --url https://[host]/AppsServices/api/jobs/jobId \
     --header 'Authorization: XXXXXXXXXX' \
     --header 'accept: application/json'

If the specified job is finished, the response returns an output that includes the risk data. Depending on the resource used to initiate the job, the output attribute may include an array of risk category scores, risk subcategory scores, or financial impact scores:

{
    "job_id": 1676,
    "user_id": 639,
    "status": "FINISHED",
    "percent_complete": 100,
    "output": [
        {
            "id": "1",
            "name": "Newark Office",
            "m": "2023.3",
             "latitude": 37.5412000000,
             "longitude": -122.060610000
            "geo_status": "User",
            "elevation": 62.0,
            "th":"2050",
            "rcp": "RCP8.5",
            "score": 35.0,
            "risk_categories": {
                "Floods": {
                "score": 3.0,
                "risk level": "Low"
            },
            "Heat Stress": {
                "score": 33.0,
                "risk level": "Medium"
            },
            "Hurricanes & Typhoons": {
                "score": 0.0,
                "risk level": "None"
            },
            "Sea Level Rise": {
                "score": 25.0,
                "risk level": "Low"
            },
            "Water Stress": {
                "score": 72.0,
                "risk level": "High"
            },
            "Wildfire": {
                "score": 74.0,
                "risk level": "High"
            },
            "Earthquakes": {
                "score": 95.0,
                "risk level": "High"
            }
        }
    }],
    "start_date": "Sept 27, 2023, 5:46:59 PM",
    "end_date": "Sept 27, 2023, 5:47:04 PM"
}

The two important attributes returned are the score (risk score) and the risk level:

  • The score attribute indicates the risk category's risk score: the severity and frequency of catastrophe events at the facility. For each risk category, the API returns a risk score. The significance of a risk score (score) varies depending on the risk category.
  • The risk level attribute returns a scenario analysis result in the form of “high”, “medium”, and “low” tiers." This version of scenario analysis is meant to highlight a range of potential outcomes based on the underlying model data.

For a detailed discussion of risk scoring and risk analysis results, see Real Assets Physical Climate Risk & Corporate Facility Operations Risk Methodology in Moody's RMS Support Center.

Python example

def scoreFacilities(token, request_json, host):
    endpoint = host + "/cod/AppsServices/api/v1/score-facilities/jobs"
    r = requests.post(url=endpoint, json=request_json, headers={'Authorization':'Bearer ' + token})
    print(f'response code: {r.status_code}') if r.status_code == requests.codes.ok:
        result = r.json()
        return result
else:        
    return None
def getJobResult(token, host, job_id):
    endpoint = host + "/cod/AppsServices/api/jobs/" + job_id
    r = requests.get(url=endpoint, headers={'Authorization': 'Bearer ' + token})
    print(f'response code: {r.status_code}')
    if r.status_code == requests.codes.ok:
        result = r.json()
        return result
else:
    return None
data = {
    "m": "P.2023.1",
    "th": "2050",
    "rcp": "RCP8.5",
    "facilities": [{
    "facilities": [{
        "id": "1",
        "name": "newark office",
        "activity": "office",
        "street1": "7575 gateway blvd., suite 300",
        "city": "newark",
        "state": "ca",
        "postal_code": "94560",
        "country": "united states",
        "latitude": 37.5412000000,
        "longitude": -122.060610000
    }]
}
response_job = scoreFacilities(access_token, data, my_host)
my_job = response_job.get('job_id')
time.sleep(30)
result = getJobResult(access_token, my_host, str(my_job))