{ "openapi": "3.1.0", "info": { "title": "MIRO Server API", "description": "REST API for managing MIRO apps and scenario data", "version": "1.0.0" }, "paths": { "/configuration/": { "get": { "tags": [ "configuration" ], "summary": "Get MIRO Server configuration information", "description": "Return configuration information of MIRO Server instance\n\n- **version**: Version of GAMS MIRO Server\n- **authentication_mode**: Authentication mode (engine or oidc)", "operationId": "get_configuration_configuration__get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConfigurationResponse" } } } }, "500": { "description": "Internal Server Error" } } } }, "/apps/": { "get": { "tags": [ "apps" ], "summary": "Get all visible MIRO apps", "description": "Get all apps registered for one of your user groups and their metadata.\n\nAn app object contains the following fields:\n\n- **id**: The unique identifier of the app\n- **display_name**: The name of the app as it appears in the library\n- **description**: The description of the app as it appears in the library\n- **version**: The app's version info (if specified)\n- **authors**: The app's authors (if specified)\n- **environment**: The app's environment (if specified)\n- **access_groups**: The user groups that can see this app. If no user groups are assigned (empty array), anyone with access to the MIRO Server instance can see the app. Displays only subset of user groups of which the logged in user is a member.", "operationId": "get_apps_apps__get", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "maximum": 10000000.0, "minimum": 1, "description": "Pagination: The page number to return (offset)", "default": 1, "title": "Page" }, "description": "Pagination: The page number to return (offset)" }, { "name": "per_page", "in": "query", "required": false, "schema": { "type": "integer", "maximum": 100, "minimum": 1, "description": "Pagination: Number of items to return per page", "default": 20, "title": "Per Page" }, "description": "Pagination: Number of items to return per page" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AppConfigOutput" }, "title": "Response Get Apps Apps Get" } } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "message": "Not found", "description": "Not Found" }, "500": { "description": "Internal Server Error" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "post": { "tags": [ "apps" ], "summary": "Add new MIRO app", "description": "Add a new MIRO app (requires write permissions on namespace).", "operationId": "add_app_apps__post", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/Body_add_app_apps__post" } } } }, "responses": { "201": { "description": "App successfully added", "content": { "application/json": { "schema": {} } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "message": "Not found", "description": "Not Found" }, "500": { "description": "Internal Server Error" }, "400": { "description": "You cannot add an app with this ID" }, "409": { "description": "An app with this id already exists" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/apps/{app_id}": { "put": { "tags": [ "apps" ], "summary": "Update an existing MIRO app", "description": "Update a MIRO app (requires write permissions on namespace).\n\nThe app as well as its metadata will be overwritten. This means that you should specify all parameters.\nFor example, if you do not specify `access_groups`, no access groups will be assigned to the app.\nThis will result in it being visible to everyone.", "operationId": "update_app_apps__app_id__put", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 60, "description": "The ID of the app to update.", "title": "App Id" }, "description": "The ID of the app to update." } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/Body_update_app_apps__app_id__put" } } } }, "responses": { "200": { "description": "App successfully updated", "content": { "application/json": { "schema": {} } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "description": "An app with this ID does not exist" }, "500": { "description": "Internal Server Error" }, "400": { "description": "You cannot update an app with this ID" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "delete": { "tags": [ "apps" ], "summary": "Remove an existing MIRO app", "description": "Remove an existing MIRO app (requires write permissions on namespace).", "operationId": "delete_app_apps__app_id__delete", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 60, "description": "The ID of the app to delete.", "title": "App Id" }, "description": "The ID of the app to delete." }, { "name": "delete_data", "in": "query", "required": false, "schema": { "type": "boolean", "description": "Whether to delete all scenario data of this app.", "default": false, "title": "Delete Data" }, "description": "Whether to delete all scenario data of this app." } ], "responses": { "200": { "description": "App successfully deleted", "content": { "application/json": { "schema": {} } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "description": "An app with this ID does not exist" }, "500": { "description": "Internal Server Error" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/scenarios/{app_id}/": { "get": { "tags": [ "scenarios" ], "summary": "Get list of all visible scenarios", "description": "Get scenarios for this app that are visible to you.\n\nA scenario object contains the following fields:\n\n- **name**: The name of the scenario\n- **owner**: The owner of this scenario\n- **tags**: The tags of the scenario\n- **last_modified**: The timestamp when the scenario was last modified\n- **read_perm**: Array of users/groups that have permissions to read the scenario data (groups are indicated by a leading hash `#`)\n- **write_perm**: Array of users/groups that have permissions to modify the scenario data (groups are indicated by a leading hash `#`)\n- **exec_perm**: Array of users/groups that have permissions to execute the scenario (groups are indicated by a leading hash `#`)", "operationId": "get_scenario_list_scenarios__app_id___get", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 60, "description": "The ID of the app whose data you want to operate on.", "title": "App Id" }, "description": "The ID of the app whose data you want to operate on." }, { "name": "page", "in": "query", "required": false, "schema": { "type": "integer", "maximum": 10000000.0, "minimum": 1, "description": "Pagination: The page number to return (offset)", "default": 1, "title": "Page" }, "description": "Pagination: The page number to return (offset)" }, { "name": "per_page", "in": "query", "required": false, "schema": { "type": "integer", "maximum": 100, "minimum": 1, "description": "Pagination: Number of items to return per page", "default": 20, "title": "Per Page" }, "description": "Pagination: Number of items to return per page" } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ScenarioConfig" }, "title": "Response Get Scenario List Scenarios App Id Get" } } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "message": "Not found", "description": "Not Found" }, "500": { "description": "Internal Server Error" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "delete": { "tags": [ "scenarios" ], "summary": "Delete an existing scenario", "description": "Delete an existing scenario.", "operationId": "delete_scenario_scenarios__app_id___delete", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 60, "description": "The ID of the app whose data you want to operate on.", "title": "App Id" }, "description": "The ID of the app whose data you want to operate on." }, { "name": "name", "in": "query", "required": true, "schema": { "type": "string", "maxLength": 63, "description": "The name of the scenario you want to download.", "title": "Name" }, "description": "The name of the scenario you want to download." }, { "name": "owner", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string", "maxLength": 70 }, { "type": "null" } ], "description": "The owner of the scenario you want to download (by default, the logged in user).", "title": "Owner" }, "description": "The owner of the scenario you want to download (by default, the logged in user)." } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "description": "A scenario with this name does not exist" }, "500": { "description": "Internal Server Error" }, "201": { "description": "Scenario successfully deleted" }, "423": { "description": "The scenario is locked and cannot be deleted" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } }, "post": { "tags": [ "scenarios" ], "summary": "Add a new scenario", "description": "Add a new scenario.", "operationId": "add_scenario_scenarios__app_id___post", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 60, "description": "The ID of the app whose data you want to operate on.", "title": "App Id" }, "description": "The ID of the app whose data you want to operate on." } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/Body_add_scenario_scenarios__app_id___post" } } } }, "responses": { "201": { "description": "Scenario successfully added", "content": { "application/json": { "schema": {} } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "message": "Not found", "description": "Not Found" }, "500": { "description": "Internal Server Error" }, "409": { "description": "A scenario with this name already exists" }, "423": { "description": "The scenario is locked and cannot be overwritten" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/scenarios/{app_id}/download": { "get": { "tags": [ "scenarios" ], "summary": "Download a scenario", "description": "Download a scenario.", "operationId": "download_scenario_scenarios__app_id__download_get", "security": [ { "HTTPBasic": [] }, { "HTTPBearer": [] } ], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string", "maxLength": 60, "description": "The ID of the app whose data you want to operate on.", "title": "App Id" }, "description": "The ID of the app whose data you want to operate on." }, { "name": "name", "in": "query", "required": true, "schema": { "type": "string", "maxLength": 63, "description": "The name of the scenario you want to download.", "title": "Name" }, "description": "The name of the scenario you want to download." }, { "name": "file_type", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ExportFileType", "description": "In which file type should the scenario be exported?", "default": "miroscen" }, "description": "In which file type should the scenario be exported?" }, { "name": "owner", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "string", "maxLength": 70 }, { "type": "null" } ], "description": "The owner of the scenario you want to download (by default, the logged in user).", "title": "Owner" }, "description": "The owner of the scenario you want to download (by default, the logged in user)." } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": {} } } }, "401": { "message": "Unauthorized", "description": "Unauthorized" }, "403": { "message": "Unauthorized access", "description": "Forbidden" }, "404": { "message": "Not found", "description": "Not Found" }, "500": { "description": "Internal Server Error" }, "422": { "description": "Duplicate records found when writing GDX file" } } } }, "/login": { "post": { "tags": [ "login" ], "summary": "Log in user and return login info", "description": "Log in user and return login info:\n\n- **token**: Bearer access token that can be used for authentication\n- **roles**: Labels of user groups that user can see\n- **permissions**: Permissions (octal) of the user in the MIRO Server namespace", "operationId": "login_login_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AuthResponse" } } } }, "401": { "description": "Unauthorized", "message": "Unauthorized" }, "500": { "description": "Internal Server Error" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } }, "/login/oidc": { "post": { "tags": [ "login" ], "summary": "Log in user via OpenID Connect and return login info", "description": "Log in user and return login info:\n\n- **token**: Bearer access token that can be used for authentication\n- **roles**: Labels of user groups that user can see\n- **permissions**: Permissions (octal) of the user in the MIRO Server namespace\n- **username**: GAMS Engine username", "operationId": "login_oidc_login_oidc_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OidcAuthRequest" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OidcAuthResponse" } } } }, "401": { "description": "Unauthorized", "message": "Unauthorized" }, "500": { "description": "Internal Server Error" }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } } }, "components": { "schemas": { "AppConfigOutput": { "properties": { "id": { "type": "string", "title": "Id" }, "display_name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Display Name" }, "description": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Description" }, "access_groups": { "items": { "type": "string" }, "type": "array", "title": "Access Groups" }, "environment": { "patternProperties": { "^[A-Z_][A-Z0-9_]*$": { "$ref": "#/components/schemas/AppEnvironmentItem" } }, "type": "object", "title": "Environment", "default": {} }, "version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Version" }, "authors": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "title": "Authors" } }, "type": "object", "required": [ "id", "display_name", "description", "access_groups" ], "title": "AppConfigOutput" }, "AppEnvironmentItem": { "properties": { "value": { "type": "string", "maxLength": 1000, "title": "Value" }, "description": { "type": "string", "maxLength": 1000, "title": "Description", "default": "" } }, "type": "object", "required": [ "value" ], "title": "AppEnvironmentItem" }, "AuthRequest": { "properties": { "username": { "type": "string", "title": "Username" }, "password": { "type": "string", "title": "Password" } }, "type": "object", "required": [ "username", "password" ], "title": "AuthRequest" }, "AuthResponse": { "properties": { "token": { "type": "string", "title": "Token" }, "roles": { "items": { "type": "string" }, "type": "array", "title": "Roles" }, "permissions": { "type": "string", "title": "Permissions" } }, "type": "object", "required": [ "token", "roles", "permissions" ], "title": "AuthResponse" }, "Body_add_app_apps__post": { "properties": { "app_data": { "type": "string", "contentMediaType": "application/octet-stream", "title": "App Data", "description": "A valid MIROAPP file deployed for a multi-user environment." }, "app_id": { "type": "string", "maxLength": 60, "title": "App Id", "description": "The ID of this app. If no ID is specified, the default ID (filename of the main `.gms` file in lower case) is used. This ID must be unique among all apps registered on this instance of MIRO Server." }, "display_name": { "type": "string", "maxLength": 40, "title": "Display Name", "description": "The name of the app as it appears in the library." }, "description": { "type": "string", "maxLength": 200, "title": "Description", "description": "The description of the app as it appears in the library." }, "environment": { "type": "string", "title": "Environment", "description": "JSON string with app environment configuration. Example: `{\"MIRO_IMPORTER_API_KEY\":{\"description\":\"Secret API key\",\"value\":\"my_super_secret_key\"}}`" }, "access_groups": { "items": { "type": "string" }, "type": "array", "title": "Access Groups", "description": "User groups that can access this app. If no groups are specified, it is visible to everyone who has access to your MIRO Server instance." }, "overwrite_data": { "type": "boolean", "title": "Overwrite Data", "description": "Whether to overwrite existing scenario data (from a previous installation of an app with the same ID).", "default": false } }, "type": "object", "required": [ "app_data" ], "title": "Body_add_app_apps__post" }, "Body_add_scenario_scenarios__app_id___post": { "properties": { "scenario_data": { "type": "string", "contentMediaType": "application/octet-stream", "title": "Scenario Data", "description": "A file that contains scenario data. Supported file types are: gdx,miroscen,xlsx,xlsm,xls,zip" }, "overwrite_data": { "type": "boolean", "title": "Overwrite Data", "description": "Whether to overwrite existing scenario data.", "default": false }, "read_perm": { "items": { "type": "string" }, "type": "array", "title": "Read Perm", "description": "Read permissions (by default all groups of logged in user). The MIRO Server REST API currently only supports assigning user groups, not individual users. Group names must be prefixed with a hash (`#`). The logged in user will always be appended to the specified permissions." }, "write_perm": { "items": { "type": "string" }, "type": "array", "title": "Write Perm", "description": "Write permissions (by default logged in user). The MIRO Server REST API currently only supports assigning user groups, not individual users. Group names must be prefixed with a hash (`#`). The logged in user will always be appended to the specified permissions." }, "exec_perm": { "items": { "type": "string" }, "type": "array", "title": "Exec Perm", "description": "Execute permissions (by default all groups of logged in user). The MIRO Server REST API currently only supports assigning user groups, not individual users. Group names must be prefixed with a hash (`#`). The logged in user will always be appended to the specified permissions." } }, "type": "object", "required": [ "scenario_data" ], "title": "Body_add_scenario_scenarios__app_id___post" }, "Body_update_app_apps__app_id__put": { "properties": { "app_data": { "type": "string", "contentMediaType": "application/octet-stream", "title": "App Data", "description": "A valid MIROAPP file deployed for a multi-user environment." }, "display_name": { "type": "string", "maxLength": 40, "title": "Display Name", "description": "The name of the app as it appears in the library." }, "description": { "type": "string", "maxLength": 200, "title": "Description", "description": "The description of the app as it appears in the library." }, "environment": { "type": "string", "title": "Environment", "description": "JSON string with app environment configuration. Example: `{\"MIRO_IMPORTER_API_KEY\":{\"description\":\"Secret API key\",\"value\":\"my_super_secret_key\"}}`" }, "access_groups": { "items": { "type": "string" }, "type": "array", "title": "Access Groups", "description": "User groups that can access this app. If no groups are specified, it is visible to everyone who has access to your MIRO Server instance." }, "overwrite_data": { "type": "boolean", "title": "Overwrite Data", "description": "Whether to overwrite existing scenario data (from a previous installation of an app with the same ID).", "default": false } }, "type": "object", "required": [ "app_data" ], "title": "Body_update_app_apps__app_id__put" }, "ConfigurationResponse": { "properties": { "version": { "type": "string", "title": "Version" }, "authentication_mode": { "type": "string", "title": "Authentication Mode" } }, "type": "object", "required": [ "version", "authentication_mode" ], "title": "ConfigurationResponse" }, "ExportFileType": { "type": "string", "enum": [ "miroscen", "gdx", "csv", "xlsx" ], "title": "ExportFileType" }, "HTTPValidationError": { "properties": { "detail": { "items": { "$ref": "#/components/schemas/ValidationError" }, "type": "array", "title": "Detail" } }, "type": "object", "title": "HTTPValidationError" }, "OidcAuthRequest": { "properties": { "id_token": { "type": "string", "title": "Id Token" } }, "type": "object", "required": [ "id_token" ], "title": "OidcAuthRequest" }, "OidcAuthResponse": { "properties": { "token": { "type": "string", "title": "Token" }, "roles": { "items": { "type": "string" }, "type": "array", "title": "Roles" }, "permissions": { "type": "string", "title": "Permissions" }, "username": { "type": "string", "title": "Username" } }, "type": "object", "required": [ "token", "roles", "permissions", "username" ], "title": "OidcAuthResponse" }, "ScenarioConfig": { "properties": { "name": { "type": "string", "title": "Name" }, "tags": { "items": { "type": "string" }, "type": "array", "title": "Tags" }, "owner": { "type": "string", "title": "Owner" }, "last_modified": { "type": "string", "format": "date-time", "title": "Last Modified" }, "read_perm": { "items": { "type": "string" }, "type": "array", "title": "Read Perm" }, "write_perm": { "items": { "type": "string" }, "type": "array", "title": "Write Perm" }, "exec_perm": { "items": { "type": "string" }, "type": "array", "title": "Exec Perm" } }, "type": "object", "required": [ "name", "tags", "owner", "last_modified", "read_perm", "write_perm", "exec_perm" ], "title": "ScenarioConfig" }, "ValidationError": { "properties": { "loc": { "items": { "anyOf": [ { "type": "string" }, { "type": "integer" } ] }, "type": "array", "title": "Location" }, "msg": { "type": "string", "title": "Message" }, "type": { "type": "string", "title": "Error Type" }, "input": { "title": "Input" }, "ctx": { "type": "object", "title": "Context" } }, "type": "object", "required": [ "loc", "msg", "type" ], "title": "ValidationError" } }, "securitySchemes": { "HTTPBasic": { "type": "http", "scheme": "basic" }, "HTTPBearer": { "type": "http", "scheme": "bearer" } } } }