# Unraid GraphQL Schema Findings ## Investigation Date 2025-11-22 ## Server Information - **Server URL**: http://192.168.2.61:81/graphql - **Authentication**: API Key via `x-api-key` header ## Schema Exploration Process This document contains our findings from systematically exploring the Unraid GraphQL API schema to identify the correct fields and types for retrieving system information. --- ## Type: Info The root `Info` type contains various system information categories. ### Available Fields ```graphql { "__type": { "name": "Info", "fields": [ { "name": "id", "type": { "name": null } }, { "name": "time", "type": { "name": null } }, { "name": "baseboard", "type": { "name": null } }, { "name": "cpu", "type": { "name": null } }, { "name": "devices", "type": { "name": null } }, { "name": "display", "type": { "name": null } }, { "name": "machineId", "type": { "name": "ID" } }, { "name": "memory", "type": { "name": null } }, { "name": "os", "type": { "name": null } }, { "name": "system", "type": { "name": null } }, { "name": "versions", "type": { "name": null } } ] } } ``` ### Field Descriptions - `id` - Identifier - `time` - Time information (unknown structure) - `baseboard` - Motherboard information - `cpu` - CPU hardware information - `devices` - Connected devices - `display` - Display/graphics information - `machineId` - Machine identifier (returns ID scalar) - `memory` - Memory hardware information (NOT usage statistics) - `os` - Operating system information - `system` - System information (potentially contains usage stats - **needs investigation**) - `versions` - Version information --- ## Type: InfoMemory The `InfoMemory` type describes physical RAM hardware, NOT runtime memory usage. ### Available Fields ```graphql { "__type": { "name": "InfoMemory", "fields": [ { "name": "id", "type": { "name": null, "kind": "NON_NULL" } }, { "name": "layout", "type": { "name": null, "kind": "NON_NULL" } } ] } } ``` ### Field Details - `id` - Memory identifier (required) - `layout` - Array of `MemoryLayout` objects (required) - Type: `[MemoryLayout!]!` ### Important Note **This type does NOT contain the fields we initially attempted to query:** - ❌ `total` - Does not exist - ❌ `free` - Does not exist - ❌ `used` - Does not exist These field names were incorrectly assumed based on documentation examples. --- ## Type: MemoryLayout Physical RAM module information (hardware specs, not usage). ### Available Fields ```graphql { "__type": { "name": "MemoryLayout", "fields": [ { "name": "id", "type": { "name": null, "kind": "NON_NULL" } }, { "name": "size", "type": { "name": null, "kind": "NON_NULL" } }, { "name": "bank", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "type", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "clockSpeed", "type": { "name": "Int", "kind": "SCALAR" } }, { "name": "partNum", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "serialNum", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "manufacturer", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "formFactor", "type": { "name": "String", "kind": "SCALAR" } }, { "name": "voltageConfigured", "type": { "name": "Int", "kind": "SCALAR" } }, { "name": "voltageMin", "type": { "name": "Int", "kind": "SCALAR" } }, { "name": "voltageMax", "type": { "name": "Int", "kind": "SCALAR" } } ] } } ``` ### Field Descriptions - `id` - Module identifier (required) - `size` - RAM module size in bytes (required) - `bank` - Memory bank location (e.g., "BANK 0") - `type` - RAM type (e.g., "DDR4", "DDR5") - `clockSpeed` - Operating frequency in MHz - `partNum` - Part number - `serialNum` - Serial number - `manufacturer` - Manufacturer name - `formFactor` - Physical form factor (e.g., "DIMM") - `voltageConfigured` - Configured voltage - `voltageMin` - Minimum voltage - `voltageMax` - Maximum voltage ### Usage Example ```graphql query { info { memory { id layout { size bank type manufacturer } } } } ``` ### Purpose This type provides hardware inventory information about installed RAM modules. It can be used to: - Calculate total installed RAM (sum of all `size` fields) - Display RAM configuration - Show hardware specifications **However, it does NOT provide:** - Current memory usage - Available memory - Memory utilization percentage --- ## ✅ RESOLVED: Runtime Statistics Location ### Memory and CPU Usage Data **Location Found:** `metrics` query root #### Type: Metrics The `Metrics` type provides real-time system utilization data. **Query Structure:** ```graphql query { metrics { cpu { percentTotal cpus { percentTotal percentUser percentSystem percentIdle } } memory { total used free available percentTotal swapTotal swapUsed swapFree percentSwapTotal } } } ``` #### CpuUtilization Fields - `percentTotal` - Overall CPU usage percentage (what we need for dashboard) - `cpus` - Array of per-core CPU loads #### MemoryUtilization Fields - `total` - Total system memory in bytes - `used` - Used memory in bytes - `free` - Free memory in bytes - `available` - Available memory in bytes - `percentTotal` - Memory usage percentage (what we need for dashboard) - `swapTotal` - Total swap memory - `swapUsed` - Used swap memory - `swapFree` - Free swap memory - `percentSwapTotal` - Swap usage percentage ### Required Introspection Queries To continue investigation, run these queries: **1. List all available types:** ```graphql query { __schema { types { name kind } } } ``` **2. Investigate InfoSystem type:** ```graphql query { __type(name: "InfoSystem") { name fields { name type { name kind } } } } ``` **3. Search for stats-related types:** Look through the full type list for names containing: - Stats - Metrics - Usage - Monitor - Performance - Resource --- ## Array Type Information ### Status The `array` query successfully returns basic state information. **Working Query:** ```graphql query { array { state } } ``` ### Fields to Investigate Based on earlier attempts, we know: - `array.state` - Works (returns array state) - `array.capacity.disks` - Contains `free`, `used`, `total` fields - `array.disks` - Contains `name`, `size`, `status`, `temp` fields **Need to verify:** - Exact structure of `capacity` field - Whether disk arrays are parallel (same index = same disk) - Parity information location --- ## Docker Container Information ### Status Docker container queries appear to work. **Working Query:** ```graphql query { dockerContainers { names state } } ``` ### Available Fields (from earlier attempts) - `id` - Container ID - `names` - Container names (array) - `state` - Container state (running/stopped/etc.) - `status` - Status string - `autoStart` - Auto-start configuration **Note:** This query succeeded in earlier tests. Docker integration appears functional. --- ## Error Patterns Observed ### Pattern 1: Field Does Not Exist ```json { "message": "Cannot query field \"fieldName\" on type \"TypeName\"." } ``` **Cause:** Field name is incorrect or does not exist in schema. **Solution:** Use introspection to discover actual field names. ### Pattern 2: Missing Subfield Selection ```json { "message": "Field \"fieldName\" of type \"[Type!]!\" must have a selection of subfields." } ``` **Cause:** Field returns a complex object/array but no subfields were specified. **Solution:** Query reveals the return type - use introspection to find available subfields. ### Pattern 3: Syntax Error ```json { "message": "Syntax Error: Expected Name, found ." } ``` **Cause:** Query has syntax error (extra characters, malformed structure). **Solution:** Verify query syntax, check for copy-paste issues. --- ## Introspection Capabilities ### Confirmed Working - `__type(name: "TypeName")` - Retrieve specific type information - `__typename` - Get runtime type name - Field type introspection with nested `ofType` ### Not Yet Tested - `__schema { types }` - Full schema type list - `queryType` / `mutationType` - Root operation types - Subscription support --- ## Next Steps 1. ✅ Run `__schema { types }` query to see all available types 2. ⏳ Locate memory usage statistics type 3. ⏳ Locate CPU usage statistics type 4. ⏳ Verify array and disk query structure 5. ⏳ Find parity status information 6. ⏳ Document complete working queries for all dashboard data 7. ⏳ Update dashboard JavaScript with correct queries --- ## Tools Used - **schema-test.html** - Custom introspection and query testing tool - Located at: `/Users/michaelsimard/dev/web/unraid-dash/schema-test.html` - Features: Introspection queries, custom query execution, preset tests, copy-to-clipboard --- ## References - [Unraid API Documentation](https://docs.unraid.net/API/how-to-use-the-api/) - [GraphQL Introspection Specification](https://graphql.org/learn/introspection/) - Project Summary: `PROJECT_SUMMARY.md` --- ## Final Working Queries for Dashboard ### Complete System Metrics Query ```graphql query { metrics { cpu { percentTotal } memory { total used free percentTotal } } } ``` ### Complete Array and Disk Query ```graphql query { array { state capacity { disks { free used total } } disks { name size status temp } parityCheckStatus { status errors date } } } ``` ### Complete Docker Containers Query ```graphql query { docker { containers { id names state status autoStart } } } ``` --- **Last Updated**: 2025-11-22 **Status**: ✅ COMPLETE - All required queries identified and working **Next Action**: Test dashboard with real Unraid server data