{"openapi":"3.1.0","info":{"version":"1.0.0","title":"Texture API","description":"# Texture REST API\n\nWelcome to the Texture REST API documentation. Texture provides a comprehensive platform for managing energy devices, sites, and customer data at scale.\n\n## Getting Started\n\n### 1. Create an Account\nVisit [app.texturehq.com](https://app.texturehq.com) to create your Texture account and access your API credentials.\n\n### 2. Obtain Your API Key\nOnce logged in to the dashboard:\n- Navigate to Developer → API Keys\n- Create a new API key with appropriate permissions\n- You can create multiple keys for different purposes or scopes so we suggest creating a different key for each purpose or scope.\n\n### 3. Authentication\n\n#### API Keys\nInclude your API key in the request header:\n```\nTexture-Api-Key: your-api-key-here\n```\n\n**Server API Keys** provide full access to all API endpoints for your workspace. These should be kept secret and only used in backend services.\n\n#### Scoped Keys\n**Scoped keys** are obtained through the [Texture Connect](https://docs.texturehq.com/integrations/texture-connect) flow and provide limited, user-specific access. They use the same authentication header:\n```\nTexture-Api-Key: scoped_abc123...\n```\n\nScoped keys are prefixed with `scoped_` and are automatically restricted to:\n- **Device read operations** - View device data, history, alerts, tags, and schedules\n- **Commands** - Send commands to devices (the only write operation supported)\n- **User's connected devices only** - Automatically filtered by referenceId\n\nScoped keys are ideal for frontend applications and mobile apps where you need secure, user-specific API access without exposing your server API key.\n\nFor complete documentation on scoped keys, see our [Scoped Keys Guide](https://docs.texturehq.com/api/scoped-keys).\n\n### 4. Make Your First Request\nTry fetching your devices:\n```bash\ncurl -H \"Texture-Api-Key: your-api-key-here\"   https://api.texturehq.com/v1/devices\n```\n\n## Core Capabilities\n\nThe Texture API enables you to:\n\n- **Device Management**: Register, monitor, and control energy devices including batteries, solar panels, and EV chargers\n- **Site Management**: Organize devices by physical locations and manage site configurations\n- **Customer Management**: Track customer information and device ownership\n- **Energy Metrics**: Access real-time and historical energy data\n- **Commands & Control**: Send commands to devices for optimization and control\n- **Alerts & Monitoring**: Configure and manage alerts for device events\n- **Programs & Schedules**: Create and manage energy programs and schedules\n- **Enrollments**: Manage device enrollments in utility, demand response, and other programs\n\n## API Design Principles\n\n- **RESTful**: Standard HTTP methods (GET, POST, PUT, DELETE)\n- **JSON**: All requests and responses use JSON format\n- **Pagination**: List endpoints support pagination\n- **Consistent Error Handling**: Standardized error responses across all endpoints\n- **Idempotency**: Safe retry mechanisms for critical operations\n\n## Rate Limits\n\nAPI requests are rate-limited to ensure platform stability:\n- **Standard**: 1,000 requests per minute\n- **Bulk Operations**: 100 requests per minute\n- Contact support for higher limits\n\n## SDKs & Client Libraries\n\nGenerate client libraries using our OpenAPI specification:\n- **Download OpenAPI Spec**: [https://api.texturehq.com/v1/docs/swagger.json](https://api.texturehq.com/v1/docs/swagger.json)\n- **TypeScript/JavaScript**: Use openapi-generator or similar tools\n- **Python**: Generate with openapi-python-client\n- **Other Languages**: Any OpenAPI 3.1 compatible generator\n\n## Support & Resources\n\n- **Documentation**: [docs.texturehq.com](https://docs.texturehq.com)\n- **API Status**: [status.texturehq.com](https://status.texturehq.com)\n- **Support**: [support@texturehq.com](mailto:support@texturehq.com)\n- **Slack Community**: [Join our Slack](https://join.slack.com/t/texture-community/shared_invite/zt-2ho02ds2o-pBNH1ZGcopxgIY3BgKcKzg)\n\n---\n\n**Note**: This API is actively maintained and expanded. We follow semantic versioning and provide migration guides for breaking changes.","contact":{"name":"Texture Support","email":"support@texturehq.com","url":"https://www.texturehq.com/contact"}},"servers":[{"url":"https://api.texturehq.com/v1"}],"security":[{"ApiKeyAuth":[]}],"externalDocs":{"description":"Find more documentation and guides","url":"https://docs.texturehq.com"},"tags":[{"name":"Devices","description":"Manage energy devices including batteries, solar panels, and EV chargers"},{"name":"Sites","description":"Organize devices by physical locations"},{"name":"Customers","description":"Customer information and device ownership"},{"name":"Metrics","description":"Real-time and historical energy data"},{"name":"Commands","description":"Device control and optimization"},{"name":"Alerts","description":"Alert configuration and management"},{"name":"Programs","description":"Energy program management"},{"name":"Schedules","description":"Schedule configuration for devices"},{"name":"Enrollments","description":"Device enrollment in utility programs"},{"name":"Connections","description":"Initiate link sessions and manage device connections"},{"name":"Leads","description":"Capture and manage potential customer leads"},{"name":"Manufacturers","description":"Details about supported device manufacturers"},{"name":"Organizations","description":"Information about your organization"},{"name":"Program Instances","description":"Manage individual instances of energy programs"},{"name":"Program Reports","description":"Aggregated program reporting and analytics, including event performance and fleet health"},{"name":"OEM Direct Integration","description":"Endpoints for OEM manufacturers and Third-Party Device Operators (TPDOs) to provision devices and push telemetry directly to Texture. These endpoints require a MANUFACTURER API key and are NOT for standard OAuth-based device integrations. If you're connecting consumer devices like Ecobee or Tesla, use the Connections API with OAuth instead."},{"name":"Management","description":"Management API endpoints for administering Texture resources such as workspaces. These endpoints require a Management API key."}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"Texture-Api-Key"}},"schemas":{"Address":{"type":"object","properties":{"streetOne":{"type":"string","minLength":1,"description":"The first line of the street address.","example":"123 Main St"},"streetTwo":{"type":"string","description":"The second line of the street address.","example":"Apt 4B"},"city":{"type":"string","minLength":1,"description":"The city of the address.","example":"New York"},"state":{"type":"string","minLength":1,"description":"The state of the address.","example":"NY"},"postalCode":{"type":"string","minLength":1,"description":"The postal code of the address.","example":"10001"},"country":{"type":"string","minLength":1,"default":"USA","description":"The country of the address.","example":"USA"}},"required":["streetOne","city","state","postalCode"]},"Alert":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the alert issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"externalId":{"type":["string","null"],"description":"The external identifier for the alert from the source system.","example":"alert-123456"},"sourceSystem":{"type":"string","description":"The source system that generated the alert.","example":"texture"},"alertType":{"type":["string","null"],"description":"Legacy free-text alert type.","example":"device_offline"},"type":{"type":"string","enum":["COMMUNICATIONS","POWER_LIMIT","GRID_STATUS","HARDWARE_FAULT","FIRMWARE_UPDATE","CONFIGURATION","VOLTAGE_FREQUENCY","STATE_OF_ENERGY","TEMPERATURE","ISLANDING","GENERATOR","SOFTWARE_PROCESS","SENSOR","SYSTEM_SHUTDOWN","PERFORMANCE_DEGRADED","SITE_LEVEL","SAFETY","UNKNOWN"],"description":"The normalized alert type.","example":"HARDWARE_FAULT","deprecated":false},"subtype":{"type":["string","null"],"enum":["BATTERY_METER_COMMS","INVERTER_COMMS","PV_INVERTER_COMMS","SITE_CONTROLLER_COMMS","SITE_MAX_LIMITED","SITE_MIN_LIMITED","RAMP_RATE_LIMITED","POWER_FACTOR_LIMITED","GRID_FORMING","GRID_FOLLOWING","GRID_RESYNC_FAILED","INVERTER_FAULT","BATTERY_FAULT","CONTACTOR_FAULT","GENERATOR_FAULT","OPTICASTER_EXE_FAILED","CONTROL_AGENT_CRASHED","LOW_SOE","SLEEP_MODE","WAIT_FOR_SOLAR","EXTERNAL_SWITCH_SHUTDOWN","GPIO_SHUTDOWN","EXCESSIVE_VOLTAGE_DROP","FREQUENCY_DEVIATION","METER_DISCONNECTED","TEMPERATURE_SENSOR_FAULT","PERFORMANCE_BELOW_EXPECTATION",null],"description":"Optional normalized subtype for the alert.","example":"BATTERY_METER_COMMS"},"providerCode":{"type":["string","null"],"description":"Provider-provided code or identifier, if any.","example":"3019"},"providerName":{"type":["string","null"],"description":"Provider display name for the alert.","example":"Battery Meter Comms"},"severity":{"type":"string","enum":["CRITICAL","WARNING","INFO"],"description":"The severity level of the alert.","example":"WARNING"},"status":{"type":"string","enum":["OPEN","ACKNOWLEDGED","IGNORED","RESOLVED"],"description":"The current status of the alert.","example":"OPEN"},"title":{"type":"string","description":"The title of the alert.","example":"Device is offline"},"description":{"type":["string","null"],"description":"Additional description or details about the alert.","example":"The thermostat in the bedroom has been offline for 15 minutes."},"deviceId":{"type":["string","null"],"description":"The unique identifier of the device this alert is related to.","example":"cllgn0u4r000008l7eazybfbo"},"siteId":{"type":["string","null"],"description":"The unique identifier of the site this alert is related to.","example":"cllgn0u4r000008l7eazybfbo"},"workspaceId":{"type":"string","description":"The workspace this alert belongs to.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time the alert was created.","example":"2024-04-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time the alert was last updated.","example":"2024-04-01T00:00:00.000Z"},"acknowledgedAt":{"type":["string","null"],"format":"date-time","description":"The date and time the alert was acknowledged.","example":"2024-04-01T00:00:00.000Z"},"ignoredAt":{"type":["string","null"],"format":"date-time","description":"The date and time the alert was ignored.","example":"2024-04-01T00:00:00.000Z"},"resolvedAt":{"type":["string","null"],"format":"date-time","description":"The date and time the alert was resolved.","example":"2024-04-01T00:00:00.000Z"},"acknowledgedBy":{"type":["string","null"],"description":"The user who acknowledged the alert.","example":"cllgn0u4r000008l7eazybfbo"},"ignoredBy":{"type":["string","null"],"description":"The user who ignored the alert.","example":"cllgn0u4r000008l7eazybfbo"},"resolvedBy":{"type":["string","null"],"description":"The user who resolved the alert.","example":"cllgn0u4r000008l7eazybfbo"},"snoozedUntil":{"type":["string","null"],"format":"date-time","description":"The date and time until which the alert is snoozed.","example":"2024-04-01T01:00:00.000Z"},"manufacturer":{"type":["string","null"],"description":"The manufacturer of the device.","example":"Sierra Wireless"},"manufacturerDeviceId":{"type":["string","null"],"description":"The manufacturer device id.","example":"C7625_S59240_DA0"},"deviceName":{"type":["string","null"],"description":"The manufacturer device name.","example":"Cell Modem"},"deviceType":{"type":["string","null"],"description":"The manufacturer device type.","example":"Sierra Wireless Event Reporting"},"deviceModel":{"type":["string","null"],"description":"The manufacturer device model.","example":"C7625"},"deviceSerialNumber":{"type":["string","null"],"description":"The manufacturer device serial number.","example":"QR1024744301B118"}},"required":["id","sourceSystem","type","severity","status","title","workspaceId","createdAt","updatedAt"]},"Alerts":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Alert"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]},"ApiKey":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the API key.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the API key.","example":"Production Key"},"type":{"type":"string","enum":["API","CONNECT","MANAGEMENT","MANUFACTURER","SCOPED","SERVER"],"description":"The type of the API key.","example":"SERVER"},"keyPrefix":{"type":"string","description":"The first 12 characters of the API key. The full key value is never exposed.","example":"server_a1b2c3"},"workspaceId":{"type":"string","description":"The workspace this API key belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"ownerId":{"type":["string","null"],"description":"The ID of the user who owns this key, if applicable.","example":null},"revoked":{"type":"boolean","description":"Whether this API key has been revoked.","example":false},"expiresAt":{"type":["string","null"],"format":"date-time","description":"The date and time this key expires, or null if it does not expire.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time this API key was created.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","type","keyPrefix","workspaceId","ownerId","revoked","expiresAt","createdAt"]},"ApiKeyCreated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the API key.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the API key.","example":"CI/CD Key"},"type":{"type":"string","enum":["API","CONNECT","MANAGEMENT","MANUFACTURER","SCOPED","SERVER"],"description":"The type of the API key.","example":"SERVER"},"key":{"type":"string","description":"The full API key value. This is only returned once at creation time — store it securely.","example":"server_a1b2c3d4e5f6g7h8i9j0k1l2"},"workspaceId":{"type":"string","description":"The workspace this API key belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"ownerId":{"type":["string","null"],"description":"The ID of the user who owns this key, if applicable.","example":null},"expiresAt":{"type":["string","null"],"format":"date-time","description":"The date and time this key expires, or null if it does not expire.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time this API key was created.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","type","key","workspaceId","ownerId","expiresAt","createdAt"]},"ApiKeyRevoked":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the API key.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the API key.","example":"Production Key"},"type":{"type":"string","enum":["API","CONNECT","MANAGEMENT","MANUFACTURER","SCOPED","SERVER"],"description":"The type of the API key.","example":"SERVER"},"keyPrefix":{"type":"string","description":"The first 12 characters of the API key. The full key value is never exposed.","example":"server_a1b2c3"},"workspaceId":{"type":"string","description":"The workspace this API key belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"ownerId":{"type":["string","null"],"description":"The ID of the user who owns this key, if applicable.","example":null},"revoked":{"type":"boolean","description":"Whether this API key has been revoked.","example":false},"expiresAt":{"type":["string","null"],"format":"date-time","description":"The date and time this key expires, or null if it does not expire.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time this API key was created.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","type","keyPrefix","workspaceId","ownerId","revoked","expiresAt","createdAt"]},"ApiKeyUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the API key.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the API key.","example":"Production Key"},"type":{"type":"string","enum":["API","CONNECT","MANAGEMENT","MANUFACTURER","SCOPED","SERVER"],"description":"The type of the API key.","example":"SERVER"},"keyPrefix":{"type":"string","description":"The first 12 characters of the API key. The full key value is never exposed.","example":"server_a1b2c3"},"workspaceId":{"type":"string","description":"The workspace this API key belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"ownerId":{"type":["string","null"],"description":"The ID of the user who owns this key, if applicable.","example":null},"revoked":{"type":"boolean","description":"Whether this API key has been revoked.","example":false},"expiresAt":{"type":["string","null"],"format":"date-time","description":"The date and time this key expires, or null if it does not expire.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time this API key was created.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","type","keyPrefix","workspaceId","ownerId","revoked","expiresAt","createdAt"]},"Collection":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the collection.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the collection.","example":"Northeast EV Fleet"},"collectionType":{"type":"string","enum":["DEVICE","SITE","CUSTOMER"],"description":"The type of entity constituting the collection.","example":"DEVICE"},"description":{"type":["string","null"],"description":"Optional description of the collection.","example":"All EV devices in the northeast region"},"criteria":{"type":"object","additionalProperties":{},"description":"The criteria used to define what belongs in the collection.","example":{"rule":{"attribute":"deviceType","operator":"EQUALS","value":"VEHICLE"}}},"criteriaVersion":{"type":"string","description":"The version of the criteria schema.","example":"2"},"workspaceId":{"type":"string","description":"The workspace this collection belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"dynamic":{"type":"boolean","description":"Whether the collection is a live query (true) or a materialized set (false).","example":true},"isActive":{"type":"boolean","description":"For materialized collections: whether the collection is actively managed (true) or frozen (false).","example":true},"visibilityLevel":{"type":"string","enum":["INTERNAL","SHARED"],"description":"The visibility of the collection.","example":"INTERNAL"},"createdById":{"type":"string","description":"The ID of the entity that created the collection.","example":"clx1234567890abcdef"},"createdByType":{"type":"string","enum":["USER","API_KEY"],"description":"The type of entity that created the collection.","example":"API_KEY"},"deletedAt":{"type":["string","null"],"format":"date-time","description":"When the collection was deleted, or null if not deleted.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the collection was created.","example":"2025-06-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When the collection was last updated.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","collectionType","description","criteria","criteriaVersion","workspaceId","dynamic","isActive","visibilityLevel","createdById","createdByType","deletedAt","createdAt","updatedAt"]},"CollectionDetail":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the collection.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the collection.","example":"Northeast EV Fleet"},"collectionType":{"type":"string","enum":["DEVICE","SITE","CUSTOMER"],"description":"The type of entity constituting the collection.","example":"DEVICE"},"description":{"type":["string","null"],"description":"Optional description of the collection.","example":"All EV devices in the northeast region"},"criteria":{"type":"object","additionalProperties":{},"description":"The criteria used to define what belongs in the collection.","example":{"rule":{"attribute":"deviceType","operator":"EQUALS","value":"VEHICLE"}}},"criteriaVersion":{"type":"string","description":"The version of the criteria schema.","example":"2"},"workspaceId":{"type":"string","description":"The workspace this collection belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"dynamic":{"type":"boolean","description":"Whether the collection is a live query (true) or a materialized set (false).","example":true},"isActive":{"type":"boolean","description":"For materialized collections: whether the collection is actively managed (true) or frozen (false).","example":true},"visibilityLevel":{"type":"string","enum":["INTERNAL","SHARED"],"description":"The visibility of the collection.","example":"INTERNAL"},"createdById":{"type":"string","description":"The ID of the entity that created the collection.","example":"clx1234567890abcdef"},"createdByType":{"type":"string","enum":["USER","API_KEY"],"description":"The type of entity that created the collection.","example":"API_KEY"},"deletedAt":{"type":["string","null"],"format":"date-time","description":"When the collection was deleted, or null if not deleted.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the collection was created.","example":"2025-06-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When the collection was last updated.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","collectionType","description","criteria","criteriaVersion","workspaceId","dynamic","isActive","visibilityLevel","createdById","createdByType","deletedAt","createdAt","updatedAt"]},"CollectionUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the collection.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The human-readable name for the collection.","example":"Northeast EV Fleet"},"collectionType":{"type":"string","enum":["DEVICE","SITE","CUSTOMER"],"description":"The type of entity constituting the collection.","example":"DEVICE"},"description":{"type":["string","null"],"description":"Optional description of the collection.","example":"All EV devices in the northeast region"},"criteria":{"type":"object","additionalProperties":{},"description":"The criteria used to define what belongs in the collection.","example":{"rule":{"attribute":"deviceType","operator":"EQUALS","value":"VEHICLE"}}},"criteriaVersion":{"type":"string","description":"The version of the criteria schema.","example":"2"},"workspaceId":{"type":"string","description":"The workspace this collection belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"dynamic":{"type":"boolean","description":"Whether the collection is a live query (true) or a materialized set (false).","example":true},"isActive":{"type":"boolean","description":"For materialized collections: whether the collection is actively managed (true) or frozen (false).","example":true},"visibilityLevel":{"type":"string","enum":["INTERNAL","SHARED"],"description":"The visibility of the collection.","example":"INTERNAL"},"createdById":{"type":"string","description":"The ID of the entity that created the collection.","example":"clx1234567890abcdef"},"createdByType":{"type":"string","enum":["USER","API_KEY"],"description":"The type of entity that created the collection.","example":"API_KEY"},"deletedAt":{"type":["string","null"],"format":"date-time","description":"When the collection was deleted, or null if not deleted.","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the collection was created.","example":"2025-06-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When the collection was last updated.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","name","collectionType","description","criteria","criteriaVersion","workspaceId","dynamic","isActive","visibilityLevel","createdById","createdByType","deletedAt","createdAt","updatedAt"]},"Command":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the command issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"status":{"type":"string","enum":["pending","delivered","completed","scheduled","failed"],"description":"The current status of the command.","example":"pending"},"reason":{"type":"string","description":"The reason for the command status."},"type":{"type":"string","enum":["battery:set-reserve","battery:set-operating-mode","charger:set-operating-mode","thermostat:set-operating-mode","thermostat:set-fan-mode","thermostat:pause-schedule","thermostat:resume-schedule","vehicle:check-pairing-status","vehicle:set-charge-limit","vehicle:set-operating-mode"],"description":"The unique slug representing the type of command.","example":"thermostat:set-operating-mode"},"issuedAt":{"type":"string","format":"date-time","description":"The date and time the command was issued."},"executedAt":{"type":"string","format":"date-time","description":"The date and time the command was executed."},"input":{"type":"object","properties":{},"additionalProperties":{},"description":"The input payload sent with the command. Includes necessary information for execution. Conforms to the schema provided on the command type.","example":{"operatingMode":"eco","heatTarget":70.5,"coolTarget":80.5}},"output":{"type":["object","null"],"properties":{},"additionalProperties":{},"description":"The command's result payload, when available.","example":{"paired":true,"required":true}},"upstream":{"type":["object","null"],"properties":{"statusCode":{"type":["integer","null"],"description":"HTTP status code returned by the upstream OEM API.","example":409},"errorCode":{"type":["string","null"],"description":"Error code from the upstream OEM API. Format varies by manufacturer.","example":"VEHICLE_STATE.CHARGING_PLUG_NOT_CONNECTED"},"errorMessage":{"type":["string","null"],"description":"Human-readable error description from the upstream OEM API (verbatim).","example":"The vehicle is not connected to an EV charger and unable to perform your request."},"requestId":{"type":["string","null"],"description":"Request/correlation ID assigned by the upstream OEM API.","example":"99f23e20-d0cd-4a5f-8709-c4947a670705"}},"required":["statusCode","errorCode","errorMessage","requestId"],"description":"Upstream OEM API response metadata. Null when no upstream call was made or the adapter does not yet support populating this data."}},"required":["id","status","type","issuedAt","input","output","upstream"]},"CommandType":{"type":"object","properties":{"slug":{"type":"string","enum":["battery:set-reserve","battery:set-operating-mode","charger:set-operating-mode","thermostat:set-operating-mode","thermostat:set-fan-mode","thermostat:pause-schedule","thermostat:resume-schedule","vehicle:check-pairing-status","vehicle:set-charge-limit","vehicle:set-operating-mode"],"description":"The unique slug representing the type of command.","example":"thermostat:set-operating-mode"},"description":{"type":"string","description":"A brief description of the command type.","example":"Sets the operating mode of the thermostat."}},"required":["slug","description"]},"ConnectSession":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the connect session.","example":"cllh2buhk000008la0ln6cb80"},"status":{"type":"string","enum":["PENDING","STARTED","ENTERING_CUSTOMER_INFO","SELECTING_MANUFACTURER","AUTHORIZING_MANUFACTURER","ENTERING_SYSTEM_INFO","UNSUPPORTED_MANUFACTURER","DUPLICATE_CONNECTION","SUCCESS","ERROR","EXPIRED"],"description":"The current status of the connect session.","example":"SUCCESS"},"customerId":{"type":["string","null"],"description":"The ID of the customer associated with the connect session.","example":"cllh2buhk000008la0ln6cb80"},"siteId":{"type":["string","null"],"description":"The ID of the site associated with the connect session.","example":"cllh2buhk000008la0ln6cb80"},"manufacturer":{"type":["string","null"],"description":"The manufacturer selected during the connect session.","example":"honeywell"},"tags":{"type":["array","null"],"items":{"type":"string"},"description":"Tags associated with the connect session.","example":["tag1","tag2"]},"createdAt":{"type":"string","format":"date-time","description":"The date and time when the connect session was created.","example":"2024-01-15T10:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"The date and time when the connect session was last updated.","example":"2024-01-15T10:35:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"The date and time when the connect session will expire.","example":"2024-01-15T11:30:00Z"}},"required":["id","status","customerId","siteId","manufacturer","tags","createdAt","updatedAt","expiresAt"]},"CreateLinkSessionParams":{"type":"object","properties":{"referenceId":{"type":"string","maxLength":1000,"description":"The reference ID of the user associated with the link session. If not provided one will be generated for you.","example":"9bb290c8-fe97-46ce-92a8-952823164277"},"redirectUrl":{"type":"string","format":"uri","description":"The URL to redirect to after the link session is complete. Will contain texture_scoped_token as a query param.","example":"https://example.com/redirect"},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":100,"description":"The tags associated with the link session.","example":["tag1","tag2"]},"clientName":{"type":"string","maxLength":100,"description":"The name of the client associated with the link session.","example":"Texture"},"manufacturerFilters":{"type":"object","properties":{"manufacturers":{"type":"array","items":{"type":"string"},"minItems":1,"description":"The manufacturers you'd like to restrict choices to or pre-select in the case of 1 manufacturer specified for this link session.","example":["honeywell","daikin"]},"deviceTypes":{"type":"array","items":{"type":"string","enum":["battery","charger","inverter","meter","thermostat","vehicle","water_heater","other","unknown"]},"minItems":1,"description":"The device types you'd like to restrict choices to (will filter out manufacturers that don't have any of the selected device types).","example":["thermostat"]}},"description":"The filters for the manufacturers associated with the link session."},"customerInfo":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"The email of the customer associated with the link session.","example":"example@example.com"},"phone":{"type":"string","minLength":5,"maxLength":20,"description":"The phone number of the customer associated with the link session.","example":"1234567890"},"firstName":{"type":"string","minLength":1,"maxLength":100,"description":"The first name of the customer associated with the link session.","example":"John"},"lastName":{"type":"string","minLength":1,"maxLength":100,"description":"The last name of the customer associated with the link session.","example":"Doe"},"location":{"type":"object","properties":{"streetOne":{"type":"string","minLength":1,"maxLength":100,"description":"The first line of the address of the location associated with the link session.","example":"123 Main St"},"streetTwo":{"type":"string","minLength":1,"maxLength":100,"description":"The second line of the address of the location associated with the link session.","example":"Unit 1"},"city":{"type":"string","minLength":1,"maxLength":100,"description":"The city of the location associated with the link session.","example":"Toronto"},"state":{"type":"string","minLength":1,"maxLength":100,"description":"The state of the location associated with the link session.","example":"Ontario"},"postalCode":{"type":"string","minLength":1,"maxLength":100,"description":"The postal code of the location associated with the link session.","example":"M5V 1A1"},"country":{"type":"string","minLength":1,"maxLength":100,"description":"The country of the location associated with the link session.","example":"Canada"}},"required":["streetOne","city","state","postalCode","country"],"description":"The location of the customer associated with the link session."}},"description":"The information about the customer associated with the link session."},"customerId":{"type":"string","format":"cuid","description":"The ID of a customer to associate with the link session.","example":"cllh2buhk000008la0ln6cb80"},"siteId":{"type":"string","format":"cuid","description":"The ID of an existing site to associate with the link session. In standard mode, when provided it takes highest priority over any site resolved from customerId or customerInfo.location. In headless mode, siteId must be paired with customerId.","example":"cllh2buhk000008la0ln6cb80"},"mode":{"type":"string","enum":["standard","headless"],"description":"The mode for the connect link session. standard (default) redirects users through the Texture-hosted Connect UI. headless bypasses the hosted UI and returns an OAuth authorization URL directly, enabling fully white-labeled flows. Headless mode requires exactly one manufacturer in manufacturerFilters and a redirectUrl, plus one of: (1) customerId alone (customer must have an associated site), (2) customerId + siteId, or (3) complete customerInfo (firstName, lastName, email, and location) to create a new customer and site.","example":"headless"},"params":{}}},"CreateProgramInstanceBody":{"type":"object","properties":{"slug":{"type":"string","description":"The slug of the program instance","example":"nyc-battery-program-2025-coned"},"programSlug":{"type":"string","description":"The slug of the program to create an instance for","example":"nyc-battery-program-2025"},"title":{"type":"string","description":"The title of the program instance","example":"NYC Battery Program 2025 - ConEd"},"description":{"type":"string","description":"The description of the program instance","example":"This program is for homeowners in NYC that have installed battery storage systems."},"eligibilityCriteria":{"type":"string","description":"The eligibility criteria of the program instance","example":"Homeowners in NYC that have installed battery storage systems."},"programTerms":{"type":"string","description":"The terms of the program instance","example":"Homeowners in NYC that have installed battery storage systems."},"customFields":{"type":"object","additionalProperties":{},"description":"The custom fields of the program instance"}},"required":["slug","programSlug","title","description","eligibilityCriteria","programTerms"]},"Customer":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the customer issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"workspaceId":{"type":"string","format":"cuid","description":"The unique identifier for the workspace issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"referenceId":{"type":["string","null"],"description":"The reference ID for the customer.","example":"01234567"},"firstName":{"type":["string","null"],"description":"The given name of the customer.","example":"John"},"lastName":{"type":["string","null"],"description":"The surname of the customer.","example":"Smith"},"email":{"type":["string","null"],"description":"The email address of the customer.","example":"test@example.com"},"phone":{"type":["string","null"],"description":"The phone number of the customer as provided during creation or update.","example":"1234567890"},"devices":{"type":"array","items":{"$ref":"#/components/schemas/Device"},"description":"The devices connected to the customer."},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time the customer was created in the system.","example":"2026-08-09T11:43:47.853Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time the customer was last updated in the system.","example":"2026-08-09T11:43:47.854Z"},"connectedSiteIds":{"type":"array","items":{"type":"string"},"description":"The unique identifiers for the sites created for the customer by Texture.","example":["clmt0f0qq000g6jez6qa2sj4t","clmt0f0qq000g6jez6qa2sj4u"]},"connectedDeviceIds":{"type":"array","items":{"type":"string"},"description":"The unique identifiers for the devices connected to the customer.","example":["clmt0f0qq000g6jez6qa2sj4t","clmt0f0qq000g6jez6qa2sj4u"]}},"required":["id","workspaceId","referenceId","createdAt","connectedSiteIds","connectedDeviceIds"]},"Destination":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the destination.","example":"clx1234567890abcdef"},"workspaceId":{"type":"string","description":"The workspace this destination belongs to."},"label":{"type":["string","null"],"description":"A human-readable label for the destination."},"destinationType":{"type":["string","null"],"enum":["WEBHOOK","SMS","EMAIL","KAFKA","MANUFACTURER_COMMAND",null],"description":"The type of destination.","example":"WEBHOOK"},"deviceType":{"type":["string","null"],"enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN",null],"description":"Device types this destination applies to.","example":"ALL"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"description":"Event types that trigger this destination."},"url":{"type":["string","null"],"description":"The webhook URL (for WEBHOOK destinations)."},"email":{"type":["string","null"],"description":"The email address (for EMAIL destinations)."},"phoneNumber":{"type":["string","null"],"description":"The phone number (for SMS destinations)."},"secret":{"type":["string","null"],"description":"The webhook signing secret (for WEBHOOK destinations)."},"headers":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations)."},"includeWeather":{"type":["boolean","null"],"description":"Whether to include weather data in events."},"kafkaConfig":{"type":["object","null"],"additionalProperties":{},"description":"Kafka configuration (for KAFKA destinations)."},"deactivated":{"type":["boolean","null"],"description":"Whether this destination is deactivated."},"deactivatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was deactivated."},"deactivatedReason":{"type":["string","null"],"description":"Reason for deactivation."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When this destination was created."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was last updated."}},"required":["id","workspaceId","label","destinationType","deviceType","eventTypes","url","email","phoneNumber","secret","headers","includeWeather","kafkaConfig","deactivated","deactivatedAt","deactivatedReason","createdAt","updatedAt"]},"DestinationUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the destination.","example":"clx1234567890abcdef"},"workspaceId":{"type":"string","description":"The workspace this destination belongs to."},"label":{"type":["string","null"],"description":"A human-readable label for the destination."},"destinationType":{"type":["string","null"],"enum":["WEBHOOK","SMS","EMAIL","KAFKA","MANUFACTURER_COMMAND",null],"description":"The type of destination.","example":"WEBHOOK"},"deviceType":{"type":["string","null"],"enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN",null],"description":"Device types this destination applies to.","example":"ALL"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"description":"Event types that trigger this destination."},"url":{"type":["string","null"],"description":"The webhook URL (for WEBHOOK destinations)."},"email":{"type":["string","null"],"description":"The email address (for EMAIL destinations)."},"phoneNumber":{"type":["string","null"],"description":"The phone number (for SMS destinations)."},"secret":{"type":["string","null"],"description":"The webhook signing secret (for WEBHOOK destinations)."},"headers":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations)."},"includeWeather":{"type":["boolean","null"],"description":"Whether to include weather data in events."},"kafkaConfig":{"type":["object","null"],"additionalProperties":{},"description":"Kafka configuration (for KAFKA destinations)."},"deactivated":{"type":["boolean","null"],"description":"Whether this destination is deactivated."},"deactivatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was deactivated."},"deactivatedReason":{"type":["string","null"],"description":"Reason for deactivation."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When this destination was created."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was last updated."}},"required":["id","workspaceId","label","destinationType","deviceType","eventTypes","url","email","phoneNumber","secret","headers","includeWeather","kafkaConfig","deactivated","deactivatedAt","deactivatedReason","createdAt","updatedAt"]},"Device":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"siteId":{"type":["string","null"],"format":"cuid","description":"The unique identifier for the site this device belongs to.","example":"cllgn0u4r000008l7eazybfbo"},"name":{"type":"string","description":"The name of the device."},"manufacturerDeviceId":{"type":"string","description":"The unique identifier for the device issued by the manufacturer.","example":"b1143000-69ac-481f-9bef-4bfd96198133"},"serialNumber":{"type":["string","null"],"description":"The serial number of the device.","example":"123456789"},"referenceId":{"type":"string","description":"A unique identifier referring to the user/account in your system","example":"2952bc94-0273-4087-830b-d0ab2bece1e7"},"manufacturer":{"type":"string","description":"The manufacturer of the device.","example":"ecobee"},"type":{"type":"string","enum":["battery","charger","inverter","meter","thermostat","vehicle","water_heater","other","unknown"],"description":"The type of the device.","example":"thermostat"},"model":{"type":"string","description":"The name of the device model.","example":"nikeSmart"},"rawType":{"type":["string","null"],"description":"The raw device type as provided by the manufacturer.","example":"Battery Storage System"},"rawModel":{"type":["string","null"],"description":"The raw device model as provided by the manufacturer.","example":"ACME-BATTERY-PRO-13.5"},"modelYear":{"type":["integer","null"],"description":"The year the device was manufactured.","example":2021},"state":{"anyOf":[{"type":"object","properties":{"chargingState":{"type":"string","enum":["charging","discharging","idle","unknown"],"description":"Whether the battery is currently charging. The state could be unknown if not provided by the manufacturer."},"charge":{"type":"number","description":"The current charge of the battery in watt-hours (Wh)."},"chargePercentage":{"type":"number","minimum":0,"maximum":100,"description":"The current charge of the battery as a percentage. Represented as a number between 0 and 100."},"chargeRate":{"type":"number","description":"The current charge rate of the battery in watts (W)."},"backupReserve":{"type":"number","minimum":0,"maximum":100,"description":"The charge percentage that should be reserved for backup power. Represented as a number between 0 and 100."},"isStormModeActive":{"type":"boolean","description":"Whether the battery has an active storm mode alert."},"isStormModeEnabled":{"type":"boolean","description":"Whether the battery has storm mode enabled."},"strategy":{"type":"string","enum":["unknown","self_consumption","time_of_use","backup"],"default":"unknown","description":"The current strategy or mode the battery is operating in."},"gridStatus":{"type":"string","enum":["exporting","importing","idle","unknown"],"description":"The current grid status (importing, exporting, idle, unknown)."},"gridPower":{"type":"integer","description":"The recent estimate of power output to/from the grid in Watts (W). Positive values indicate importing from the grid, negative values indicate exporting to the grid."},"gridEnergy":{"type":"integer","description":"Estimated recent grid energy usage in Watt-hours (Wh)."},"loadPower":{"type":"number","minimum":0,"description":"The measured or projected power consumption for the home load during the measurement interval in Watts (W)."},"loadEnergy":{"type":"number","minimum":0,"description":"The measured or projected energy usage for the home load during the measurement interval in Watt-hours (Wh)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"},"whConsumed":{"type":["number","null"]}},"required":["chargingState","charge","chargePercentage","id","createdAt","whConsumed"],"title":"BatteryState"},{"type":"object","properties":{"chargingState":{"type":"string","enum":["charging","discharging","idle","unknown"],"description":"Whether the charger is currently charging. The state could be unknown if not provided by the manufacturer."},"isPluggedIn":{"type":"boolean","description":"Whether the charger is plugged in."},"chargerVoltage":{"type":"number","minimum":0,"maximum":1000,"description":"The voltage of the charger in volts (V)."},"chargerCurrent":{"type":"number","minimum":0,"maximum":1000,"description":"The current of the charger in amps (A)."},"chargerWattage":{"type":"number","minimum":0,"maximum":1000000,"description":"The wattage of the charger in watts (W)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["chargingState","id","createdAt"],"title":"ChargerState"},{"type":"object","properties":{"ambientTemperature":{"type":"number","description":"The ambient temperature in degrees Fahrenheit."},"operatingMode":{"type":"string","enum":["heat","cool","auto","eco","off","unknown"],"description":"The current operating mode of the thermostat."},"coolTarget":{"type":"number","description":"The current target temperature for the cooling function in degrees Fahrenheit."},"heatTarget":{"type":"number","description":"The current target temperature for the heating function in degrees Fahrenheit."},"fanMode":{"type":"string","enum":["auto","on","off","circulate","unknown"],"description":"The current fan mode of the thermostat."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["ambientTemperature","operatingMode","fanMode","id","createdAt"],"title":"ThermostatState"},{"type":"object","properties":{"power":{"type":"number","minimum":0,"maximum":10000000,"description":"The power output of the inverter in watts (W)."},"generatedEnergy":{"type":"number","minimum":0,"description":"The energy generated by the inverter during the measurement interval in watt-hours (Wh)."},"lifetimeEnergyGenerated":{"type":"number","minimum":0,"description":"The cumulative energy generated by the inverter over its lifetime in watt-hours (Wh)."},"gridStatus":{"type":"string","enum":["exporting","importing","idle","unknown"],"description":"The current grid status (importing, exporting, idle, unknown)."},"gridPower":{"type":"integer","description":"The recent estimate of power output to/from the grid in Watts (W). Positive values indicate importing from the grid, negative values indicate exporting to the grid."},"gridEnergy":{"type":"integer","description":"Estimated recent grid energy usage in Watt-hours (Wh)."},"loadPower":{"type":"number","minimum":0,"description":"The measured or projected power consumption for the home load during the measurement interval in Watts (W)."},"loadEnergy":{"type":"number","minimum":0,"description":"The measured or projected energy usage for the home load during the measurement interval in Watt-hours (Wh)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["power","id","createdAt"],"title":"InverterState"},{"type":"object","properties":{"chargingState":{"type":"string","enum":["charging","discharging","idle","unknown"],"description":"Whether the vehicle is currently charging. The state could be unknown if not provided by the manufacturer."},"chargePercentage":{"type":"number","minimum":0,"maximum":100,"description":"The current charge of the vehicle as a percentage. Represented as a number between 0 and 100."},"chargeCompletedAt":{"type":"string","format":"date-time","description":"The estimated date and time when the vehicle will be fully charged."},"chargeLimit":{"type":"number","description":"The current charge limit of the vehicle as a percentage."},"charge":{"type":"number","minimum":0,"description":"The current charge of the vehicle battery in watt-hours (Wh)."},"isPluggedIn":{"type":"boolean","description":"Whether the vehicle is plugged in."},"chargerVoltage":{"type":"number","minimum":0,"maximum":1000,"description":"The voltage of the charger in volts (V)."},"chargerCurrent":{"type":"number","minimum":0,"maximum":1000,"description":"The current of the charger in amps (A)."},"chargerWattage":{"type":"number","minimum":0,"maximum":1000000,"description":"The wattage of the charger in watts (W)."},"range":{"type":"number","minimum":0,"maximum":10000,"description":"The current (estimated) range of the vehicle in miles (mi)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["chargingState","chargePercentage","range","id","createdAt"],"title":"VehicleState"}],"description":"The current state of the device.","example":{"id":"cllgn0u4r000008l7eazybfbo","ambientTemperature":72.3,"operatingMode":"auto","heatTarget":72.5,"coolTarget":75.5,"fanMode":"auto","createdAt":"2024-04-01T00:00:00.000Z"}},"staticState":{"anyOf":[{"type":"object","properties":{"capacity":{"type":"number","exclusiveMinimum":0,"description":"The rated maximum capacity of the battery in watt-hours (Wh)."},"maxChargeRate":{"type":"number","exclusiveMinimum":0,"description":"The rated maximum charge rate of the battery in watts (W)."},"maxDischargeRate":{"type":"number","exclusiveMinimum":0,"description":"The rated maximum discharge rate of the battery in watts (W)."},"numberOfBatteries":{"type":"integer","exclusiveMinimum":0,"description":"The number of batteries in the system."}},"required":["capacity"],"title":"BatteryStaticState"},{"type":"object","properties":{"power":{"type":"number","minimum":0,"maximum":10000000,"description":"The maximum power output of the inverter in watts (W)."}},"required":["power"],"title":"InverterStaticState"},{"type":"object","properties":{"allowedModes":{"type":"array","items":{"type":"string","enum":["heat","cool","auto","eco","off","unknown"]},"description":"Operating modes supported by this thermostat."},"minHeatSetpoint":{"type":"integer","description":"Minimum heat setpoint temperature in degrees Fahrenheit."},"maxHeatSetpoint":{"type":"integer","description":"Maximum heat setpoint temperature in degrees Fahrenheit."},"minCoolSetpoint":{"type":"integer","description":"Minimum cool setpoint temperature in degrees Fahrenheit."},"maxCoolSetpoint":{"type":"integer","description":"Maximum cool setpoint temperature in degrees Fahrenheit."},"allowedFanModes":{"type":"array","items":{"type":"string","enum":["auto","on","off","circulate","unknown"]},"description":"Fan modes supported by this thermostat."},"extendedCapabilities":{"type":"object","additionalProperties":{},"description":"Extended capabilities including scheduling support, deadband settings, and mode-specific temperature constraints. Flexible structure for manufacturer-specific features."}},"required":["allowedModes","allowedFanModes"],"title":"ThermostatStaticState"},{"type":"object","properties":{"capacity":{"type":"number","description":"The rated maximum capacity of the vehicle battery in watt-hours (Wh)."},"keyPaired":{"type":["boolean","null"],"description":"Whether the manufacturer virtual key has been paired with this vehicle. Null for manufacturers where virtual key pairing is not applicable."},"extendedCapabilities":{"type":"object","additionalProperties":{},"description":"Extended manufacturer-specific capabilities and metadata (e.g. firmware version, fleet telemetry support, data-streaming toggles). Flexible structure for manufacturer-specific features."}},"title":"VehicleStaticState"}],"description":"Static state of the device.","example":{"capacity":13500,"maxChargeRate":5000,"maxDischargeRate":11500}},"location":{"type":"object","properties":{"address":{"type":"object","properties":{"streetOne":{"type":["string","null"]},"streetTwo":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"postalCode":{"type":["string","null"]},"country":{"type":["string","null"]},"county":{"type":["string","null"]},"hashedAddress":{"type":["string","null"]}}},"coordinates":{"type":"object","properties":{"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["latitude","longitude"]}},"required":["address"],"description":"The location of the device.","example":{"address":{"streetOne":"123 Main St","streetTwo":"Apt 101","city":"Beverly Hills","state":"CA","postalCode":"90210","country":"USA"},"coordinates":{"latitude":34.1,"longitude":-118.3}}},"availableCommands":{"type":"array","items":{"$ref":"#/components/schemas/CommandType"},"description":"The list of commands that can be sent to the device.","examples":[[{"slug":"thermostat:set-operating-mode","description":"Sets the operating mode of the thermostat."},{"slug":"thermostat:set-fan-mode","description":"Sets the fan mode of the thermostat."}]]},"tags":{"type":"array","items":{"type":"string"},"description":"The list of tags associated with the device.","example":["bedroom","upstairs"]},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time that this device was created.","example":"2024-04-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time that this device was last updated.","example":"2024-04-01T00:00:00.000Z"},"isHome":{"type":["boolean","null"],"description":"Whether the vehicle is at its home location. True if the vehicle's current position is within 250 m of its registered location, false otherwise, or null if coordinates are unavailable. Only applicable to vehicle-type devices.","example":true},"connectedAt":{"type":["string","null"],"format":"date-time","description":"The date and time when the device was most recently connected.","example":"2024-04-01T00:00:00.000Z"},"disconnectedAt":{"type":["string","null"],"format":"date-time","description":"The date and time when the device was most recently disconnected.","example":"2024-04-02T00:00:00.000Z"},"onlineStatus":{"type":"string","enum":["online","asleep","offline","unknown"],"description":"Current reachability of the device. Distinct from connectedAt/disconnectedAt which track OAuth connection state. Possible values: online (reachable, telemetry flowing), asleep (sleep / low-power state, e.g. parked Tesla), offline (unreachable), unknown (indeterminate).","example":"online"},"lastOnlineAt":{"type":["string","null"],"format":"date-time","description":"The last time the device was confirmed reachable. Null if the device has never been seen reachable.","example":"2024-04-01T00:00:00.000Z"}},"required":["id","name","manufacturerDeviceId","referenceId","manufacturer","type","model","state","availableCommands","tags","createdAt","onlineStatus"]},"DeviceCommandsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Command"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]},"DeviceHistoryResponse":{"type":"object","properties":{"data":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"chargingState":{"type":"string","enum":["charging","discharging","idle","unknown"],"description":"Whether the battery is currently charging. The state could be unknown if not provided by the manufacturer."},"charge":{"type":"number","description":"The current charge of the battery in watt-hours (Wh)."},"chargePercentage":{"type":"number","minimum":0,"maximum":100,"description":"The current charge of the battery as a percentage. Represented as a number between 0 and 100."},"chargeRate":{"type":"number","description":"The current charge rate of the battery in watts (W)."},"backupReserve":{"type":"number","minimum":0,"maximum":100,"description":"The charge percentage that should be reserved for backup power. Represented as a number between 0 and 100."},"isStormModeActive":{"type":"boolean","description":"Whether the battery has an active storm mode alert."},"isStormModeEnabled":{"type":"boolean","description":"Whether the battery has storm mode enabled."},"strategy":{"type":"string","enum":["unknown","self_consumption","time_of_use","backup"],"default":"unknown","description":"The current strategy or mode the battery is operating in."},"gridStatus":{"type":"string","enum":["exporting","importing","idle","unknown"],"description":"The current grid status (importing, exporting, idle, unknown)."},"gridPower":{"type":"integer","description":"The recent estimate of power output to/from the grid in Watts (W). Positive values indicate importing from the grid, negative values indicate exporting to the grid."},"gridEnergy":{"type":"integer","description":"Estimated recent grid energy usage in Watt-hours (Wh)."},"loadPower":{"type":"number","minimum":0,"description":"The measured or projected power consumption for the home load during the measurement interval in Watts (W)."},"loadEnergy":{"type":"number","minimum":0,"description":"The measured or projected energy usage for the home load during the measurement interval in Watt-hours (Wh)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"},"whConsumed":{"type":["number","null"]}},"required":["chargingState","charge","chargePercentage","id","createdAt","whConsumed"],"title":"BatteryState"},{"type":"object","properties":{"chargingState":{"type":"string","enum":["charging","discharging","idle","unknown"],"description":"Whether the charger is currently charging. The state could be unknown if not provided by the manufacturer."},"isPluggedIn":{"type":"boolean","description":"Whether the charger is plugged in."},"chargerVoltage":{"type":"number","minimum":0,"maximum":1000,"description":"The voltage of the charger in volts (V)."},"chargerCurrent":{"type":"number","minimum":0,"maximum":1000,"description":"The current of the charger in amps (A)."},"chargerWattage":{"type":"number","minimum":0,"maximum":1000000,"description":"The wattage of the charger in watts (W)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["chargingState","id","createdAt"],"title":"ChargerState"},{"type":"object","properties":{"ambientTemperature":{"type":"number","description":"The ambient temperature in degrees Fahrenheit."},"operatingMode":{"type":"string","enum":["heat","cool","auto","eco","off","unknown"],"description":"The current operating mode of the thermostat."},"coolTarget":{"type":"number","description":"The current target temperature for the cooling function in degrees Fahrenheit."},"heatTarget":{"type":"number","description":"The current target temperature for the heating function in degrees Fahrenheit."},"fanMode":{"type":"string","enum":["auto","on","off","circulate","unknown"],"description":"The current fan mode of the thermostat."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["ambientTemperature","operatingMode","fanMode","id","createdAt"],"title":"ThermostatState"},{"type":"object","properties":{"power":{"type":"number","minimum":0,"maximum":10000000,"description":"The power output of the inverter in watts (W)."},"generatedEnergy":{"type":"number","minimum":0,"description":"The energy generated by the inverter during the measurement interval in watt-hours (Wh)."},"lifetimeEnergyGenerated":{"type":"number","minimum":0,"description":"The cumulative energy generated by the inverter over its lifetime in watt-hours (Wh)."},"gridStatus":{"type":"string","enum":["exporting","importing","idle","unknown"],"description":"The current grid status (importing, exporting, idle, unknown)."},"gridPower":{"type":"integer","description":"The recent estimate of power output to/from the grid in Watts (W). Positive values indicate importing from the grid, negative values indicate exporting to the grid."},"gridEnergy":{"type":"integer","description":"Estimated recent grid energy usage in Watt-hours (Wh)."},"loadPower":{"type":"number","minimum":0,"description":"The measured or projected power consumption for the home load during the measurement interval in Watts (W)."},"loadEnergy":{"type":"number","minimum":0,"description":"The measured or projected energy usage for the home load during the measurement interval in Watt-hours (Wh)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["power","id","createdAt"],"title":"InverterState"},{"type":"object","properties":{"chargingState":{"type":"string","enum":["charging","discharging","idle","unknown"],"description":"Whether the vehicle is currently charging. The state could be unknown if not provided by the manufacturer."},"chargePercentage":{"type":"number","minimum":0,"maximum":100,"description":"The current charge of the vehicle as a percentage. Represented as a number between 0 and 100."},"chargeCompletedAt":{"type":"string","format":"date-time","description":"The estimated date and time when the vehicle will be fully charged."},"chargeLimit":{"type":"number","description":"The current charge limit of the vehicle as a percentage."},"charge":{"type":"number","minimum":0,"description":"The current charge of the vehicle battery in watt-hours (Wh)."},"isPluggedIn":{"type":"boolean","description":"Whether the vehicle is plugged in."},"chargerVoltage":{"type":"number","minimum":0,"maximum":1000,"description":"The voltage of the charger in volts (V)."},"chargerCurrent":{"type":"number","minimum":0,"maximum":1000,"description":"The current of the charger in amps (A)."},"chargerWattage":{"type":"number","minimum":0,"maximum":1000000,"description":"The wattage of the charger in watts (W)."},"range":{"type":"number","minimum":0,"maximum":10000,"description":"The current (estimated) range of the vehicle in miles (mi)."},"id":{"type":"string","format":"cuid","description":"The unique identifier for the recorded state.","example":"cllgn0u4r000008l7eazybfbo"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the device state was recorded.","example":"2021-03-10T18:00:00.000Z"}},"required":["chargingState","chargePercentage","range","id","createdAt"],"title":"VehicleState"}]}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]},"DeviceSchedule":{"type":"object","properties":{"deviceTimezone":{"type":"string","description":"A valid timezone string","example":"America/New_York"},"startsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule starts.","example":"2021-04-01T00:00:00.000Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule ends.","example":"2021-04-01T00:00:00.000Z"},"defaultDeviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}},"id":{"type":"string","description":"The unique identifier for the device schedule.","example":"clpkn2je80006102tx7d0jhb8","readOnly":true},"deviceId":{"type":"string","description":"The device ID that this schedule belongs to.","example":"clpkn2je80006102tx7d0jhb8"},"rules":{"type":"array","items":{"type":"object","properties":{"daysOfWeek":{"type":"array","items":{"type":"integer"},"example":[0,1,2,3,4,5,6],"description":"The days of the week the rule is active, numbered 0-6, where 0 is Sunday. In the example the rule is active every day of the week."},"startTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"endTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"deviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}}},"required":["daysOfWeek","startTime","endTime","deviceOperatingMode"]}},"createdAt":{"type":"string","format":"date-time","description":"The date and time that this schedule was created.","example":"2021-04-01T00:00:00.000Z","readOnly":true},"updatedAt":{"type":"string","format":"date-time","description":"The date and time that this schedule was last updated.","example":"2021-04-01T00:00:00.000Z","readOnly":true}},"required":["defaultDeviceOperatingMode","id","deviceId","rules","createdAt"]},"DevicesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Device"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]},"DeviceTypes":{"type":"array","items":{"type":"string","enum":["battery","charger","inverter","meter","thermostat","vehicle","water_heater","other","unknown"]}},"Eligibility":{"type":"object","properties":{"status":{"type":"string","enum":["candidate","eligible","ineligible","submitted","approved","rejected","unenrolling","unenrolled"]},"reason":{"type":"string","description":"The reason for the eligibility status.","example":"The customer is already enrolled in another program."},"programInstanceId":{"type":"string","description":"The unique identifier for the program instance.","example":"cllgn0u4r000008l7eazybfbo"}},"required":["status"]},"EmailDestinationCreated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the destination.","example":"clx1234567890abcdef"},"workspaceId":{"type":"string","description":"The workspace this destination belongs to."},"label":{"type":["string","null"],"description":"A human-readable label for the destination."},"destinationType":{"type":["string","null"],"enum":["WEBHOOK","SMS","EMAIL","KAFKA","MANUFACTURER_COMMAND",null],"description":"The type of destination.","example":"WEBHOOK"},"deviceType":{"type":["string","null"],"enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN",null],"description":"Device types this destination applies to.","example":"ALL"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"description":"Event types that trigger this destination."},"url":{"type":["string","null"],"description":"The webhook URL (for WEBHOOK destinations)."},"email":{"type":["string","null"],"description":"The email address (for EMAIL destinations)."},"phoneNumber":{"type":["string","null"],"description":"The phone number (for SMS destinations)."},"secret":{"type":["string","null"],"description":"The webhook signing secret (for WEBHOOK destinations)."},"headers":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations)."},"includeWeather":{"type":["boolean","null"],"description":"Whether to include weather data in events."},"kafkaConfig":{"type":["object","null"],"additionalProperties":{},"description":"Kafka configuration (for KAFKA destinations)."},"deactivated":{"type":["boolean","null"],"description":"Whether this destination is deactivated."},"deactivatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was deactivated."},"deactivatedReason":{"type":["string","null"],"description":"Reason for deactivation."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When this destination was created."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was last updated."}},"required":["id","workspaceId","label","destinationType","deviceType","eventTypes","url","email","phoneNumber","secret","headers","includeWeather","kafkaConfig","deactivated","deactivatedAt","deactivatedReason","createdAt","updatedAt"]},"EnergyModelingData":{"type":"object","properties":{"consumption":{"type":["object","null"],"properties":{"buildingCharacteristics":{"type":["object","null"],"properties":{"type":{"type":["string","null"],"description":"The type of the building.","example":"Residential"},"floorArea":{"type":["number","null"],"description":"The floor area of the building.","example":1000},"numStories":{"type":["number","null"],"description":"The number of stories in the building.","example":1},"numBedrooms":{"type":["number","null"],"description":"The number of bedrooms in the building.","example":1},"numOccupants":{"type":["number","null"],"description":"The number of occupants in the building.","example":1}}}}},"costs":{"type":["object","null"],"properties":{"utilityRates":{"type":["object","null"],"properties":{"electricity":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the electricity cost.","example":0.1},"units":{"type":["string","null"],"description":"The units of the electricity cost.","example":"kWh"}}},"fossilFuel":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the fossil fuel cost.","example":0.1},"units":{"type":["string","null"],"description":"The units of the fossil fuel cost.","example":"kWh"}}}}},"emissionRates":{"type":["object","null"],"properties":{"electricity":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the electricity emission rate.","example":0.1},"units":{"type":["string","null"],"description":"The units of the electricity emission rate.","example":"kgCO2e/kWh"}}},"fossilFuel":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the fossil fuel emission rate.","example":0.1},"units":{"type":["string","null"],"description":"The units of the fossil fuel emission rate.","example":"kgCO2e/kWh"}}}}}}},"intervals":{"type":["array","null"],"items":{"type":"object","properties":{"from":{"type":"string","format":"date-time","description":"The start date and time of the interval.","example":"2024-04-01T00:00:00.000Z"},"to":{"type":"string","format":"date-time","description":"The end date and time of the interval.","example":"2024-04-01T00:00:00.000Z"},"grid":{"type":["object","null"],"properties":{"import":{"type":["object","null"],"properties":{"electricity":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the grid electricity.","example":0.1},"units":{"type":["string","null"],"description":"The units of the grid electricity.","example":"kWh"}}},"fossilFuel":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the grid fossil fuel.","example":0.1},"units":{"type":["string","null"],"description":"The units of the grid fossil fuel.","example":"kWh"}}}}},"costs":{"type":["object","null"],"properties":{}}}},"costs":{"type":["object","null"],"properties":{"electricity":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the electricity cost.","example":0.1},"units":{"type":["string","null"],"description":"The units of the electricity cost.","example":"kWh"}}},"fossilFuel":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the fossil fuel cost.","example":0.1},"units":{"type":["string","null"],"description":"The units of the fossil fuel cost.","example":"kWh"}}}}},"consumption":{"type":["object","null"],"properties":{"electricity":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the electricity consumption.","example":0.1},"units":{"type":["string","null"],"description":"The units of the electricity consumption.","example":"kWh"}}},"fossilFuel":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the fossil fuel consumption.","example":0.1},"units":{"type":["string","null"],"description":"The units of the fossil fuel consumption.","example":"kWh"}}}}},"emissions":{"type":["object","null"],"properties":{"electricity":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the electricity emissions.","example":0.1},"units":{"type":["string","null"],"description":"The units of the electricity emissions.","example":"kgCO2e/kWh"}}},"fossilFuel":{"type":["object","null"],"properties":{"value":{"type":["number","null"],"description":"The value of the fossil fuel emissions.","example":0.1},"units":{"type":["string","null"],"description":"The units of the fossil fuel emissions.","example":"kgCO2e/kWh"}}}}}},"required":["from","to"]}}},"description":"The energy modeling data for the Site. Only available for workspaces with an enabled site intelligence integration."},"Enrollment":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the enrollment","example":"cllgn0u4r000008l7eazybfbo"},"leadId":{"type":"string","description":"The unique identifier for the lead","example":"cllgn0u4r000008l7eazybfbo"},"customerId":{"type":"string","description":"The unique identifier for the customer","example":"cllgn0u4r000008l7eazybfbo"},"firstName":{"type":"string","description":"The first name of the customer","example":"Suzie"},"lastName":{"type":"string","description":"The last name of the customer","example":"Homeowner"},"email":{"type":"string","format":"email","description":"The email address of the customer","example":"suzie.homeowner@example.com"},"phone":{"type":["string","null"],"description":"The phone number of the customer","example":"+1234567890"},"manufacturerSlugs":{"type":"array","items":{"type":"string"},"default":[],"description":"The slugs of the manufacturers associated with this enrollment","example":["tesla","enphase"]},"meta":{"type":"object","additionalProperties":{},"description":"Additional metadata as key-value pairs."},"serialNumber":{"type":["string","null"],"description":"The serial number of the device","example":"1234567890"},"referenceId":{"type":"string","description":"The reference ID of the customer","example":"1234567890"},"referenceDescription":{"type":["string","null"],"description":"The description of the reference ID","example":"Tesla Grid Services id."},"programInstanceId":{"type":"string","description":"The unique identifier for the program instance","example":"cllgn0u4r000008l7eazybfbo"},"enrollmentStartDate":{"type":["string","null"],"description":"The start date of the enrollment","example":"2025-01-01T00:00:00Z"},"tags":{"type":"array","items":{"type":"string"},"default":[],"description":"The tags for the enrollment.","example":["tag1","tag2"]},"devices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"}},"required":["id","type"]},"default":[],"description":"The devices associated with this enrollment","example":[{"id":"cllgn0u4r000008l7eazyefgh","type":"battery"}]},"address":{"$ref":"#/components/schemas/Address"},"eligibility":{"$ref":"#/components/schemas/Eligibility"},"createdAt":{"type":["string","null"],"description":"The date the enrollment was created","example":"2025-01-01T00:00:00Z"},"updatedAt":{"type":["string","null"],"description":"The date the enrollment was updated","example":"2025-01-01T00:00:00Z"}},"required":["id","eligibility"]},"EnrollmentInput":{"anyOf":[{"type":"object","properties":{"identificationType":{"type":"string","enum":["customerInfo"]},"firstName":{"type":"string","description":"The first name of the customer","example":"John"},"lastName":{"type":"string","description":"The last name of the customer","example":"Doe"},"email":{"type":"string","format":"email","description":"The email address of the customer","example":"john.doe@example.com"},"address":{"$ref":"#/components/schemas/Address"},"phone":{"type":["string","null"],"description":"The phone number of the customer.","example":"+1234567890"},"manufacturerSlugs":{"type":"array","items":{"type":"string"},"default":[],"description":"Optional array of manufacturer slugs associated with this enrollment. Defaults to empty array if not provided.","example":["tesla","enphase"]},"meta":{"type":"object","additionalProperties":{},"description":"Additional metadata as key-value pairs."},"serialNumber":{"type":["string","null"],"description":"The serial number of the device.","example":"1234567890"},"referenceId":{"type":"string","description":"The reference ID of the customer.","example":"1234567890"},"referenceDescription":{"type":["string","null"],"description":"The description of the reference ID.","example":"The customer is a new lead."},"tags":{"type":"array","items":{"type":"string"},"default":[],"description":"The tags for the enrollment.","example":["tag1","tag2"]},"enrollmentStartDate":{"type":["string","null"],"description":"The start date of the enrollment.","example":"2025-01-01T00:00:00Z"},"eligibility":{"type":"object","properties":{"status":{"type":"string","enum":["candidate","eligible","ineligible","submitted","approved","rejected","unenrolling","unenrolled"]},"reason":{"type":"string"}},"required":["status"],"description":"Initial eligibility status for the enrollment. If not provided, eligibility will be determined automatically."}},"required":["identificationType","firstName","lastName","email","address"],"title":"Customer Info Enrollment"},{"type":"object","properties":{"identificationType":{"type":"string","enum":["customerId"]},"customerId":{"type":"string","description":"The unique identifier for the customer","example":"cllgn0u4r000008l7eazybfbo"},"address":{"$ref":"#/components/schemas/Address"},"phone":{"type":["string","null"],"description":"The phone number of the customer.","example":"+1234567890"},"manufacturerSlugs":{"type":"array","items":{"type":"string"},"default":[],"description":"Optional array of manufacturer slugs associated with this enrollment. Defaults to empty array if not provided.","example":["tesla","enphase"]},"meta":{"type":"object","additionalProperties":{},"description":"Additional metadata as key-value pairs."},"serialNumber":{"type":["string","null"],"description":"The serial number of the device.","example":"1234567890"},"referenceId":{"type":"string","description":"The reference ID of the customer.","example":"1234567890"},"referenceDescription":{"type":["string","null"],"description":"The description of the reference ID.","example":"The customer is a new lead."},"tags":{"type":"array","items":{"type":"string"},"default":[],"description":"The tags for the enrollment.","example":["tag1","tag2"]},"enrollmentStartDate":{"type":["string","null"],"description":"The start date of the enrollment.","example":"2025-01-01T00:00:00Z"},"eligibility":{"type":"object","properties":{"status":{"type":"string","enum":["candidate","eligible","ineligible","submitted","approved","rejected","unenrolling","unenrolled"]},"reason":{"type":"string"}},"required":["status"],"description":"Initial eligibility status for the enrollment. If not provided, eligibility will be determined automatically."}},"required":["identificationType","customerId"],"title":"Customer ID Enrollment"},{"type":"object","properties":{"identificationType":{"type":"string","enum":["enrollmentId"]},"enrollmentId":{"type":"string","description":"The unique identifier for the enrollment","example":"cllgn0u4r000008l7eazybfbo"},"address":{"$ref":"#/components/schemas/Address"},"phone":{"type":["string","null"],"description":"The phone number of the customer.","example":"+1234567890"},"manufacturerSlugs":{"type":"array","items":{"type":"string"},"default":[],"description":"Optional array of manufacturer slugs associated with this enrollment. Defaults to empty array if not provided.","example":["tesla","enphase"]},"meta":{"type":"object","additionalProperties":{},"description":"Additional metadata as key-value pairs."},"serialNumber":{"type":["string","null"],"description":"The serial number of the device.","example":"1234567890"},"referenceId":{"type":"string","description":"The reference ID of the customer.","example":"1234567890"},"referenceDescription":{"type":["string","null"],"description":"The description of the reference ID.","example":"The customer is a new lead."},"tags":{"type":"array","items":{"type":"string"},"default":[],"description":"The tags for the enrollment.","example":["tag1","tag2"]},"enrollmentStartDate":{"type":["string","null"],"description":"The start date of the enrollment.","example":"2025-01-01T00:00:00Z"},"eligibility":{"type":"object","properties":{"status":{"type":"string","enum":["candidate","eligible","ineligible","submitted","approved","rejected","unenrolling","unenrolled"]},"reason":{"type":"string"}},"required":["status"],"description":"Initial eligibility status for the enrollment. If not provided, eligibility will be determined automatically."}},"required":["identificationType","enrollmentId"],"title":"Enrollment ID Enrollment"},{"type":"object","properties":{"identificationType":{"type":"string","enum":["leadId"]},"leadId":{"type":"string","description":"The unique identifier for the lead","example":"cllgn0u4r000008l7eazybfbo"},"address":{"$ref":"#/components/schemas/Address"},"phone":{"type":["string","null"],"description":"The phone number of the customer.","example":"+1234567890"},"manufacturerSlugs":{"type":"array","items":{"type":"string"},"default":[],"description":"Optional array of manufacturer slugs associated with this enrollment. Defaults to empty array if not provided.","example":["tesla","enphase"]},"meta":{"type":"object","additionalProperties":{},"description":"Additional metadata as key-value pairs."},"serialNumber":{"type":["string","null"],"description":"The serial number of the device.","example":"1234567890"},"referenceId":{"type":"string","description":"The reference ID of the customer.","example":"1234567890"},"referenceDescription":{"type":["string","null"],"description":"The description of the reference ID.","example":"The customer is a new lead."},"tags":{"type":"array","items":{"type":"string"},"default":[],"description":"The tags for the enrollment.","example":["tag1","tag2"]},"enrollmentStartDate":{"type":["string","null"],"description":"The start date of the enrollment.","example":"2025-01-01T00:00:00Z"},"eligibility":{"type":"object","properties":{"status":{"type":"string","enum":["candidate","eligible","ineligible","submitted","approved","rejected","unenrolling","unenrolled"]},"reason":{"type":"string"}},"required":["status"],"description":"Initial eligibility status for the enrollment. If not provided, eligibility will be determined automatically."}},"required":["identificationType","leadId","address"],"title":"Lead ID Enrollment","deprecated":true}]},"GetAuditLogsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string"},"resourceType":{"type":"string"},"resourceId":{"type":"string"},"actorType":{"type":"string"},"actorId":{"type":"string"},"organizationId":{"type":"string"},"workspaceId":{"type":["string","null"]},"metadata":{"type":["object","null"],"additionalProperties":{}},"createdAt":{"type":"string"}},"required":["id","action","resourceType","resourceId","actorType","actorId","organizationId","workspaceId","metadata","createdAt"]}},"meta":{"type":"object","properties":{"total":{"type":"number"},"page":{"type":"number"},"perPage":{"type":"number"}},"required":["total","page","perPage"]}},"required":["data","meta"]},"GetProgramInstanceParams":{"type":"object","properties":{"instanceId":{"type":"string","format":"cuid","description":"The ID of the program instance to retrieve.","example":"cllgn0u4r0000008l7eazybfbo"}},"required":["instanceId"]},"Interval":{"type":"object","properties":{"startDate":{"type":"string","format":"date-time","description":"The start date and time of the interval.","example":"2024-04-01T00:00:00.000Z"},"endDate":{"type":"string","format":"date-time","description":"The end date and time of the interval.","example":"2024-04-01T00:15:00.000Z"},"consumption":{"type":["number","null"],"description":"The amount of energy consumed during the interval.","example":3.2}},"required":["startDate","endDate"]},"InvitationCreated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the invitation.","example":"clx1234567890abcdef"},"email":{"type":"string","description":"The email address of the invited user.","example":"user@example.com"},"status":{"type":"string","enum":["PENDING","ACCEPTED","REVOKED"],"description":"The status of the invitation.","example":"PENDING"},"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The role assigned to the invitee upon acceptance.","example":"USER"},"organizationId":{"type":"string","description":"The ID of the organization the user is invited to.","example":"clx0987654321fedcba"},"organizationName":{"type":"string","description":"The name of the organization the user is invited to.","example":"Acme Corp"},"userId":{"type":"string","description":"The ID of the user who was invited.","example":"clx1111111111111111"},"userExists":{"type":"boolean","description":"Whether the invited user already has an account.","example":false},"sentAt":{"type":["string","null"],"format":"date-time","description":"The ISO 8601 timestamp when the invitation email was last sent.","example":"2025-01-15T00:00:00.000Z"},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the invitation was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the invitation was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","email","status","role","organizationId","organizationName","userId","userExists","sentAt","createdAt","updatedAt"]},"KafkaDestinationCreated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the destination.","example":"clx1234567890abcdef"},"workspaceId":{"type":"string","description":"The workspace this destination belongs to."},"label":{"type":["string","null"],"description":"A human-readable label for the destination."},"destinationType":{"type":["string","null"],"enum":["WEBHOOK","SMS","EMAIL","KAFKA","MANUFACTURER_COMMAND",null],"description":"The type of destination.","example":"WEBHOOK"},"deviceType":{"type":["string","null"],"enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN",null],"description":"Device types this destination applies to.","example":"ALL"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"description":"Event types that trigger this destination."},"url":{"type":["string","null"],"description":"The webhook URL (for WEBHOOK destinations)."},"email":{"type":["string","null"],"description":"The email address (for EMAIL destinations)."},"phoneNumber":{"type":["string","null"],"description":"The phone number (for SMS destinations)."},"secret":{"type":["string","null"],"description":"The webhook signing secret (for WEBHOOK destinations)."},"headers":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations)."},"includeWeather":{"type":["boolean","null"],"description":"Whether to include weather data in events."},"kafkaConfig":{"type":["object","null"],"additionalProperties":{},"description":"Kafka configuration (for KAFKA destinations)."},"deactivated":{"type":["boolean","null"],"description":"Whether this destination is deactivated."},"deactivatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was deactivated."},"deactivatedReason":{"type":["string","null"],"description":"Reason for deactivation."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When this destination was created."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was last updated."}},"required":["id","workspaceId","label","destinationType","deviceType","eventTypes","url","email","phoneNumber","secret","headers","includeWeather","kafkaConfig","deactivated","deactivatedAt","deactivatedReason","createdAt","updatedAt"]},"LinkSessionResponse":{"type":"object","properties":{"customerId":{"type":"string","description":"The ID of the customer associated with the link session.","example":"cllh2buhk000008la0ln6cb80"},"linkUrl":{"type":"string","format":"uri","description":"The URL to redirect to in order to start the link session.","example":"https://connect.texturehq.com/link_e47b6d39dd3e6b3ab55969f55dc88ae6"},"linkToken":{"type":"string","description":"The token used to identify the link session.","example":"link_e47b6d39dd3e6b3ab55969f55dc88ae6"},"linkSessionId":{"type":"string","description":"The ID of the connect session created for this link.","example":"cllh2buhk000008la0ln6cb80"},"expiresAt":{"type":"string","format":"date-time","description":"The date and time when the link session will expire.","example":"2022-02-22T22:22:22Z"},"siteId":{"type":"string","description":"The ID of the site resolved for this link session. Populated in headless mode.","example":"cllh2buhk000008la0ln6cb80"},"authorization":{"type":["object","null"],"properties":{"type":{"type":"string","description":"The type of authorization flow. For headless OAuth, this will be \"oauth_redirect\".","example":"oauth_redirect"},"url":{"type":["string","null"],"description":"The direct OAuth authorization URL to redirect the user to. Present only in headless mode.","example":"https://auth.manufacturer.com/oauth/authorize?client_id=..."}},"required":["type","url"],"description":"Authorization details returned in headless mode. Contains the OAuth URL to redirect the user to for device authorization."}},"required":["customerId","linkUrl","linkToken","linkSessionId","expiresAt"]},"ListApiKeysResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of API keys in the workspace."},"page":{"type":"number","description":"Current page number."},"perPage":{"type":"number","description":"Number of items per page."}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ListCollectionEntitiesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The entity ID.","example":"clx1234567890abcdef"},"name":{"type":["string","null"],"description":"The entity name.","example":"My EV"},"deviceType":{"type":["string","null"],"description":"The device type.","example":"VEHICLE"},"workspaceId":{"type":"string","description":"The workspace ID.","example":"clmt0f0qq000g6jez6qa2sj4t"},"manufacturer":{"type":["string","null"],"description":"The device manufacturer.","example":"TESLA"}},"required":["id","name","deviceType","workspaceId","manufacturer"]}},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of entities in the collection."},"page":{"type":"number","description":"Current page number."},"perPage":{"type":"number","description":"Number of items per page."}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ListCollectionsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Collection"}},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of collections in the workspace."},"page":{"type":"number","description":"Current page number."},"perPage":{"type":"number","description":"Number of items per page."}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ListDestinationsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Destination"}},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of destinations in the workspace."},"page":{"type":"number","description":"Current page number."},"perPage":{"type":"number","description":"Number of items per page."}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ListInvitationsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the invitation.","example":"clx1234567890abcdef"},"email":{"type":"string","description":"The email address of the invited user.","example":"user@example.com"},"status":{"type":"string","enum":["PENDING","ACCEPTED","REVOKED"],"description":"The status of the invitation.","example":"PENDING"},"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The role assigned to the invitee upon acceptance.","example":"USER"},"organizationId":{"type":"string","description":"The ID of the organization the user is invited to.","example":"clx0987654321fedcba"},"organizationName":{"type":"string","description":"The name of the organization the user is invited to.","example":"Acme Corp"},"userId":{"type":"string","description":"The ID of the user who was invited.","example":"clx1111111111111111"},"userExists":{"type":"boolean","description":"Whether the invited user already has an account.","example":false},"sentAt":{"type":["string","null"],"format":"date-time","description":"The ISO 8601 timestamp when the invitation email was last sent.","example":"2025-01-15T00:00:00.000Z"},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the invitation was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the invitation was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","email","status","role","organizationId","organizationName","userId","userExists","sentAt","createdAt","updatedAt"]},"description":"List of pending invitations."},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of invitations.","example":3},"page":{"type":"number","description":"Current page number.","example":1},"perPage":{"type":"number","description":"Number of items per page.","example":20}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ListMembersResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the membership.","example":"clx1234567890abcdef"},"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The role of the member in the organization.","example":"USER"},"organizationId":{"type":"string","description":"The ID of the organization this membership belongs to.","example":"clx0987654321fedcba"},"owner":{"type":"boolean","description":"Whether this member is the organization owner.","example":false},"isAdmin":{"type":"boolean","description":"Whether this member has admin privileges.","example":false},"userId":{"type":"string","description":"The ID of the user associated with this membership.","example":"clx1111111111111111"},"userProfile":{"type":["object","null"],"properties":{"id":{"type":"string","description":"The unique identifier of the user."},"firstName":{"type":["string","null"],"description":"The user's first name."},"lastName":{"type":["string","null"],"description":"The user's last name."},"email":{"type":["string","null"],"description":"The user's email address."}},"required":["id","firstName","lastName","email"],"description":"Profile of the member."},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the membership was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the membership was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","role","organizationId","owner","isAdmin","userId","userProfile","createdAt","updatedAt"]},"description":"List of organization members."},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of members.","example":5},"page":{"type":"number","description":"Current page number.","example":1},"perPage":{"type":"number","description":"Number of items per page.","example":20}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ListOAuthAppsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OAuthApp"}},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of OAuth applications in the workspace."},"page":{"type":"number","description":"Current page number."},"perPage":{"type":"number","description":"Number of items per page."}},"required":["total","page","perPage"]}},"required":["data","meta"]},"ManagementOrganization":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the organization.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The name of the organization.","example":"Acme Energy"},"domain":{"type":["string","null"],"description":"The domain of the organization.","example":"acme.energy"},"logo":{"type":["string","null"],"description":"URL to the organization's logo.","example":"https://cdn.example.com/logo.png"},"industry":{"type":["string","null"],"description":"The industry of the organization.","example":"solar"},"preferredTemperatureUnit":{"type":"string","description":"The preferred temperature unit.","example":"CELSIUS"},"mfaEmailOtpEnabled":{"type":"boolean","description":"Whether MFA email OTP is enabled.","example":false},"location":{"type":["object","null"],"properties":{"streetOne":{"type":["string","null"],"example":"123 Main St"},"streetTwo":{"type":["string","null"],"example":"Suite 100"},"city":{"type":["string","null"],"example":"San Francisco"},"state":{"type":["string","null"],"example":"CA"},"postalCode":{"type":["string","null"],"example":"94105"},"country":{"type":["string","null"],"example":"US"}},"description":"The physical location of the organization."},"createdAt":{"type":"string","description":"The ISO 8601 timestamp when the organization was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","description":"The ISO 8601 timestamp when the organization was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","name","preferredTemperatureUnit","mfaEmailOtpEnabled","createdAt","updatedAt"]},"ManagementOrganizationWithLocation":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the organization.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The name of the organization.","example":"Acme Energy"},"domain":{"type":["string","null"],"description":"The domain of the organization.","example":"acme.energy"},"logo":{"type":["string","null"],"description":"URL to the organization's logo.","example":"https://cdn.example.com/logo.png"},"industry":{"type":["string","null"],"description":"The industry of the organization.","example":"solar"},"preferredTemperatureUnit":{"type":"string","description":"The preferred temperature unit.","example":"CELSIUS"},"mfaEmailOtpEnabled":{"type":"boolean","description":"Whether MFA email OTP is enabled.","example":false},"location":{"type":["object","null"],"properties":{"streetOne":{"type":["string","null"],"example":"123 Main St"},"streetTwo":{"type":["string","null"],"example":"Suite 100"},"city":{"type":["string","null"],"example":"San Francisco"},"state":{"type":["string","null"],"example":"CA"},"postalCode":{"type":["string","null"],"example":"94105"},"country":{"type":["string","null"],"example":"US"}},"description":"The physical location of the organization."},"createdAt":{"type":"string","description":"The ISO 8601 timestamp when the organization was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","description":"The ISO 8601 timestamp when the organization was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","name","preferredTemperatureUnit","mfaEmailOtpEnabled","createdAt","updatedAt"]},"Manufacturers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the manufacturer.","example":"Tesla"},"slug":{"type":"string","description":"The unique string used internally to refer to the manufacturer.","example":"tesla"},"deviceTypes":{"type":"array","items":{"type":"string","enum":["battery","charger","inverter","meter","thermostat","vehicle","water_heater","other","unknown"]},"description":"The types of devices that this manufacturer supports.","example":["battery"]}},"required":["name","slug","deviceTypes"]}},"Member":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the membership.","example":"clx1234567890abcdef"},"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The role of the member in the organization.","example":"USER"},"organizationId":{"type":"string","description":"The ID of the organization this membership belongs to.","example":"clx0987654321fedcba"},"owner":{"type":"boolean","description":"Whether this member is the organization owner.","example":false},"isAdmin":{"type":"boolean","description":"Whether this member has admin privileges.","example":false},"userId":{"type":"string","description":"The ID of the user associated with this membership.","example":"clx1111111111111111"},"userProfile":{"type":["object","null"],"properties":{"id":{"type":"string","description":"The unique identifier of the user."},"firstName":{"type":["string","null"],"description":"The user's first name."},"lastName":{"type":["string","null"],"description":"The user's last name."},"email":{"type":["string","null"],"description":"The user's email address."}},"required":["id","firstName","lastName","email"],"description":"Profile of the member."},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the membership was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the membership was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","role","organizationId","owner","isAdmin","userId","userProfile","createdAt","updatedAt"]},"MemberUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the membership.","example":"clx1234567890abcdef"},"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The role of the member in the organization.","example":"USER"},"organizationId":{"type":"string","description":"The ID of the organization this membership belongs to.","example":"clx0987654321fedcba"},"owner":{"type":"boolean","description":"Whether this member is the organization owner.","example":false},"isAdmin":{"type":"boolean","description":"Whether this member has admin privileges.","example":false},"userId":{"type":"string","description":"The ID of the user associated with this membership.","example":"clx1111111111111111"},"userProfile":{"type":["object","null"],"properties":{"id":{"type":"string","description":"The unique identifier of the user."},"firstName":{"type":["string","null"],"description":"The user's first name."},"lastName":{"type":["string","null"],"description":"The user's last name."},"email":{"type":["string","null"],"description":"The user's email address."}},"required":["id","firstName","lastName","email"],"description":"Profile of the member."},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the membership was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the membership was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","role","organizationId","owner","isAdmin","userId","userProfile","createdAt","updatedAt"]},"OAuthApp":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the OAuth application.","example":"clx1234567890abcdef"},"clientId":{"type":"string","description":"The OAuth client ID used in authorization flows.","example":"texture_client_a1b2c3d4"},"name":{"type":"string","description":"The human-readable name for the OAuth application.","example":"My Energy App"},"description":{"type":["string","null"],"description":"An optional description of the OAuth application.","example":"Connects customers to their energy data."},"redirectUris":{"type":"array","items":{"type":"string"},"description":"The list of allowed redirect URIs for the OAuth flow.","example":["https://myapp.com/callback"]},"allowedScopes":{"type":"array","items":{"type":"string"},"description":"The list of OAuth scopes this application is allowed to request.","example":["read:devices","read:sites"]},"type":{"type":"string","enum":["PUBLIC","CONFIDENTIAL"],"description":"The OAuth application type. CONFIDENTIAL apps can store secrets securely; PUBLIC apps cannot.","example":"CONFIDENTIAL"},"isFirstParty":{"type":"boolean","description":"Whether this is a first-party Texture application.","example":false},"workspaceId":{"type":"string","description":"The workspace this OAuth application belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time this OAuth application was created.","example":"2025-06-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time this OAuth application was last updated.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","clientId","name","description","redirectUris","allowedScopes","type","isFirstParty","workspaceId","createdAt","updatedAt"]},"OAuthAppCreated":{"allOf":[{"$ref":"#/components/schemas/OAuthApp"},{"type":"object","properties":{"clientSecret":{"type":"string","description":"The OAuth client secret. This is only returned once at creation time — store it securely. It cannot be retrieved again.","example":"texture_secret_a1b2c3d4e5f6g7h8i9j0"}},"required":["clientSecret"]}]},"OAuthAppSecret":{"type":"object","properties":{"clientId":{"type":"string","description":"The OAuth client ID.","example":"texture_client_a1b2c3d4"},"clientSecret":{"type":"string","description":"The new OAuth client secret. Store it securely — it will not be shown again.","example":"texture_secret_newxyz987"}},"required":["clientId","clientSecret"]},"OAuthAppUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the OAuth application.","example":"clx1234567890abcdef"},"clientId":{"type":"string","description":"The OAuth client ID used in authorization flows.","example":"texture_client_a1b2c3d4"},"name":{"type":"string","description":"The human-readable name for the OAuth application.","example":"My Energy App"},"description":{"type":["string","null"],"description":"An optional description of the OAuth application.","example":"Connects customers to their energy data."},"redirectUris":{"type":"array","items":{"type":"string"},"description":"The list of allowed redirect URIs for the OAuth flow.","example":["https://myapp.com/callback"]},"allowedScopes":{"type":"array","items":{"type":"string"},"description":"The list of OAuth scopes this application is allowed to request.","example":["read:devices","read:sites"]},"type":{"type":"string","enum":["PUBLIC","CONFIDENTIAL"],"description":"The OAuth application type. CONFIDENTIAL apps can store secrets securely; PUBLIC apps cannot.","example":"CONFIDENTIAL"},"isFirstParty":{"type":"boolean","description":"Whether this is a first-party Texture application.","example":false},"workspaceId":{"type":"string","description":"The workspace this OAuth application belongs to.","example":"clmt0f0qq000g6jez6qa2sj4t"},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time this OAuth application was created.","example":"2025-06-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time this OAuth application was last updated.","example":"2025-06-01T00:00:00.000Z"}},"required":["id","clientId","name","description","redirectUris","allowedScopes","type","isFirstParty","workspaceId","createdAt","updatedAt"]},"OrganizationUsage":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the usage record.","example":"clx1234567890abcdef"},"date":{"type":"string","description":"The ISO 8601 date for this usage record.","example":"2025-01-15T00:00:00.000Z"},"deviceCount":{"type":"integer","description":"The number of active devices on this date.","example":42},"energyUsage":{"type":"number","description":"The total energy usage in kWh on this date.","example":1234.56},"organizationId":{"type":"string","description":"The organization this usage record belongs to.","example":"clx0987654321fedcba"},"workspaceId":{"type":"string","description":"The workspace this usage record belongs to.","example":"clx1111111111111111"}},"required":["id","date","deviceCount","energyUsage","organizationId","workspaceId"]},"description":"List of usage records for the organization."}},"required":["data"]},"Permit":{"type":"object","properties":{"id":{"type":"string","description":"The ID of the permit.","example":"123"},"description":{"type":["string","null"],"description":"The description on the permit. This is a free-form text field that can contain any information about the permit.","example":"Install 27 kwh back-up batteries in cabinet"},"number":{"type":"string","description":"The permit number provided by the jurisdiction.","example":"B2303829"},"jurisdiction":{"type":"string","description":"The jurisdiction where permit was filled.","example":"Berkeley"},"jobValue":{"type":["number","null"],"description":"The reported job value on the permit in cents (integer value representing dollars * 100).","example":500100},"type":{"type":["string","null"],"description":"The type of permit.","example":"Building alteration: 3+ residential units or commercial"},"status":{"type":["string","null"],"description":"The status of the permit.","example":"active"},"fileDate":{"type":["string","null"],"description":"The date the permit was filed.","example":"2023-10-02"},"tags":{"type":["array","null"],"items":{"type":["string","null"]},"description":"The list of tags associated with the permit.","example":["solar","utilities","residential","solar_battery_storage"]}},"required":["id","number","jurisdiction"]},"PostAlertsBody":{"type":"object","properties":{"siteId":{"type":"string","format":"cuid","description":"The unique identifier of the site this alert is related to.","example":"cllgn0u4r000008l7eazybfbo"},"deviceId":{"type":["string","null"],"format":"cuid","description":"The unique identifier of the device this alert is related to.","example":"cllgn0u4r000008l7eazybfbo"},"title":{"type":"string","description":"The title of the alert.","example":"Device is offline"},"description":{"type":["string","null"],"description":"Additional description or details about the alert.","example":"The thermostat in the bedroom has been offline for 15 minutes."},"sourceSystem":{"type":"string","description":"The source system that generated the alert.","example":"texture"},"alertType":{"type":["string","null"],"description":"The type/category of the alert.","example":"device_offline"},"type":{"type":["string","null"],"enum":["COMMUNICATIONS","POWER_LIMIT","GRID_STATUS","HARDWARE_FAULT","FIRMWARE_UPDATE","CONFIGURATION","VOLTAGE_FREQUENCY","STATE_OF_ENERGY","TEMPERATURE","ISLANDING","GENERATOR","SOFTWARE_PROCESS","SENSOR","SYSTEM_SHUTDOWN","PERFORMANCE_DEGRADED","SITE_LEVEL","SAFETY","UNKNOWN",null],"description":"Normalized alert type. Defaults to UNKNOWN when omitted.","example":"HARDWARE_FAULT"},"subtype":{"type":["string","null"],"enum":["BATTERY_METER_COMMS","INVERTER_COMMS","PV_INVERTER_COMMS","SITE_CONTROLLER_COMMS","SITE_MAX_LIMITED","SITE_MIN_LIMITED","RAMP_RATE_LIMITED","POWER_FACTOR_LIMITED","GRID_FORMING","GRID_FOLLOWING","GRID_RESYNC_FAILED","INVERTER_FAULT","BATTERY_FAULT","CONTACTOR_FAULT","GENERATOR_FAULT","OPTICASTER_EXE_FAILED","CONTROL_AGENT_CRASHED","LOW_SOE","SLEEP_MODE","WAIT_FOR_SOLAR","EXTERNAL_SWITCH_SHUTDOWN","GPIO_SHUTDOWN","EXCESSIVE_VOLTAGE_DROP","FREQUENCY_DEVIATION","METER_DISCONNECTED","TEMPERATURE_SENSOR_FAULT","PERFORMANCE_BELOW_EXPECTATION",null],"description":"Optional normalized subtype.","example":"BATTERY_METER_COMMS"},"providerCode":{"type":["string","null"],"description":"Provider specific code associated with the alert.","example":"3019"},"providerName":{"type":["string","null"],"description":"Provider display name associated with the alert.","example":"Battery Meter Comms"},"severity":{"type":"string","enum":["CRITICAL","WARNING","INFO"],"description":"The severity level of the alert.","example":"WARNING"}},"required":["siteId","title","sourceSystem","severity"]},"PostVirtualAccountsBody":{"type":"object","properties":{"type":{"type":"string","enum":["DEFAULT","OAUTH"],"description":"Account type. Defaults to OAUTH for Connect flow testing.","example":"OAUTH"},"name":{"type":"string","maxLength":255,"description":"Optional display name for the account.","example":"Test Tester 1"},"tags":{"type":"array","items":{"type":"string"},"description":"Optional tags.","example":[]}}},"PostVirtualDevicesBody":{"type":"object","properties":{"type":{"type":"string","enum":["battery","charger","thermostat","vehicle","inverter"],"description":"The type of virtual device to create.","example":"thermostat"},"accountType":{"type":"string","enum":["DEFAULT","OAUTH"],"description":"Account type. OAUTH creates a new account with Connect flow credentials. DEFAULT (or omitted) reuses the workspace's single DEFAULT account.","example":"OAUTH"},"accountId":{"type":"string","description":"Add the device to an existing account. Takes precedence over accountType.","example":"cmndh0b1w000311cwn3fpdxa7"},"tags":{"type":"array","items":{"type":"string"},"description":"Optional tags to associate with the device.","example":["site-123","program-abc"]}},"required":["type"]},"PostVirtualDevicesConnectBody":{"type":"object","properties":{"siteId":{"type":"string","description":"Optional Texture site ID to associate the device with.","example":"clmqmlukr000008jud0fofjgp"},"customerId":{"type":"string","description":"Optional Texture contact (customer) ID to associate the device with.","example":"clmqmlukr000008jud0fofjgp"},"referenceId":{"type":"string","minLength":1,"description":"Optional external reference ID to store on the device. Takes precedence over everything else. If omitted, defaults to the linked customer's referenceId when `customerId` is provided, otherwise the virtual account ID.","example":"external-ref-123"},"tags":{"type":"array","items":{"type":"string"},"description":"Optional tags to apply to the device.","example":["integration-test"]},"name":{"type":"string","maxLength":255,"description":"Optional display name for the device on the platform.","example":"Living Room Thermostat"}}},"Program":{"type":"object","properties":{"slug":{"type":"string","description":"The slug of the program. Machine-readable identifier.","example":"nyc-battery-program-2025"},"name":{"type":"string","description":"The name of the program.","example":"NYC Battery Program 2025"},"description":{"type":"string","description":"The description of the program.","example":"This program is for homeowners in NYC that have installed battery storage systems."},"endTime":{"type":"string","format":"date-time","description":"The end time of the program.","example":"2025-12-31T23:59:59Z"},"states":{"type":"array","items":{"type":"string","pattern":"^[A-Z]{2}$"},"description":"The states of the program.","example":["NY","NJ"]},"year":{"type":["integer","null"],"description":"The year of the program.","example":2025},"active":{"type":"boolean","description":"Whether the program is currently active.","example":true}},"required":["slug","name","description","states","year","active"]},"ProgramEvent":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the program event.","example":"cllgn0u4r000008l7eazybfbo"},"programInstanceId":{"type":"string","format":"cuid","description":"The unique identifier of the program instance this event belongs to.","example":"cllgn0u4r000008l7eazybfbo"},"type":{"type":"string","description":"The type of the program event.","example":"discharge"},"startsAt":{"type":"string","format":"date-time","description":"The date and time the program event starts.","example":"2025-01-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time the program event ends.","example":"2025-01-01T00:00:00Z"},"dispatches":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the command batch.","example":"cllgn0u4r000008l7eazybfbo"},"startsAt":{"type":"string","format":"date-time","description":"The date and time the command batch starts.","example":"2025-01-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time the command batch ends.","example":"2025-01-01T00:00:00Z"},"type":{"type":"string","enum":["battery:set-reserve","battery:set-operating-mode","charger:set-operating-mode","thermostat:set-operating-mode","thermostat:set-fan-mode","thermostat:pause-schedule","thermostat:resume-schedule","vehicle:check-pairing-status","vehicle:set-charge-limit","vehicle:set-operating-mode"],"description":"The unique slug representing the type of command.","example":"thermostat:set-operating-mode"},"issuedAt":{"type":"string","format":"date-time","description":"The date and time the command was issued."},"input":{"type":"object","properties":{},"additionalProperties":{},"description":"The input payload sent with the command. Includes necessary information for execution. Conforms to the schema provided on the command type.","example":{"operatingMode":"eco","heatTarget":70.5,"coolTarget":80.5}},"metrics":{"type":"object","properties":{"counts":{"type":"object","properties":{"total":{"type":"number","description":"Total number of commands in the batch","example":100},"pending":{"type":"number","description":"Number of pending commands","example":50},"scheduled":{"type":"number","description":"Number of commands scheduled","example":20},"delivered":{"type":"number","description":"Number of commands in the `delivered` state: the OEM accepted the command but device state verification has not yet completed.","example":10},"completed":{"type":"number","description":"Number of completed commands","example":25},"failed":{"type":"number","description":"Number of failed commands","example":5}},"required":["total","pending","scheduled","delivered","completed","failed"],"description":"Counts of commands by their status within the batch"}},"required":["counts"],"description":"Metrics about the commands in the batch."}},"required":["id","startsAt","endsAt","type","issuedAt","input","metrics"]},"description":"The command batches associated with the program event."}},"required":["id","programInstanceId","type","startsAt","endsAt","dispatches"]},"ProgramInstance":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the program instance.","example":"cllgn0u4r000008l7eazybfbo"},"program":{"$ref":"#/components/schemas/Program"},"slug":{"type":"string","description":"The slug of the program instance.","example":"nyc-battery-program-2025-instance-1"},"title":{"type":"string","description":"The title of the program instance.","example":"NYC Battery Program 2025"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the program instance was created.","example":"2025-01-01T00:00:00Z"}},"required":["id","program","slug","title","createdAt"]},"PublicDeviceModels":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","description":"The unique slug identifier for the device model.","example":"tesla:powerwall_2"},"name":{"type":"string","description":"The human-readable name of the device model.","example":"Powerwall 2"},"type":{"type":"string","description":"The type of device.","example":"battery"},"manufacturer":{"type":"object","properties":{"slug":{"type":"string","description":"The manufacturer slug.","example":"tesla"},"name":{"type":"string","description":"The manufacturer name.","example":"Tesla"}},"required":["slug","name"],"description":"The manufacturer of this device model."},"available_commands":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string","description":"The command slug identifier.","example":"battery:set-reserve"},"support_level":{"type":"string","description":"The support level of this command.","example":"production"}},"required":["slug","support_level"]},"description":"Commands available for this device model."}},"required":["slug","name","type","manufacturer","available_commands"]}},"total":{"type":"number"},"limit":{"type":"number"},"page":{"type":"number"},"pageCount":{"type":"number"}},"required":["data","total","limit","page","pageCount"]},"PublicManufacturers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the manufacturer.","example":"Tesla"},"slug":{"type":"string","description":"The unique slug identifier for the manufacturer.","example":"tesla"},"supportLevel":{"type":"string","enum":["blocked","planned","development","uat","production"],"description":"The current support level of the manufacturer integration.","example":"production"},"supportsGridServices":{"type":"boolean","description":"Whether this manufacturer supports grid services.","example":true},"deviceTypes":{"type":"array","items":{"type":"string"},"description":"The types of devices this manufacturer supports.","example":["battery","inverter"]},"pollingInterval":{"type":["string","null"],"description":"How frequently Texture polls this manufacturer for device state updates.","example":"FIFTEEN_MINUTES"},"logoUrl":{"type":"string","description":"URL to the manufacturer's logo image.","example":"https://brands.texturehq.com/brands/logo/128/tesla.png"},"iconUrl":{"type":"string","description":"URL to the manufacturer's icon image (64px).","example":"https://brands.texturehq.com/brands/icon/64/tesla.png"},"vectorIconUrl":{"type":"string","description":"URL to the manufacturer's high-resolution icon image (512px).","example":"https://brands.texturehq.com/brands/icon/512/tesla.png"}},"required":["name","slug","supportLevel","supportsGridServices","deviceTypes","pollingInterval","logoUrl","iconUrl","vectorIconUrl"]}},"Site":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the Site issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"name":{"type":["string","null"],"description":"The name of the Site."},"referenceId":{"type":["string","null"],"description":"The reference ID of the Site.","example":"9bb290c8-fe97-46ce-92a8-952823164277"},"workspaceId":{"type":"string","format":"cuid","description":"The unique identifier for the Workspace to which the Site belongs, issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time that this Site was created.","example":"2024-04-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time that this Site was last updated.","example":"2024-04-01T00:00:00.000Z"},"devices":{"type":"array","items":{"$ref":"#/components/schemas/Device"}},"connectedCustomers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the customer issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"workspaceId":{"type":"string","format":"cuid","description":"The unique identifier for the workspace issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"referenceId":{"type":["string","null"],"description":"The reference ID for the customer.","example":"01234567"},"firstName":{"type":["string","null"],"description":"The given name of the customer.","example":"John"},"lastName":{"type":["string","null"],"description":"The surname of the customer.","example":"Smith"},"email":{"type":["string","null"],"description":"The email address of the customer.","example":"test@example.com"},"phone":{"type":["string","null"],"description":"The phone number of the customer as provided during creation or update.","example":"1234567890"},"devices":{"type":"array","items":{"$ref":"#/components/schemas/Device"},"description":"The devices connected to the customer."},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time the customer was created in the system.","example":"2026-08-09T11:43:47.853Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time the customer was last updated in the system.","example":"2026-08-09T11:43:47.854Z"}},"required":["id","workspaceId","referenceId","createdAt"]}},"location":{"type":"object","properties":{"streetOne":{"type":["string","null"],"description":"The first line of the street location.","example":"123 Main St"},"streetTwo":{"type":["string","null"],"description":"The second line of the street location.","example":"Apt 4B"},"city":{"type":["string","null"],"description":"The city of the location.","example":"Springfield"},"state":{"type":["string","null"],"description":"The state or province of the location.","example":"IL"},"postalCode":{"type":["string","null"],"description":"The postal or ZIP code of the location.","example":"62701"},"country":{"type":["string","null"],"description":"The country of the location.","example":"USA"},"latitude":{"type":["number","null"],"description":"The latitude coordinate of the location.","example":39.7817},"longitude":{"type":["number","null"],"description":"The longitude coordinate of the location.","example":-89.6501}}},"energyUsage":{"type":["array","null"],"items":{"type":"object","properties":{"startDate":{"type":"string","format":"date-time","description":"The start date and time of the energy usage period.","example":"2024-04-01T00:00:00.000Z"},"endDate":{"type":"string","format":"date-time","description":"The end date and time of the energy usage period.","example":"2024-04-01T00:00:00.000Z"},"consumption":{"type":"number","description":"Total energy consumed at the Site during the period.","example":100},"price":{"type":"number","description":"The price of the energy consumed during the period.","example":0.1},"emissions":{"type":"number","description":"The amount of emissions produced during the period.","example":0.1},"cost":{"type":"object","properties":{"amount":{"type":"integer","description":"The integer representation of the cost of the energy consumed during the period.","example":10},"currencyCode":{"type":"string","description":"The currency code of the cost.","example":"USD"},"formatted":{"type":"string","description":"The formatted cost of the energy consumed during the period.","example":"$10.00"}},"required":["amount","currencyCode","formatted"]}},"required":["startDate","endDate","consumption"]}},"utility":{"type":"object","properties":{"name":{"type":"string","description":"The name of the utility provider.","example":"Pacifc Gas and Electric"}},"required":["name"],"description":"The utility for the Site."},"wholesaleMarket":{"type":"object","properties":{"name":{"type":"string","description":"The name of the wholesale market.","example":"California Independent Systems Operator"}},"required":["name"],"description":"The wholesale market for the Site."},"weather":{"$ref":"#/components/schemas/WeatherData"},"permits":{"type":"array","items":{"$ref":"#/components/schemas/Permit"},"description":"The list of permits associated with the Site. Only available for workspaces with an enabled permits integration."},"energyModeling":{"$ref":"#/components/schemas/EnergyModelingData"},"intervals":{"type":"array","items":{"$ref":"#/components/schemas/Interval"},"description":"The list of intervals associated with the Site."}},"required":["id","workspaceId","createdAt"]},"Sites":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Site"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]},"TagSchedule":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the device schedule.","example":"clpkn2je80006102tx7d0jhb8","readOnly":true},"workspaceId":{"type":"string","description":"The workspace ID that this schedule belongs to.","example":"clpkn2je80006102tx7d0jhb8"},"tag":{"type":"string","description":"The tag that this schedule belongs to.","example":"tag-value"},"deviceType":{"type":"string","enum":["battery","thermostat","vehicle"],"description":"The device type that this schedule belongs to.","example":"thermostat"},"timezone":{"type":"string","description":"A valid timezone string","example":"America/New_York"},"startsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule starts.","example":"2021-04-01T00:00:00.000Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule ends.","example":"2021-04-01T00:00:00.000Z"},"defaultDeviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}},"rules":{"type":"array","items":{"type":"object","properties":{"daysOfWeek":{"type":"array","items":{"type":"integer"},"example":[0,1,2,3,4,5,6],"description":"The days of the week the rule is active, numbered 0-6, where 0 is Sunday. In the example the rule is active every day of the week."},"startTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"endTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"deviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}}},"required":["daysOfWeek","startTime","endTime","deviceOperatingMode"]}},"createdAt":{"type":"string","format":"date-time","description":"The date and time that this schedule was created.","example":"2021-04-01T00:00:00.000Z","readOnly":true},"updatedAt":{"type":"string","format":"date-time","description":"The date and time that this schedule was last updated.","example":"2021-04-01T00:00:00.000Z","readOnly":true}},"required":["id","workspaceId","tag","deviceType","timezone","startsAt","defaultDeviceOperatingMode","rules","createdAt"]},"VirtualDeviceCreatedResponse":{"type":"object","properties":{"id":{"type":"string","example":"cmne5f7jj0001z5d2bbeyz5bj"},"type":{"type":"string","example":"thermostat"},"model":{"type":"string","example":"texture:thermostat"},"tags":{"type":"array","items":{"type":"string"},"example":[]},"accountId":{"type":"string","example":"cmn8ic73x0004gd21pyyxfuop"},"accountType":{"type":"string","enum":["DEFAULT","OAUTH"],"example":"DEFAULT"}},"required":["id","type","model","tags","accountId","accountType"]},"WeatherData":{"type":"object","properties":{"provider":{"type":"string","description":"The provider of the weather data.","example":"OpenWeatherMap"},"dewPoint":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the dew point.","example":"C"},"value":{"type":"number","description":"The value of the dew point.","example":20}},"required":["unit","value"]},"humidity":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the humidity.","example":"%"},"value":{"type":"number","description":"The value of the humidity.","example":50}},"required":["unit","value"]},"temperature":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the temperature.","example":"C"},"value":{"type":"number","description":"The value of the temperature.","example":20}},"required":["unit","value"]},"conditions":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the conditions.","example":"Sunny"},"value":{"type":"string","description":"The value of the conditions.","example":"Sunny"}},"required":["unit","value"]},"cloudiness":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the cloudiness.","example":"%"},"value":{"type":"number","description":"The value of the cloudiness.","example":50}},"required":["unit","value"]},"sunrise":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the sunrise.","example":"iso8601"},"value":{"type":"string","description":"The value of the sunrise.","example":"2024-04-01T07:00:00.000Z"}},"required":["unit","value"]},"sunset":{"type":["object","null"],"properties":{"unit":{"type":"string","description":"The unit of the sunset.","example":"iso8601"},"value":{"type":"string","description":"The value of the sunset.","example":"2024-04-01T19:00:00.000Z"}},"required":["unit","value"]}},"required":["provider"],"description":"Current weather and forecast data for the site location. Only included when specifically requested."},"WebhookDestinationCreated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the destination.","example":"clx1234567890abcdef"},"workspaceId":{"type":"string","description":"The workspace this destination belongs to."},"label":{"type":["string","null"],"description":"A human-readable label for the destination."},"destinationType":{"type":["string","null"],"enum":["WEBHOOK","SMS","EMAIL","KAFKA","MANUFACTURER_COMMAND",null],"description":"The type of destination.","example":"WEBHOOK"},"deviceType":{"type":["string","null"],"enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN",null],"description":"Device types this destination applies to.","example":"ALL"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"description":"Event types that trigger this destination."},"url":{"type":["string","null"],"description":"The webhook URL (for WEBHOOK destinations)."},"email":{"type":["string","null"],"description":"The email address (for EMAIL destinations)."},"phoneNumber":{"type":["string","null"],"description":"The phone number (for SMS destinations)."},"secret":{"type":["string","null"],"description":"The webhook signing secret (for WEBHOOK destinations)."},"headers":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations)."},"includeWeather":{"type":["boolean","null"],"description":"Whether to include weather data in events."},"kafkaConfig":{"type":["object","null"],"additionalProperties":{},"description":"Kafka configuration (for KAFKA destinations)."},"deactivated":{"type":["boolean","null"],"description":"Whether this destination is deactivated."},"deactivatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was deactivated."},"deactivatedReason":{"type":["string","null"],"description":"Reason for deactivation."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When this destination was created."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was last updated."}},"required":["id","workspaceId","label","destinationType","deviceType","eventTypes","url","email","phoneNumber","secret","headers","includeWeather","kafkaConfig","deactivated","deactivatedAt","deactivatedReason","createdAt","updatedAt"]},"WebhookDestinationEnabled":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the destination.","example":"clx1234567890abcdef"},"workspaceId":{"type":"string","description":"The workspace this destination belongs to."},"label":{"type":["string","null"],"description":"A human-readable label for the destination."},"destinationType":{"type":["string","null"],"enum":["WEBHOOK","SMS","EMAIL","KAFKA","MANUFACTURER_COMMAND",null],"description":"The type of destination.","example":"WEBHOOK"},"deviceType":{"type":["string","null"],"enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN",null],"description":"Device types this destination applies to.","example":"ALL"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"description":"Event types that trigger this destination."},"url":{"type":["string","null"],"description":"The webhook URL (for WEBHOOK destinations)."},"email":{"type":["string","null"],"description":"The email address (for EMAIL destinations)."},"phoneNumber":{"type":["string","null"],"description":"The phone number (for SMS destinations)."},"secret":{"type":["string","null"],"description":"The webhook signing secret (for WEBHOOK destinations)."},"headers":{"type":["object","null"],"additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations)."},"includeWeather":{"type":["boolean","null"],"description":"Whether to include weather data in events."},"kafkaConfig":{"type":["object","null"],"additionalProperties":{},"description":"Kafka configuration (for KAFKA destinations)."},"deactivated":{"type":["boolean","null"],"description":"Whether this destination is deactivated."},"deactivatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was deactivated."},"deactivatedReason":{"type":["string","null"],"description":"Reason for deactivation."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When this destination was created."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When this destination was last updated."}},"required":["id","workspaceId","label","destinationType","deviceType","eventTypes","url","email","phoneNumber","secret","headers","includeWeather","kafkaConfig","deactivated","deactivatedAt","deactivatedReason","createdAt","updatedAt"]},"Workspace":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the workspace.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The display name of the workspace.","example":"Production"},"organizationId":{"type":"string","description":"The ID of the organization this workspace belongs to.","example":"clx0987654321fedcba"},"deletionProtection":{"type":"boolean","description":"Whether deletion protection is enabled for this workspace.","example":true},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","name","organizationId","deletionProtection","createdAt","updatedAt"]},"WorkspaceInvitationCreated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the workspace invitation.","example":"clx1234567890abcdef"},"recipientEmail":{"type":"string","description":"The email address of the invited user.","example":"user@example.com"},"status":{"type":"string","enum":["PENDING","CANCELLED","ACCEPTED"],"description":"The status of the workspace invitation.","example":"PENDING"},"createdBy":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the user who created the invitation.","example":"clx1234567890abcdef"},"firstName":{"type":["string","null"],"description":"The first name of the user who created the invitation.","example":"Jane"},"lastName":{"type":["string","null"],"description":"The last name of the user who created the invitation.","example":"Doe"},"fullName":{"type":["string","null"],"description":"The full name of the user who created the invitation.","example":"Jane Doe"}},"required":["id","firstName","lastName","fullName"]}},"required":["id","recipientEmail","status","createdBy"]},"WorkspaceInvitationsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the workspace invitation.","example":"clx1234567890abcdef"},"recipientEmail":{"type":"string","description":"The email address of the invited user.","example":"user@example.com"},"status":{"type":"string","enum":["PENDING","CANCELLED","ACCEPTED"],"description":"The status of the workspace invitation.","example":"PENDING"},"createdBy":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the user who created the invitation.","example":"clx1234567890abcdef"},"firstName":{"type":["string","null"],"description":"The first name of the user who created the invitation.","example":"Jane"},"lastName":{"type":["string","null"],"description":"The last name of the user who created the invitation.","example":"Doe"},"fullName":{"type":["string","null"],"description":"The full name of the user who created the invitation.","example":"Jane Doe"}},"required":["id","firstName","lastName","fullName"]}},"required":["id","recipientEmail","status","createdBy"]},"description":"List of workspace invitations."}},"required":["data"]},"WorkspaceList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the workspace.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The display name of the workspace.","example":"Production"},"organizationId":{"type":"string","description":"The ID of the organization this workspace belongs to.","example":"clx0987654321fedcba"},"deletionProtection":{"type":"boolean","description":"Whether deletion protection is enabled for this workspace.","example":true},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","name","organizationId","deletionProtection","createdAt","updatedAt"]},"description":"List of workspaces."},"meta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of workspaces across all pages.","example":3},"page":{"type":"number","description":"Current page number.","example":1},"perPage":{"type":"number","description":"Number of items per page.","example":20}},"required":["total","page","perPage"]}},"required":["data","meta"]},"WorkspaceProtectionUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the workspace.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The display name of the workspace.","example":"Production"},"organizationId":{"type":"string","description":"The ID of the organization this workspace belongs to.","example":"clx0987654321fedcba"},"deletionProtection":{"type":"boolean","description":"Whether deletion protection is enabled for this workspace.","example":true},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","name","organizationId","deletionProtection","createdAt","updatedAt"]},"WorkspaceUpdated":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the workspace.","example":"clx1234567890abcdef"},"name":{"type":"string","description":"The display name of the workspace.","example":"Production"},"organizationId":{"type":"string","description":"The ID of the organization this workspace belongs to.","example":"clx0987654321fedcba"},"deletionProtection":{"type":"boolean","description":"Whether deletion protection is enabled for this workspace.","example":true},"createdAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was created.","example":"2025-01-15T00:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"The ISO 8601 timestamp when the workspace was last updated.","example":"2025-01-15T00:00:00.000Z"}},"required":["id","name","organizationId","deletionProtection","createdAt","updatedAt"]}},"parameters":{}},"paths":{"/alerts":{"get":{"description":"Get a list of alerts","summary":"Get all alerts for a workspace with additional optional filtering","tags":["alerts"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid"},"required":false,"in":"query","name":"id","description":"Filter alerts by ID.","example":"clm1a2b3c4d5e6f7g8h9i0j1"},{"schema":{"type":"string"},"required":false,"in":"query","name":"externalId","description":"Filter alerts by external ID.","example":"124254116"},{"schema":{"type":"string","enum":["CRITICAL","WARNING","INFO"],"description":"The severity level of the alert.","example":"WARNING"},"required":false,"description":"Filter alerts by severity level.","in":"query","name":"severity"},{"schema":{"type":"string","enum":["OPEN","ACKNOWLEDGED","IGNORED","RESOLVED"],"description":"The current status of the alert.","example":"OPEN"},"required":false,"description":"Filter alerts by status.","in":"query","name":"status"},{"schema":{"type":"string"},"required":false,"in":"query","name":"deviceId","description":"Filter alerts by device ID.","example":"cllgn0u4r000008l7eazybfbo"},{"schema":{"type":"string"},"required":false,"in":"query","name":"siteId","description":"Filter alerts by site ID.","example":"cllgn0u4r000008l7eazybfbo"},{"schema":{"type":"string"},"required":false,"in":"query","name":"sourceSystem","description":"Filter alerts by source system.","example":"Inverter 01"},{"schema":{"type":"string"},"required":false,"in":"query","name":"manufacturerDeviceId","description":"Filter alerts by manufacturer device ID.","example":"123456"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Object with alerts data and pagination info","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Alert"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized"},"404":{"description":"Not found"},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new alert","summary":"Create a new alert for a workspace","tags":["alerts"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostAlertsBody"}}}},"responses":{"201":{"description":"Alert created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"400":{"description":"Invalid input or API key","content":{"text/plain":{"schema":{"type":"string","example":"Invalid input"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"text/plain":{"schema":{"type":"string","example":"Forbidden"}}}},"500":{"description":"Internal server error","content":{"text/plain":{"schema":{"type":"string","example":"Something went wrong"}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/alerts/{id}/acknowledge":{"patch":{"description":"Acknowledge an alert","summary":"Acknowledge an alert","tags":["alerts"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the alert issued by Texture.","example":"clm1a2b3c4d5e6f7g8h9i0j1"},"required":true,"description":"The unique identifier for the alert issued by Texture.","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"snoozeUntil":{"type":["string","null"],"format":"date-time","description":"Optional date and time to snooze alert until.","example":"2024-01-15T12:00:00Z"}}}}}},"responses":{"200":{"description":"Acknowledge an alert","content":{"application/json":{"schema":{"type":"object","properties":{"snoozeUntil":{"type":["string","null"],"format":"date-time","description":"Optional date and time to snooze alert until.","example":"2024-01-15T12:00:00Z"}}}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Alert not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/alerts/{id}/ignore":{"patch":{"description":"Ignore an alert","summary":"Ignore an alert","tags":["alerts"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the alert issued by Texture.","example":"clm1a2b3c4d5e6f7g8h9i0j1"},"required":true,"description":"The unique identifier for the alert issued by Texture.","name":"id","in":"path"}],"responses":{"200":{"description":"Ignore an alert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Alert not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/alerts/{id}/resolve":{"patch":{"description":"Resolve an alert","summary":"Resolve an alert","tags":["alerts"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the alert issued by Texture.","example":"clm1a2b3c4d5e6f7g8h9i0j1"},"required":true,"description":"The unique identifier for the alert issued by Texture.","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the alert issued by Texture.","example":"clm1a2b3c4d5e6f7g8h9i0j1"}},"required":["id"]}}}},"responses":{"200":{"description":"Resolve an alert","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the alert issued by Texture.","example":"clm1a2b3c4d5e6f7g8h9i0j1"}},"required":["id"]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Alert not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/api-keys":{"get":{"description":"List all API keys for the authenticated workspace. Key values are never exposed — only a masked prefix is returned.","summary":"List API keys","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Paginated list of API keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListApiKeysResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key"},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new API key for the workspace. The full key value is returned only in this response — store it securely. It cannot be retrieved again.","summary":"Create API key","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"A human-readable name for the API key.","example":"CI/CD Key"},"type":{"type":"string","enum":["API","SERVER","MANUFACTURER","MANAGEMENT"],"description":"The type of API key to create. CONNECT and SCOPED keys are system-generated and cannot be created via this endpoint.","example":"SERVER"},"manufacturerScope":{"type":"array","items":{"type":"string"},"default":[],"description":"Required when type is MANUFACTURER. The list of manufacturer slugs this key can access.","example":[]},"ownerId":{"type":"string","description":"The ID of the user who will own this key. Required when type is MANAGEMENT. If omitted for MANAGEMENT keys, defaults to the owner of the authenticating key.","example":"clx1234567890abcdef"}},"required":["name","type"]}}}},"responses":{"201":{"description":"The created API key including the full key value (one-time reveal).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"400":{"description":"Bad Request — invalid input data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/api-keys/{id}":{"get":{"description":"Get a single API key by ID. The full key value is never exposed — only a masked prefix is returned.","summary":"Get an API key by ID","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the API key to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the API key to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"API key details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"description":"Unauthorized — missing or invalid API key"},"404":{"description":"API key not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["API key not found"]}},"required":["message"]}}}},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update an API key's metadata (name). The key value itself cannot be changed.","summary":"Update API key","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the API key to update.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the API key to update.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"The new name for the API key.","example":"Updated Production Key"}},"required":["name"]}}}},"responses":{"200":{"description":"The updated API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyUpdated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"API key not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/api-keys/{id}/revoke":{"post":{"description":"Revoke an API key. Once revoked, the key can no longer be used for authentication. This action cannot be undone.","summary":"Revoke API key","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the API key to revoke.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the API key to revoke.","in":"path","name":"id"}],"responses":{"200":{"description":"The revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRevoked"}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"API key not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/audit-logs":{"get":{"description":"List management audit log entries for the organization. Supports filtering by action, resource type, and date range.","summary":"List Audit Logs","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"action","in":"query"},{"schema":{"type":"string"},"required":false,"name":"resourceType","in":"query"},{"schema":{"type":"string"},"required":false,"name":"startDate","in":"query"},{"schema":{"type":"string"},"required":false,"name":"endDate","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"default":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"perPage","in":"query"}],"responses":{"200":{"description":"Paginated list of audit log entries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAuditLogsResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key"},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/batches/{id}":{"get":{"description":"Get details of a specific batch.","summary":"Get batch","tags":["Batches"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier of the batch","example":"cllgn0u4r000008l7eazybfb2"},"required":true,"description":"The unique identifier of the batch","name":"id","in":"path"}],"responses":{"200":{"description":"Batch details","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the command batch.","example":"cllgn0u4r000008l7eazybfbo"},"startsAt":{"type":"string","format":"date-time","description":"The date and time the command batch starts.","example":"2025-01-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time the command batch ends.","example":"2025-01-01T00:00:00Z"},"type":{"type":"string","enum":["battery:set-reserve","battery:set-operating-mode","charger:set-operating-mode","thermostat:set-operating-mode","thermostat:set-fan-mode","thermostat:pause-schedule","thermostat:resume-schedule","vehicle:check-pairing-status","vehicle:set-charge-limit","vehicle:set-operating-mode"],"description":"The unique slug representing the type of command.","example":"thermostat:set-operating-mode"},"issuedAt":{"type":"string","format":"date-time","description":"The date and time the command was issued."},"input":{"type":"object","properties":{},"additionalProperties":{},"description":"The input payload sent with the command. Includes necessary information for execution. Conforms to the schema provided on the command type.","example":{"operatingMode":"eco","heatTarget":70.5,"coolTarget":80.5}},"metrics":{"type":"object","properties":{"counts":{"type":"object","properties":{"total":{"type":"number","description":"Total number of commands in the batch","example":100},"pending":{"type":"number","description":"Number of pending commands","example":50},"scheduled":{"type":"number","description":"Number of commands scheduled","example":20},"delivered":{"type":"number","description":"Number of commands in the `delivered` state: the OEM accepted the command but device state verification has not yet completed.","example":10},"completed":{"type":"number","description":"Number of completed commands","example":25},"failed":{"type":"number","description":"Number of failed commands","example":5}},"required":["total","pending","scheduled","delivered","completed","failed"],"description":"Counts of commands by their status within the batch"}},"required":["counts"],"description":"Metrics about the commands in the batch."}},"required":["id","startsAt","endsAt","type","issuedAt","input","metrics"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Batch not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete a batch by ID. This endpoint is not currently implemented.","summary":"Delete batch","tags":["Batches"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier of the batch","example":"cllgn0u4r000008l7eazybfb2"},"required":true,"description":"The unique identifier of the batch","name":"id","in":"path"}],"responses":{"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Batch not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Response message","example":"Not implemented"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/collections":{"get":{"description":"List all collections for the authenticated workspace.","summary":"List collections","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."},{"schema":{"type":"string","enum":["DEVICE","SITE","CUSTOMER"],"description":"Filter by collection type.","example":"DEVICE"},"required":false,"description":"Filter by collection type.","in":"query","name":"collectionType"}],"responses":{"200":{"description":"Paginated list of collections","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCollectionsResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key"},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new collection for the workspace.","summary":"Create collection","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The name for the collection.","example":"Northeast EV Fleet"},"collectionType":{"type":"string","enum":["DEVICE","SITE","CUSTOMER"],"description":"The type of entity constituting the collection.","example":"DEVICE"},"description":{"type":"string","minLength":1,"description":"Optional description of the collection.","example":"All EV devices in the northeast region"},"criteria":{"type":"object","properties":{"rule":{"type":"object","properties":{"attribute":{"type":"string","description":"The field to apply the rule to.","example":"deviceType"},"operator":{"type":"string","enum":["EQUALS","NOT_EQUALS","IN"],"description":"The comparison operator.","example":"EQUALS"},"value":{"description":"The value to compare against.","example":"VEHICLE"}},"required":["attribute","operator"]},"and":{"type":"array","items":{}},"or":{"type":"array","items":{}}},"description":"The criteria defining what belongs in the collection."}},"required":["name","collectionType","criteria"]}}}},"responses":{"201":{"description":"The created collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Collection"}}}},"400":{"description":"Bad Request — invalid input data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/collections/{id}":{"get":{"description":"Get a collection by ID.","summary":"Get collection","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the collection.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the collection.","in":"path","name":"id"}],"responses":{"200":{"description":"The collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionDetail"}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"404":{"description":"Collection not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update a collection's metadata or criteria.","summary":"Update collection","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the collection.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the collection.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"New name for the collection.","example":"Updated Fleet Name"},"description":{"type":"string","minLength":1,"description":"New description for the collection.","example":"Updated description"},"dynamic":{"type":"boolean","description":"Whether the collection is dynamic (live query) or materialized.","example":true},"isActive":{"type":"boolean","description":"For materialized collections: whether actively managed or frozen.","example":true},"visibility":{"type":"string","enum":["INTERNAL","SHARED"],"description":"The visibility level of the collection.","example":"INTERNAL"},"criteria":{"type":"object","properties":{"rule":{"type":"object","properties":{"attribute":{"type":"string","description":"The field to apply the rule to.","example":"deviceType"},"operator":{"type":"string","enum":["EQUALS","NOT_EQUALS","IN"],"description":"The comparison operator.","example":"EQUALS"},"value":{"description":"The value to compare against.","example":"VEHICLE"}},"required":["attribute","operator"]},"and":{"type":"array","items":{}},"or":{"type":"array","items":{}}},"description":"New criteria for the collection."}}}}}},"responses":{"200":{"description":"The updated collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionUpdated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Collection not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete a collection. This action cannot be undone.","summary":"Delete collection","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the collection.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the collection.","in":"path","name":"id"}],"responses":{"200":{"description":"The ID of the deleted collection.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"}}}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Collection not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/collections/{id}/entities":{"get":{"description":"List all entities in a collection.","summary":"List collection entities","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the collection.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the collection.","in":"path","name":"id"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Paginated list of entities in the collection.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCollectionEntitiesResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"404":{"description":"Collection not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/collections/{id}/share":{"post":{"description":"Share a collection with another organization.","summary":"Share collection","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the collection.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the collection.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"recipientOrgEmail":{"type":"string","format":"email","description":"Email address to identify the recipient organization.","example":"partner@example.com"}},"required":["recipientOrgEmail"]}}}},"responses":{"200":{"description":"The collection was successfully shared.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Collection not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/battery/set-operating-mode":{"post":{"description":"Send set-operating-mode command to a battery.","summary":"Send set-operating-mode command to a battery.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{"operatingMode":{"type":"string","enum":["charge","discharge","idle","reset"],"description":"The desired operating mode or charging state of the battery."},"minimumBatteryReserve":{"type":"number","minimum":0,"maximum":100,"description":"The target minimum battery reserve percentage when discharging."},"maximumBatteryReserve":{"type":"number","minimum":0,"maximum":100,"default":100,"description":"The target maximum battery reserve percentage when charging."},"enableGridInteraction":{"type":"boolean","default":false,"description":"Whether or not the battery should attempt to interact with the grid, only applies if the battery is able to interact with the grid and it aids in achieving the desired operating mode."},"executionPriority":{"type":"array","items":{"type":"string","enum":["grid_services","baseline"]},"default":["grid_services","baseline"],"description":"The execution priority overrides for the battery, this will be used to determine the order in which a battery command will attempt to be executed. By default, the battery will attempt to execute grid-services first, falling back to baseline battery control if grid-services is not available. To bypass the grid-services attempt, set this to an empty array, or specify only ['baseline']. The baseline priority is always attempted last (whether specified or not)."},"dischargePowerRate":{"type":"number","exclusiveMinimum":0,"description":"Target discharge rate in watts (positive-only magnitude — direction comes from operatingMode='discharge'). Takes precedence over dischargePowerPercent and dischargeStrategy. Ignored when operatingMode is not 'discharge'."},"dischargePowerPercent":{"type":"number","exclusiveMinimum":0,"maximum":100,"description":"Target discharge power as percentage of device maximum (positive-only magnitude — direction comes from operatingMode='discharge'). Used only if dischargePowerRate not provided. Ignored when operatingMode is not 'discharge'."},"dischargeStrategy":{"type":"string","enum":["smooth","max"],"description":"'smooth' calculates power to fill/drain evenly over event duration; 'max' (default) uses the device's maximum rate. Applies to both operatingMode='charge' and operatingMode='discharge' — the device-domain command strategy layer branches on operatingMode for the math (drains-toward-minimumBatteryReserve vs fills-toward-maximumBatteryReserve). Only used if dischargePowerRate and dischargePowerPercent are not provided."}},"required":["operatingMode"],"description":"The expected payload of the battery:set-operating-mode command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/battery/set-operating-mode/batch":{"post":{"description":"Send set-operating-mode batch command to a group of batteries.","summary":"Send set-operating-mode batch command to a group of batteries.","tags":["Batch Commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tag":{"type":"string","description":"The tag for the group of batteries to target.","example":"my-battery-tag"},"input":{"type":"object","properties":{"operatingMode":{"type":"string","enum":["charge","discharge","idle","reset"],"description":"The desired operating mode or charging state of the battery."},"minimumBatteryReserve":{"type":"number","minimum":0,"maximum":100,"description":"The target minimum battery reserve percentage when discharging."},"maximumBatteryReserve":{"type":"number","minimum":0,"maximum":100,"default":100,"description":"The target maximum battery reserve percentage when charging."},"enableGridInteraction":{"type":"boolean","default":false,"description":"Whether or not the battery should attempt to interact with the grid, only applies if the battery is able to interact with the grid and it aids in achieving the desired operating mode."},"executionPriority":{"type":"array","items":{"type":"string","enum":["grid_services","baseline"]},"default":["grid_services","baseline"],"description":"The execution priority overrides for the battery, this will be used to determine the order in which a battery command will attempt to be executed. By default, the battery will attempt to execute grid-services first, falling back to baseline battery control if grid-services is not available. To bypass the grid-services attempt, set this to an empty array, or specify only ['baseline']. The baseline priority is always attempted last (whether specified or not)."},"dischargePowerRate":{"type":"number","exclusiveMinimum":0,"description":"Target discharge rate in watts (positive-only magnitude — direction comes from operatingMode='discharge'). Takes precedence over dischargePowerPercent and dischargeStrategy. Ignored when operatingMode is not 'discharge'."},"dischargePowerPercent":{"type":"number","exclusiveMinimum":0,"maximum":100,"description":"Target discharge power as percentage of device maximum (positive-only magnitude — direction comes from operatingMode='discharge'). Used only if dischargePowerRate not provided. Ignored when operatingMode is not 'discharge'."},"dischargeStrategy":{"type":"string","enum":["smooth","max"],"description":"'smooth' calculates power to fill/drain evenly over event duration; 'max' (default) uses the device's maximum rate. Applies to both operatingMode='charge' and operatingMode='discharge' — the device-domain command strategy layer branches on operatingMode for the math (drains-toward-minimumBatteryReserve vs fills-toward-maximumBatteryReserve). Only used if dischargePowerRate and dischargePowerPercent are not provided."}},"required":["operatingMode"],"description":"The expected payload of the battery:set-operating-mode command."}},"required":["tag","input"]}}}},"responses":{"202":{"description":"The list of commands that were sent to the group or batch of devices","content":{"application/json":{"schema":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/Command"},{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}]}}}}},"400":{"description":"There was an issue sending the batch command.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/battery/set-reserve":{"post":{"description":"Send set-reserve command to a battery.","summary":"Send set-reserve command to a battery.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{"chargePercentage":{"type":"number","minimum":0,"maximum":100,"description":"The percentage of the battery to reserve."}},"required":["chargePercentage"],"description":"The expected payload of the battery:set-reserve command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/charger/set-operating-mode":{"post":{"description":"Send set-operating-mode command to a charger.","summary":"Send set-operating-mode command to a charger.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{"operatingMode":{"type":"string","enum":["start-charging","stop-charging"],"description":"The desired operating mode or charging state of the charger."}},"required":["operatingMode"],"description":"The expected payload of the charger:set-operating-mode command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/thermostat/pause-schedule":{"post":{"description":"Pause the on-device thermostat schedule to allow Texture platform schedules to control the device.","summary":"Pause the on-device thermostat schedule.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{},"description":"The expected payload of the thermostat:pause-schedule command. This command temporarily deactivates the on-device schedule without removing it."}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/thermostat/resume-schedule":{"post":{"description":"Resume the on-device thermostat schedule after it has been paused.","summary":"Resume the on-device thermostat schedule.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{},"description":"The expected payload of the thermostat:resume-schedule command. This command reactivates the on-device schedule after it has been paused."}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/thermostat/set-fan-mode":{"post":{"description":"Send set-fan-mode command to a thermostat.","summary":"Send set-fan-mode command to a thermostat.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"anyOf":[{"type":"object","properties":{"fanMode":{"type":"string","enum":["auto"],"description":"Sets the thermostat fan mode to auto."}},"required":["fanMode"],"additionalProperties":false},{"type":"object","properties":{"fanMode":{"type":"string","enum":["on"],"description":"Sets the thermostat fan mode to on."}},"required":["fanMode"],"additionalProperties":false},{"type":"object","properties":{"fanMode":{"type":"string","enum":["circulate"],"description":"Sets the thermostat fan mode to circulate."}},"required":["fanMode"],"additionalProperties":false},{"type":"object","properties":{"fanMode":{"type":"string","enum":["off"],"description":"Sets the thermostat fan mode to off."}},"required":["fanMode"],"additionalProperties":false}],"description":"The expected payload of the thermostat:set-fan-mode command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/thermostat/set-operating-mode":{"post":{"description":"Send set-operating-mode command to a thermostat.","summary":"Send set-operating-mode command to a thermostat.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"anyOf":[{"type":"object","properties":{"operatingMode":{"type":"string","enum":["off"],"description":"Sets the thermostat operating mode to off."}},"required":["operatingMode"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["heat"],"description":"Sets the thermostat operating mode to heat."},"heatTarget":{"type":"number","description":"The target temperature for heating in degrees Fahrenheit. Required for operating modes `heat`, `auto`, and `eco`."}},"required":["operatingMode","heatTarget"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["cool"],"description":"Sets the thermostat operating mode to cool."},"coolTarget":{"type":"number","description":"The target temperature for cooling in degrees Fahrenheit. Required for operating modes `cool`, `auto`, and `eco`."}},"required":["operatingMode","coolTarget"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["auto"],"description":"Sets the thermostat operating mode to auto."},"heatTarget":{"type":"number","description":"The target temperature for heating in degrees Fahrenheit. Required for operating modes `heat`, `auto`, and `eco`."},"coolTarget":{"type":"number","description":"The target temperature for cooling in degrees Fahrenheit. Required for operating modes `cool`, `auto`, and `eco`."}},"required":["operatingMode","heatTarget","coolTarget"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["eco"],"description":"Sets the thermostat operating mode to eco."},"heatTarget":{"type":"number","description":"The target temperature for heating in degrees Fahrenheit. Required for operating modes `heat`, `auto`, and `eco`."},"coolTarget":{"type":"number","description":"The target temperature for cooling in degrees Fahrenheit. Required for operating modes `cool`, `auto`, and `eco`."}},"required":["operatingMode","heatTarget","coolTarget"]}],"description":"The expected payload of the thermostat:set-operating-mode command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and it's status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/thermostat/set-operating-mode/batch":{"post":{"description":"Send set-operating-mode batch command to a group of thermostats.","summary":"Send set-operating-mode batch command to a group of thermostats.","tags":["Batch Commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tag":{"type":"string","description":"The tag for the group of thermostats to target.","example":"my-thermostat-tag"},"input":{"anyOf":[{"type":"object","properties":{"operatingMode":{"type":"string","enum":["off"],"description":"Sets the thermostat operating mode to off."}},"required":["operatingMode"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["heat"],"description":"Sets the thermostat operating mode to heat."},"heatTarget":{"type":"number","description":"The target temperature for heating in degrees Fahrenheit. Required for operating modes `heat`, `auto`, and `eco`."}},"required":["operatingMode","heatTarget"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["cool"],"description":"Sets the thermostat operating mode to cool."},"coolTarget":{"type":"number","description":"The target temperature for cooling in degrees Fahrenheit. Required for operating modes `cool`, `auto`, and `eco`."}},"required":["operatingMode","coolTarget"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["auto"],"description":"Sets the thermostat operating mode to auto."},"heatTarget":{"type":"number","description":"The target temperature for heating in degrees Fahrenheit. Required for operating modes `heat`, `auto`, and `eco`."},"coolTarget":{"type":"number","description":"The target temperature for cooling in degrees Fahrenheit. Required for operating modes `cool`, `auto`, and `eco`."}},"required":["operatingMode","heatTarget","coolTarget"]},{"type":"object","properties":{"operatingMode":{"type":"string","enum":["eco"],"description":"Sets the thermostat operating mode to eco."},"heatTarget":{"type":"number","description":"The target temperature for heating in degrees Fahrenheit. Required for operating modes `heat`, `auto`, and `eco`."},"coolTarget":{"type":"number","description":"The target temperature for cooling in degrees Fahrenheit. Required for operating modes `cool`, `auto`, and `eco`."}},"required":["operatingMode","heatTarget","coolTarget"]}],"description":"The expected payload of the thermostat:set-operating-mode command."}},"required":["tag","input"]}}}},"responses":{"202":{"description":"The list of commands that were sent to the group or batch of devices","content":{"application/json":{"schema":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/Command"},{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}]}}}}},"400":{"description":"There was an issue sending the batch command.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/vehicle/check-pairing-status":{"post":{"description":"Check whether a vehicle's command-signing key is paired (read-only).","summary":"Check a vehicle's key-pairing status.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"}},"required":["deviceId"]}}}},"responses":{"201":{"description":"The command that was sent to the device and its status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"},"example":{"id":"cllgn0u4r000008l7eazybfbo","status":"pending","reason":"","type":"vehicle:check-pairing-status","issuedAt":"2019-08-24T14:15:22Z","executedAt":null,"input":{}}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/vehicle/set-charge-limit":{"post":{"description":"Send set-charge-limit command to a vehicle.","summary":"Send set-charge-limit command to a vehicle.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{"chargeLimit":{"type":"integer","minimum":0,"maximum":100,"description":"The desired charge limit of the vehicle (in percent, from 0 up to 100)."},"requireHomeLocation":{"type":"boolean","default":false,"description":"When true, command only executes if vehicle is at its home location. Defaults to false."},"homeRadiusMeters":{"type":"number","exclusiveMinimum":0,"default":250,"description":"Radius in meters for home location check. Only used when requireHomeLocation is true. Defaults to 250."}},"required":["chargeLimit"],"description":"The expected payload of the vehicle:set-charge-limit command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and its status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"},"example":{"id":"cllgn0u4r000008l7eazybfbo","status":"pending","reason":"","type":"vehicle:set-charge-limit","issuedAt":"2019-08-24T14:15:22Z","executedAt":null,"input":{"chargeLimit":80,"requireHomeLocation":false,"homeRadiusMeters":250}}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/vehicle/set-operating-mode":{"post":{"description":"Send set-operating-mode command to a vehicle.","summary":"Send set-operating-mode command to a vehicle.","tags":["commands"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture to send the command.","example":"clmv27bxa000b6jx0qdv3atp6"},"input":{"type":"object","properties":{"operatingMode":{"type":"string","enum":["start-charging","stop-charging"],"description":"The desired operating mode or charging state of the vehicle."},"requireHomeLocation":{"type":"boolean","default":false,"description":"When true, command only executes if vehicle is at its home location. Defaults to false."},"homeRadiusMeters":{"type":"number","exclusiveMinimum":0,"default":250,"description":"Radius in meters for home location check. Only used when requireHomeLocation is true. Defaults to 250."}},"required":["operatingMode"],"description":"The expected payload of the vehicle:set-operating-mode command."},"startAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the start of the override detection window. The command executes immediately regardless of this value. If omitted, monitoring begins at command completion.","example":"2026-02-12T18:00:00Z"},"endAt":{"type":"string","format":"date-time","description":"Optional ISO 8601 datetime marking the end of the override detection window. When set, the system monitors the device for manual overrides until this time and emits a command.overridden webhook event if the device state diverges. This does not schedule the command — execution is immediate.","example":"2026-02-12T20:00:00Z"}},"required":["deviceId","input"]}}}},"responses":{"201":{"description":"The command that was sent to the device and its status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"},"example":{"id":"cllgn0u4r000008l7eazybfbo","status":"pending","reason":"","type":"vehicle:set-operating-mode","issuedAt":"2019-08-24T14:15:22Z","executedAt":null,"input":{"operatingMode":"start-charging","requireHomeLocation":false,"homeRadiusMeters":250}}}}},"400":{"description":"There was an issue sending the command to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/commands/{id}":{"get":{"description":"Get command data by its ID.","summary":"Get a single command","tags":["commands"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the command issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the command issued by Texture.","name":"id","in":"path"}],"responses":{"200":{"description":"Object with command data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Command"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Command not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete a command by ID. This endpoint is not currently implemented.","summary":"Delete command","tags":["Commands"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier of the command","example":"cllgn0u4r000008l7eazybfb2"},"required":true,"description":"The unique identifier of the command","name":"id","in":"path"}],"responses":{"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Command not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Response message","example":"Not implemented"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/customers":{"get":{"description":"Fetches Customers for a Workspace by Workspace ID","summary":"Fetches Customers for a Workspace by Workspace ID","tags":["customers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."},{"schema":{"type":"string","description":"The reference ID of the customer to filter by.","example":"01234567"},"required":false,"description":"The reference ID of the customer to filter by.","name":"referenceId","in":"query"}],"responses":{"200":{"description":"The organization details.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"Failed to fetch customers from upstream","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Failed to fetch customers from upstream"]}},"required":["message"]}}}}}},"post":{"description":"Create a new customer within the workspace associated with the API key.","summary":"Create Customer","tags":["customers"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"referenceId":{"type":"string","description":"An external ID to link the Customer to an external system"},"firstName":{"type":"string","description":"Customer's first name"},"lastName":{"type":"string","description":"Customer's last name"},"email":{"type":"string","format":"email","description":"Customer's email address"},"phone":{"type":"string","description":"Customer's phone number"}},"required":["referenceId"]}}}},"responses":{"201":{"description":"The customer that was successfully created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"400":{"description":"Bad Request - Invalid input data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Unauthorized - Invalid or missing API key.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"500":{"description":"Internal Server Error - Error creating customer.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/customers/{id}":{"get":{"description":"Fetches a Customer and that Customer's associated by the Customer ID","summary":"Fetches a Customer by ID","tags":["customers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The ID of the customer to fetch.","example":"cjoq4z9zv0000kz6z1z1z1z1z"},"required":true,"description":"The ID of the customer to fetch.","name":"id","in":"path"}],"responses":{"200":{"description":"The organization details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Customer not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["CUSTOMER_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete a single Customer by its ID.","summary":"Delete a single Customer by its ID","tags":["customers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"responses":{"204":{"description":"Customer deleted","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Customer deleted"]}},"required":["message"]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Resource not found"]}},"required":["message"]}}}},"500":{"description":"Server failure","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Server failure"]}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/customers/{id}/sites":{"get":{"description":"Fetches a Customer's Sites by Customer ID","summary":"Fetches a Customer's Sites by Customer ID","tags":["customers"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The ID of the customer who's sites we are fetching.","example":"cjoq4z9zv0000kz6z1z1z1z1z"},"required":true,"description":"The ID of the customer who's sites we are fetching.","name":"id","in":"path"}],"responses":{"200":{"description":"The organization details.","content":{"application/json":{"schema":{"type":"object","properties":{"sites":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the Site issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"name":{"type":["string","null"],"description":"The name of the Site."},"referenceId":{"type":["string","null"],"description":"The reference ID of the Site.","example":"9bb290c8-fe97-46ce-92a8-952823164277"},"workspaceId":{"type":"string","format":"cuid","description":"The unique identifier for the Workspace to which the Site belongs, issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time that this Site was created.","example":"2024-04-01T00:00:00.000Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time that this Site was last updated.","example":"2024-04-01T00:00:00.000Z"},"connectedCustomers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the customer issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"workspaceId":{"type":"string","format":"cuid","description":"The unique identifier for the workspace issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"referenceId":{"type":["string","null"],"description":"The reference ID for the customer.","example":"01234567"},"firstName":{"type":["string","null"],"description":"The given name of the customer.","example":"John"},"lastName":{"type":["string","null"],"description":"The surname of the customer.","example":"Smith"},"email":{"type":["string","null"],"description":"The email address of the customer.","example":"test@example.com"},"phone":{"type":["string","null"],"description":"The phone number of the customer as provided during creation or update.","example":"1234567890"},"devices":{"type":"array","items":{"$ref":"#/components/schemas/Device"},"description":"The devices connected to the customer."},"createdAt":{"type":["string","null"],"format":"date-time","description":"The date and time the customer was created in the system.","example":"2026-08-09T11:43:47.853Z"},"updatedAt":{"type":["string","null"],"format":"date-time","description":"The date and time the customer was last updated in the system.","example":"2026-08-09T11:43:47.854Z"}},"required":["id","workspaceId","referenceId","createdAt"]}},"location":{"type":"object","properties":{"streetOne":{"type":["string","null"],"description":"The first line of the address.","example":"123 Main St"},"streetTwo":{"type":["string","null"],"description":"The second line of the address.","example":"Apt 101"},"city":{"type":["string","null"],"description":"The city of the site.","example":"San Francisco"},"state":{"type":["string","null"],"description":"The state of the site.","example":"CA"},"postalCode":{"type":["string","null"],"description":"The postal code of the site.","example":"94105"},"country":{"type":["string","null"],"description":"The country of the site.","example":"USA"},"latitude":{"type":"number","description":"The latitude of the site.","example":37.7749},"longitude":{"type":"number","description":"The longitude of the site.","example":-122.4194}},"required":["latitude","longitude"]},"energyUsage":{"type":["array","null"],"items":{"type":"object","properties":{"startDate":{"type":"string","format":"date-time","description":"The start date and time of the energy usage period.","example":"2024-04-01T00:00:00.000Z"},"endDate":{"type":"string","format":"date-time","description":"The end date and time of the energy usage period.","example":"2024-04-01T00:00:00.000Z"},"consumption":{"type":"number","description":"Total energy consumed at the Site during the period.","example":100},"price":{"type":"number","description":"The price of the energy consumed during the period.","example":0.1},"emissions":{"type":"number","description":"The amount of emissions produced during the period.","example":0.1},"cost":{"type":"object","properties":{"amount":{"type":"integer","description":"The integer representation of the cost of the energy consumed during the period.","example":10},"currencyCode":{"type":"string","description":"The currency code of the cost.","example":"USD"},"formatted":{"type":"string","description":"The formatted cost of the energy consumed during the period.","example":"$10.00"}},"required":["amount","currencyCode","formatted"]}},"required":["startDate","endDate","consumption"]}},"utility":{"type":"object","properties":{"name":{"type":"string","description":"The name of the utility provider.","example":"Pacifc Gas and Electric"}},"required":["name"],"description":"The utility for the Site."},"wholesaleMarket":{"type":"object","properties":{"name":{"type":"string","description":"The name of the wholesale market.","example":"California Independent Systems Operator"}},"required":["name"],"description":"The wholesale market for the Site."},"weather":{"$ref":"#/components/schemas/WeatherData"},"permits":{"type":"array","items":{"$ref":"#/components/schemas/Permit"},"description":"The list of permits associated with the Site. Only available for workspaces with an enabled permits integration."},"energyModeling":{"$ref":"#/components/schemas/EnergyModelingData"},"intervals":{"type":"array","items":{"$ref":"#/components/schemas/Interval"},"description":"The list of intervals associated with the Site."}},"required":["id","workspaceId","createdAt","location"]}}},"required":["sites"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Customer not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Customer not found"]}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"Failed to fetch customer sites from upstream","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Failed to fetch customer sites from upstream"]}},"required":["message"]}}}}}}},"/destinations":{"get":{"description":"List all destinations for the authenticated workspace.","summary":"List destinations","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Paginated list of destinations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDestinationsResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key"},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/destinations/{id}":{"get":{"description":"Get a single destination by ID.","summary":"Get destination by ID","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the destination to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the destination to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"Destination details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Destination"}}}},"401":{"description":"Unauthorized — missing or invalid API key"},"404":{"description":"Destination not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Destination not found"]}},"required":["message"]}}}},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update a destination's configuration. Fields vary by destination type.","summary":"Update destination","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the destination to update.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the destination to update.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":255,"description":"A human-readable label for this destination.","example":"Updated Webhook"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"minItems":1,"description":"The event types that trigger this destination.","example":["DEVICE_UPDATED"]},"deviceType":{"type":"string","enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN"],"description":"The device types this destination applies to.","example":"ALL"},"url":{"type":"string","format":"uri","description":"The webhook URL (for WEBHOOK destinations).","example":"https://example.com/webhook"},"email":{"type":"string","format":"email","description":"The email address (for EMAIL destinations).","example":"alerts@example.com"},"phoneNumber":{"type":"string","description":"The phone number (for SMS destinations).","example":"+15555551234"},"secret":{"type":"string","description":"The webhook signing secret (for WEBHOOK destinations)."},"includeWeather":{"type":"boolean","description":"Whether to include weather data with events (for WEBHOOK destinations)."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Custom HTTP headers (for WEBHOOK destinations).","example":{"X-Custom-Header":"value"}}}}}}},"responses":{"200":{"description":"The updated destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DestinationUpdated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Destination not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete a destination by ID.","summary":"Delete destination","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the destination to delete.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the destination to delete.","in":"path","name":"id"}],"responses":{"204":{"description":"Destination deleted successfully."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Destination not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/destinations/webhooks":{"post":{"description":"Create a new webhook destination for the workspace.","summary":"Create webhook destination","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":255,"description":"A human-readable label for this destination.","example":"Production Webhook"},"url":{"type":"string","format":"uri","description":"The URL to deliver events to.","example":"https://example.com/webhook"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"minItems":1,"description":"The event types that trigger this destination.","example":["DEVICE_UPDATED","DEVICE_CONNECTED"]},"deviceType":{"type":"string","enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN"],"description":"The device types this destination applies to.","example":"ALL"},"secret":{"type":"string","description":"An optional signing secret for HMAC verification.","example":"my-webhook-secret"},"includeWeather":{"type":"boolean","description":"Whether to include weather data with events.","example":false},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Custom HTTP headers to include in webhook requests.","example":{"X-Custom-Header":"value"}}},"required":["label","url","eventTypes","deviceType"]}}}},"responses":{"201":{"description":"The created webhook destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDestinationCreated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/destinations/emails":{"post":{"description":"Create a new email destination for the workspace.","summary":"Create email destination","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":255,"description":"A human-readable label for this destination.","example":"Alert Emails"},"email":{"type":"string","format":"email","description":"The email address to deliver event notifications to.","example":"alerts@example.com"},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"minItems":1,"description":"The event types that trigger this destination.","example":["DEVICE_CONNECTED","DEVICE_DISCONNECTED"]},"deviceType":{"type":"string","enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN"],"description":"The device types this destination applies to.","example":"ALL"}},"required":["label","email","eventTypes","deviceType"]}}}},"responses":{"201":{"description":"The created email destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDestinationCreated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/destinations/kafka":{"post":{"description":"Create a new Kafka destination for the workspace. Events will be published to the configured Kafka topic.","summary":"Create Kafka destination","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":255,"description":"A human-readable label for this destination.","example":"Production Kafka Stream"},"kafkaConfig":{"type":"object","properties":{"brokers":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"List of Kafka broker addresses.","example":["broker1.example.com:9092","broker2.example.com:9092"]},"topic":{"type":"string","minLength":1,"description":"The Kafka topic to publish events to.","example":"texture-device-events"},"authentication":{"type":"object","properties":{"mechanism":{"type":"string","enum":["PLAIN","SCRAM-SHA-256","SCRAM-SHA-512"],"description":"The SASL authentication mechanism.","example":"PLAIN"},"username":{"type":"string","minLength":1,"description":"The SASL username.","example":"my-kafka-user"},"password":{"type":"string","minLength":1,"description":"The SASL password.","example":"my-kafka-password"}},"required":["mechanism","username","password"],"description":"Optional SASL authentication configuration."},"ssl":{"type":"boolean","description":"Whether to use SSL/TLS for the Kafka connection.","example":true}},"required":["brokers","topic"],"description":"Kafka connection and topic configuration."},"eventTypes":{"type":"array","items":{"type":"string","enum":["COMMAND_FAILED","COMMAND_SCHEDULED","COMMAND_SUCCEEDED","COMMAND_OVERRIDDEN","CONNECTION_FAILED","CUSTOMER_CREATED","CUSTOMER_DELETED","CUSTOMER_UPDATED","DEVICE_CONNECTED","DEVICE_DISCONNECTED","DEVICE_DISCOVERED","DEVICE_UPDATED","ENROLLMENT_APPROVED","ENROLLMENT_REJECTED","ENROLLMENT_SUBMITTED","SITE_CREATED","SITE_DELETED","SITE_UPDATED","ALERT_CREATED","ALERT_UPDATED"],"description":"The event type.","example":"DEVICE_UPDATED"},"minItems":1,"description":"The event types that trigger this destination.","example":["DEVICE_UPDATED","DEVICE_CONNECTED"]},"deviceType":{"type":"string","enum":["ALL","BATTERIES","CHARGERS","SOLAR_INVERTERS","THERMOSTATS","VEHICLES","OTHER","UNKNOWN"],"description":"The device types this destination applies to.","example":"ALL"}},"required":["label","kafkaConfig","eventTypes"]}}}},"responses":{"201":{"description":"The created Kafka destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KafkaDestinationCreated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/destinations/{id}/enabled":{"put":{"description":"Enable or disable a webhook destination.","summary":"Enable/disable webhook destination","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the webhook destination.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the webhook destination.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether to enable (true) or disable (false) the webhook destination.","example":true}},"required":["enabled"]}}}},"responses":{"200":{"description":"The updated webhook destination.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDestinationEnabled"}}}},"400":{"description":"Bad Request — only WEBHOOK destinations support enable/disable."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Destination not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices":{"post":{"description":"Create a new OEM-provisioned device. Requires a MANUFACTURER API key. Returns 201 for newly created devices, 200 for existing devices with matching parameters (idempotent), or 409 if a device exists with the same manufacturerDeviceId but different parameters.","summary":"Create OEM Device","tags":["OEM Direct Integration"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"manufacturerDeviceId":{"type":"string","minLength":1},"deviceModelId":{"type":"string","minLength":1},"siteId":{"type":"string","minLength":1},"serialNumber":{"type":"string"},"name":{"type":"string"}},"required":["manufacturerDeviceId","deviceModelId","siteId"]}}}},"responses":{"200":{"description":"An existing device with matching parameters was found (idempotent).","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"manufacturerDeviceId":{"type":"string"},"deviceModelId":{"type":["string","null"]},"siteId":{"type":["string","null"]},"provisioningType":{"type":"string","enum":["TEXTURE_MANAGED","OEM_DIRECT"]},"serialNumber":{"type":["string","null"]},"name":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","manufacturerDeviceId","deviceModelId","siteId","provisioningType","serialNumber","name","createdAt"]}}}},"201":{"description":"The device that was successfully created.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"manufacturerDeviceId":{"type":"string"},"deviceModelId":{"type":["string","null"]},"siteId":{"type":["string","null"]},"provisioningType":{"type":"string","enum":["TEXTURE_MANAGED","OEM_DIRECT"]},"serialNumber":{"type":["string","null"]},"name":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","manufacturerDeviceId","deviceModelId","siteId","provisioningType","serialNumber","name","createdAt"]}}}},"400":{"description":"Bad Request - Invalid input data, device model not found, or site not found.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Unauthorized - Invalid or missing MANUFACTURER API key.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"403":{"description":"Forbidden - Device model does not belong to manufacturers in API key scope.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"409":{"description":"Conflict - A device with this manufacturerDeviceId exists but with different parameters.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string","enum":["PARAMETER_MISMATCH"]},"mismatchedFields":{"type":"array","items":{"type":"string"}}},"required":["message","code","mismatchedFields"]}}}},"500":{"description":"Internal Server Error - Error creating device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"get":{"description":"Get all devices for a workspace with additional optional filtering.","summary":"Get a list of devices","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"in":"query","name":"referenceId","description":"The reference ID to filter devices by.","example":"9bb290c8-fe97-46ce-92a8-952823164277"},{"schema":{"type":"string"},"required":false,"in":"query","name":"manufacturer","description":"The manufacturer to filter devices by."},{"schema":{"type":"string"},"required":false,"in":"query","name":"manufacturerDeviceId","description":"The manufacturer device ID to filter devices by.","example":"b1143000-69ac-481f-9bef-4bfd96198133"},{"schema":{"type":"string"},"required":false,"in":"query","name":"type","description":"The device type to filter devices by."},{"schema":{"type":"string"},"required":false,"in":"query","name":"model","description":"The device model to filter devices by."},{"schema":{"type":"string"},"required":false,"name":"source","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Object with device data and pagination info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevicesResponse"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/telemetry":{"post":{"description":"Push telemetry data for an OEM-provisioned device. Requires a MANUFACTURER API key. The device must have provisioningType OEM_DIRECT and belong to a manufacturer in the API key scope.","summary":"Push Device Telemetry","tags":["OEM Direct Integration"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the device","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","description":"The timestamp for the telemetry reading. Defaults to current time if not provided.","example":"2024-01-15T10:32:15Z"},"state":{"type":"object","additionalProperties":{},"description":"Device state data. Schema varies by device type.","example":{"chargePercentage":85,"charge":15725,"chargeRate":2400,"chargingState":"charging","backupReserve":20}}},"required":["state"]}}}},"responses":{"202":{"description":"Telemetry accepted for processing.","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]},"deviceId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}},"required":["accepted","deviceId","timestamp"]}}}},"400":{"description":"Bad Request - Telemetry validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"error":{"type":"string"},"value":{}},"required":["field","error"]}}},"required":["error","message"]}}}},"401":{"description":"Unauthorized - Invalid or missing MANUFACTURER API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"error":{"type":"string"},"value":{}},"required":["field","error"]}}},"required":["error","message"]}}}},"403":{"description":"Forbidden - Device is not OEM_DIRECT or does not belong to manufacturers in API key scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"error":{"type":"string"},"value":{}},"required":["field","error"]}}},"required":["error","message"]}}}},"404":{"description":"Not Found - Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"error":{"type":"string"},"value":{}},"required":["field","error"]}}},"required":["error","message"]}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"error":{"type":"string"},"value":{}},"required":["field","error"]}}},"required":["error","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/types":{"get":{"description":"List the device types supported by the Texture API","summary":"Get a list of device types","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"List of device types","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTypes"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/history":{"get":{"description":"Get all archived state data for a single device","summary":"Get historical data for a device state","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"in":"query","name":"from","description":"The date and time from which to return device state historical data.","example":"2023-09-10T11:43:33.266Z"},{"schema":{"type":"string"},"required":false,"in":"query","name":"to","description":"The date and time to which to return device state historical data.","example":"2023-09-21T11:43:33.266Z"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Device historical state data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceHistoryResponse"}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided"]}},"required":["message"]}}}},"401":{"description":"Invalid authentication","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid authentication"]}},"required":["message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/commands":{"get":{"description":"Get paginated commands for a single device","summary":"Get commands data for a device","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"},{"schema":{"type":"array","items":{"type":"string","enum":["pending","delivered","completed","scheduled","failed"],"description":"The current status of the command.","example":"pending"},"example":["pending","delivered","completed","scheduled","failed"]},"required":false,"in":"query","name":"status","description":"Array of command statuses to filter by. If not provided, all commands will be returned."},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Device commands data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceCommandsResponse"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/alerts":{"get":{"description":"Get a list of alerts for a device","summary":"Get all alerts for a device with additional optional filtering","tags":["alerts","devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path","description":"The device ID to get alerts for","example":"cllgn0u4r000008l7eazybfbo"},{"schema":{"type":"string"},"required":false,"in":"query","name":"externalId","description":"Filter alerts by external ID.","example":"124254116"},{"schema":{"type":"string","enum":["CRITICAL","WARNING","INFO"],"description":"The severity level of the alert.","example":"WARNING"},"required":false,"description":"Filter alerts by severity level.","in":"query","name":"severity"},{"schema":{"type":"string","enum":["OPEN","ACKNOWLEDGED","IGNORED","RESOLVED"],"description":"The current status of the alert.","example":"OPEN"},"required":false,"description":"Filter alerts by status.","in":"query","name":"status"},{"schema":{"type":"string"},"required":false,"in":"query","name":"siteId","description":"Filter alerts by site ID.","example":"cllgn0u4r000008l7eazybfbo"},{"schema":{"type":"string"},"required":false,"in":"query","name":"sourceSystem","description":"Filter alerts by source system.","example":"Inverter 01"},{"schema":{"type":"string"},"required":false,"in":"query","name":"manufacturerDeviceId","description":"Filter alerts by manufacturer device ID.","example":"123456"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Object with alerts data and pagination info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alerts"}}}},"401":{"description":"Unauthorized - Missing or invalid API key"},"403":{"description":"Forbidden - Access denied"},"404":{"description":"Not found"},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/tags":{"get":{"description":"Get tags associated with a device.","summary":"Get device tags","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"responses":{"200":{"description":"Array of tags associated with the device.","content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"},"description":"The tags associated with the device.","example":["tag1","tag2"]}},"required":["tags"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"put":{"description":"Update tags associated with a device.","summary":"Update device tags","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"},"description":"The tags to update for the device.","example":["tag1","tag2"]}},"required":["tags"]}}}},"responses":{"200":{"description":"Updated array of tags associated with the device.","content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"},"description":"The updated tags associated with the device.","example":["tag1","tag2"]}},"required":["tags"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/site":{"put":{"description":"Update the site associated with a device. Sets the siteProfileId on the device, linking it to a specific site within the workspace.","summary":"Update device site","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"siteProfileId":{"type":"string","description":"The ID of the site to associate this device with.","example":"cmg8kxvmq0a676l5domv8g5of"}},"required":["siteProfileId"]}}}},"responses":{"200":{"description":"The device with updated site association.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the device.","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteProfileId":{"type":["string","null"],"description":"The ID of the site this device is associated with.","example":"cmg8kxvmq0a676l5domv8g5of"}},"required":["id","siteProfileId"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized access","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The error message.","example":"Device not found"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}":{"get":{"description":"Get device data by its ID.","summary":"Get a single device","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"responses":{"200":{"description":"Object with device data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Device"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Device not found"]}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete device by its ID.","summary":"Delete a single device","tags":["devices"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"clmt0f0qq000g6jez6qa2sj4t"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"responses":{"204":{"description":"Device deleted","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Device deleted"]}},"required":["message"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided"]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided"]}},"required":["message"]}}}},"403":{"description":"Unauthorized action","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Unauthorized action"]}},"required":["message"]}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Resource not found"]}},"required":["message"]}}}},"500":{"description":"Server failure","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Server failure"]}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/schedules":{"get":{"description":"Looks up the schedules related to a device.","summary":"Get a device's schedules","tags":["schedules","devices"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"responses":{"200":{"description":"The given device schedule.","content":{"application/json":{"schema":{"type":"object","properties":{"deviceSchedules":{"type":"array","items":{"$ref":"#/components/schemas/DeviceSchedule"}}},"required":["deviceSchedules"]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Deletes all of a device's schedules (if any exist) and returns the deleted schedule info.","summary":"Deletes a device's schedules","tags":["schedules","devices"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"responses":{"200":{"description":"The schedule(s) that was deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deviceSchedules":{"type":"array","items":{"$ref":"#/components/schemas/DeviceSchedule"}}},"required":["deviceSchedules"]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/schedule/{scheduleId}":{"get":{"description":"Looks up a schedule related to a device.","summary":"Get a device schedule","tags":["schedules","devices"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"},{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the schedule issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the schedule issued by Texture.","name":"scheduleId","in":"path"}],"responses":{"200":{"description":"The given device schedule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceSchedule"}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Schedule not found for device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Schedule not found for device."]}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Deletes a device's schedule by id.","summary":"Delete a device schedule","tags":["schedules","devices"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"},{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the schedule issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the schedule issued by Texture.","name":"scheduleId","in":"path"}],"responses":{"200":{"description":"The schedule that was deleted.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/DeviceSchedule"},{"type":["object","null"]}]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device or schedule not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND","SCHEDULE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/devices/{id}/schedule":{"post":{"description":"Create a new device schedule.","summary":"Create new device schedule","tags":["schedules","devices"],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the device issued by Texture.","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"schedule":{"type":"object","properties":{"deviceTimezone":{"type":"string","description":"A valid timezone string","example":"America/New_York"},"startsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule starts.","example":"2021-04-01T00:00:00.000Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule ends.","example":"2021-04-01T00:00:00.000Z"},"defaultDeviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}}},"required":["defaultDeviceOperatingMode"]},"rules":{"type":"array","items":{"type":"object","properties":{"daysOfWeek":{"type":"array","items":{"type":"integer"},"example":[0,1,2,3,4,5,6],"description":"The days of the week the rule is active, numbered 0-6, where 0 is Sunday. In the example the rule is active every day of the week."},"startTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"endTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"deviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}}},"required":["daysOfWeek","startTime","endTime","deviceOperatingMode"]}},"force":{"type":"boolean","description":"If true, the device schedule will be set even if it overlaps with an existing schedule. The overlapping schedule will be deleted. If false, we will throw an error if the schedule overlap. You need to delete the existing schedule manually before creating a new one.","example":false}},"required":["schedule","rules"]}}}},"responses":{"200":{"description":"The newly created device schedule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceSchedule"}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/enrollments/{enrollmentId}":{"get":{"description":"Get details of a specific enrollment.","summary":"Get enrollment by ID","tags":["enrollments"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"in":"path","name":"enrollmentId","description":"The unique identifier of the enrollment to retrieve"}],"responses":{"200":{"description":"Enrollment details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enrollment"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Enrollment not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete an enrollment by ID. This operation sets the enrollment status to 'unenrolling'.","summary":"Delete enrollment","tags":["enrollments"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The unique identifier of the enrollment to delete","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier of the enrollment to delete","name":"enrollmentId","in":"path"}],"responses":{"204":{"description":"Enrollment successfully deleted (status set to unenrolling)"},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Enrollment not found"},"500":{"description":"Internal server error"},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/enrollments/{enrollmentId}/metadata":{"patch":{"description":"Update enrollment metadata using merge semantics. Provided keys will be added or updated, while existing keys not mentioned will remain unchanged. This operation does not replace the entire metadata object.","summary":"Update enrollment metadata (merge)","tags":["enrollments"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"in":"path","name":"enrollmentId","description":"The unique identifier of the enrollment"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Metadata key-value pairs to merge with existing enrollment metadata. Keys will be added or updated; existing keys not mentioned will remain unchanged.","example":{"source":"api","campaign":"summer2026","partner_id":"ABC123"}}},"required":["metadata"]}}}},"responses":{"200":{"description":"Enrollment metadata updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enrollment"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden - not authorized to update this enrollment","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Enrollment not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/enrollments/{enrollmentId}/status":{"put":{"description":"Update the eligibility status of a specific enrollment. Valid statuses: candidate, eligible, ineligible, submitted, approved, rejected, unenrolling.","summary":"Update enrollment status","tags":["enrollments"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"in":"path","name":"enrollmentId","description":"The unique identifier of the enrollment to update"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["candidate","eligible","ineligible","submitted","approved","rejected","unenrolling"],"description":"The new eligibility status for the enrollment","example":"eligible"},"reason":{"type":"string","description":"Optional reason for this status change","example":"no device connected"}},"required":["status"]}}}},"responses":{"200":{"description":"Enrollment status updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enrollment"}}}},"400":{"description":"Invalid status value","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"Enrollment not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/invitations":{"get":{"description":"List all pending invitations for the organization associated with the API key.","summary":"List invitations","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to retrieve."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"in":"query","name":"perPage","description":"Number of invitations to return per page."}],"responses":{"200":{"description":"Paginated list of invitations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListInvitationsResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Send an invitation to a user to join the organization.","summary":"Send invitation","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"The email address of the user to invite.","example":"user@example.com"},"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The role to assign to the user upon accepting the invitation.","example":"USER"}},"required":["email","role"]}}}},"responses":{"201":{"description":"Invitation created and sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/invitations/{id}":{"delete":{"description":"Revoke a pending invitation.","summary":"Revoke invitation","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the invitation.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the invitation.","in":"path","name":"id"}],"responses":{"200":{"description":"Invitation successfully revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Invitation not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/invitations/{id}/resend":{"post":{"description":"Resend the invitation email to the invitee.","summary":"Resend invitation","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the invitation.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the invitation.","in":"path","name":"id"}],"responses":{"200":{"description":"Invitation email successfully resent.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Invitation not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/leads":{"get":{"description":"Get a list of leads for a workspace","summary":"Get a list of leads","tags":["leads"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Object with lead data and pagination info","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"email":{"type":"string","format":"email"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"phone":{"type":["string","null"]},"address1":{"type":["string","null"]},"address2":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"postalCode":{"type":["string","null"]},"country":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":{"type":"string"}},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","email","firstName","lastName","phone","address1","address2","city","state","postalCode","country","metadata","createdAt","updatedAt"]}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Unauthorized - Invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new lead","summary":"Create a new lead","tags":["leads"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"phone":{"type":["string","null"]},"address1":{"type":["string","null"]},"address2":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"postalCode":{"type":["string","null"]},"country":{"type":["string","null"]},"metadata":{"type":["object","null"],"additionalProperties":{"type":"string"}}},"required":["email"]}}}},"responses":{"200":{"description":"The lead that was created.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"email":{"type":"string","format":"email"},"firstName":{"type":["string","null"]},"lastName":{"type":["string","null"]},"phone":{"type":["string","null"]},"address1":{"type":["string","null"]},"address2":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"postalCode":{"type":["string","null"]},"country":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":{"type":"string"}},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","email","firstName","lastName","phone","address1","address2","city","state","postalCode","country","metadata","createdAt","updatedAt"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Error from creating lead.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/members":{"get":{"description":"List all members of the organization associated with the API key.","summary":"List members","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to retrieve."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"in":"query","name":"perPage","description":"Number of members to return per page."}],"responses":{"200":{"description":"Paginated list of organization members.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMembersResponse"}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/members/{id}":{"get":{"description":"Get a single organization member by their membership ID.","summary":"Get a member","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the membership to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the membership to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"Member details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Member"}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Member not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update the role of an organization member.","summary":"Update member role","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the membership to update.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the membership to update.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["USER","ADMIN","VIEWER","OPERATOR"],"description":"The new role for the member.","example":"ADMIN"}},"required":["role"]}}}},"responses":{"200":{"description":"The updated member.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberUpdated"}}}},"400":{"description":"Bad Request — invalid input data."},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Member not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Remove a member from the organization.","summary":"Remove a member","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the membership to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the membership to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"Member successfully removed.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized — missing or invalid API key."},"403":{"description":"Forbidden."},"404":{"description":"Member not found."},"500":{"description":"Internal server error."},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/metrics/consumption":{"get":{"description":"Metric detailing the total energy consumed in watt hours for each time bucket. Applicable to battery devices.","summary":"Get energy consumption metrics","tags":["metrics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","name":"filterDeviceId","in":"query"},{"schema":{"type":"array","items":{"type":"string"},"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","name":"filterSiteId","in":"query"},{"schema":{"type":"string","pattern":"^([1-9]\\d{0,1}[hwdmMy])$","description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","example":"24h"},"required":false,"description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","name":"filterRangeRelative","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range start point which to fetch metrics","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range start point which to fetch metrics","name":"filterRangeAfter","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","name":"filterRangeBefore","in":"query"},{"schema":{"type":"string","enum":["FIFTEEN_MINUTES","HOUR","DAY","WEEK","MONTH","YEAR"],"description":"Size of the window to fetch metrics for","example":"HOUR"},"required":false,"description":"Size of the window to fetch metrics for","name":"windowSize","in":"query"},{"schema":{"type":"string","enum":["SITE"],"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","example":"SITE"},"required":false,"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","name":"groupBy","in":"query"}],"responses":{"200":{"description":"Object with energy consumption metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ts":{"type":["string","null"],"format":"date-time","description":"Timestamp of the data point","example":"2021-01-01T00:00:00Z"},"v":{"type":"number","description":"Total energy consumed in watt hours for the time bucket","example":100},"deviceId":{"type":["string","null"],"description":"Device ID for the data point","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteId":{"type":["string","null"]},"customerId":{"type":["string","null"]}},"required":["ts","v"]}},"meta":{"type":"object","properties":{"label":{"type":"string","description":"Label for the metric","example":"energyConsumedWhr"},"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"],"description":"Unit of the metric","example":"WATT_HOURS"},"displayUnit":{"type":"string","description":"Display unit of the metric","example":"whr"},"sparse":{"type":"boolean","description":"Whether the metric is sparse","example":false},"series":{"type":["array","null"],"items":{"type":"string"},"description":"Series for the metric","example":["clmt0f0qq000g6jez6qa2sj4t"]},"domainMeta":{"type":"object","properties":{"label":{"type":"string"},"sparse":{"type":"boolean"},"rate":{"type":"object","properties":{"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"]},"displayUnit":{"type":"string"},"scaleFactor":{"type":"number"}},"required":["unit","displayUnit","scaleFactor"]}},"required":["label","sparse","rate"],"description":"Domain metadata for the metric"}},"required":["label","unit","displayUnit","sparse","domainMeta"]}},"required":["data","meta"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Invalid parameters provided.","details":{"error":"filterRangeRelative: Relative time must be in the format Nh, Nd, Nw, Nm, Ny"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Internal server error."}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/metrics/production":{"get":{"description":"Metric detailing the total energy produced/discharged in watt hours for each time bucket. Applicable to battery devices.","summary":"Get energy production metrics","tags":["metrics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","name":"filterDeviceId","in":"query"},{"schema":{"type":"array","items":{"type":"string"},"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","name":"filterSiteId","in":"query"},{"schema":{"type":"string","pattern":"^([1-9]\\d{0,1}[hwdmMy])$","description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","example":"24h"},"required":false,"description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","name":"filterRangeRelative","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range start point which to fetch metrics","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range start point which to fetch metrics","name":"filterRangeAfter","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","name":"filterRangeBefore","in":"query"},{"schema":{"type":"string","enum":["FIFTEEN_MINUTES","HOUR","DAY","WEEK","MONTH","YEAR"],"description":"Size of the window to fetch metrics for","example":"HOUR"},"required":false,"description":"Size of the window to fetch metrics for","name":"windowSize","in":"query"},{"schema":{"type":"string","enum":["SITE"],"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","example":"SITE"},"required":false,"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","name":"groupBy","in":"query"}],"responses":{"200":{"description":"Object with energy production metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ts":{"type":["string","null"],"format":"date-time","description":"Timestamp of the data point","example":"2021-01-01T00:00:00Z"},"v":{"type":"number","description":"Total energy produced/discharged in watt hours for the time bucket","example":100},"deviceId":{"type":["string","null"],"description":"Device ID for the data point","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteId":{"type":["string","null"]},"customerId":{"type":["string","null"]}},"required":["ts","v"]}},"meta":{"type":"object","properties":{"label":{"type":"string","description":"Label for the metric","example":"energyProducedWhr"},"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"],"description":"Unit of the metric","example":"WATT_HOURS"},"displayUnit":{"type":"string","description":"Display unit of the metric","example":"whr"},"sparse":{"type":"boolean","description":"Whether the metric is sparse","example":false},"series":{"type":["array","null"],"items":{"type":"string"},"description":"Series for the metric","example":["clmt0f0qq000g6jez6qa2sj4t"]},"domainMeta":{"type":"object","properties":{"label":{"type":"string"},"sparse":{"type":"boolean"},"rate":{"type":"object","properties":{"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"]},"displayUnit":{"type":"string"},"scaleFactor":{"type":"number"}},"required":["unit","displayUnit","scaleFactor"]}},"required":["label","sparse","rate"],"description":"Domain metadata for the metric"}},"required":["label","unit","displayUnit","sparse","domainMeta"]}},"required":["data","meta"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Invalid parameters provided.","details":{"error":"filterRangeAfter: Start time must be in the past"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Internal server error."}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/metrics/storage":{"get":{"description":"Metric detailing the latest energy stored in watt hours for each time bucket. Applicable to battery devices.","summary":"Get energy storage metrics","tags":["metrics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","name":"filterDeviceId","in":"query"},{"schema":{"type":"array","items":{"type":"string"},"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","name":"filterSiteId","in":"query"},{"schema":{"type":"string","pattern":"^([1-9]\\d{0,1}[hwdmMy])$","description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","example":"24h"},"required":false,"description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","name":"filterRangeRelative","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range start point which to fetch metrics","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range start point which to fetch metrics","name":"filterRangeAfter","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","name":"filterRangeBefore","in":"query"},{"schema":{"type":"string","enum":["FIFTEEN_MINUTES","HOUR","DAY","WEEK","MONTH","YEAR"],"description":"Size of the window to fetch metrics for","example":"HOUR"},"required":false,"description":"Size of the window to fetch metrics for","name":"windowSize","in":"query"},{"schema":{"type":"string","enum":["SITE"],"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","example":"SITE"},"required":false,"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","name":"groupBy","in":"query"}],"responses":{"200":{"description":"Object with energy storage metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ts":{"type":["string","null"],"format":"date-time","description":"Timestamp of the data point","example":"2021-01-01T00:00:00Z"},"v":{"type":"number","description":"Latest energy stored in watt hours for the time bucket","example":100},"deviceId":{"type":["string","null"],"description":"Device ID for the data point","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteId":{"type":["string","null"]},"customerId":{"type":["string","null"]}},"required":["ts","v"]}},"meta":{"type":"object","properties":{"label":{"type":"string","description":"Label for the metric","example":"charge"},"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"],"description":"Unit of the metric","example":"WATT_HOURS"},"displayUnit":{"type":"string","description":"Display unit of the metric","example":"whr"},"sparse":{"type":"boolean","description":"Whether the metric is sparse","example":false},"series":{"type":["array","null"],"items":{"type":"string"},"description":"Series for the metric","example":["clmt0f0qq000g6jez6qa2sj4t"]},"domainMeta":{"type":"object","properties":{"label":{"type":"string"},"sparse":{"type":"boolean"},"rate":{"type":"object","properties":{"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"]},"displayUnit":{"type":"string"},"scaleFactor":{"type":"number"}},"required":["unit","displayUnit","scaleFactor"]}},"required":["label","sparse","rate"],"description":"Domain metadata for the metric"}},"required":["label","unit","displayUnit","sparse","domainMeta"]}},"required":["data","meta"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Internal server error."}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/metrics/emissions":{"get":{"description":"Metric detailing the total energy emissions in pounds of CO2 for each time bucket.","summary":"Get energy emissions metrics","tags":["metrics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","name":"filterDeviceId","in":"query"},{"schema":{"type":"array","items":{"type":"string"},"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","name":"filterSiteId","in":"query"},{"schema":{"type":"string","pattern":"^([1-9]\\d{0,1}[hwdmMy])$","description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","example":"24h"},"required":false,"description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","name":"filterRangeRelative","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range start point which to fetch metrics","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range start point which to fetch metrics","name":"filterRangeAfter","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","name":"filterRangeBefore","in":"query"},{"schema":{"type":"string","enum":["FIFTEEN_MINUTES","HOUR","DAY","WEEK","MONTH","YEAR"],"description":"Size of the window to fetch metrics for","example":"HOUR"},"required":false,"description":"Size of the window to fetch metrics for","name":"windowSize","in":"query"},{"schema":{"type":"string","enum":["SITE"],"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","example":"SITE"},"required":false,"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","name":"groupBy","in":"query"}],"responses":{"200":{"description":"Object with energy emissions metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ts":{"type":["string","null"],"format":"date-time","description":"Timestamp of the data point","example":"2021-01-01T00:00:00Z"},"v":{"type":"number","description":"Total energy emissions in pounds of CO2 for the time bucket","example":100},"deviceId":{"type":["string","null"],"description":"Device ID for the data point","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteId":{"type":["string","null"]},"customerId":{"type":["string","null"]}},"required":["ts","v"]}},"meta":{"type":"object","properties":{"label":{"type":"string","description":"Label for the metric","example":"energyEmissions"},"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"],"description":"Unit of the metric","example":"POUNDS_CO2"},"displayUnit":{"type":"string","description":"Display unit of the metric","example":"lbs_co2"},"sparse":{"type":"boolean","description":"Whether the metric is sparse","example":false},"series":{"type":["array","null"],"items":{"type":"string"},"description":"Series for the metric","example":["clmt0f0qq000g6jez6qa2sj4t"]},"domainMeta":{"type":"object","properties":{"label":{"type":"string"},"sparse":{"type":"boolean"},"rate":{"type":"object","properties":{"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"]},"displayUnit":{"type":"string"},"scaleFactor":{"type":"number"}},"required":["unit","displayUnit","scaleFactor"]}},"required":["label","sparse","rate"],"description":"Domain metadata for the metric"}},"required":["label","unit","displayUnit","sparse","domainMeta"]}},"required":["data","meta"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Invalid parameters provided.","details":{"error":"At least one filterDeviceId or filterSiteId must be specified"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Internal server error."}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/metrics/generation":{"get":{"description":"Metric detailing the total energy generated in watt hours for each time bucket. Applicable to inverter devices.","summary":"Get energy generation metrics","tags":["metrics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","name":"filterDeviceId","in":"query"},{"schema":{"type":"array","items":{"type":"string"},"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","name":"filterSiteId","in":"query"},{"schema":{"type":"string","pattern":"^([1-9]\\d{0,1}[hwdmMy])$","description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","example":"24h"},"required":false,"description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","name":"filterRangeRelative","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range start point which to fetch metrics","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range start point which to fetch metrics","name":"filterRangeAfter","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","name":"filterRangeBefore","in":"query"},{"schema":{"type":"string","enum":["FIFTEEN_MINUTES","HOUR","DAY","WEEK","MONTH","YEAR"],"description":"Size of the window to fetch metrics for","example":"HOUR"},"required":false,"description":"Size of the window to fetch metrics for","name":"windowSize","in":"query"},{"schema":{"type":"string","enum":["SITE"],"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","example":"SITE"},"required":false,"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","name":"groupBy","in":"query"}],"responses":{"200":{"description":"Object with energy generation metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ts":{"type":["string","null"],"format":"date-time","description":"Timestamp of the data point","example":"2021-01-01T00:00:00Z"},"v":{"type":"number","description":"Total energy generated in watt hours for the time bucket","example":100},"deviceId":{"type":["string","null"],"description":"Device ID for the data point","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteId":{"type":["string","null"]},"customerId":{"type":["string","null"]}},"required":["ts","v"]}},"meta":{"type":"object","properties":{"label":{"type":"string","description":"Label for the metric","example":"energyProducedWhr"},"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"],"description":"Unit of the metric","example":"WATT_HOURS"},"displayUnit":{"type":"string","description":"Display unit of the metric","example":"whr"},"sparse":{"type":"boolean","description":"Whether the metric is sparse","example":false},"series":{"type":["array","null"],"items":{"type":"string"},"description":"Series for the metric","example":["clmt0f0qq000g6jez6qa2sj4t"]},"domainMeta":{"type":"object","properties":{"label":{"type":"string"},"sparse":{"type":"boolean"},"rate":{"type":"object","properties":{"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"]},"displayUnit":{"type":"string"},"scaleFactor":{"type":"number"}},"required":["unit","displayUnit","scaleFactor"]}},"required":["label","sparse","rate"],"description":"Domain metadata for the metric"}},"required":["label","unit","displayUnit","sparse","domainMeta"]}},"required":["data","meta"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Invalid parameters provided.","details":{"error":"filterRangeAfter: Minimum range is 15 minutes"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Internal server error."}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/metrics/grid-energy":{"get":{"description":"Metric detailing the net grid import/export energy in watt hours for each time bucket. Negative values represent energy export, positive values represent energy import. Applicable to sites or devices.","summary":"Get grid energy metrics","tags":["metrics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Device IDs to fetch metrics for. Required when filterSiteId is not provided.","name":"filterDeviceId","in":"query"},{"schema":{"type":"array","items":{"type":"string"},"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","example":["clmt0f0qq000g6jez6qa2sj4t"]},"required":false,"description":"Site IDs to fetch metrics for. Required when filterDeviceId is not provided.","name":"filterSiteId","in":"query"},{"schema":{"type":"string","pattern":"^([1-9]\\d{0,1}[hwdmMy])$","description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","example":"24h"},"required":false,"description":"The time range relative to the current time to fetch metrics, if range, after, and before are all not set, this will default to '1d'","name":"filterRangeRelative","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range start point which to fetch metrics","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range start point which to fetch metrics","name":"filterRangeAfter","in":"query"},{"schema":{"type":["string","null"],"format":"date-time","description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","example":"2021-01-01T00:00:00Z"},"required":false,"description":"Time range end which to fetch metrics, used in combination with filterRangeAfter to limit the time range. If not set, defaults to now","name":"filterRangeBefore","in":"query"},{"schema":{"type":"string","enum":["FIFTEEN_MINUTES","HOUR","DAY","WEEK","MONTH","YEAR"],"description":"Size of the window to fetch metrics for","example":"HOUR"},"required":false,"description":"Size of the window to fetch metrics for","name":"windowSize","in":"query"},{"schema":{"type":"string","enum":["SITE"],"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","example":"SITE"},"required":false,"description":"Facet to group the metrics by. Only SITE is supported by this REST endpoint.","name":"groupBy","in":"query"}],"responses":{"200":{"description":"Object with grid energy metrics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"ts":{"type":["string","null"],"format":"date-time","description":"Timestamp of the data point","example":"2021-01-01T00:00:00Z"},"v":{"type":"number","description":"Net grid energy in watt hours for the time bucket. Negative values represent export, positive values represent import.","example":100},"deviceId":{"type":["string","null"],"description":"Device ID for the data point","example":"clmt0f0qq000g6jez6qa2sj4t"},"siteId":{"type":["string","null"]},"customerId":{"type":["string","null"]}},"required":["ts","v"]}},"meta":{"type":"object","properties":{"label":{"type":"string","description":"Label for the metric","example":"gridEnergy"},"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"],"description":"Unit of the metric","example":"WATT_HOURS"},"displayUnit":{"type":"string","description":"Display unit of the metric","example":"whr"},"sparse":{"type":"boolean","description":"Whether the metric is sparse","example":false},"series":{"type":["array","null"],"items":{"type":"string"},"description":"Series for the metric","example":["clmt0f0qq000g6jez6qa2sj4t"]},"domainMeta":{"type":"object","properties":{"label":{"type":"string"},"sparse":{"type":"boolean"},"rate":{"type":"object","properties":{"unit":{"type":"string","enum":["AMPERE","CELSIUS","DAY","FAHRENHEIT","HOUR","KILOMETER","KILOMETER_PER_HOUR","METER","MILE","MILE_PER_HOUR","MINUTE","MONTH","PERCENT","POUNDS_CO2","SECOND","STRING","TIMESTAMP","UNIT","VOLT","WATT","WATT_HOURS","WEEK","YEAR"]},"displayUnit":{"type":"string"},"scaleFactor":{"type":"number"}},"required":["unit","displayUnit","scaleFactor"]}},"required":["label","sparse","rate"],"description":"Domain metadata for the metric"}},"required":["label","unit","displayUnit","sparse","domainMeta"]}},"required":["data","meta"]}}}},"400":{"description":"Invalid parameters provided","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Invalid parameters provided.","details":{"error":"filterRangeAfter: Minimum range is 15 minutes"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"details":{"type":"object","properties":{"error":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}}}},"required":["message"],"example":{"message":"Internal server error."}}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/oauth-apps":{"get":{"description":"List all OAuth applications for the authenticated workspace.","summary":"List OAuth applications","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Paginated list of OAuth applications","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListOAuthAppsResponse"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new OAuth application. The client secret is returned only in this response — store it securely. It cannot be retrieved again.","summary":"Create OAuth application","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"A human-readable name for the OAuth application.","example":"My Energy App"},"description":{"type":"string","maxLength":1000,"description":"An optional description of the OAuth application.","example":"Connects customers to their energy data."},"redirectUris":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"description":"The list of allowed redirect URIs for the OAuth flow. At least one is required.","example":["https://myapp.com/callback"]},"allowedScopes":{"type":"array","items":{"type":"string"},"minItems":1,"description":"The list of OAuth scopes this application is allowed to request.","example":["read:devices","read:sites"]},"type":{"type":"string","enum":["PUBLIC","CONFIDENTIAL"],"description":"The OAuth application type. CONFIDENTIAL apps can store secrets securely; PUBLIC apps cannot.","example":"CONFIDENTIAL"}},"required":["name","redirectUris","allowedScopes","type"]}}}},"responses":{"201":{"description":"The created OAuth application including the client secret (one-time reveal).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthAppCreated"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/oauth-apps/{id}":{"get":{"description":"Get a single OAuth application by ID.","summary":"Get an OAuth application by ID","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the OAuth application to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the OAuth application to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"OAuth application details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthApp"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"OAuth application not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["OAuth application not found"]}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update an OAuth application's metadata. The client ID and secret cannot be changed via this endpoint.","summary":"Update OAuth application","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the OAuth application to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the OAuth application to retrieve.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"A new human-readable name for the OAuth application.","example":"Updated App Name"},"description":{"type":"string","maxLength":1000,"description":"A new description for the OAuth application.","example":"Updated description."},"redirectUris":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"description":"A new list of allowed redirect URIs.","example":["https://myapp.com/callback","https://myapp.com/auth"]},"allowedScopes":{"type":"array","items":{"type":"string"},"minItems":1,"description":"A new list of allowed OAuth scopes.","example":["read:devices"]}}}}}},"responses":{"200":{"description":"The updated OAuth application.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthAppUpdated"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"OAuth application not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Delete an OAuth application. This action cannot be undone.","summary":"Delete OAuth application","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the OAuth application to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the OAuth application to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"The OAuth application was successfully deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"OAuth application not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/oauth-apps/{id}/rotate-secret":{"post":{"description":"Rotate the client secret for an OAuth application. The previous secret is immediately invalidated. The new secret is returned only in this response — store it securely.","summary":"Rotate OAuth application client secret","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the OAuth application to retrieve.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the OAuth application to retrieve.","in":"path","name":"id"}],"responses":{"200":{"description":"The new client credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthAppSecret"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"OAuth application not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/program-events/{eventId}":{"get":{"description":"Get details of a specific program event.","summary":"Get program event","tags":["Program Events"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier of the program event","example":"cllgn0u4r000008l7eazybfb2"},"required":true,"description":"The unique identifier of the program event","name":"eventId","in":"path"}],"responses":{"200":{"description":"Program event details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgramEvent"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Program event not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/program-events":{"post":{"description":"Create a program event.","summary":"Create program event","tags":["Program Events"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"programInstanceId":{"type":"string","format":"cuid","description":"The unique identifier of the program instance to create the event for.","example":"cllgn0u4r000008l7eazybfbo"},"type":{"type":"string","description":"The type of the program event.","example":"discharge"},"startsAt":{"type":"string","format":"date-time","description":"The date and time the workspace program event starts.","example":"2025-01-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time the workspace program event ends.","example":"2025-01-01T00:00:00Z"},"dispatches":{"type":"array","items":{"type":"object","properties":{"tag":{"type":"string","description":"Tag associated with the devices to dispatch the command batch to.","example":"group-5"},"startsAt":{"type":"string","format":"date-time","description":"The date and time the command batch starts.","example":"2025-01-01T00:00:00Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time the command batch ends.","example":"2025-01-01T00:00:00Z"},"type":{"type":"string","enum":["battery:set-reserve","battery:set-operating-mode","charger:set-operating-mode","thermostat:set-operating-mode","thermostat:set-fan-mode","thermostat:pause-schedule","thermostat:resume-schedule","vehicle:check-pairing-status","vehicle:set-charge-limit","vehicle:set-operating-mode"],"description":"The unique slug representing the type of command.","example":"thermostat:set-operating-mode"},"input":{"type":"object","properties":{},"additionalProperties":{},"description":"The input payload sent with the command. Includes necessary information for execution. Conforms to the schema provided on the command type.","example":{"operatingMode":"eco","heatTarget":70.5,"coolTarget":80.5}}},"required":["tag","startsAt","endsAt","type","input"]},"description":"The command batches associated with the program event."}},"required":["programInstanceId","type","startsAt","endsAt","dispatches"]}}}},"responses":{"201":{"description":"Program event created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgramEvent"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"404":{"description":"Program instance not found","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Program instance not found"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/program-events/{id}":{"delete":{"description":"Delete a program event by ID. This endpoint is not currently implemented.","summary":"Delete program event","tags":["Program Events"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier of the program event","example":"cllgn0u4r000008l7eazybfb2"},"required":true,"description":"The unique identifier of the program event","name":"id","in":"path"}],"responses":{"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Program event not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Response message","example":"Not implemented"}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programInstances/{instanceId}":{"get":{"description":"Get details of a specific program instance by its ID without needing the program slug.","summary":"Get program instance by ID","tags":["Program Instances"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The ID of the program instance to retrieve.","example":"cllgn0u4r0000008l7eazybfbo"},"required":true,"description":"The ID of the program instance to retrieve.","name":"instanceId","in":"path"}],"responses":{"200":{"description":"Program instance details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgramInstance"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to access the program instance","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"404":{"description":"Program instance not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programInstances":{"post":{"description":"Create a new instance of a program. This allows you to activate a program for a specific organization.","summary":"Create program instance","tags":["Program Instances"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProgramInstanceBody"}}}},"responses":{"201":{"description":"Program instance created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgramInstance"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to create program instance","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programInstances/{instanceId}/enrollments":{"post":{"description":"Enroll a customer into a specific program instance.","summary":"Create an enrollment for a program instance","tags":["Program Instances","Enrollments"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The ID of the program instance to retrieve.","example":"cllgn0u4r0000008l7eazybfbo"},"required":true,"description":"The ID of the program instance to retrieve.","name":"instanceId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentInput"}}}},"responses":{"201":{"description":"Enrollment created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Enrollment"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to create enrollment","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"404":{"description":"Program instance not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"get":{"description":"Returns a list of enrollments for a specific program instance. You can filter enrollments by eligibility status using the status query parameter.","summary":"Retrieve program instance enrollments","tags":["Program Instances","Enrollments"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The ID of the program instance to retrieve.","example":"cllgn0u4r0000008l7eazybfbo"},"required":true,"description":"The ID of the program instance to retrieve.","name":"instanceId","in":"path"},{"schema":{"type":"string"},"required":false,"in":"query","name":"status","description":"Filter enrollments by eligibility status."},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":9999,"default":100},"required":false,"name":"perPage","in":"query"}],"responses":{"200":{"description":"A list of enrollments for the program instance","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Enrollment"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to view enrollments","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"404":{"description":"Program instance not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programInstances/{instanceId}/events":{"get":{"description":"List events of a specific program instance.","summary":"List program instance events","tags":["Program Instances"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","format":"cuid","description":"The unique identifier of the program instance","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier of the program instance","name":"instanceId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Program instance events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProgramEvent"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Program instance not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs":{"get":{"description":"Returns a list of Programs (the catalog). By default, returns only those programs that have at least one active instance for the current organization.","summary":"Retrieve programs","tags":["programs"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"boolean"},"required":false,"in":"query","name":"include_all","description":"If true, returns all available programs; if false (default), returns only programs with an active instance."},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"A list of programs","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Program"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to access programs","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs/{programSlug}/instances":{"get":{"description":"Returns instances (activations) of a program for the current organization.","summary":"Get program instances","tags":["programs"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"programSlug","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"A list of program instances","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProgramInstance"}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Program not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs/{programSlug}/instances/{instanceId}":{"get":{"description":"Get details of a specific program instance.","summary":"Get program instance","tags":["programs"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The slug of the program","example":"nyc-battery-program-2025"},"required":true,"description":"The slug of the program","name":"programSlug","in":"path"},{"schema":{"type":"string","description":"The unique identifier of the program instance","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier of the program instance","name":"instanceId","in":"path"}],"responses":{"200":{"description":"Program instance details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgramInstance"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Program instance not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs/{programSlug}":{"post":{"description":"Create a new instance of a program. This allows you to activate a program for a specific organization.","summary":"Create program instance","tags":["programs"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The slug of the program to create an instance for","example":"nyc-battery-program-2025"},"required":true,"description":"The slug of the program to create an instance for","name":"programSlug","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the program instance","example":"NYC Battery Program 2025 - ConEd"}},"required":["name"]}}}},"responses":{"201":{"description":"Program instance created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"cuid","description":"The unique identifier for the program instance","example":"cllgn0u4r000008l7eazybfbo"},"programSlug":{"type":"string","description":"The slug of the program","example":"nyc-battery-program-2025"},"name":{"type":"string","description":"The name of the program instance","example":"NYC Battery Program 2025 - ConEd"},"createdAt":{"type":"string","format":"date-time","description":"The date and time the program instance was created","example":"2025-01-01T00:00:00Z"}},"required":["id","programSlug","name","createdAt"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Program not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs/reports/event-performance":{"get":{"description":"Returns aggregated event performance data for program reporting. Includes summary KPIs, per-event metrics with hourly energy buckets, and batch status. Note: each event's `label` and `startHour` (and the corresponding CSV/Excel columns) are derived in UTC; use the raw ISO `startsAt`/`endsAt` and `hourlyBuckets[].bucket` timestamps for timezone conversion.","summary":"Retrieve event performance report","tags":["programs","Program Reports"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by specific program ID","example":"prog_123"},"required":false,"description":"Filter by specific program ID","name":"program_id","in":"query"},{"schema":{"type":"string","format":"date","description":"Start date for time range filter (YYYY-MM-DD format)","example":"2024-01-01"},"required":false,"description":"Start date for time range filter (YYYY-MM-DD format)","name":"start_date","in":"query"},{"schema":{"type":"string","format":"date","description":"End date for time range filter (YYYY-MM-DD format)","example":"2024-12-31"},"required":false,"description":"End date for time range filter (YYYY-MM-DD format)","name":"end_date","in":"query"},{"schema":{"type":"string","enum":["json","csv","xlsx"],"default":"json","description":"Response format: json (default), csv, or xlsx"},"required":false,"description":"Response format: json (default), csv, or xlsx","name":"format","in":"query"},{"schema":{"type":"string","description":"Filter by specific event ID","example":"evt_456"},"required":false,"description":"Filter by specific event ID","name":"event_id","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":15,"description":"Maximum number of events to return (default: 15, max: 100)"},"required":false,"description":"Maximum number of events to return (default: 15, max: 100)","name":"max_events","in":"query"}],"responses":{"200":{"description":"Event performance report data","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"totalEvents":{"type":"number"},"devicesEnrolled":{"type":"number"},"devicesParticipated":{"type":"number"},"successRate":{"type":"number"},"totalEnergyKwh":{"type":"number"},"avgPeakKw":{"type":"number"}},"required":["totalEvents","devicesEnrolled","devicesParticipated","successRate","totalEnergyKwh","avgPeakKw"]},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"startsAt":{"type":"string"},"endsAt":{"type":["string","null"]},"label":{"type":"string"},"startHour":{"type":"number"},"durationHours":{"type":"number"},"totalEnergyKwh":{"type":"number"},"avgParticipationRate":{"type":"number"},"hourlyBuckets":{"type":"array","items":{"type":"object","properties":{"bucket":{"type":"string"},"energyKwh":{"type":"number"},"deviceCount":{"type":"number"},"participationRate":{"type":"number"}},"required":["bucket","energyKwh","deviceCount","participationRate"]}},"batchMetrics":{"type":"object","properties":{"issued":{"type":"number"},"succeeded":{"type":"number"},"failed":{"type":"number"},"pending":{"type":"number"}},"required":["issued","succeeded","failed","pending"]}},"required":["id","startsAt","endsAt","label","startHour","durationHours","totalEnergyKwh","avgParticipationRate","hourlyBuckets","batchMetrics"]}},"energyRange":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]},"meta":{"type":"object","properties":{"eventCount":{"type":"number"},"deviceCount":{"type":"number"},"timeRange":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"}},"required":["start","end"]}},"required":["eventCount","deviceCount","timeRange"]}},"required":["summary","events","energyRange","meta"]}},"text/csv":{"schema":{"type":"string"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request - validation error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to access program reports","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs/reports/device-participation":{"get":{"description":"Returns device-level participation data for program reporting. Includes summary statistics and per-device participation status, energy metrics, and response times.","summary":"Retrieve device participation report","tags":["programs","Program Reports"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by specific program ID","example":"prog_123"},"required":false,"description":"Filter by specific program ID","name":"program_id","in":"query"},{"schema":{"type":"string","format":"date","description":"Start date for time range filter (YYYY-MM-DD format)","example":"2024-01-01"},"required":false,"description":"Start date for time range filter (YYYY-MM-DD format)","name":"start_date","in":"query"},{"schema":{"type":"string","format":"date","description":"End date for time range filter (YYYY-MM-DD format)","example":"2024-12-31"},"required":false,"description":"End date for time range filter (YYYY-MM-DD format)","name":"end_date","in":"query"},{"schema":{"type":"string","enum":["json","csv","xlsx"],"default":"json","description":"Response format: json (default), csv, or xlsx"},"required":false,"description":"Response format: json (default), csv, or xlsx","name":"format","in":"query"},{"schema":{"type":"string","description":"Filter by specific event ID","example":"evt_456"},"required":false,"description":"Filter by specific event ID","name":"event_id","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":15,"description":"Maximum number of events to return (default: 15, max: 100)"},"required":false,"description":"Maximum number of events to return (default: 15, max: 100)","name":"max_events","in":"query"}],"responses":{"200":{"description":"Device participation report data","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"enrolled":{"type":"number"},"participated":{"type":"number"},"participatedPercentage":{"type":"number"},"didNotParticipate":{"type":"number"},"didNotParticipatePercentage":{"type":"number"}},"required":["enrolled","participated","participatedPercentage","didNotParticipate","didNotParticipatePercentage"]},"devices":{"type":"array","items":{"type":"object","properties":{"deviceId":{"type":"string"},"deviceName":{"type":"string"},"manufacturer":{"type":"string"},"model":{"type":"string"},"manufacturerDisplayName":{"type":["string","null"]},"displayModelName":{"type":["string","null"]},"manufacturerLogoUrl":{"type":["string","null"]},"memberName":{"type":["string","null"]},"deviceType":{"type":"string"},"status":{"type":"string"},"energyKwh":{"type":["number","null"]},"dischargeEnergyKwh":{"type":["number","null"]},"responseTimeSeconds":{"type":["number","null"]}},"required":["deviceId","deviceName","manufacturer","model","manufacturerDisplayName","displayModelName","manufacturerLogoUrl","memberName","deviceType","status","energyKwh","dischargeEnergyKwh","responseTimeSeconds"]}},"meta":{"type":"object","properties":{"eventCount":{"type":"number"},"deviceCount":{"type":"number"},"timeRange":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"}},"required":["start","end"]}},"required":["eventCount","deviceCount","timeRange"]}},"required":["summary","devices","meta"]}},"text/csv":{"schema":{"type":"string"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request - validation error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to access program reports","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/programs/reports/fleet-health":{"get":{"description":"Returns fleet health report for enrolled devices. Includes health metrics (success rate, response time, connectivity), issues flagged for attention, and program enrollments. Uses a 30-day rolling window by default. Note: `meta.timeWindowLabel` (and the corresponding CSV/Excel column) is formatted in UTC; use the raw ISO timestamps for timezone conversion.","summary":"Retrieve fleet health report","tags":["programs","Program Reports"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by specific program ID","example":"prog_123"},"required":false,"description":"Filter by specific program ID","name":"program_id","in":"query"},{"schema":{"type":"string","format":"date","description":"Start date for time range filter (YYYY-MM-DD format)","example":"2024-01-01"},"required":false,"description":"Start date for time range filter (YYYY-MM-DD format)","name":"start_date","in":"query"},{"schema":{"type":"string","format":"date","description":"End date for time range filter (YYYY-MM-DD format)","example":"2024-12-31"},"required":false,"description":"End date for time range filter (YYYY-MM-DD format)","name":"end_date","in":"query"},{"schema":{"type":"string","enum":["json","csv","xlsx"],"default":"json","description":"Response format: json (default), csv, or xlsx"},"required":false,"description":"Response format: json (default), csv, or xlsx","name":"format","in":"query"}],"responses":{"200":{"description":"Fleet health report data","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"total":{"type":"number"},"online":{"type":"number"},"onlinePercent":{"type":"number"},"offline":{"type":"number"},"offlinePercent":{"type":"number"},"needsAttention":{"type":"number"}},"required":["total","online","onlinePercent","offline","offlinePercent","needsAttention"]},"devices":{"type":"array","items":{"type":"object","properties":{"deviceId":{"type":"string"},"deviceName":{"type":"string"},"deviceType":{"type":"string"},"manufacturer":{"type":"string"},"model":{"type":"string"},"manufacturerDisplayName":{"type":["string","null"]},"displayModelName":{"type":["string","null"]},"manufacturerLogoUrl":{"type":["string","null"]},"memberName":{"type":["string","null"]},"status":{"type":"string"},"uptimePercent":{"type":["number","null"]},"successPercent":{"type":["number","null"]},"avgResponseSeconds":{"type":["number","null"]},"issues":{"type":"array","items":{"type":"string"}},"programEnrollments":{"type":["array","null"],"items":{"type":"object","properties":{"programId":{"type":"string"},"programName":{"type":"string"}},"required":["programId","programName"]}}},"required":["deviceId","deviceName","deviceType","manufacturer","model","manufacturerDisplayName","displayModelName","manufacturerLogoUrl","memberName","status","uptimePercent","successPercent","avgResponseSeconds","issues","programEnrollments"]}},"meta":{"type":"object","properties":{"timeWindowLabel":{"type":"string"},"deviceCount":{"type":"number"},"dataAsOf":{"type":"string"}},"required":["timeWindowLabel","deviceCount","dataAsOf"]}},"required":["summary","devices","meta"]}},"text/csv":{"schema":{"type":"string"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request - validation error","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - not authorized to access program reports","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"You are not authorized to perform this action"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/schedules/tags/{tag}":{"post":{"description":"Create a new tag schedule.","summary":"Create new tag schedule","tags":["schedules"],"parameters":[{"schema":{"type":"string","description":"The tag that this schedule belongs to.","example":"tag-value"},"required":true,"description":"The tag that this schedule belongs to.","name":"tag","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deviceType":{"type":"string","enum":["battery","thermostat","vehicle"],"description":"The device type that this schedule belongs to.","example":"thermostat"},"schedule":{"type":"object","properties":{"timezone":{"type":"string","description":"A valid timezone string","example":"America/New_York"},"startsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule starts.","example":"2021-04-01T00:00:00.000Z"},"endsAt":{"type":"string","format":"date-time","description":"The date and time that this schedule ends.","example":"2021-04-01T00:00:00.000Z"},"defaultDeviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}}},"required":["timezone","defaultDeviceOperatingMode"]},"rules":{"type":"array","items":{"type":"object","properties":{"daysOfWeek":{"type":"array","items":{"type":"integer"},"example":[0,1,2,3,4,5,6],"description":"The days of the week the rule is active, numbered 0-6, where 0 is Sunday. In the example the rule is active every day of the week."},"startTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"endTime":{"type":"string","example":"13:00","description":"The hour and minute of the day the rule is to start or ending (in 24 hour clock)"},"deviceOperatingMode":{"type":"object","additionalProperties":{},"description":"The operating mode to set the device to during the specified time.","example":{"operatingMode":"auto","heatTarget":70,"coolTarget":78}}},"required":["daysOfWeek","startTime","endTime","deviceOperatingMode"]}},"force":{"type":"boolean","description":"If true, the tag schedule will be set even if it overlaps with an existing schedule. The overlapping schedule will be deleted. If false, we will throw an error if the schedule overlap. You need to delete the existing schedule manually before creating a new one.","example":false}},"required":["deviceType","schedule","rules"]}}}},"responses":{"200":{"description":"The newly created tag schedule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagSchedule"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"get":{"description":"Gets all schedules for a tag.","summary":"Get all schedules for a tag","tags":["schedules"],"parameters":[{"schema":{"type":"string","description":"The tag that this schedule belongs to.","example":"tag-value"},"required":true,"description":"The tag that this schedule belongs to.","name":"tag","in":"path"}],"responses":{"200":{"description":"The list of schedules by tag.","content":{"application/json":{"schema":{"type":"object","properties":{"tagSchedules":{"type":"array","items":{"$ref":"#/components/schemas/TagSchedule"}}},"required":["tagSchedules"]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Schedule not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SCHEDULE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Deletes all schedules for a tag.","summary":"Deletes all schedules for a tag","tags":["schedules"],"parameters":[{"schema":{"type":"string","description":"The tag that the schedules belongs to.","example":"tag-value"},"required":true,"description":"The tag that the schedules belongs to.","name":"tag","in":"path"}],"responses":{"200":{"description":"The list of deleted schedules by tag.","content":{"application/json":{"schema":{"type":"object","properties":{"tagSchedules":{"type":"array","items":{"$ref":"#/components/schemas/TagSchedule"}}},"required":["tagSchedules"]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Schedule not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SCHEDULE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/schedules/tags/{tag}/{scheduleId}":{"get":{"description":"Gets a schedule for a tag by id.","summary":"Get a schedule for a tag by id","tags":["schedules"],"parameters":[{"schema":{"type":"string","description":"The tag that this schedule belongs to.","example":"tag-value"},"required":true,"description":"The tag that this schedule belongs to.","name":"tag","in":"path"},{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the device schedule.","example":"clpkn2je80006102tx7d0jhb8"},"required":true,"description":"The unique identifier for the device schedule.","name":"scheduleId","in":"path"}],"responses":{"200":{"description":"The tag schedule.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagSchedule"}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Schedule not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SCHEDULE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"delete":{"description":"Deletes a tag's schedule by id.","summary":"Deletes a tag's schedule by id","tags":["schedules"],"parameters":[{"schema":{"type":"string","description":"The tag that the schedules belongs to.","example":"tag-value"},"required":true,"description":"The tag that the schedules belongs to.","name":"tag","in":"path"},{"schema":{"type":"string","format":"cuid","description":"The unique identifier for the schedule issued by Texture.","example":"cllgn0u4r000008l7eazybfbo"},"required":true,"description":"The unique identifier for the schedule issued by Texture.","name":"scheduleId","in":"path"}],"responses":{"200":{"description":"The deleted tag schedule.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/TagSchedule"},{"type":["object","null"]}]}}}},"400":{"description":"Invalid parameters provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid parameters provided."]}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Schedule not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SCHEDULE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/virtual/devices":{"post":{"summary":"Create a virtual device","description":"Creates a simulated device that produces random state data. Use [POST /virtual/devices/:id/connect](https://docs.texturehq.com/api#/paths/virtual-devices-id--connect/post) to register the device on the platform and optionally link it to a site and contact.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostVirtualDevicesBody"}}}},"responses":{"201":{"description":"Virtual device created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualDeviceCreatedResponse"}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Account not found.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"504":{"description":"Virtual device service timed out.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}},"get":{"summary":"List virtual devices","description":"List all virtual devices for the workspace.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"List of virtual devices.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"cmne5f7jj0001z5d2bbeyz5bj"},"type":{"type":"string","example":"thermostat"},"model":{"type":"string","example":"texture:thermostat"},"tags":{"type":"array","items":{"type":"string"},"example":[]},"accountId":{"type":"string","example":"cmn8ic73x0004gd21pyyxfuop"},"accountType":{"type":"string","enum":["DEFAULT","OAUTH"],"example":"DEFAULT"}},"required":["id","type","model","tags","accountId","accountType"]}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/virtual/devices/{id}/connect":{"post":{"summary":"Connect a virtual device to the platform","description":"Registers a virtual device on the platform so it appears as a connected device, retrievable via [GET /v1/devices/:id](https://docs.texturehq.com/api#/paths/devices-id/get). Optionally links to a [site](https://docs.texturehq.com/api#/paths/sites/post) and [contact](https://docs.texturehq.com/api#/paths/customers/post) — create those first if needed. OAUTH virtual devices must use the Connect flow instead.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The virtual device ID returned as `id` from [POST /virtual/devices](https://docs.texturehq.com/api#/paths/virtual-devices/post).","example":"cmne5f7jj0001z5d2bbeyz5bj"},"required":true,"description":"The virtual device ID returned as `id` from [POST /virtual/devices](https://docs.texturehq.com/api#/paths/virtual-devices/post).","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostVirtualDevicesConnectBody"}}}},"responses":{"201":{"description":"Virtual device connected and registered on the platform.","content":{"application/json":{"schema":{"type":"object","properties":{"device":{"$ref":"#/components/schemas/Device"}},"required":["device"]}}}},"400":{"description":"OAUTH devices must use the Connect flow.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Virtual device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"422":{"description":"The provided customer has no referenceId to assign to the device.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/virtual/accounts":{"post":{"summary":"Create a virtual account","description":"Creates a virtual OEM account with Connect flow credentials. Use OAUTH type to get email/password for testing the Connect flow without adding a device yet.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostVirtualAccountsBody"}}}},"responses":{"201":{"description":"Virtual account created.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cmn8ic73x0004gd21pyyxfuop"},"type":{"type":"string","enum":["DEFAULT","OAUTH"],"example":"OAUTH"},"name":{"type":["string","null"],"example":null},"email":{"type":"string","example":"talu@texture-simulated.com"},"password":{"type":"string","example":"a9aba064b5effe2f"},"tags":{"type":"array","items":{"type":"string"},"example":[]}},"required":["id","type","name","email","password","tags"]}}}},"400":{"description":"Invalid request.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"get":{"summary":"List virtual accounts","description":"List virtual accounts for the workspace. Use type=OAUTH to find accounts with Connect flow credentials.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["DEFAULT","OAUTH"],"description":"Filter by account type.","example":"OAUTH"},"required":false,"description":"Filter by account type.","name":"type","in":"query"}],"responses":{"200":{"description":"List of virtual accounts.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"cmn8ic73x0004gd21pyyxfuop"},"type":{"type":"string","enum":["DEFAULT","OAUTH"],"example":"OAUTH"},"name":{"type":["string","null"],"example":null},"email":{"type":"string","example":"talu@texture-simulated.com"},"password":{"type":"string","example":"a9aba064b5effe2f"},"tags":{"type":"array","items":{"type":"string"},"example":[]}},"required":["id","type","name","email","password","tags"]}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/virtual/accounts/{id}":{"get":{"summary":"Get a virtual account","description":"Fetch a single virtual account by ID, including Connect flow credentials.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The virtual account ID.","example":"cmn8ic73x0004gd21pyyxfuop"},"required":true,"description":"The virtual account ID.","name":"id","in":"path"}],"responses":{"200":{"description":"Virtual account.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"cmn8ic73x0004gd21pyyxfuop"},"type":{"type":"string","enum":["DEFAULT","OAUTH"],"example":"OAUTH"},"name":{"type":["string","null"],"example":null},"email":{"type":"string","example":"talu@texture-simulated.com"},"password":{"type":"string","example":"a9aba064b5effe2f"},"tags":{"type":"array","items":{"type":"string"},"example":[]}},"required":["id","type","name","email","password","tags"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Account not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"504":{"description":"Gateway timeout — virtual device service timed out.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/virtual/devices/{id}":{"delete":{"summary":"Delete a virtual device","description":"Deletes a virtual device. The device stops producing data immediately. The platform device record is not deleted — use [DELETE /v1/devices/:id](https://docs.texturehq.com/api#/paths/devices-id/delete) to remove it from the workspace.","tags":["virtual"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The virtual device ID returned as `id` from [POST /virtual/devices](https://docs.texturehq.com/api#/paths/virtual-devices/post) or [GET /virtual/devices](https://docs.texturehq.com/api#/paths/virtual-devices/get).","example":"cmne5f7jj0001z5d2bbeyz5bj"},"required":true,"description":"The virtual device ID returned as `id` from [POST /virtual/devices](https://docs.texturehq.com/api#/paths/virtual-devices/post) or [GET /virtual/devices](https://docs.texturehq.com/api#/paths/virtual-devices/get).","name":"id","in":"path"}],"responses":{"200":{"description":"Device deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]}},"required":["deleted"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Device not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["DEVICE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"504":{"description":"Gateway timeout.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/workspaces":{"get":{"description":"List all workspaces for the organization associated with the API key.","summary":"List workspaces","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to retrieve."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"in":"query","name":"perPage","description":"Number of workspaces to return per page."}],"responses":{"200":{"description":"Paginated list of workspaces.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceList"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Insufficient permissions for this resource or action.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["FORBIDDEN"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new workspace within the organization associated with the API key.","summary":"Create Workspace","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The name of the workspace"}},"required":["name"]}}}},"responses":{"201":{"description":"The workspace that was successfully created.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the workspace"},"name":{"type":"string","description":"The name of the workspace"},"organizationId":{"type":"string","description":"The organization this workspace belongs to"},"deletionProtection":{"type":"boolean","description":"Whether the workspace has deletion protection enabled"},"createdAt":{"type":"string","description":"The date and time the workspace was created"},"updatedAt":{"type":"string","description":"The date and time the workspace was last updated"}},"required":["id","name","organizationId","deletionProtection","createdAt","updatedAt"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden - The API key cannot create a workspace for this organization.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/workspaces/{id}/invitations":{"get":{"description":"List all invitations for a workspace. Used for cross-organization workspace sharing.","summary":"List workspace invitations","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","description":"The ID of the workspace.","required":true}],"responses":{"200":{"description":"List of workspace invitations.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceInvitationsResponse"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Send an invitation to share a workspace with another user or organization.","summary":"Send workspace invitation","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","description":"The ID of the workspace.","required":true}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"recipientEmail":{"type":"string","format":"email","description":"The email address of the user to invite to this workspace.","example":"user@example.com"}},"required":["recipientEmail"]}}}},"responses":{"201":{"description":"Workspace invitation created and sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceInvitationCreated"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/workspaces/{id}/invitations/{invitationId}":{"delete":{"description":"Cancel a pending workspace invitation.","summary":"Cancel workspace invitation","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","description":"The ID of the workspace.","required":true},{"name":"invitationId","in":"path","description":"The ID of the invitation to cancel.","required":true}],"responses":{"200":{"description":"Invitation successfully cancelled.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/workspaces/{id}":{"get":{"description":"Retrieve a single workspace by its ID.","summary":"Get workspace by ID","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","description":"The ID of the workspace to retrieve.","required":true}],"responses":{"200":{"description":"The workspace details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update a workspace's settings such as its name.","summary":"Update workspace","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the workspace to update.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the workspace to update.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The new name for the workspace.","example":"Production Environment"}},"required":["name"]}}}},"responses":{"200":{"description":"The updated workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdated"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/workspaces/{id}/protection":{"put":{"description":"Toggle deletion protection on or off for a workspace.","summary":"Update workspace deletion protection","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the workspace to update.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the workspace to update.","in":"path","name":"id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"deletionProtection":{"type":"boolean","description":"Whether to enable deletion protection for the workspace.","example":true}},"required":["deletionProtection"]}}}},"responses":{"200":{"description":"The updated workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceProtectionUpdated"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/workspaces/{id}/clear":{"post":{"description":"Clear all devices, sites, and customers from a workspace. Requires deletion protection to be disabled.","summary":"Clear workspace data","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","description":"The ID of the workspace to clear.","example":"clx1234567890abcdef"},"required":true,"description":"The ID of the workspace to clear.","in":"path","name":"id"}],"responses":{"200":{"description":"Workspace cleared successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether all operations completed successfully."},"message":{"type":"string","description":"A summary message indicating the result of the clear operation.","example":"Workspace cleared successfully"},"totalDeleted":{"type":"number","description":"Total number of records deleted across all entity types.","example":128},"results":{"type":"array","items":{"type":"object","properties":{"operation":{"type":"string","description":"The entity type that was cleared (e.g., 'devices', 'sites', 'customers').","example":"devices"},"success":{"type":"boolean","description":"Whether this particular operation succeeded."},"deletedCount":{"type":"number","description":"Number of records deleted for this entity type.","example":42},"error":{"type":["string","null"],"description":"Error message if this operation failed."}},"required":["operation","success","deletedCount"]},"description":"Per-entity-type breakdown of the clear operation."}},"required":["success","message","totalDeleted","results"]}}}},"207":{"description":"Workspace partially cleared — some operations failed.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether all operations completed successfully."},"message":{"type":"string","description":"A summary message indicating the result of the clear operation.","example":"Workspace cleared successfully"},"totalDeleted":{"type":"number","description":"Total number of records deleted across all entity types.","example":128},"results":{"type":"array","items":{"type":"object","properties":{"operation":{"type":"string","description":"The entity type that was cleared (e.g., 'devices', 'sites', 'customers').","example":"devices"},"success":{"type":"boolean","description":"Whether this particular operation succeeded."},"deletedCount":{"type":"number","description":"Number of records deleted for this entity type.","example":42},"error":{"type":["string","null"],"description":"Error message if this operation failed."}},"required":["operation","success","deletedCount"]},"description":"Per-entity-type breakdown of the clear operation."}},"required":["success","message","totalDeleted","results"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden."},"404":{"description":"Workspace not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["WORKSPACE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/connections":{"post":{"description":"Endpoint for setting up and creating a link session for a user to connect their devices.","summary":"Create a new link session","tags":["connections"],"requestBody":{"description":"The parameters for creating a new link session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLinkSessionParams"}}}},"responses":{"200":{"description":"Details about the created link session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkSessionResponse"}}}},"400":{"description":"Invalid request parameters.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"path":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"}]}}},"required":["message"]}}}},"401":{"description":"Invalid API key provided.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Invalid API key provided."]}},"required":["message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"get":{"description":"List connect sessions for your workspace. Connect sessions represent the state of a user's journey through the Texture Connect flow. Use this endpoint to check the status of connect links you've created.","summary":"List connect sessions","tags":["connections"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."},{"schema":{"type":"string","example":"cllh2buhk000008la0ln6cb80"},"required":false,"in":"query","name":"customerId","description":"Filter connect sessions by customer ID."},{"schema":{"type":"string","enum":["PENDING","STARTED","ENTERING_CUSTOMER_INFO","SELECTING_MANUFACTURER","AUTHORIZING_MANUFACTURER","ENTERING_SYSTEM_INFO","UNSUPPORTED_MANUFACTURER","DUPLICATE_CONNECTION","SUCCESS","ERROR","EXPIRED"],"example":"SUCCESS"},"required":false,"in":"query","name":"status","description":"Filter connect sessions by status."}],"responses":{"200":{"description":"A paginated list of connect sessions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the connect session.","example":"cllh2buhk000008la0ln6cb80"},"status":{"type":"string","enum":["PENDING","STARTED","ENTERING_CUSTOMER_INFO","SELECTING_MANUFACTURER","AUTHORIZING_MANUFACTURER","ENTERING_SYSTEM_INFO","UNSUPPORTED_MANUFACTURER","DUPLICATE_CONNECTION","SUCCESS","ERROR","EXPIRED"],"description":"The current status of the connect session.","example":"SUCCESS"},"customerId":{"type":["string","null"],"description":"The ID of the customer associated with the connect session.","example":"cllh2buhk000008la0ln6cb80"},"siteId":{"type":["string","null"],"description":"The ID of the site associated with the connect session.","example":"cllh2buhk000008la0ln6cb80"},"manufacturer":{"type":["string","null"],"description":"The manufacturer selected during the connect session.","example":"honeywell"},"tags":{"type":["array","null"],"items":{"type":"string"},"description":"Tags associated with the connect session.","example":["tag1","tag2"]},"createdAt":{"type":"string","format":"date-time","description":"The date and time when the connect session was created.","example":"2024-01-15T10:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"The date and time when the connect session was last updated.","example":"2024-01-15T10:35:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"The date and time when the connect session will expire.","example":"2024-01-15T11:30:00Z"}},"required":["id","status","customerId","siteId","manufacturer","tags","createdAt","updatedAt","expiresAt"]}},"page":{"type":"number"},"perPage":{"type":"number"},"totalItems":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","page","perPage","totalItems","totalPages"]}}}},"401":{"description":"Unauthorized - Invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Unauthorized - Invalid API key."]}},"required":["message"]}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Internal server error."]}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/connections/{id}":{"get":{"description":"Get a single connect session by its ID. Returns the current status and details of the connect session.","summary":"Get a connect session","tags":["connections"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string","example":"cllh2buhk000008la0ln6cb80"},"required":true,"in":"path","name":"id","description":"The ID of the connect session to retrieve."}],"responses":{"200":{"description":"The connect session details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectSession"}}}},"401":{"description":"Unauthorized - Invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Unauthorized - Invalid API key."]}},"required":["message"]}}}},"404":{"description":"Connect session not found.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Connect session not found."]}},"required":["message"]}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Internal server error."]}},"required":["message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/manufacturers":{"get":{"description":"Get all manufacturers that Texture currently supports.","summary":"Get a list of manufacturers","tags":["manufacturers"],"responses":{"200":{"description":"Array with manufacturer data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Manufacturers"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/organization":{"get":{"description":"Get details about the current organization.","summary":"Get the current organization","tags":["organizations"],"responses":{"200":{"description":"The organization details.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the organization.","example":"Texture"},"domain":{"type":"string","description":"The domain of the organization.","example":"texturehq.com"},"logo":{"type":"string","format":"uri","description":"The URL to the organization's logo.","example":"https://texturehq.com/logo.png"},"url":{"type":"string","format":"uri","description":"The URL to the organization's website.","example":"https://texturehq.com"},"industry":{"type":"string","description":"The industry of the organization.","example":"Retail energy provider"},"preferredTemperatureUnit":{"type":"string","description":"The preferred temperature unit for the organization.","example":"FAHRENHEIT"},"oemSpecifics":{"type":"object","properties":{"enphase":{"type":"object","properties":{"gridServicesAuthorizationUrl":{"type":"string","format":"uri","description":"Unique Enphase Grid Services authorization url for organization. Only populated if enabled for the organization.","example":"https://enphase.connect.texturehq.com/d1fcb908-0673-47c6-98dd-708ccaf74c64"}}}},"description":"Contains any oem specific data, if applicable, for the organization."}},"required":["name","domain","preferredTemperatureUnit"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new organization. The authenticated user will become the owner.","summary":"Create Organization","tags":["organizations"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the organization"},"domain":{"type":"string","description":"The domain of the organization (e.g. 'example.com')"},"logo":{"type":"string","format":"uri","description":"URL to the organization's logo"},"industry":{"type":"string","description":"The industry of the organization"},"preferredTemperatureUnit":{"type":"string","enum":["FAHRENHEIT","CELSIUS"],"description":"The preferred temperature unit for the organization"}},"required":["name","domain"]}}}},"responses":{"201":{"description":"The organization that was successfully created.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for the organization"},"name":{"type":"string","description":"The name of the organization"},"domain":{"type":"string","description":"The domain of the organization"},"logo":{"type":["string","null"],"description":"URL to the organization's logo"},"industry":{"type":["string","null"],"description":"The industry of the organization"},"preferredTemperatureUnit":{"type":"string","description":"The preferred temperature unit for the organization"},"createdAt":{"type":"string","description":"The date and time the organization was created"}},"required":["id","name","domain","preferredTemperatureUnit","createdAt"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update organization settings such as name, logo, domain, industry, MFA, and temperature unit.","summary":"Update organization","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the organization.","example":"Acme Energy"},"logo":{"type":"string","format":"uri","description":"URL to the organization's logo.","example":"https://cdn.example.com/logo.png"},"domain":{"type":"string","description":"The domain of the organization.","example":"acme.energy"},"industry":{"type":"string","description":"The industry of the organization.","example":"solar"},"preferredTemperatureUnit":{"type":"string","enum":["FAHRENHEIT","CELSIUS"],"description":"The preferred temperature unit for the organization.","example":"CELSIUS"},"mfaEmailOtpEnabled":{"type":"boolean","description":"Whether MFA email OTP is enabled for this organization.","example":true}}}}}},"responses":{"200":{"description":"The updated organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagementOrganization"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden — requires a Management API key."},"404":{"description":"Organization not found."},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/organization/location":{"put":{"description":"Update the physical location (address) of the organization.","summary":"Update organization location","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"streetOne":{"type":"string","description":"The first line of the street address.","example":"123 Main St"},"streetTwo":{"type":"string","description":"The second line of the street address.","example":"Suite 100"},"city":{"type":"string","description":"The city.","example":"San Francisco"},"state":{"type":"string","description":"The state or province.","example":"CA"},"postalCode":{"type":"string","description":"The postal or ZIP code.","example":"94105"},"country":{"type":"string","description":"The country code.","example":"US"}}}}}},"responses":{"200":{"description":"The updated organization with the new location.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagementOrganizationWithLocation"}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden — requires a Management API key."},"404":{"description":"Organization not found."},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/organization/usage":{"get":{"description":"Get usage statistics for the organization, including device counts and energy usage per workspace.","summary":"Get organization usage","tags":["Management"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Organization usage statistics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUsage"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Forbidden — requires a Management API key."},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/public/device-models":{"get":{"description":"Get device models supported by Texture. This endpoint is public and does not require authentication.","summary":"Get a public list of device models","tags":["Public"],"security":[],"parameters":[{"name":"manufacturer","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by manufacturer slug."},{"name":"slug","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by device model slug."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100},"description":"Maximum number of results to return."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1},"description":"Page number for pagination."}],"responses":{"200":{"description":"Paginated array of device model data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicDeviceModels"}}}},"429":{"description":"Rate limit exceeded."},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/public/manufacturers":{"get":{"description":"Get all manufacturers supported by Texture. This endpoint is public and does not require authentication.","summary":"Get a public list of manufacturers","tags":["Public"],"security":[],"responses":{"200":{"description":"Array of manufacturer data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicManufacturers"}}}},"429":{"description":"Rate limit exceeded."},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/sites":{"get":{"description":"Get a list of sites","summary":"Get all sites for a workspace with additional optional filtering","tags":["sites"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"array","items":{"type":"string"},"description":"The reference ID or customerID to filter sites by.","example":["9bb290c8-fe97-46ce-92a8-952823164277"]},"required":false,"description":"The reference ID or customerID to filter sites by.","name":"referenceId","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Object with site data and pagination info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sites"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized"},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"post":{"description":"Create a new site within the workspace associated with the API key.","summary":"Create Site","tags":["sites"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"city":{"type":"string","minLength":1},"country":{"type":"string","minLength":1},"postalCode":{"type":"string","minLength":1},"state":{"type":"string","minLength":1},"streetOne":{"type":"string","minLength":1},"streetTwo":{"type":"string"},"customerId":{"type":"string","format":"cuid","description":"Optional customer ID to associate with the site"}},"required":["city","country","postalCode","state","streetOne"]}}}},"responses":{"201":{"description":"The site that was successfully created.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"location":{"type":"object","properties":{"streetOne":{"type":"string"},"streetTwo":{"type":["string","null"]},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string"}},"required":["streetOne","city","state","postalCode","country"]},"provider":{"type":["string","null"]},"name":{"type":["string","null"]},"workspaceId":{"type":"string"},"referenceId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","location","workspaceId","createdAt"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"409":{"description":"A site with this address already exists.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SITE_ALREADY_EXISTS"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/sites/{id}":{"get":{"description":"Get a site by ID.","summary":"Get a site for a workspace by ID.","tags":["sites"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","description":"The ID of the site to retrieve.","required":true},{"name":"include","in":"query","description":"Additional data to include with the site response (comma-separated values).","required":false,"schema":{"type":"array","items":{"type":"string","enum":["weather","permits","statements","intervals","energy-modeling"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Object with Site and associated data.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Site"},{"description":"The schema for the response of the GET /sites/{id} endpoint."}]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized"},"404":{"description":"Site not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SITE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}},"patch":{"description":"Update an existing site. All fields are optional — only provided fields will be updated. When location fields (streetOne, city, etc.) or coordinates (latitude, longitude) are provided, the site's location will be updated.","summary":"Update a site","tags":["sites"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","description":"The ID of the site to update.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":["string","null"],"description":"User-provided name for the site."},"referenceId":{"type":["string","null"],"description":"Customer reference ID for the site."},"streetOne":{"type":"string","description":"Primary street address."},"streetTwo":{"type":["string","null"],"description":"Secondary street address."},"city":{"type":"string","description":"City where the site is located."},"state":{"type":"string","description":"State or province."},"postalCode":{"type":"string","description":"Postal or ZIP code."},"country":{"type":"string","description":"Country."},"latitude":{"type":"number","minimum":-90,"maximum":90,"description":"Latitude coordinate."},"longitude":{"type":"number","minimum":-180,"maximum":180,"description":"Longitude coordinate."}}}}}},"responses":{"200":{"description":"The updated site.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"referenceId":{"type":["string","null"]},"workspaceId":{"type":"string"},"location":{"type":"object","properties":{"streetOne":{"type":"string"},"streetTwo":{"type":["string","null"]},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string"},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]}},"required":["streetOne","city","state","postalCode","country"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","workspaceId","location","createdAt"]}}}},"400":{"description":"Request validation failed — required fields missing or values invalid.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["VALIDATION_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"},"details":{"type":"object","additionalProperties":{},"description":"Field-level validation errors"}},"required":["code","message"]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"404":{"description":"Site not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SITE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}},"/sites/{id}/alerts":{"get":{"description":"Get a list of alerts for a site","summary":"Get all alerts for a site with additional optional filtering","tags":["alerts","sites"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path","description":"The site ID to get alerts for","example":"cllgn0u4r000008l7eazybfbo"},{"schema":{"type":"string"},"required":false,"in":"query","name":"externalId","description":"Filter alerts by external ID.","example":"124254116"},{"schema":{"type":"string","enum":["CRITICAL","WARNING","INFO"],"description":"The severity level of the alert.","example":"WARNING"},"required":false,"description":"Filter alerts by severity level.","in":"query","name":"severity"},{"schema":{"type":"string","enum":["OPEN","ACKNOWLEDGED","IGNORED","RESOLVED"],"description":"The current status of the alert.","example":"OPEN"},"required":false,"description":"Filter alerts by status.","in":"query","name":"status"},{"schema":{"type":"string"},"required":false,"in":"query","name":"deviceId","description":"Filter alerts by device ID.","example":"cllgn0u4r000008l7eazybfbo"},{"schema":{"type":"string"},"required":false,"in":"query","name":"sourceSystem","description":"Filter alerts by source system.","example":"Inverter 01"},{"schema":{"type":"string"},"required":false,"in":"query","name":"manufacturerDeviceId","description":"Filter alerts by manufacturer device ID.","example":"123456"},{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":1},"required":false,"in":"query","name":"page","description":"The page number to fetch devices from."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":10},"required":false,"in":"query","name":"perPage","description":"The number of devices per page to return."}],"responses":{"200":{"description":"Object with alerts data and pagination info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alerts"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNAUTHENTICATED"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"403":{"description":"Unauthorized"},"404":{"description":"Site not found.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SITE_NOT_FOUND"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"500":{"description":"An unexpected error occurred.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["UNKNOWN_ERROR"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}},"502":{"description":"A dependent service is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","enum":["SERVICE_UNAVAILABLE"],"description":"Machine-readable error code"},"message":{"type":"string","description":"Human-readable error description"}},"required":["code","message"]}}}}}}}},"webhooks":{}}