# Component: Inbound API ## Purpose The Inbound API exposes a web API on the central cluster that external systems can call into. This is the reverse of the External System Gateway — where that component handles the SCADA system calling out to external systems, this component handles external systems calling in. It provides API key authentication, method-level authorization, and script-based method implementations. ## Location Central cluster only (active node). Not available at site clusters. ## Responsibilities - Host a web API endpoint on the central cluster. - Authenticate inbound requests via API keys. - Route requests to the appropriate API method definition. - Enforce per-method API key authorization (only approved keys can call a given method). - Execute the C# script implementation for the called method. - Return structured responses to the caller. - Failover: API becomes available on the new active node after central failover. ## API Key Management ### Storage - API keys are stored in the **configuration database (MS SQL)**. ### Key Properties - **Name/Label**: Human-readable identifier for the key (e.g., "MES-Production", "RecipeManager-Dev"). - **Key Value**: The secret key string used for authentication. - **Enabled/Disabled Flag**: Keys can be disabled without deletion. ### Management - Managed by users with the **Admin** role via the Central UI. - All key changes (create, enable/disable, delete) are audit logged. ## API Method Definition ### Properties Each API method definition includes: - **Method Name**: Unique identifier and URL path segment for the endpoint. - **Approved API Keys**: List of API keys authorized to invoke this method. Requests from non-approved keys are rejected. - **Parameter Definitions**: Ordered list of input parameters, each with: - Parameter name. - Data type (Boolean, Integer, Float, String — same fixed set as template attributes). - **Return Value Definition**: Structure of the response, with: - Field names and data types. Supports returning **lists of objects**. - **Implementation Script**: C# script that executes when the method is called. Stored **inline** in the method definition. Follows standard C# authoring patterns but has no template inheritance — it is a standalone script tied to this method. - **Timeout**: Configurable per method. Defines the maximum time the method is allowed to execute (including any routed calls to sites) before returning a timeout error to the caller. ### Management - Managed by users with the **Design** role via the Central UI. - All method definition changes are audit logged. ## HTTP Contract ### URL Structure - All API calls use `POST /api/{methodName}`. - Method names map directly to URL path segments (e.g., method "GetProductionReport" → `POST /api/GetProductionReport`). - All calls are POST — these are RPC-style script invocations, not RESTful resource operations. ### API Key Header - API key is passed via the `X-API-Key` HTTP header. ### Request Format - Content-Type: `application/json`. - Parameters are top-level JSON fields in the request body matching the method's parameter definitions: ```json { "siteId": "SiteA", "startDate": "2026-03-01", "endDate": "2026-03-16" } ``` ### Response Format - **Success (200)**: The response body is the method's return value as JSON, with fields matching the return value definition: ```json { "siteName": "Site Alpha", "totalUnits": 14250, "lines": [ { "lineName": "Line-1", "units": 8200, "efficiency": 92.5 }, { "lineName": "Line-2", "units": 6050, "efficiency": 88.1 } ] } ``` - **Failure (4xx/5xx)**: The response body is an error object: ```json { "error": "Site unreachable", "code": "SITE_UNREACHABLE" } ``` - HTTP status codes distinguish success from failure — no envelope wrapper. ### Extended Type System - API method parameter and return type definitions support an **extended type system** beyond the four template attribute types (Boolean, Integer, Float, String): - **Object**: A named structure with typed fields. Supports nesting. - **List**: An ordered collection of objects or primitive types. - This allows complex request/response structures (e.g., an object containing properties and a list of nested objects). - Template attributes retain the simpler four-type system. The extended types apply only to Inbound API method definitions and External System Gateway method definitions. ## Script Compilation & Hot-Reload API method scripts are compiled at central startup — all method definitions are loaded from the configuration database and compiled into in-memory delegates. ### Update Workflow - Updating a method via the CLI (`api-method update --id --code '...'`) or Management API triggers immediate recompilation (`CompileAndRegister`). The updated script takes effect on the next API call — no node restart is required. - Creating a new method after startup: if the method is created but not yet compiled, the first invocation triggers lazy (on-demand) compilation. ### Direct SQL Warning > **Do not edit API method scripts via direct SQL.** The in-memory compiled script will not be updated until the next node restart. Always use the CLI, Management API, or Central UI to modify API method scripts. --- ## API Call Logging - **Only failures are logged.** Script execution errors (500 responses) are logged centrally. - Successful API calls are **not** logged — the audit log is reserved for configuration changes, not operational traffic. - No rate limiting — this is a private API in a controlled industrial environment with a known set of callers. Misbehaving callers are handled operationally (disable the API key). ## Request Flow ``` External System │ ▼ Inbound API (Central) ├── 1. Extract API key from request ├── 2. Validate key exists and is enabled ├── 3. Resolve method by name ├── 4. Check API key is in method's approved list ├── 5. Validate and deserialize parameters ├── 6. Execute implementation script (subject to method timeout) ├── 7. Serialize return value └── 8. Return response ``` ## Implementation Script Capabilities The C# script that implements an API method executes on the central cluster. Unlike instance scripts at sites, inbound API scripts run on central and can interact with **any instance at any site** through a routing API. Inbound API scripts **cannot** call shared scripts directly — shared scripts are deployed to sites only and execute inline in Script Actors. To execute logic on a site, use `Route.To().Call()`. ### Script Runtime API #### Instance Routing - `Route.To("instanceUniqueCode").Call("scriptName", parameters)` — Invoke a script on a specific instance at any site. Central routes the call to the appropriate site via the Communication Layer. The call reaches the target Instance Actor's Script Actor, which spawns a Script Execution Actor to execute the script. The return value flows back to the calling API script. - `Route.To("instanceUniqueCode").GetAttribute("attributeName")` — Read a single attribute value from a specific instance at any site. - `Route.To("instanceUniqueCode").GetAttributes("attr1", "attr2", ...)` — Read multiple attribute values in a **single call**, returned as a dictionary of name-value pairs. - `Route.To("instanceUniqueCode").SetAttribute("attributeName", value)` — Write a single attribute value on a specific instance at any site. - `Route.To("instanceUniqueCode").SetAttributes(dictionary)` — Write multiple attribute values in a **single call**, accepting a dictionary of name-value pairs. #### Input/Output - **Input parameters** are available as defined in the method definition. - **Return value** construction matching the defined return structure. #### Parameter Access - `Parameters["key"]` — Raw dictionary access. - `Parameters.Get("key")` — Typed access (same API as site runtime scripts). See Site Runtime component for full type support. #### Database Access - `Database.Connection("connectionName")` — Obtain a raw MS SQL client connection for querying the configuration or machine data databases directly from central. ### Routing Behavior - The `Route.To()` helper resolves the instance's site assignment from the configuration database and routes the request to the correct site cluster via the Communication Layer. - The call is **synchronous from the API caller's perspective** — the API method blocks until the site responds or the **method-level timeout** is reached. - If the target site is unreachable or the call times out, the call fails and the API returns an error to the caller. No store-and-forward buffering is used for inbound API calls. ## Authentication Details - API key is passed via the `X-API-Key` HTTP header. - The system validates: 1. The key exists in the configuration database. 2. The key is enabled. 3. The key is in the approved list for the requested method. - Failed authentication returns an appropriate HTTP error (401 Unauthorized or 403 Forbidden). ## Error Handling - Invalid API key → 401 Unauthorized. - Valid key but not approved for method → 403 Forbidden. - Invalid parameters → 400 Bad Request. - Script execution failure → 500 Internal Server Error (with safe error message, no internal details exposed). - Script errors are logged in the central audit/event system. ## Dependencies - **Configuration Database (MS SQL)**: Stores API keys and method definitions. - **Communication Layer**: Routes requests to sites when method implementations need site data. - **Security & Auth**: API key validation (separate from LDAP/AD — API uses key-based auth). - **Configuration Database (via IAuditService)**: All API key and method definition changes are audit logged. Optionally, API call activity can be logged. - **Cluster Infrastructure**: API is hosted on the active central node and fails over with it. ## Interactions - **External Systems**: Call the API with API keys. - **Communication Layer**: API method scripts use this to reach sites. - **Site Runtime (Instance Actors, Script Actors)**: Routed calls execute on site Instance Actors via their Script Actors. - **Central UI**: Admin manages API keys; Design manages method definitions. - **Configuration Database (via IAuditService)**: Configuration changes are audited.