{ "openapi": "3.0.3", "info": { "title": "UMEI API Specification", "description": "Specification for the API that FMOs, DSOs, and FSPs in the eUniversal project should support. \n\nThe UMEI v1 includes a set of OpenAPI specifications developed by the flexibility market operators NODES and N-SIDE as part of the EUniversal project.\nIn case of further development or modification of the existing specifications, please contact either NODES or N-SIDE.\n\n\n# Glossary and abbreviations\n\n**Activation market:** Flexibility market where the assets are dispatched for the \n period covered by a trade. \n\n**Asset:** In this context, an asset represents a physical or virtual device which \nhas power characteristics that can be controlled, thus providing flexibility. \nTypically, assets are either consumers (e.g. heating systems, factories) or producers\n(e.g. renewable energy sources or traditional power plants), while some assets\n(e.g. batteries) can both produce and consume. \n\n**Baseline:** The forecasted aggregated consumption/production of an asset portfolio (see portfolio) during a defined time period. \n\n**DSO:** Distribution System Operator, the entity responsible for operating a electrical grid. \n\n**Fill-and-kill:** Type of order that is immediately matched. The order is killed and instantly removed after matching, whether it is matched fully, partially or not at all. Available in NODES continuous market. Commonly abbreviated as FaK. Also known as Immediate-or-Cancel (IoC).\n\n**Fill-or-kill:** Type of order that is immediately matched. The order is either matched in full and then killed, or else it is killed and instantly removed. No partial matching is allowed. Available in NODES continuous market. Commonly abbreviated as FoK. \n\n**FlexibilityZone** Set of several portfolios where the DSO defines specific flexibility needs and sensitivities.\nA flexibility zone does not necessarily correspond to a physical zone of the electrical grid.\n\n**FMO:** Flexible Market Operator, the operator of the platform hosting a market on which participants can trade flexibility. \n\n**FSP:** Flexibility Service Provider, an entity offering flexible assets into a market. \n\n**GridNode:** Physical node of the electrical grid to which an asset portfolio is connected and on which \n trading happens.\n\n**Interpolated orders:** Order with a non-uniform price, i.e. instead of having one single price independently of the accepted part of the order, the price is evolving with the quantity accepted. Available on N-Side auction market. \n\n**Limit price:** For buy orders, this is the upper limit of what the buyer is willing to pay. \nFor a sell order, this is the lower limit of what the seller is willing to accept. See \"Market price\". \n\n**Market price:** For buy orders, this means that the buyer will is willing to pay the current market sell price. For sell orders, this means that the seller is willing to sell at the current market buy price. \n\n**MeterReading:** Registration of the actual power consumed/produced by an asset\n\n**Order:** Flexibility order placed on a market. The order can be either “Buy” in case the market participant wants to procure flexibility or “Sell” in case the market participant wants to offer flexibility. \n\n**PayAsBid:** This is a market rule stating that the price at which trade between two orders will occur is the proposed price of the first order placed on the platform. \n\n**PayAsCleared:** This is a market rule stating that the price at which a trade will occur is the one of the market equilibrium (determined by the buy and sell curves). \n\n**Portfolio:** A portfolio represents one or more assets (aggregated) that can participate in a flexibility market, e.g. batteries, dispatchable generators, etc. \n\n**QuantityType:** What is traded on a market / in an order. Possible values are \n*ActivePower*, *ReactivePower*, *Energy*, *Capacity*. \n\n**Reservation Market:** Flexibility market in which participants offer the reservation of their flexibility (possibly weeks or years in advance depending on market rules) before actual dispatching.\nThe actual dispatching can be done outside the market or in a consecutive activation market. \n\n**Trade:** A trade either between two participants of a market, or between one participant \nand the FMO. A trade is always the result of two or more orders being matched. \n\n\n# Categorization of orders\n\nOrders can be categorized along several *axes*. Some categorizations follow \ndirectly from the market, while other can vary between orders with the same market. \n\n\n**QuantityType:** Some orders are for adjusting active power supply, some are for energy etc. \nEach market operates in one quantity type. \n\n**Quantity:** Some orders are can be matched-in-part, and some orders need to be fully \"filled\". This is deduced from the minimumAcceptanceQuantity. Possible categorizations are *Curtailable* (minimumAcceptanceQuantity < Quantity) and *AllOrNothing* (minimumAcceptanceQuantity == Quantity)\n\n**PriceCurve:** Some orders have a fixed price regardless of quantity, while some orders have price depending on quantity bought (using the piecewise linear price curve concept). Possible categorizations are *FixedPrice* or *VariablePrice*.\n\n**Period:** Some orders needs to be matched for the whole period stated in the order \n(e.g. 1300-1800), while other orders can be divided into time-slots and some of them met \n(e.g. buying 1300-1500 of an order that has period 1300-1800). \nPossible categorizations are *SingleSlot* (must match the whole period) \nor *MultiSlot* (one can match/buy parts of the period).\n\n**FillType:** Depending on the fill type, some orders are killed immediately after matching, \nwhile some can remain in the market. \nPossible categorizations are *Normal* (remains in market), *FillOrKill*, *FillAndKill*.\n\n**PriceType:** Some orders have a fixed limit on how high (for buy orders) or low (for sell orders) \nthe price can be. Other orders will buy/sell at the current market price. \nPossible categorizations are: *Limit*, *Market*. \n\n\n# Status of items\n\nEach of the items within an FMO can have different statuses at different stages in their lifecycle. \nNot all status are relevant for all items. Each FMO can have limitations on allowed statuses, \ndepending on entity types and other factors (e.g. market rules). \n\nHowever, each of the statuses have the same meaning across different FMOs: \n\n**Received:** The item has been received but not yet processed. If the response includes a \nlink or id, the status of the item can be polled at a later time. \n\n**Pending:** The item has been received, but is pending approval from an external system, \neither manual or automatic. \n\n**Rejected:** The item has been received and stored, but rejected. The rejection can be \nautomatic or manual, by external partners or by the FMO, and can possibly be revoked. \n\n**Active:** The item is now active in the FMO system. \nNote that for orders in a continuous market, this means that the order in financial terms also \nis referred to as *passive*, meaning that it is lying in the system, \nawaiting possible future matches. \n\n**Inactive:** The item has manually or automatically been marked as not operational. The \nstatus might be changed at a later time. \n\n**Completed:** The item has completed it lifecycle and is no longer active. An example of this \nis an order that has been fully matched. \n\n**Deleted:** The item has been deleted, manually or automatically, and is no longer active. \n\n## Completion Type\n\nIn addition to Status, an extra field (CompletionType) is available for orders. It exposes extra information regarding what caused the order to be completed. The usage is dependent on the FMO and it will not be set for statuses other than Completed.\n\nThe possible values are:\n\n**Filled:** The order has been traded in full.\n\n**Killed:** The order was set up as either FillAndKill or FillOrKill, and was killed after being processed.\n\n**Expired:** The order has come to the end of the period of validity and still had quantity remaining.\n\n**Cancelled:** The order was explicitly cancelled.\n\nAuthentication\n===\n\nAuthentication towards an UMEI-compliant FMO server is performed using a user-provided token. This token should be sent on each request as a \"Bearer\" token in the HTTP headers, like this:\n\n`Authentication: Bearer eyJ...`\n\nHow the token is acquired is not covered by the UMEI specification and is specified by the individual FMO. \n\n\nAuthorization / Access control\n===\n\nEach FMO is required to authorize individual API calls based on the provided authentication. FMOs may have different rules and this is not covered by the UMEI specification. \n\nHowever, each FMO is required to return correct http status codes and error details if the authorization fails, as detailed in the section of error codes. \n\n\n# List of error codes\n\nThis is a non-exhaustive list of error codes. The main purpose is to harmonize error codes between different FMOs, enabling users and code to handle common errors in the same way even when interfacing with different FMOs. \n\nNote that this list is non-exhaustive. FMOs are free to perform additional validations and to provide errors messages with error codes not in this list. However, FMOs are strongly encouraged to re-use existing error codes if possible. \n\nSee the definition of the ProblemDetails object in the OpenAPI documentation for usage, or the problem details RFC: https://datatracker.ietf.org/doc/html/rfc7807\n\n\n### Security related error codes\n\n**Forbidden:** The current user is not authorized to perform the requested operation. Corresponds to http status 403 Forbidden.\n\n**Unauthenticated:** This operation requires a logged-in user, but the request did not specify valid authentication parameters. Corresponds to http status 401 Unauthorized (sic).\n\n\n### Error codes related to invalid request data \n\n**EndpointNotSupported** The requested endpoint is known by the server, but the market platform does not support this method. The 'allow' header field of the response contains a list of methods that the market platform currently supports.\n\n**InconsistentPeriods:** 'periodTo' must be subsequent to 'periodFrom'\n\n**InvalidBaseline** The baseline provided is not valid (input data validation error)\n\n**InvalidFlexibilityZone** The flexibility zone provided is not valid (input data validation error)\n\n**InvalidGridNode:** The given grid node does not exist, is not available for the current user, or is otherwise not available for the given order\n\n**InvalidLongflexContractId:** The given longflex contract does not exist, or is not available for the current user\n\n**InvalidMarket** The given market does not exist, is not available for the current user, or is otherwise not available for the given order\n\n**InvalidMeterReading** The meter reading provided is not valid (input data validation error)\n\n**InvalidOrder** The order provided is not valid (input data validation error)\n\n**InvalidPortfolio:** The given portfolio is not valid (input data validation error), does not exist, or is not available for the current user\n\n**InvalidStatus:** The status specified is not valid for the item selected\n\n**MarketClosed:** The market is not open for trading for the period specified in the order\n\n**MarketNotYetOpen:** The market has not yet opened for trading for the period specified in the order\n\n**NonUpdatablePortfolio:** The portfolio can not be updated\n\n**NonZeroFirstQuantity:** The quantity of the first 'QuantityPricePoint' of an interpolated order must always be zero\n\n**ResourceNotFound** The resource identified by the path parameter does not exist or the logged-in user does not have sufficient privileges.\n\n\n\n", "version": "1.0.0" }, "servers": [ { "url": "https://localhost:8080" } ], "paths": { "/Portfolios": { "get": { "tags": [ "Portfolio" ], "summary": "List or search one or several Portfolio(s) using a query", "operationId": "Portfolio_Search", "parameters": [ { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/flexibilityZoneId" }, { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" } ], "responses": { "200": { "description": "Portfolio(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PortfolioSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "post": { "tags": [ "Portfolio" ], "summary": "Create a Portfolio", "operationId": "Portfolio_Create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "responses": { "201": { "description": "Portfolio successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/Portfolios/{id}": { "get": { "tags": [ "Portfolio" ], "summary": "Get an existing Portfolio by id", "operationId": "Portfolio_GetById", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "200": { "description": "Portfolio successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "put": { "tags": [ "Portfolio" ], "summary": "Update an existing Portfolio, or create if missing", "operationId": "Portfolio_Update", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "responses": { "200": { "description": "Portfolios successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "201": { "description": "Portfolios successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "patch": { "tags": [ "Portfolio" ], "summary": "Patch / partially update an existing Portfolio", "operationId": "Portfolio_Patch", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "responses": { "200": { "description": "Portfolio successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Portfolio" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "delete": { "tags": [ "Portfolio" ], "summary": "Delete/Remove an existing Portfolio", "operationId": "Portfolio_Delete", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "204": { "description": "Portfolio successfully deleted" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/Markets": { "get": { "tags": [ "Market" ], "summary": "List all Markets", "operationId": "Market_List", "responses": { "200": { "description": "Market(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarketSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/BaselineIntervals": { "get": { "tags": [ "BaselineInterval" ], "summary": "List or search one or several BaselineInterval(s) using a query", "operationId": "BaselineInterval_Search", "parameters": [ { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "200": { "description": "BaselineInterval(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineIntervalSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "post": { "tags": [ "BaselineInterval" ], "summary": "Create a BaselineInterval", "operationId": "BaselineInterval_Create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "responses": { "201": { "description": "BaselineInterval successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/BaselineIntervals/{id}": { "get": { "tags": [ "BaselineInterval" ], "summary": "Get an existing BaselineInterval by id", "operationId": "BaselineInterval_GetById", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "200": { "description": "BaselineInterval successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "put": { "tags": [ "BaselineInterval" ], "summary": "Update an existing BaselineInterval, or create if missing", "operationId": "BaselineInterval_Update", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "responses": { "200": { "description": "BaselineInterval successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "201": { "description": "BaselineInterval successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "patch": { "tags": [ "BaselineInterval" ], "summary": "Patch / partially update an existing BaselineInterval", "operationId": "BaselineInterval_Patch", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "responses": { "200": { "description": "BaselineInterval successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BaseLineInterval" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "delete": { "tags": [ "BaselineInterval" ], "summary": "Delete/Remove an existing BaselineInterval", "operationId": "BaselineInterval_Delete", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "204": { "description": "BaselineInterval successfully deleted" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/BaselineIntervals/import": { "post": { "tags": [ "BaselineInterval" ], "summary": "Import (update or create) multiple BaselineIntervals", "operationId": "BaselineIntervals_Import", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "type": "array", "items": { "type": "string", "format": "binary" }, "nullable": true } } }, "encoding": { "file": { "style": "form" } } } } }, "responses": { "204": { "description": "Baseline intervals successfully imported and created and/or updated" }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/MeterReadings/{id}": { "get": { "tags": [ "MeterReading" ], "summary": "Get an existing MeterReading by id", "operationId": "MeterReading_GetById", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "200": { "description": "MeterReading successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "put": { "tags": [ "MeterReading" ], "summary": "Update an existing MeterReading, or create if missing", "operationId": "MeterReading_Update", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "responses": { "200": { "description": "MeterReading successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "201": { "description": "MeterReading successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "patch": { "tags": [ "MeterReading" ], "summary": "Patch / partially update an existing MeterReading", "operationId": "MeterReading_Patch", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "responses": { "200": { "description": "MeterReading successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "delete": { "tags": [ "MeterReading" ], "summary": "Delete/Remove an existing MeterReading", "operationId": "MeterReading_Delete_By_ID", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "204": { "description": "MeterReading successfully deleted" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/MeterReadings": { "post": { "tags": [ "MeterReading" ], "summary": "Create a MeterReading", "operationId": "MeterReading_Create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "responses": { "201": { "description": "MeterReading successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReading" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "delete": { "tags": [ "MeterReading" ], "summary": "Delete/Remove one or several existing MeterReading(s) using a query", "operationId": "MeterReading_Delete_By_Query", "parameters": [ { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "204": { "description": "MeterReading(s) successfully deleted" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" } } }, "get": { "tags": [ "MeterReading" ], "summary": "List or search one or several MeterReading(s) using a query", "operationId": "MeterReading_Search", "parameters": [ { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "200": { "description": "MeterReading(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeterReadingSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/MeterReadings/create-multiple": { "post": { "tags": [ "MeterReading" ], "summary": "Create and/or update several MeterReadings", "operationId": "MeterReading_CreateMultiple", "requestBody": { "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/MeterReading" }, "nullable": true } } } }, "responses": { "204": { "description": "MeterReadings successfully created and/or updated" }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/MeterReadings/import": { "post": { "tags": [ "MeterReading" ], "summary": "Import (update or create) multiple MeterReadings", "operationId": "MeterReading_Import", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "type": "array", "items": { "type": "string", "format": "binary" }, "nullable": true } } }, "encoding": { "file": { "style": "form" } } } } }, "responses": { "204": { "description": "MeterReadings successfully imported and created and/or updated" }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/PublicOrders": { "get": { "tags": [ "Order" ], "summary": "View publicly available order information", "description": "This endpoint returns information about publicly visible flexibility orders. Publicly visible orders may contain less details then the information in an organizations own orders, in which case some fields will be empty. Different FMOs and different markets may have different rules regarding which information is publicly available. Each 'Order' returned in this endpoint represents either a single order, or multiple orders that have been aggregated together. ", "operationId": "PublicOrder_Search", "parameters": [ { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/flexibilityZoneId" }, { "$ref": "#/components/parameters/marketId" }, { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/ownerOrganizationId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/completionType" }, { "$ref": "#/components/parameters/side" }, { "$ref": "#/components/parameters/regulationType" }, { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "200": { "description": "Order(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/Orders": { "get": { "tags": [ "Order" ], "summary": "List or search Order(s) using a query", "description": "This endpoint returns your organization's orders, and possibly other orders which you have full access to. Use the /PublicOrders endpoint to get a (possibly limited) view of all publicly visible orders. ", "operationId": "Order_Search", "parameters": [ { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/flexibilityZoneId" }, { "$ref": "#/components/parameters/marketId" }, { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/ownerOrganizationId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/completionType" }, { "$ref": "#/components/parameters/side" }, { "$ref": "#/components/parameters/regulationType" }, { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "200": { "description": "Order(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "post": { "tags": [ "Order" ], "summary": "Create an Order", "operationId": "Order_Create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "responses": { "201": { "description": "Order successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/Orders/{id}": { "get": { "tags": [ "Order" ], "summary": "Get an existing Order by id", "operationId": "Order_GetById", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "200": { "description": "Order successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "put": { "tags": [ "Order" ], "summary": "Update an existing Order, or create if missing", "operationId": "Order_Update", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "responses": { "200": { "description": "Order successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "201": { "description": "Order successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "patch": { "tags": [ "Order" ], "summary": "Patch / partially update an existing Order", "operationId": "Order_Patch", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "responses": { "200": { "description": "Order successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Order" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "delete": { "tags": [ "Order" ], "summary": "Delete/Remove an existing Order", "operationId": "Order_Delete", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "204": { "description": "Order successfully deleted" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/Trades": { "get": { "tags": [ "Trade" ], "summary": "List or search one or several Trade(s) using a query", "operationId": "Trade_Search", "parameters": [ { "$ref": "#/components/parameters/orderId" }, { "$ref": "#/components/parameters/gridNodeId" }, { "$ref": "#/components/parameters/flexibilityZoneId" }, { "$ref": "#/components/parameters/marketId" }, { "$ref": "#/components/parameters/portfolioId" }, { "$ref": "#/components/parameters/status" }, { "$ref": "#/components/parameters/side" }, { "$ref": "#/components/parameters/regulationType" }, { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "200": { "description": "Trade(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TradeSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/FlexibilityZones": { "get": { "tags": [ "FlexibilityZone" ], "summary": "List or search one or several flexibility zone(s) using a query", "operationId": "FlexibilityZone_Search", "parameters": [ { "$ref": "#/components/parameters/take" }, { "$ref": "#/components/parameters/skip" }, { "$ref": "#/components/parameters/orderBy" }, { "$ref": "#/components/parameters/periodFrom" }, { "$ref": "#/components/parameters/periodFrom.lt" }, { "$ref": "#/components/parameters/periodFrom.lte" }, { "$ref": "#/components/parameters/periodFrom.gt" }, { "$ref": "#/components/parameters/periodFrom.gte" }, { "$ref": "#/components/parameters/periodTo" }, { "$ref": "#/components/parameters/periodTo.lt" }, { "$ref": "#/components/parameters/periodTo.lte" }, { "$ref": "#/components/parameters/periodTo.gt" }, { "$ref": "#/components/parameters/periodTo.gte" } ], "responses": { "200": { "description": "Flexibility zone(s) successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZoneSearchResult" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "post": { "tags": [ "FlexibilityZone" ], "summary": "Create a new flexibility zone", "operationId": "FlexibilityZone_Create", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "responses": { "201": { "description": "Flexibility zone successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } }, "/FlexibilityZones/{id}": { "get": { "tags": [ "FlexibilityZone" ], "summary": "Get an existing flexibility zone by id", "operationId": "FlexibilityZone_GetById", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "200": { "description": "Flexibility zone successfully returned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "put": { "tags": [ "FlexibilityZone" ], "summary": "Update an existing flexibility zone, or create if missing", "operationId": "FlexibilityZone_Update", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "responses": { "200": { "description": "Flexibility zone successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "201": { "description": "Flexibility zone successfully created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "patch": { "tags": [ "FlexibilityZone" ], "summary": "Patch / partially update an existing flexibility zone", "operationId": "FlexibilityZone_Patch", "parameters": [ { "$ref": "#/components/parameters/id" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "responses": { "200": { "description": "Flexibility zone successfully updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FlexibilityZone" } } } }, "400": { "$ref": "#/components/responses/ValidationError" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } }, "delete": { "tags": [ "FlexibilityZone" ], "summary": "Delete/Remove an existing flexibility zone", "operationId": "FlexibilityZone_Delete", "parameters": [ { "$ref": "#/components/parameters/id" } ], "responses": { "204": { "description": "Flexibility zone successfully deleted" }, "401": { "$ref": "#/components/responses/UnauthenticatedError" }, "403": { "$ref": "#/components/responses/ForbiddenError" }, "404": { "$ref": "#/components/responses/ResourceNotFoundError" }, "405": { "$ref": "#/components/responses/EndpointNotSupportedError" } } } } }, "components": { "responses": { "ValidationError": { "description": "The server cannot or will not process the request due to something that is perceived to be a client error", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "UnauthenticatedError": { "description": "Lack of valid authentication credentials for the requested resource", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "ForbiddenError": { "description": "The server understands the request but refuses to authorize it (insufficient rights to a resource)", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "ResourceNotFoundError": { "description": "The server has not found anything matching the request URL", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } }, "EndpointNotSupportedError": { "description": "The requested endpoint is known by the server, but the market platform does not support this method.", "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/ProblemDetails" } } } } }, "parameters": { "id": { "name": "id", "description": "The id of the item", "in": "path", "required": true, "schema": { "type": "string" } }, "take": { "name": "take", "in": "query", "description": "Number of hits to return. If client does not specify Take the server MAY apply a default Take value (which will be returned in the SearchResult object). The default value is not guaranteed to be the same for different requests\"", "schema": { "type": "integer", "format": "int32" } }, "skip": { "name": "skip", "description": "Skip the specified number of hits, used when paging", "in": "query", "schema": { "type": "integer", "format": "int32" } }, "orderBy": { "name": "orderBy", "description": "Order the hits by the specified property. Legal values will depend on the FMO implementation but as a minimum the same properties that can be used for filtering can be used for sorting. ", "in": "query", "schema": { "type": "array", "items": { "type": "string" }, "nullable": true } }, "status": { "name": "status", "in": "query", "description": "Search by status", "schema": { "type": "string", "enum": [ "Received", "Pending", "Rejected", "Active", "Inactive", "Completed", "Deleted" ], "nullable": true } }, "completionType": { "name": "completionType", "in": "query", "description": "Search by completion type", "schema": { "type": "string", "enum": [ "Filled", "Killed", "Expired", "Cancelled" ], "nullable": true } }, "side": { "name": "side", "in": "query", "description": "Search by order side", "schema": { "type": "string", "enum": [ "Buy", "Sell" ], "nullable": true } }, "regulationType": { "name": "regulationType", "in": "query", "description": "Search by regulationType", "schema": { "type": "string", "enum": [ "Up", "Down" ], "nullable": true } }, "portfolioId": { "name": "portfolioId", "description": "Search by portfolio id", "in": "query", "schema": { "type": "string", "nullable": true } }, "ownerOrganizationId": { "name": "ownerOrganizationId", "description": "Search by ownerOrganizationId. This search parameter might be optional, unsupported or mandatory, depending on the FMO. An error message will be returned if the parameter is specified but unsupported, or if the parameter is unspecified but mandatory, or if the parameter is supported and specified but with an invalid value (e.g. an organization you do not have permission to view). ", "in": "query", "schema": { "type": "string", "nullable": true } }, "gridNodeId": { "name": "gridNodeId", "description": "Search by grid node id", "in": "query", "schema": { "type": "string", "nullable": true } }, "flexibilityZoneId": { "name": "flexibilityZoneId", "description": "Search by flexibility zone id", "in": "query", "schema": { "type": "string", "nullable": true } }, "baselineId": { "name": "baselineId", "description": "Search by baseline id", "in": "query", "schema": { "type": "string", "nullable": true } }, "meterReadingId": { "name": "meterReadingId", "description": "Search by measurement id", "in": "query", "schema": { "type": "string", "nullable": true } }, "orderId": { "name": "orderId", "description": "Search by order id", "in": "query", "schema": { "type": "string", "nullable": true } }, "marketId": { "name": "marketId", "description": "Search by market id", "in": "query", "schema": { "type": "string", "nullable": true } }, "periodFrom": { "name": "periodFrom", "description": "Specify the \"periodFrom\" by exact match (with a resolution of one second)", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodFrom.gt": { "name": "periodFrom.gt", "description": "If specified, only return entries with a \"periodFrom\" that is greater (later) than this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodFrom.gte": { "name": "periodFrom.gte", "description": "If specified, only return entries with a \"periodFrom\" that is equal to (with a resolution of one second) or greater (later) than this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodFrom.lt": { "name": "periodFrom.lt", "description": "If specified, only return entries with a \"periodFrom\" smaller (earlier) than this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodFrom.lte": { "name": "periodFrom.lte", "description": "If specified, only return entries with a \"periodFrom\" smaller (earlier) than or equal to (with a resolution of one second) this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodTo": { "name": "periodTo", "description": "Specify the \"periodTo\" by exact match (with a resolution of one second)", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodTo.gt": { "name": "periodTo.gt", "description": "If specified, only return entries with a \"periodTo\" that is greater (later) than this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodTo.gte": { "name": "periodTo.gte", "description": "If specified, only return entries with a \"periodTo\" that is equal to (with a resolution of one second) or greater (later) than this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodTo.lt": { "name": "periodTo.lt", "description": "If specified, only return entries with a \"periodTo\" smaller (earlier) than this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } }, "periodTo.lte": { "name": "periodTo.lte", "description": "If specified, only return entries with a \"periodTo\" smaller (earlier) than or equal to (with a resolution of one second) this specified value. ", "in": "query", "schema": { "$ref": "#/components/schemas/TimeStamp" } } }, "schemas": { "QuantityType": { "type": "string", "enum": [ "ActivePower", "ReactivePower", "Energy", "Capacity" ], "description": "The type of quantity which this is traded in this market. Each market can operate in only one type of quantity. ", "nullable": false }, "Quantity": { "type": "number", "description": "Average production/consumption in the given period. The unit is deduced from the quantity type. A positive value corresponds to production and a negative value represents consumption.", "format": "double", "minimum": -1000000, "maximum": 1000000, "multipleOf": 0.001, "nullable": true }, "TimeStamp": { "type": "string", "description": "A timestamp, with a resolution of seconds, in ISO-8601 format with Z (preferred), timezone identifier or offset", "format": "date-time", "nullable": true }, "PeriodFrom": { "type": "string", "description": "The timestamp indicating the start of the interval for which this item applies, with a resolution of seconds, in ISO-8601 format with Z (preferred), timezone identifier or offset", "format": "date-time", "nullable": false }, "PeriodTo": { "type": "string", "description": "The timestamp indicating the end of the interval for which this item applies, with a resolution of seconds, in ISO-8601 format with Z (preferred), timezone identifier or offset", "format": "date-time", "nullable": false }, "OwnerOrganizationId": { "type": "string", "description": "Which organization this item is owned by" }, "Link": { "type": "object", "properties": { "rel": { "type": "string", "nullable": true }, "title": { "type": "string", "nullable": true }, "href": { "type": "string", "nullable": true }, "method": { "type": "string", "nullable": true } } }, "BaseLineInterval": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the baseline (should be unique)", "nullable": false }, "status": { "enum": [ "Received", "Pending", "Rejected", "Active", "Inactive", "Completed", "Deleted" ], "type": "string", "description": "Status for this baseline", "nullable": false }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": false, "readOnly": true }, "portfolioId": { "type": "string", "description": "The portfolio for which this baseline applies. An error will be returned if this portfolio does not exist.", "nullable": false }, "periodFrom": { "$ref": "#/components/schemas/PeriodFrom" }, "periodTo": { "$ref": "#/components/schemas/PeriodTo" }, "quantity": { "$ref": "#/components/schemas/Quantity" }, "quantityType": { "$ref": "#/components/schemas/QuantityType", "description": "The type of quantity this baseline applies to" } }, "description": "Baseline of a portfolio for a time interval. \r\nA baseline covers a fixed interval in time, e.g. one minute from 15:00 to 15:01 on a specific date. Dates are always UTC and should always be sent and parsed as ISO-8856-1 with the UTC time zone reference, 'Z', to avoid ambiguity." }, "BaseLineIntervalSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/BaseLineInterval" }, "nullable": false }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": false, "readOnly": true } } }, "Portfolio": { "type": "object", "description": "A portfolio represents one or more assets that can participate in a flexibility market, e.g. batteries, dispatchable generators etc", "properties": { "id": { "type": "string", "description": "Id of the portfolio (should be unique)", "nullable": true }, "status": { "enum": [ "Received", "Pending", "Rejected", "Active", "Inactive", "Completed", "Deleted" ], "type": "string", "description": "Status for this portfolio", "nullable": true }, "name": { "type": "string", "description": "Name of the portfolio", "nullable": false }, "gridNodeId": { "type": "string", "description": "Id of the grid node where the assets are located. An error will be returned if this node does not exist in the grid.", "nullable": true }, "ownerOrganizationId": { "$ref": "#/components/schemas/OwnerOrganizationId" } } }, "PortfolioSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Portfolio" }, "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "Market": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the market. This id will be used to define to which market an order belongs.", "nullable": false }, "name": { "type": "string", "description": "The name of the market", "nullable": true }, "description": { "type": "string", "description": "A small description of the market", "nullable": true }, "quantityType": { "$ref": "#/components/schemas/QuantityType", "description": "The type of quantity which this is traded in this market. Each market can operate in only one type of quantity. " } } }, "MarketSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Market" }, "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "MeterReading": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the measurement (should be unique)", "nullable": true }, "status": { "enum": [ "Received", "Pending", "Rejected", "Active", "Inactive", "Completed", "Deleted" ], "type": "string", "description": "Status for this measurement", "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true }, "portfolioId": { "type": "string", "description": "The portfolio for which this measurement applies. An error will be returned if this portfolio does not exist.", "nullable": true }, "periodFrom": { "$ref": "#/components/schemas/PeriodFrom" }, "periodTo": { "$ref": "#/components/schemas/PeriodTo" }, "quantity": { "$ref": "#/components/schemas/Quantity" }, "quantityType": { "$ref": "#/components/schemas/QuantityType", "description": "The type of quantity this measurement refers to. " } }, "description": "Quantity measured for a portfolio for a time interval. \r\nA measurement covers a fixed interval in time, e.g. one minute from 15:00 to 15:01 on a specific date. Dates are always UTC and should always be sent and parsed as ISO-8856-1 with the UTC time zone reference, 'Z', to avoid ambiguity." }, "MeterReadingSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/MeterReading" }, "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "Order": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the order (should be unique)", "nullable": true }, "ownerOrganizationId": { "$ref": "#/components/schemas/OwnerOrganizationId" }, "status": { "enum": [ "Received", "Pending", "Rejected", "Active", "Inactive", "Completed", "Deleted" ], "type": "string", "description": "Status of the order", "nullable": true }, "completionType": { "enum": [ "Filled", "Killed", "Expired", "Cancelled" ], "type": "string", "description": "Completion type of the order. When the status of the order is Completed, it gives extra information regarding how it completed.", "nullable": true }, "gridNodeId": { "type": "string", "description": "The grid node this order applies to. An error will be returned if this grid node does not exist.", "nullable": true }, "flexibilityZoneId": { "type": "string", "description": "The flexibility zone this order applies to. An error will be returned if this flexibility zone does not exist.", "nullable": true }, "marketId": { "type": "string", "description": "Reference to the market. An error will be returned if this market does not exist.", "nullable": true }, "portfolioId": { "type": "string", "description": "The portfolio for which this order applies. Required for sell orders only (an error will be returned if this portfolio does not exist). Not updatable.", "nullable": true }, "regulationType": { "enum": [ "Up", "Down" ], "type": "string", "description": "Type of regulation of the order. 'Up' means an increase in available quantity (either increased production or reduced consumption) and 'Down' means a decrease in available quantity (either reduced production or increased consumption).", "nullable": true }, "side": { "enum": [ "Sell", "Buy" ], "type": "string", "description": "Type of submission of the order (buy / sell)", "nullable": false }, "pricePoints": { "type": "array", "description": "The array of quantity-price points of the order. If the order is a fixed-price order (meaning that the price is uniform/constant whatever the quantity) then the array will contain only one value. On the other hand, the array will contain several values if the order is an interpolated order (meaning that different prices will be defined for different quantities). In that case, the first quantity must always be zero.", "items": { "$ref": "#/components/schemas/QuantityPricePoint" }, "minItems": 1, "nullable": true }, "minimumAcceptanceQuantity": { "type": "number", "description": "The minimum quantity that should be traded/filled in the order.", "format": "double", "nullable": true }, "periodFrom": { "$ref": "#/components/schemas/PeriodFrom" }, "periodTo": { "$ref": "#/components/schemas/PeriodTo" }, "longflexContractId": { "type": "string", "description": "A reference to the corresponding longflex contract, if this order is part of or based on a longflex contract", "nullable": true } }, "description": "Order defining a quantity submitted (sell or buy) on a market (defined by a market id) for a given time interval, the type of quantity (i.e. power, energy, ...) being deduced from the market. The portfolio id is required for sell orders. The grid node id is required only for sell orders and buy orders unless it can be derived from the portfolio. The portfolio id and the grid node id are not required if flexibility zones are created by the DSO, but in that case the flexibility zone id is required instead. The order can either be a fixed-price order (i.e. order with uniform/constant price that can be traded/filled only with a minimum quantity) or an interpolated order (i.e. order described by a piecewise linear function described by a list of price-points (prices and quantities). " }, "FlexibilityZone": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the flexibility zone (should be unique)", "nullable": true }, "flexibilityNeed": { "type": "number", "description": "An amount of quantity needed in the zone, the type of quantity (i.e. power, energy, ...) being deduced from the market. For both quantities the unit is MW.", "format": "double", "nullable": true }, "periodFrom": { "$ref": "#/components/schemas/PeriodFrom" }, "periodTo": { "$ref": "#/components/schemas/PeriodTo" }, "portfolioIds": { "type": "array", "description": "The list of ids of the portfolios contained in the flexibility zone", "items": { "type": "string", "description": "Id of a portfolio contained in the flexibility zone", "nullable": false }, "nullable": true } }, "description": "Flexibility zone defined by a flexibility need, a time period and a list of portfolios" }, "QuantityPricePoint": { "type": "object", "description": "A price-quantity-point of an order. A non-empty set of quantity-price-points describes a piecewise linear mapping from quantity to price. ", "properties": { "quantity": { "type": "number", "description": "An amount of quantity offered/bid in the order, the type of quantity (i.e. power, energy, ...) being deduced from the market. For both quantities the unit is MW. \r\n\r\nFor power, it denotes the max (in absolute terms) power\r\nconsumption/production in MW during the specified period.\r\n \r\nFor energy, it denotes the energy available during the specified period. The unit is still MW, thus the length of the interval needs to be taken into account to calculate the actual energy consumption/production.", "format": "double", "nullable": false }, "unitPrice": { "type": "number", "description": "The price per unit (currency/MWh) for the quantity offered/bid in the order, the currency being deduced from the market.", "format": "double", "nullable": false } } }, "OrderSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Order" }, "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "FlexibilityZoneSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/FlexibilityZone" }, "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "Trade": { "type": "object", "properties": { "id": { "type": "string", "description": "Id of the trade (should be unique)", "nullable": true }, "ownerOrganizationId": { "$ref": "#/components/schemas/OwnerOrganizationId" }, "status": { "enum": [ "Received", "Pending", "Rejected", "Active", "Inactive", "Completed", "Deleted" ], "type": "string", "description": "Status for this trade", "nullable": true }, "marketId": { "type": "string", "description": "Reference to the market.", "nullable": true }, "orderId": { "type": "string", "description": "Reference to the order.", "nullable": true }, "quantity": { "$ref": "#/components/schemas/Quantity" }, "side": { "enum": [ "Buy", "Sell" ], "type": "string", "description": "Type of the trade (buy / sell)", "nullable": true }, "unitPrice": { "type": "number", "description": "Price at which the quantity has been traded/filled", "format": "double", "nullable": true }, "periodFrom": { "$ref": "#/components/schemas/PeriodFrom" }, "periodTo": { "$ref": "#/components/schemas/PeriodTo" }, "gridNodeId": { "type": "string", "description": "Reference to the grid node.", "nullable": true }, "flexibilityZoneId": { "type": "string", "description": "Reference to the flexibility zone.", "nullable": true }, "portfolioId": { "type": "string", "description": "Reference to the portfolio.", "nullable": true }, "regulationType": { "enum": [ "Up", "Down" ], "type": "string", "description": "Type of regulation of the trade. 'Up' means an increase in available quantity (either increased production or reduced consumption) and 'Down' means an decrease in available quantity (either reduced production or increased consumption). ", "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "TradeSearchResult": { "type": "object", "properties": { "numberOfHits": { "type": "integer", "format": "int32", "nullable": true }, "items": { "type": "array", "items": { "$ref": "#/components/schemas/Trade" }, "nullable": true }, "links": { "type": "array", "items": { "$ref": "#/components/schemas/Link" }, "nullable": true, "readOnly": true } } }, "ProblemDetails": { "type": "object", "description": "An object describing the problem in a machine-and-user readable version, based on / extending RFC7807. ", "properties": { "type": { "type": "string", "description": "A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when de-referenced, it provide human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\"", "nullable": false, "example": "https://umei.org/error-codes/InvalidGridNode" }, "title": { "type": "string", "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation;", "example": "The grid node id is not found or not valid for this operation" }, "status": { "type": "string", "description": "The HTTP status code generated by the origin server for this occurrence of the problem. ", "example": "400", "nullable": true }, "detail": { "type": "string", "description": "A human-readable explanation specific to this occurrence of the problem.", "example": "Grid node #231432 MyGridNode is not participating in this market" }, "instance": { "type": "string", "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if de-referenced.", "example": "https://my-fmo.eu/error-instances/4232312" }, "validation-errors": { "type": "array", "description": "If present, contains a list of invalid parameters that the client should correct before retrying the operation", "items": { "$ref": "#/components/schemas/ValidationError" } } } }, "ValidationError": { "type": "object", "description": "Reference to a field that failed validation along with an description of the validation error", "properties": { "property": { "type": "string", "description": "The name of the property, specified as a relative or absolute json path, e.g. 'marketId' or 'quantities[1].quantity'", "nullable": false, "example": "gridNodeId" }, "message": { "type": "string", "description": "Description of the issue with this property", "example": "The specified grid node is not participating in this market", "nullable": false }, "value": { "type": "string", "description": "Value received as input for this property", "example": "231432", "nullable": true } } } } } }