{
  "openapi": "3.0.3",
  "info": {
    "title": "WEii-API",
    "version": "3.1.0",
    "description": "<p>Deze API berekent de WEii van een gebouw op basis van het werkelijke, gemeten energiegebruik en het gebruiksoppervlakte van het gebouw.<br><br>Om de API te gebruiken heeft u een API-key nodig. Deze kunt u <a href=\"https://www.weii.nl/licentiehouder-worden-20\">hier</a> aanvragen.</p>"
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/building-certificate/{id}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/certificateReponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized: Your request was made with invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Your request was made with invalid credentials."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden: You are not allowed to perform this action",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "You are not allowed to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Certificate not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Certificate not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Rate limit exceeded."
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized: Your request was made with invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Your request was made with invalid credentials."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden: You are not allowed to perform this action",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "You are not allowed to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Certificate not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Certificate not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Rate limit exceeded."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/building-certificate": {
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/requestInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/certificateReponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request: The request was malformed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized: Your request was made with invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "Your request was made with invalid credentials."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden: You are not allowed to perform this action",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error",
                      "example": "You are not allowed to perform this action."
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable entity: The request was syntactically valid, but there was some semantic issue",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/fieldErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "A text message describing an error.",
                      "example": "Rate limit exceeded."
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Default Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/errorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.weii.nl.staging.tremani.nl/v3"
    },
    {
      "url": "https://localhost/weii-nl-api/www/v3"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "certificateReponse": {
        "type": "object",
        "required": [
          "statusLink",
          "queuedAt",
          "publicationStatus",
          "pdfStatus"
        ],
        "properties": {
          "statusLink": {
            "type": "string"
          },
          "queuedAt": {
            "type": "string"
          },
          "publicationStatus": {
            "type": "string",
            "enum": ["concept", "final"]
          },
          "pdfStatus": {
            "type": "string",
            "enum": ["queued", "failed", "done"]
          },
          "pdfDownloadLink": {
            "type": "string",
            "nullable": true
          },
          "linkValidUntil": {
            "type": "string",
            "nullable": true
          },
          "registrationNumber": {
            "type": "string",
            "nullable": true
          },
          "WEii": {
            "type": "integer",
            "nullable": true
          },
          "class": {
            "type": "string",
            "nullable": true
          },
          "year": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "errorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A text message describing an error.",
            "example": "Invalid JSON data in request body: Syntax error."
          }
        }
      },
      "fieldErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A text message describing an error.",
            "example": "Keyword validation failed: Value 0 must be greater or equal to 1."
          },
          "field": {
            "type": "string",
            "description": "A description of the field that caused the error.",
            "example": "building.surfaces.0.usableSurface"
          }
        }
      },
      "requestInput": {
        "type": "object",
        "required": [
          "certificate",
          "year",
          "building"
        ],
        "additionalProperties": false,
        "properties": {
          "certificate": {
            "type": "object",
            "required": [
              "licenseHolderName",
              "publicationStatus"
            ],
            "additionalProperties": false,
            "properties": {
              "licenseHolderName": {
                "type": "string",
                "description": "Name of the license holder."
              },
              "publicationStatus": {
                "type": "string",
                "enum": ["concept", "final"]
              }
            }
          },
          "year": {
            "type": "integer",
            "description": "Year of measurement of all meters.",
            "minimum": 2017
          },
          "building": {
            "type": "object",
            "required": [
              "address",
              "surfaces",
              "mainMeters"
            ],
            "additionalProperties": false,
            "properties": {
              "buildingName": {
                "type": "string",
                "description": "Name of the building."
              },
              "companyName": {
                "type": "string",
                "description": "Name of the company."
              },
              "address": {
                "$ref": "#/components/schemas/address"
              },
              "surfaces": {
                "type": "array",
                "description": "Usable surfaces of the building per buildingtype.",
                "items": {
                  "$ref": "#/components/schemas/surface"
                },
                "minItems": 1
              },
              "apartmentSurfaces": {
                "type": "array",
                "description": "Surfaces of the apartments in an apartment building. Only applicable and used if `building.surfaces` has a surface where buildingtype is 'Appartementengebouw'. Total sum of all apartments cannot exceed the area of buildingtype 'Appartementengebouw'. This array should contain the separate surfaces of all apartments in the building to ensure a correct calculation. Apartments smaller than 75 m² have a special benchmark calculation.",
                "items": {
                  "type": "integer",
                  "minimum": 1
                },
                "minItems": 1
              },
              "mainMeters": {
                "type": "object",
                "required": [
                  "input"
                ],
                "additionalProperties": false,
                "description": "Input and output energy meters of the building.",
                "properties": {
                  "input": {
                    "type": "array",
                    "description": "Meters for total energy supplied to the building. MUST contain at least one meter with a > 0 volume.",
                    "items": {
                      "$ref": "#/components/schemas/meter"
                    },
                    "minItems": 1
                  },
                  "output": {
                    "type": "array",
                    "description": "Meters for total energy feed-in of the building (from building back to grid).",
                    "items": {
                      "$ref": "#/components/schemas/meter"
                    }
                  }
                }
              },
              "excludedEnergy": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/meter"
                },
                "description": "Energy from `building.mainMeters.input` which should not count for the usable surfaces provided in `building.surfaces`. Since these excluded meters are subtracted from the meters `building.mainMeters.input`, each excluded meter must have one or more counterparts with the same energyType in `building.mainMeters.input`. The volume of the excluded energy of a certain energyType can never be bigger than the volume of it's counterpart(s) in `building.mainMeters.input`, minus the output meters of the same energyType in `building.mainMeters.output` - you can not exclude more than net input."
              },
              "climateCorrection": {
                "type": "object",
                "description": "Data used to, optionally, normalize for weather influence. Note that if climateCorrection data is provided, then the optional `address` field of `building` MUST also be set, to look up local weather information.",
                "additionalProperties": false,
                "properties": {
                  "heatingEnergy": {
                    "type": "array",
                    "description": "All energy that is used specifically for heating the building. Each heating meter must have one or more counterparts with the same energyType in `building.mainMeters.input`. The volume of the heating energy of a certain energyType can never be bigger than the volume of it's counterpart(s) in `building.mainMeters.input`, minus the output meters of the same energyType in `building.mainMeters.output` and the exluded meters of the same energyType in `building.excludedEnergy` - you can not use more for heating than net input/usage.",
                    "items": {
                      "type": "object",
                      "required": [
                        "energyType",
                        "volume"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "energyType": {
                          "type": "string",
                          "enum": [
                            "Elektriciteit",
                            "Aardgas",
                            "Warmte",
                            "Biomassa",
                            "Waterstof",
                            "Olie",
                            "Propaangas"
                          ],
                          "description": "Type of energy measured"
                        },
                        "volume": {
                          "type": "integer",
                          "description": "Volume of the measured energyType, rounded down to an integer. Expected units (in order of energyType list): kWh, m³, GJ, kg, m³, ltr, ltr.",
                          "minimum": 0
                        }
                      }
                    }
                  },
                  "solarEnergy": {
                    "type": "array",
                    "description": "Generated solar energy by the building. Unit: kWh.",
                    "items": {
                      "type": "integer",
                      "minimum": 0
                    }
                  }
                }
              }
            },
            "description": "The building for which the WEii should be calculated."
          }
        }
      },
      "meter": {
        "type": "object",
        "required": [
          "energyType",
          "volume"
        ],
        "additionalProperties": false,
        "properties": {
          "energyType": {
            "type": "string",
            "enum": [
              "Elektriciteit",
              "Aardgas",
              "Warmte",
              "Koude",
              "Biomassa",
              "Waterstof",
              "Olie",
              "Propaangas"
            ],
            "description": "Type of energy measured."
          },
          "volume": {
            "type": "integer",
            "description": "Volume of the measured energyType, rounded down to an integer. Expected units (in order of energyType list): kWh, m³, GJ, GJ, kg, m³, ltr, ltr.",
            "minimum": 0,
            "example": 1
          }
        }
      },
      "surface": {
        "type": "object",
        "required": [
          "buildingType",
          "usableSurface"
        ],
        "additionalProperties": false,
        "properties": {
          "buildingType": {
            "type": "string",
            "enum": [
              "Restaurant",
              "Café",
              "Kinderopvang",
              "Sauna",
              "Bijeenkomstfunctie overig",
              "Cellengebouw",
              "Ziekenhuis",
              "Tehuis met overnachting",
              "Medische (groeps) praktijk",
              "Opvang zonder overnachting",
              "Bedrijfshal",
              "Koelvrieshuis",
              "Garage/Showroom",
              "Kantoor",
              "Hotel",
              "Vakantiepark",
              "Basis/Voortgezet onderwijs",
              "MBO/HBO/Universiteit",
              "Sportaccommodatie binnen",
              "Sportaccommodatie buiten",
              "Zwembad",
              "Winkel met warenkoeling",
              "Winkel zonder warenkoeling",
              "Enkele woning - appartement",
              "Enkele woning - grondgebonden",
              "Appartementengebouw"
            ]
          },
          "usableSurface": {
            "type": "integer",
            "description": "Usable surface of the building type. Expected unit m².",
            "minimum": 1
          }
        }
      },
      "address": {
        "type": "object",
        "required": [
          "postalCode",
          "houseNumber",
          "street",
          "city"
        ],
        "additionalProperties": false,
        "properties": {
          "postalCode": {
            "type": "string",
            "description": "Valid Dutch postal code with pattern 1234AB.",
            "pattern": "^[1-9][0-9]{3}?[A-Z]{2}$",
            "example": "1234AB"
          },
          "houseNumber": {
            "type": "integer",
            "description": "The integer houseNumber. Any additions to the house number (numerical or non numerical) must be given as a string in `houseNumberSuffix`.",
            "minimum": 1
          },
          "houseNumberSuffix": {
            "type": "string",
            "description": "Optional suffix that comes after the (integer) `houseNumber`. Suffix must always be given as a string, even if it is numeric.",
            "example": "B"
          },
          "street": {
            "type": "string"
          },
          "city": {
            "type": "string"
          }
        }
      }
    }
  }
}
