# Create an Access Code Source: https://docs.seam.co/api/access_codes/create /openapi.json post /access_codes/create Creates a new [access code](/low-level-apis/smart-locks/access-codes). For granting access, we recommend [Access Grants](/use-cases/granting-access) instead: they work across both standalone smart locks and access control systems and manage the underlying codes for you. Use this low-level endpoint only when you need direct control over a code on a single device, such as setting a custom PIN value. # Create Multiple Linked Access Codes Source: https://docs.seam.co/api/access_codes/create_multiple /openapi.json post /access_codes/create_multiple Creates new [access codes](/low-level-apis/smart-locks/access-codes) that share a common code across multiple devices. Users with more than one door lock in a property may want to create groups of linked access codes, all of which have the same code (PIN). For example, a short-term rental host may want to provide guests the same PIN for both a front door lock and a back door lock. If you specify a custom code, Seam assigns this custom code to each of the resulting access codes. However, in this case, Seam does not link these access codes together with a `common_code_key`. That is, `common_code_key` remains null for these access codes. If you want to change these access codes that are not linked by a `common_code_key`, you cannot use `/access_codes/update_multiple`. However, you can update each of these access codes individually, using `/access_codes/update`. See also [Creating and Updating Multiple Linked Access Codes](/low-level-apis/smart-locks/access-codes/creating-and-updating-multiple-linked-access-codes). For granting a person access to a space, [Access Grants](/use-cases/granting-access) are the default and recommended approach and work across both standalone smart locks and access systems. Use the lower-level Access Codes API directly only when you specifically need to manage individual PIN codes. # Delete an Access Code Source: https://docs.seam.co/api/access_codes/delete /openapi.json post /access_codes/delete Deletes an [access code](/low-level-apis/smart-locks/access-codes). # Access Code Errors and Warnings Source: https://docs.seam.co/api/access_codes/errors Errors and warnings that Seam reports on the Access Code resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "provider_issue", "message": "Indicates a provider-specific issue that prevents the access code from being set or managed. Check the error message for details.", "created_at": "2025-01-01T00:00:00.000Z", "is_access_code_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates the type of external modification. `modified` means the code's PIN or schedule was changed. `removed` means the code was deleted from the device. Indicates that this is an access code error. Indicates whether the error is related to [Seam Bridge](/capability-guides/seam-bridge). Indicates that the error is a [connected account](/api/connected_accounts/object) error. Indicates that the error is not a device error. ID of the managed access code that conflicts with this managed access code, when Seam can identify it. List of fields that were changed externally, with their previous and new values. ID of the unmanaged access code that conflicts with this managed access code, when Seam can identify it. ### `access_code_inactive` Indicates that the access code is disabled or inactive on the device. The code exists but will not grant access until re-enabled. *** ### `conflicting_external_modification` Code was modified or removed externally after Seam successfully set it on the device. The external change conflicts with the state that Seam is trying to apply, so Seam will attempt to set the code on the device again. *** ### `duplicate_code_on_device` Duplicate access code detected on device. *** ### `failed_to_remove_from_device` Failed to remove code from device. *** ### `failed_to_set_on_device` Failed to set code on device. *** ### `no_space_for_access_code_on_device` No space for access code on device. *** ### `provider_issue` Indicates a provider-specific issue that prevents the access code from being set or managed. Check the error message for details. *** ### Connected Account These errors are inherited from the [Connected Account](/api/connected_accounts/errors) resource. When they are set on the parent connected account, they are propagated to this resource's errors list. #### `account_disconnected` Indicates that the account is disconnected. *** #### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if the Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** #### `dormakaba_sites_disconnected` Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. *** #### `insufficient_permissions` Indicates that Seam's integration user does not have sufficient permissions on the provider's system to which this device belongs, so Seam cannot manage access codes or unlock the device. See the error message for specifics, then either reauthorize the connected account in Seam or grant the integration user the required permissions in the provider's system. *** #### `salto_ks_subscription_limit_exceeded` Indicates that the Salto site user limit has been reached. *** ### Device These errors are inherited from the [Device](/api/devices/errors) resource. When they are set on the parent device, they are propagated to this resource's errors list. #### `august_lock_not_authorized` Indicates that the user is not authorized to use the August lock. *** #### `device_disconnected` Indicates that the device is disconnected. *** #### `device_offline` Indicates that the device is offline. *** #### `device_removed` Indicates that the device has been removed. *** #### `hub_disconnected` Indicates that the hub is disconnected. *** #### `missing_device_credentials` Indicates that device credentials are missing. *** #### `subscription_required` Indicates that a subscription is required to connect. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "code_rotates_periodically", "message": "The access code's PIN rotates periodically when the code is renewed. Retrieve the latest code before each use.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. Indicates the type of external modification. `modified` means the code's PIN or schedule was changed. `removed` means the code was deleted from the device. List of fields that were changed externally, with their previous and new values. ### `being_deleted` Access code is being deleted. *** ### `code_rotates_periodically` The access code's PIN rotates periodically when the code is renewed. Retrieve the latest code before each use. *** ### `delay_in_removing_from_device` Delay in removing code from device. *** ### `delay_in_setting_on_device` Delay in setting code on device. *** ### `external_modification_in_effect` Code was modified or removed externally after Seam successfully set it on the device. External modification is allowed for this code, so the externally modified state is being honored. *** ### `igloo_algopin_must_be_used_within_24_hours` Algopins must be used within 24 hours. *** ### `management_transferred` Management was transferred to another workspace. *** ### `third_party_integration_detected` Third-party integration detected that may cause access codes to fail. *** ### `time_frame_adjusted_for_unknown_time_zone` The device's time zone is unknown and this code's time frame crosses a daylight-saving transition in at least one plausible time zone. A 1-hour safety buffer has been applied to the side of the time frame affected by the transition (`ends_at` for spring-forward, `starts_at` for fall-back) so the code stays active through the shift — the code may be usable up to 1 hour beyond your requested window. Set the device's time zone via `/devices/report_provider_metadata` to clear the buffer and guarantee exact handling. *** ### `unknown_issue_with_access_code` An unknown issue occurred with the access code. *** ### `using_backup_access_code` A backup access code has been pulled and is being used in place of this access code. *** # Access Code Events Source: https://docs.seam.co/api/access_codes/events Webhook events that Seam emits for the Access Code resource, with example payloads and properties. ## `access_code.created` An [access code](/low-level-apis/smart-locks/access-codes) was created. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was created.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.created", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.created` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.changed` An [access code](/low-level-apis/smart-locks/access-codes) was changed. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "change_reason": "", "changed_properties": [], "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was changed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.changed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Human-readable reason for the change (e.g. `ongoing code auto-renewed`). List of properties that changed on the access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.changed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.name_changed` The name of an [access code](/low-level-apis/smart-locks/access-codes) was changed on the device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "description": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "The name of an [access code](/low-level-apis/smart-locks/access-codes) was changed on the device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.name_changed", "from": { "name": "My Access Code" }, "occurred_at": "2025-01-01T00:00:00.000Z", "to": { "name": "My Access Code" }, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Human-readable description of the change and its source. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.name_changed` Previous access code name configuration. Previous name of the access code. Date and time at which the event occurred. New access code name configuration. New name of the access code. ID of the workspace associated with the event. ## `access_code.code_changed` The pin code of an [access code](/low-level-apis/smart-locks/access-codes) was changed on the device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "description": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "The pin code of an [access code](/low-level-apis/smart-locks/access-codes) was changed on the device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.code_changed", "from": { "code": "1234" }, "occurred_at": "2025-01-01T00:00:00.000Z", "to": { "code": "1234" }, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Human-readable description of the change and its source. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.code_changed` Previous pin code configuration. Previous pin code. Date and time at which the event occurred. New pin code configuration. New pin code. ID of the workspace associated with the event. ## `access_code.time_frame_changed` The time frame of an [access code](/low-level-apis/smart-locks/access-codes) was changed on the device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "description": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "The time frame of an [access code](/low-level-apis/smart-locks/access-codes) was changed on the device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.time_frame_changed", "from": { "ends_at": "2025-01-01T00:00:00.000Z", "starts_at": "2025-01-01T00:00:00.000Z" }, "occurred_at": "2025-01-01T00:00:00.000Z", "to": { "ends_at": "2025-01-01T00:00:00.000Z", "starts_at": "2025-01-01T00:00:00.000Z" }, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Human-readable description of the change and its source. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.time_frame_changed` Previous time frame configuration. Previous end time. Previous start time. Date and time at which the event occurred. New time frame configuration. New end time. New start time. ID of the workspace associated with the event. ## `access_code.mutations_requested` Mutations were requested on an [access code](/low-level-apis/smart-locks/access-codes). This event fires at request time, before the change is confirmed on the device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "Mutations were requested on an [access code](/low-level-apis/smart-locks/access-codes). This event fires at request time, before the change is confirmed on the device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.mutations_requested", "occurred_at": "2025-01-01T00:00:00.000Z", "requested_mutations": [], "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.mutations_requested` Date and time at which the event occurred. Array of mutations requested on the access code, each containing the mutation type and from/to values. ID of the workspace associated with the event. ## `access_code.scheduled_on_device` An [access code](/low-level-apis/smart-locks/access-codes) was [scheduled natively](/low-level-apis/smart-locks/access-codes#native-scheduling) on a device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was [scheduled natively](/low-level-apis/smart-locks/access-codes#native-scheduling) on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.scheduled_on_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Code for the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.scheduled_on_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.set_on_device` An [access code](/low-level-apis/smart-locks/access-codes) was set on a device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was set on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.set_on_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Code for the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.set_on_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.removed_from_device` An [access code](/low-level-apis/smart-locks/access-codes) was removed from a device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was removed from a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.removed_from_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.removed_from_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.delay_in_setting_on_device` There was an unusually long delay in setting an [access code](/low-level-apis/smart-locks/access-codes) on a device. ```json Example webhook payload theme={null} { "access_code_errors": [], "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_warnings": [], "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "There was an unusually long delay in setting an [access code](/low-level-apis/smart-locks/access-codes) on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.delay_in_setting_on_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Errors associated with the access code. ID of the affected access code. Warnings associated with the access code. Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the affected access code. Warnings associated with the connected account. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the device associated with the affected access code. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.delay_in_setting_on_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.failed_to_set_on_device` An [access code](/low-level-apis/smart-locks/access-codes) failed to be set on a device. ```json Example webhook payload theme={null} { "access_code_errors": [], "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_warnings": [], "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) failed to be set on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.failed_to_set_on_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Errors associated with the access code. ID of the affected access code. Warnings associated with the access code. Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the affected access code. Warnings associated with the connected account. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the device associated with the affected access code. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.failed_to_set_on_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.deleted` An [access code](/low-level-apis/smart-locks/access-codes) was deleted. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Code for the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.delay_in_removing_from_device` There was an unusually long delay in removing an [access code](/low-level-apis/smart-locks/access-codes) from a device. ```json Example webhook payload theme={null} { "access_code_errors": [], "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_warnings": [], "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "There was an unusually long delay in removing an [access code](/low-level-apis/smart-locks/access-codes) from a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.delay_in_removing_from_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Errors associated with the access code. ID of the affected access code. Warnings associated with the access code. Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the affected access code. Warnings associated with the connected account. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the device associated with the affected access code. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.delay_in_removing_from_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.failed_to_remove_from_device` An [access code](/low-level-apis/smart-locks/access-codes) failed to be removed from a device. ```json Example webhook payload theme={null} { "access_code_errors": [], "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_warnings": [], "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) failed to be removed from a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.failed_to_remove_from_device", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Errors associated with the access code. ID of the affected access code. Warnings associated with the access code. Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the affected access code. Warnings associated with the connected account. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the device associated with the affected access code. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.failed_to_remove_from_device` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.modified_external_to_seam` An [access code](/low-level-apis/smart-locks/access-codes) was modified outside of Seam. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was modified outside of Seam.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.modified_external_to_seam", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.modified_external_to_seam` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.deleted_external_to_seam` An [access code](/low-level-apis/smart-locks/access-codes) was deleted outside of Seam. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [access code](/low-level-apis/smart-locks/access-codes) was deleted outside of Seam.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.deleted_external_to_seam", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.deleted_external_to_seam` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.backup_access_code_pulled` A [backup access code](/low-level-apis/smart-locks/access-codes/backup-access-codes) was pulled from the backup access code pool and set on a device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "backup_access_code_id": "", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [backup access code](/low-level-apis/smart-locks/access-codes/backup-access-codes) was pulled from the backup access code pool and set on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.backup_access_code_pulled", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. ID of the backup access code that was pulled from the pool. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.backup_access_code_pulled` Date and time at which the event occurred. ID of the workspace associated with the event. # Generate a Code Source: https://docs.seam.co/api/access_codes/generate_code /openapi.json post /access_codes/generate_code Generates a code for an [access code](/low-level-apis/smart-locks/access-codes), given a device ID. # Get an Access Code Source: https://docs.seam.co/api/access_codes/get /openapi.json post /access_codes/get Returns a specified [access code](/low-level-apis/smart-locks/access-codes). You must specify either `access_code_id` or both `device_id` and `code`. You must include at least one request parameter. # List Access Codes Source: https://docs.seam.co/api/access_codes/list /openapi.json post /access_codes/list Returns a list of all [access codes](/low-level-apis/smart-locks/access-codes). Specify `device_id`, `access_code_ids`, `access_method_id`, `access_grant_id`, or `access_grant_key`. You must include at least one request parameter. # The Access Code Object Source: https://docs.seam.co/api/access_codes/object Learn how the access_code object represents a smart lock PIN code you can customize, track, and program across hundreds of supported keypad and pinpad locks. ## The access\_code Object Represents a smart lock [access code](/low-level-apis/smart-locks/access-codes). An access code is a code used for a keypad or pinpad device. Unlike physical keys, which can easily be lost or duplicated, PIN codes can be customized, tracked, and altered on the fly. Using the Seam Access Code API, you can easily generate access codes on the hundreds of door lock models with which we integrate. Seam supports programming two types of access codes: [ongoing](/low-level-apis/smart-locks/access-codes#ongoing-access-codes) and [time-bound](/low-level-apis/smart-locks/access-codes#time-bound-access-codes). To differentiate between the two, refer to the `type` property of the access code. Ongoing codes display as `ongoing`, whereas time-bound codes are labeled `time_bound`. An ongoing access code is active, until it has been removed from the device. To specify an ongoing access code, leave both `starts_at` and `ends_at` empty. A time-bound access code will be programmed at the `starts_at` time and removed at the `ends_at` time. In addition, for certain devices, Seam also supports [offline access codes](/low-level-apis/smart-locks/access-codes#offline-access-codes). Offline access (PIN) codes are designed for door locks that might not always maintain an internet connection. For this type of access code, the device manufacturer uses encryption keys (tokens) to create server-based registries of algorithmically-generated offline PIN codes. Because the tokens remain synchronized with the managed devices, the locks do not require an active internet connection—and you do not need to be near the locks—to create an offline access code. Then, owners or managers can share these offline codes with users through a variety of mechanisms, such as messaging applications. That is, lock users do not need to install a smartphone application to receive an offline access code. For granting a person access to a space, [Access Grants](/use-cases/granting-access) are the default and recommended approach and work across both standalone smart locks and access systems. Use the lower-level Access Codes API directly only when you specifically need to manage individual PIN codes. ```json One-Time-Use Offline Access Code theme={null} { "access_code_id": "e9cf6dd6-89aa-477f-a701-c08f3de13c1f", "code": "1234", "common_code_key": null, "created_at": "2025-06-14T16:54:17.946242Z", "device_id": "c9cd621d-ef0c-45c8-b608-026ebdb74615", "ends_at": "2025-07-04T16:54:17.946049Z", "errors": [], "pending_mutations": [], "is_backup": false, "is_backup_access_code_available": false, "is_external_modification_allowed": false, "is_managed": true, "is_offline_access_code": true, "is_one_time_use": true, "is_scheduled_on_device": true, "is_waiting_for_code_assignment": false, "name": "My Access Code", "pulled_backup_access_code_id": null, "starts_at": "2025-07-02T16:54:17.946049Z", "status": "set", "type": "time_bound", "warnings": [], "workspace_id": "750fc0bc-4450-4356-8d9f-18c6a3a6b2c7" } ``` ```json Ongoing Online Access Code theme={null} { "access_code_id": "e9cf6dd6-89aa-477f-a701-c08f3de13c1f", "code": "1234", "common_code_key": "auto_set_by_create_multiple_550e8400-e29b-41d4-a716-446655440000", "created_at": "2025-06-14T16:54:17.946242Z", "device_id": "c9cd621d-ef0c-45c8-b608-026ebdb74615", "ends_at": null, "errors": [], "pending_mutations": [], "is_backup": false, "is_backup_access_code_available": true, "is_external_modification_allowed": true, "is_managed": true, "is_offline_access_code": false, "is_one_time_use": false, "is_scheduled_on_device": true, "is_waiting_for_code_assignment": false, "name": "My Access Code", "pulled_backup_access_code_id": null, "starts_at": null, "status": "set", "type": "ongoing", "warnings": [], "workspace_id": "750fc0bc-4450-4356-8d9f-18c6a3a6b2c7" } ``` ```json Time-bound Online Access Code theme={null} { "access_code_id": "e9cf6dd6-89aa-477f-a701-c08f3de13c1f", "code": "1234", "common_code_key": "auto_set_by_create_multiple_550e8400-e29b-41d4-a716-446655440000", "created_at": "2025-06-14T16:54:17.946242Z", "device_id": "c9cd621d-ef0c-45c8-b608-026ebdb74615", "ends_at": "2025-07-04T16:54:17.946049Z", "errors": [], "pending_mutations": [], "is_backup": false, "is_backup_access_code_available": true, "is_external_modification_allowed": true, "is_managed": true, "is_offline_access_code": false, "is_one_time_use": false, "is_scheduled_on_device": true, "is_waiting_for_code_assignment": false, "name": "My Access Code", "pulled_backup_access_code_id": null, "starts_at": "2025-07-02T16:54:17.946049Z", "status": "set", "type": "time_bound", "warnings": [], "workspace_id": "750fc0bc-4450-4356-8d9f-18c6a3a6b2c7" } ``` ```json Time-bound Offline Access Code theme={null} { "access_code_id": "e9cf6dd6-89aa-477f-a701-c08f3de13c1f", "code": "1234", "common_code_key": null, "created_at": "2025-06-14T16:54:17.946242Z", "device_id": "c9cd621d-ef0c-45c8-b608-026ebdb74615", "ends_at": "2025-07-04T16:54:17.946049Z", "errors": [], "pending_mutations": [], "is_backup": false, "is_backup_access_code_available": false, "is_external_modification_allowed": false, "is_managed": true, "is_offline_access_code": true, "is_one_time_use": false, "is_scheduled_on_device": true, "is_waiting_for_code_assignment": false, "name": "My Access Code", "pulled_backup_access_code_id": null, "starts_at": "2025-07-02T16:54:17.946049Z", "status": "set", "type": "time_bound", "warnings": [], "workspace_id": "750fc0bc-4450-4356-8d9f-18c6a3a6b2c7" } ``` *** ## Properties Unique identifier for the access code. Code used for access. Typically, a numeric or alphanumeric string. Unique identifier for a group of access codes that share the same code. Date and time at which the access code was created. Unique identifier for the device associated with the access code. Metadata for a dormakaba Oracode managed access code. Only present for access codes from dormakaba Oracode devices. Indicates whether the stay can be cancelled via the Dormakaba Oracode API. Indicates whether early check-in is available for this stay. Indicates whether the stay can be extended via the Dormakaba Oracode API. Indicates whether the access code can be overridden. When false, the maximum number of overrides has been reached. Dormakaba Oracode site name associated with this access code. Dormakaba Oracode stay ID associated with this access code. Dormakaba Oracode user level ID associated with this access code. Dormakaba Oracode user level name associated with this access code. Date and time after which the time-bound access code becomes inactive. Errors associated with the [access code](/low-level-apis/smart-locks/access-codes). Indicates whether the access code is a backup code. Indicates whether a backup access code is available for use if the primary access code is lost or compromised. Indicates whether changes to the access code from external sources are permitted. Indicates whether Seam manages the access code. Indicates whether the access code is intended for use in offline scenarios. If `true`, this code can be created on a device without a network connection. Indicates whether the access code can only be used once. If `true`, the code becomes invalid after the first use. Indicates whether the code is set on the device according to a preconfigured schedule. Indicates whether the access code is waiting for a code assignment. Name of the access code. Enables administrators and users to identify the access code easily, especially when there are numerous access codes. Note that the name provided on Seam is used to identify the code on Seam and is not necessarily the name that will appear in the lock provider's app or on the device. This is because lock providers may have constraints on names, such as length, uniqueness, or characters that can be used. In addition, some lock providers may break down names into components such as `first_name` and `last_name`. To provide a consistent experience, Seam identifies the code on Seam by its name but may modify the name that appears on the lock provider's app or on the device. For example, Seam may add additional characters or truncate the name to meet provider constraints. To help your users identify codes set by Seam, Seam provides the name exactly as it appears on the lock provider's app or on the device as a separate property called `appearance`. This is an object with a `name` property and, optionally, `first_name` and `last_name` properties (for providers that break down a name into components). Collection of pending mutations for the access code. Indicates changes that Seam is in the process of pushing to the device. Identifier of the pulled backup access code. Used to associate the pulled backup access code with the original access code. Date and time at which the time-bound access code becomes active. Current status of the access code within the operational lifecycle. Values are `setting`, a transitional phase that indicates that the code is being configured or activated; `set`, which indicates that the code is active and operational; `unset`, which indicates a deactivated or unused state, either before activation or after deliberate deactivation; `removing`, which indicates a transitional period in which the code is being deleted or made inactive; and `unknown`, which indicates an indeterminate state, due to reasons such as system errors or incomplete data, that highlights a potential need for system review or troubleshooting. See also [Lifecycle of Access Codes](/low-level-apis/smart-locks/access-codes/lifecycle-of-access-codes). Type of the access code. `ongoing` access codes are active continuously until deactivated manually. `time_bound` access codes have a specific duration. Warnings associated with the [access code](/low-level-apis/smart-locks/access-codes). Unique identifier for the Seam workspace associated with the access code. # Pull a Backup Access Code Source: https://docs.seam.co/api/access_codes/pull_backup_access_code /openapi.json post /access_codes/pull_backup_access_code Retrieves a backup access code for an [access code](/low-level-apis/smart-locks/access-codes). See also [Managing Backup Access Codes](/low-level-apis/smart-locks/access-codes/backup-access-codes). A backup access code pool is a collection of pre-programmed access codes stored on a device, ready for use. These codes are programmed in addition to the regular access codes on Seam, serving as a safety net for any issues with the primary codes. If there's ever a complication with a primary access code—be it due to intermittent connectivity, manual removal from a device, or provider outages—a backup code can be retrieved. Its end time can then be adjusted to align with the original code, facilitating seamless and uninterrupted access. You can pull a backup access code from the pool at any time. These backup codes are guaranteed to work immediately and automatically programmed to be removed from the device after the access code ends. You can only pull backup access codes for time-bound access codes. Before pulling a backup access code, make sure that the device's `properties.supports_backup_access_code_pool` is `true`. Then, to activate the backup pool, set `use_backup_access_code_pool` to `true` when creating an access code. # Report Device Access Code Constraints Source: https://docs.seam.co/api/access_codes/report_device_constraints /openapi.json post /access_codes/report_device_constraints Enables you to report access code-related constraints for a device. Currently, supports reporting supported code length constraints for SmartThings devices. Specify either `supported_code_lengths` or `min_code_length`/`max_code_length`. # Simulate Creating an Unmanaged Access Code Source: https://docs.seam.co/api/access_codes/simulate/create_unmanaged_access_code /openapi.json post /access_codes/simulate/create_unmanaged_access_code Simulates the creation of an [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) in a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). # Convert an Unmanaged Access Code Source: https://docs.seam.co/api/access_codes/unmanaged/convert_to_managed /openapi.json post /access_codes/unmanaged/convert_to_managed Converts an [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) to an [access code managed through Seam](/low-level-apis/smart-locks/access-codes). An unmanaged access code has a limited set of operations that you can perform on it. Once you convert an unmanaged access code to a managed access code, the full set of access code operations and lifecycle events becomes available for it. Note that not all device providers support converting an unmanaged access code to a managed access code. # Delete an Unmanaged Access Code Source: https://docs.seam.co/api/access_codes/unmanaged/delete /openapi.json post /access_codes/unmanaged/delete Deletes an [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes). # Unmanaged Access Codes Errors and Warnings Source: https://docs.seam.co/api/access_codes/unmanaged/errors Errors and warnings that Seam reports on the Unmanaged Access Codes resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "provider_issue", "message": "Indicates a provider-specific issue that prevents the access code from being set or managed. Check the error message for details.", "created_at": "2025-01-01T00:00:00.000Z", "is_access_code_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates the type of external modification. `modified` means the code's PIN or schedule was changed. `removed` means the code was deleted from the device. Indicates that this is an access code error. Indicates whether the error is related to [Seam Bridge](/capability-guides/seam-bridge). Indicates that the error is a [connected account](/api/connected_accounts/object) error. Indicates that the error is not a device error. ID of the managed access code that conflicts with this managed access code, when Seam can identify it. List of fields that were changed externally, with their previous and new values. ID of the unmanaged access code that conflicts with this managed access code, when Seam can identify it. ### `access_code_inactive` Indicates that the access code is disabled or inactive on the device. The code exists but will not grant access until re-enabled. *** ### `conflicting_external_modification` Code was modified or removed externally after Seam successfully set it on the device. The external change conflicts with the state that Seam is trying to apply, so Seam will attempt to set the code on the device again. *** ### `duplicate_code_on_device` Duplicate access code detected on device. *** ### `failed_to_remove_from_device` Failed to remove code from device. *** ### `failed_to_set_on_device` Failed to set code on device. *** ### `no_space_for_access_code_on_device` No space for access code on device. *** ### `provider_issue` Indicates a provider-specific issue that prevents the access code from being set or managed. Check the error message for details. *** ### Connected Account These errors are inherited from the [Connected Account](/api/connected_accounts/errors) resource. When they are set on the parent connected account, they are propagated to this resource's errors list. #### `account_disconnected` Indicates that the account is disconnected. *** #### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if the Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** #### `dormakaba_sites_disconnected` Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. *** #### `insufficient_permissions` Indicates that Seam's integration user does not have sufficient permissions on the provider's system to which this device belongs, so Seam cannot manage access codes or unlock the device. See the error message for specifics, then either reauthorize the connected account in Seam or grant the integration user the required permissions in the provider's system. *** #### `salto_ks_subscription_limit_exceeded` Indicates that the Salto site user limit has been reached. *** ### Device These errors are inherited from the [Device](/api/devices/errors) resource. When they are set on the parent device, they are propagated to this resource's errors list. #### `august_lock_not_authorized` Indicates that the user is not authorized to use the August lock. *** #### `device_disconnected` Indicates that the device is disconnected. *** #### `device_offline` Indicates that the device is offline. *** #### `device_removed` Indicates that the device has been removed. *** #### `hub_disconnected` Indicates that the hub is disconnected. *** #### `missing_device_credentials` Indicates that device credentials are missing. *** #### `subscription_required` Indicates that a subscription is required to connect. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "code_rotates_periodically", "message": "The access code's PIN rotates periodically when the code is renewed. Retrieve the latest code before each use.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. Indicates the type of external modification. `modified` means the code's PIN or schedule was changed. `removed` means the code was deleted from the device. List of fields that were changed externally, with their previous and new values. ### `being_deleted` Access code is being deleted. *** ### `code_rotates_periodically` The access code's PIN rotates periodically when the code is renewed. Retrieve the latest code before each use. *** ### `delay_in_removing_from_device` Delay in removing code from device. *** ### `delay_in_setting_on_device` Delay in setting code on device. *** ### `external_modification_in_effect` Code was modified or removed externally after Seam successfully set it on the device. External modification is allowed for this code, so the externally modified state is being honored. *** ### `igloo_algopin_must_be_used_within_24_hours` Algopins must be used within 24 hours. *** ### `management_transferred` Management was transferred to another workspace. *** ### `third_party_integration_detected` Third-party integration detected that may cause access codes to fail. *** ### `time_frame_adjusted_for_unknown_time_zone` The device's time zone is unknown and this code's time frame crosses a daylight-saving transition in at least one plausible time zone. A 1-hour safety buffer has been applied to the side of the time frame affected by the transition (`ends_at` for spring-forward, `starts_at` for fall-back) so the code stays active through the shift — the code may be usable up to 1 hour beyond your requested window. Set the device's time zone via `/devices/report_provider_metadata` to clear the buffer and guarantee exact handling. *** ### `unknown_issue_with_access_code` An unknown issue occurred with the access code. *** ### `using_backup_access_code` A backup access code has been pulled and is being used in place of this access code. *** # Unmanaged Access Codes Events Source: https://docs.seam.co/api/access_codes/unmanaged/events Webhook events that Seam emits for the Unmanaged Access Codes resource, with example payloads and properties. ## `access_code.unmanaged.converted_to_managed` An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) was converted successfully to a managed access code. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) was converted successfully to a managed access code.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.unmanaged.converted_to_managed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.unmanaged.converted_to_managed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.unmanaged.failed_to_convert_to_managed` An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) failed to be converted to a managed access code. ```json Example webhook payload theme={null} { "access_code_errors": [], "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_warnings": [], "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) failed to be converted to a managed access code.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.unmanaged.failed_to_convert_to_managed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Errors associated with the access code. ID of the affected access code. Warnings associated with the access code. Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the affected access code. Warnings associated with the connected account. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the device associated with the affected access code. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.unmanaged.failed_to_convert_to_managed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.unmanaged.created` An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) was created on a device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) was created on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.unmanaged.created", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.unmanaged.created` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_code.unmanaged.removed` An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) was removed from a device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) was removed from a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_code.unmanaged.removed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access code. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the affected access code. Date and time at which the event was created. Custom metadata of the device, present when device\_id is provided. ID of the device associated with the affected access code. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_code.unmanaged.removed` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Unmanaged Access Code Source: https://docs.seam.co/api/access_codes/unmanaged/get /openapi.json post /access_codes/unmanaged/get Returns a specified [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes). You must specify either `access_code_id` or both `device_id` and `code`. You must include at least one request parameter. # List Unmanaged Access Codes Source: https://docs.seam.co/api/access_codes/unmanaged/list /openapi.json post /access_codes/unmanaged/list Returns a list of all [unmanaged access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes). # Unmanaged Access Codes Source: https://docs.seam.co/api/access_codes/unmanaged/object Learn how the unmanaged_access_code object represents an existing smart lock PIN code that Seam tracks but does not manage until you convert it. ## The unmanaged\_access\_code Object Represents an [unmanaged smart lock access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes). An access code is a code used for a keypad or pinpad device. Unlike physical keys, which can easily be lost or duplicated, PIN codes can be customized, tracked, and altered on the fly. When you create an access code on a device in Seam, it is created as a managed access code. Access codes that exist on a device that were not created through Seam are considered unmanaged codes. We strictly limit the operations that can be performed on unmanaged codes. Prior to using Seam to manage your devices, you may have used another lock management system to manage the access codes on your devices. Where possible, we help you keep any existing access codes on devices and transition those codes to ones managed by your Seam workspace. Not all providers support unmanaged access codes. The following providers do not support unmanaged access codes: * [Kwikset](/device-and-system-integration-guides/kwikset-locks) ```json Unmanaged Access Code theme={null} { "access_code_id": "88fa1812-bef8-4108-9fb4-4855376c3edf", "code": "1234", "created_at": "2025-06-16T16:54:17.946283Z", "device_id": "b3439f17-7273-46f3-9e20-9a283d9cb5b4", "ends_at": "2025-06-23T16:54:17.946261Z", "errors": [], "is_managed": false, "name": "My Unmanaged Access Code", "starts_at": "2025-06-21T16:54:17.946261Z", "status": "set", "type": "time_bound", "warnings": [], "workspace_id": "750fc0bc-4450-4356-8d9f-18c6a3a6b2c7" } ``` *** ## Properties Unique identifier for the access code. Indicates that Seam cannot convert this unmanaged access code to a managed access code. Some providers do not support management of unmanaged access codes through API integrations. Indicates that Seam cannot delete this unmanaged access code through the provider. If this access code needs to be deleted, it will only be possible from the manufacturer app. Code used for access. Typically, a numeric or alphanumeric string. Date and time at which the access code was created. Unique identifier for the device associated with the access code. Metadata for a dormakaba Oracode unmanaged access code. Only present for unmanaged access codes from dormakaba Oracode devices. Indicates whether the stay can be cancelled via the Dormakaba Oracode API. Indicates whether early check-in is available for this stay. Indicates whether the stay can be extended via the Dormakaba Oracode API. Indicates whether the access code can be overridden. When false, the maximum number of overrides has been reached. Dormakaba Oracode site name associated with this access code. Dormakaba Oracode stay ID associated with this access code. Dormakaba Oracode user level ID associated with this access code. Dormakaba Oracode user level name associated with this access code. Date and time after which the time-bound access code becomes inactive. Errors associated with the [access code](/low-level-apis/smart-locks/access-codes). Indicates that Seam does not manage the access code. Name of the access code. Enables administrators and users to identify the access code easily, especially when there are numerous access codes. Note that the name provided on Seam is used to identify the code on Seam and is not necessarily the name that will appear in the lock provider's app or on the device. This is because lock providers may have constraints on names, such as length, uniqueness, or characters that can be used. In addition, some lock providers may break down names into components such as `first_name` and `last_name`. To provide a consistent experience, Seam identifies the code on Seam by its name but may modify the name that appears on the lock provider's app or on the device. For example, Seam may add additional characters or truncate the name to meet provider constraints. To help your users identify codes set by Seam, Seam provides the name exactly as it appears on the lock provider's app or on the device as a separate property called `appearance`. This is an object with a `name` property and, optionally, `first_name` and `last_name` properties (for providers that break down a name into components). Date and time at which the time-bound access code becomes active. Current status of the access code within the operational lifecycle. `set` indicates that the code is active and operational. `unset` indicates that the code exists on the provider but is not usable on the device. Type of the access code. `ongoing` access codes are active continuously until deactivated manually. `time_bound` access codes have a specific duration. Warnings associated with the [access code](/low-level-apis/smart-locks/access-codes). Unique identifier for the Seam workspace associated with the access code. # Update an Unmanaged Access Code Source: https://docs.seam.co/api/access_codes/unmanaged/update /openapi.json post /access_codes/unmanaged/update Updates a specified [unmanaged access code](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes). # Update an Access Code Source: https://docs.seam.co/api/access_codes/update /openapi.json post /access_codes/update Updates a specified active or upcoming [access code](/low-level-apis/smart-locks/access-codes). See also [Modifying Access Codes](/low-level-apis/smart-locks/access-codes/modifying-access-codes). # Update Multiple Linked Access Codes Source: https://docs.seam.co/api/access_codes/update_multiple /openapi.json post /access_codes/update_multiple Updates [access codes](/low-level-apis/smart-locks/access-codes) that share a common code across multiple devices. Specify the `common_code_key` to identify the set of access codes that you want to update. See also [Update Linked Access Codes](/low-level-apis/smart-locks/access-codes/creating-and-updating-multiple-linked-access-codes#update-linked-access-codes). # Create an Access Grant Source: https://docs.seam.co/api/access_grants/create /openapi.json post /access_grants/create Creates a new [Access Grant](/use-cases/granting-access). Access Grants are the default and recommended way to grant a user access to any physical space, irrespective of the locking hardware. They work with both standalone smart locks (using `device_ids`) and access control systems (using `acs_entrance_ids` or `space_ids`), and can issue PIN codes, key cards, and mobile keys through a single request. # Delete an Access Grant Source: https://docs.seam.co/api/access_grants/delete /openapi.json post /access_grants/delete Delete an Access Grant. # Access Grant Errors and Warnings Source: https://docs.seam.co/api/access_grants/errors Errors and warnings that Seam reports on the Access Grant resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "cannot_create_requested_access_methods", "message": "Indicates that Seam could not create one or more of the requested access methods for the access grant.", "created_at": "2025-01-01T00:00:00.000Z", "missing_device_ids": [] } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. IDs of the devices that did not receive an access code at grant creation. Use these to identify which specific devices failed when the message reports a partial failure. ### `cannot_create_requested_access_methods` Indicates that Seam could not create one or more of the requested access methods for the access grant. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "being_deleted", "message": "Indicates that the access grant is being deleted.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. IDs of the access methods being updated. ID of the device where the requested code was unavailable. Devices whose access codes could not be revoked during reconciliation. Present when the provider does not support revoking an offline access code (e.g. Dormakaba oracode with exhausted override budget). The new PIN code that was assigned instead. The originally requested PIN code that was unavailable. Specific reason why the grant's times are not programmable on the device. ### `being_deleted` Indicates that the [access grant](/use-cases/granting-access) is being deleted. *** ### `device_does_not_support_access_codes` Indicates that a device in the access grant does not support access codes and was excluded from code materialization. *** ### `device_time_constraints_violated` Indicates that a device in the access grant cannot program an access code for the grant's time range because of device-specific time constraints. *** ### `overprovisioned_access` Indicates that the access grant has access to locations it should not have. Access methods are being removed from the extra locations. *** ### `requested_code_unavailable` Indicates that the requested PIN code was already in use on a device, so a different code was assigned. *** ### `underprovisioned_access` Indicates that the access grant should have access to more locations than it currently does. Access methods are being created for the missing locations. *** ### `updating_access_times` Indicates that the access times for this [access grant](/use-cases/granting-access) are being updated. *** # Access Grant Events Source: https://docs.seam.co/api/access_grants/events Webhook events that Seam emits for the Access Grant resource, with example payloads and properties. ## `access_grant.created` An Access Grant was created. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An Access Grant was created.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.created", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.created` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_grant.deleted` An Access Grant was deleted. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An Access Grant was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_grant.access_granted_to_all_doors` All access requested for an Access Grant was successfully granted. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "All access requested for an Access Grant was successfully granted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.access_granted_to_all_doors", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.access_granted_to_all_doors` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_grant.access_granted_to_door` Access requested as part of an Access Grant to a particular door was successfully granted. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "acs_entrance_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "Access requested as part of an Access Grant to a particular door was successfully granted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.access_granted_to_door", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. ID of the affected [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.access_granted_to_door` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_grant.access_to_door_lost` Access to a particular door that was requested as part of an Access Grant was lost. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "acs_entrance_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "Access to a particular door that was requested as part of an Access Grant was lost.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.access_to_door_lost", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. ID of the affected [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.access_to_door_lost` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_grant.access_times_changed` An Access Grant's start or end time was changed. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "access_grant_key": "", "created_at": "2025-01-01T00:00:00.000Z", "ends_at": "2025-01-01T00:00:00.000Z", "event_description": "An Access Grant's start or end time was changed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.access_times_changed", "occurred_at": "2025-01-01T00:00:00.000Z", "starts_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. Key of the affected Access Grant (if present). Date and time at which the event was created. The new end time for the access grant. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.access_times_changed` Date and time at which the event occurred. The new start time for the access grant. ID of the workspace associated with the event. ## `access_grant.could_not_create_requested_access_methods` One or more requested access methods could not be created for an Access Grant. ```json Example webhook payload theme={null} { "access_grant_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "error_message": "", "event_description": "One or more requested access methods could not be created for an Access Grant.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_grant.could_not_create_requested_access_methods", "missing_device_ids": [], "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Access Grant. Date and time at which the event was created. Description of why the access methods could not be created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_grant.could_not_create_requested_access_methods` IDs of the devices that did not receive a requested access method. Use these to identify which specific devices failed without having to fetch the Access Grant. Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Access Grant Source: https://docs.seam.co/api/access_grants/get /openapi.json post /access_grants/get Get an Access Grant. You must include at least one request parameter. # Get related Access Grant resources Source: https://docs.seam.co/api/access_grants/get_related /openapi.json post /access_grants/get_related Gets all related resources for one or more Access Grants. You must include at least one request parameter. # List Access Grants Source: https://docs.seam.co/api/access_grants/list /openapi.json post /access_grants/list Gets an Access Grant. # The Access Grant Object Source: https://docs.seam.co/api/access_grants/object Learn how the access_grant object grants a user identity access to spaces, entrances, and devices through mobile keys, plastic cards, and PIN codes. ## The access\_grant Object Represents an Access Grant. Access Grants enable you to grant a user identity access to spaces, entrances, and devices through one or more access methods, such as mobile keys, plastic cards, and PIN codes. You can create an Access Grant for an existing user identity, or you can create a new user identity *while* creating the new Access Grant. ```json Access Grant theme={null} { "access_grant_id": "ef83cca9-5fdf-4ac2-93f3-c21c5a8be54b", "access_method_ids": [ "a1b2c3d4-e5f6-4a3b-2c1d-0e9f8a7b6c5d", "5f4e3d2c-1b0a-9f8e-7d6c-5b4a3c2d1e0f", "c7d8e9f0-1a2b-3c4d-5e6f-7a8b9c0d1e2f" ], "created_at": "2025-06-16T16:54:17.946606Z", "display_name": "My Access Grant", "ends_at": "2025-06-18T16:54:17.946606Z", "instant_key_url": "https://ik.seam.co/ABCXYZ", "requested_access_methods": [ { "display_name": "PIN Code Credential", "mode": "code", "created_at": "2025-06-16T16:54:17.946606Z", "created_access_method_ids": [ "a1b2c3d4-e5f6-4a3b-2c1d-0e9f8a7b6c5d" ] }, { "display_name": "Card Credential", "mode": "card", "created_at": "2025-06-16T16:54:19.946606Z", "created_access_method_ids": [ "5f4e3d2c-1b0a-9f8e-7d6c-5b4a3c2d1e0f" ] }, { "display_name": "Mobile Key Credential", "mode": "mobile_key", "created_at": "2025-06-16T16:54:21.946606Z", "created_access_method_ids": [ "c7d8e9f0-1a2b-3c4d-5e6f-7a8b9c0d1e2f" ] } ], "space_ids": [ "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d", "7f8e9d0a-1b2c-3d4e-5f6a-7b8c9d0e1f2a" ], "starts_at": "2025-06-16T16:54:17.946606Z", "user_identity_id": "e3d736c1-540d-4d10-83e5-9a4e135453b4", "workspace_id": "750fc0bc-4450-4356-8d9f-18c6a3a6b2c7" } ``` *** ## Properties ID of the Access Grant. Unique key for the access grant within the workspace. IDs of the access methods created for the Access Grant. Client Session Token. Only returned if the Access Grant has a mobile\_key access method. Date and time at which the Access Grant was created. ID of the customization profile associated with the Access Grant. Display name of the Access Grant. Date and time at which the Access Grant ends. Errors associated with the [access grant](/use-cases/granting-access). Instant Key URL. Only returned if the Access Grant has a single mobile\_key access\_method. **Deprecated**. Use `space_ids`. The location ids. Name of the Access Grant. If not provided, the display name will be computed. List of pending mutations for the access grant. This shows updates that are in progress. Access methods that the user requested for the Access Grant. Specific PIN code to use for this access method. Only applicable when mode is 'code'. IDs of the access methods created for the requested access method. Date and time at which the requested access method was added to the Access Grant. Display name of the access method. Maximum number of times the instant key can be used. Only applicable when mode is 'mobile\_key'. Defaults to 1 if not specified. Access method mode. Supported values: `code`, `card`, `mobile_key`, `cloud_key`. Reservation key for the access grant. IDs of the spaces to which the Access Grant gives access. Date and time at which the Access Grant starts. ID of user identity to which the Access Grant gives access. Warnings associated with the [access grant](/use-cases/granting-access). ID of the Seam workspace associated with the Access Grant. # Add Requested Access Methods to Access Grant Source: https://docs.seam.co/api/access_grants/request_access_methods /openapi.json post /access_grants/request_access_methods Adds additional requested access methods to an existing Access Grant. # Get an Unmanaged Access Grant Source: https://docs.seam.co/api/access_grants/unmanaged/get /openapi.json post /access_grants/unmanaged/get Get an unmanaged Access Grant (where is_managed = false). # List Unmanaged Access Grants Source: https://docs.seam.co/api/access_grants/unmanaged/list /openapi.json post /access_grants/unmanaged/list Gets unmanaged Access Grants (where is_managed = false). # Update an Unmanaged Access Grant Source: https://docs.seam.co/api/access_grants/unmanaged/update /openapi.json post /access_grants/unmanaged/update Updates an unmanaged Access Grant to make it managed. This endpoint can only be used to convert unmanaged access grants to managed ones by setting `is_managed` to `true`. It cannot be used to convert managed access grants back to unmanaged. When converting an unmanaged access grant to managed, all associated access methods will also be converted to managed. # Update an Access Grant Source: https://docs.seam.co/api/access_grants/update /openapi.json post /access_grants/update Updates an existing Access Grant's time window. You must include at least one request parameter. # Assign a Card Credential to an Access Method Source: https://docs.seam.co/api/access_methods/assign_card /openapi.json post /access_methods/assign_card Assigns a pre-registered card credential, identified by `card_number`, to a card-mode access method. Use this endpoint for access systems that use pre-registered cards, where a physical card must be associated with an access method before it can be used for access. Assigning a card credential also triggers issuance of the access method. # Delete an Access Method Source: https://docs.seam.co/api/access_methods/delete /openapi.json post /access_methods/delete Deletes an access method. You must include at least one request parameter. # Encode an Access Method Source: https://docs.seam.co/api/access_methods/encode /openapi.json post /access_methods/encode Encodes an existing access method onto a plastic card placed on the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). # Access Method Errors and Warnings Source: https://docs.seam.co/api/access_methods/errors Errors and warnings that Seam reports on the Access Method resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "failed_to_issue", "message": "Indicates that Seam was unable to issue this access method before its access grant started, so the recipient may be unable to access the space. This usually points to a problem that needs attention, such as an offline or disconnected device. Seam keeps retrying, and this error clears automatically if the access method is eventually issued.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. ### `failed_to_issue` Indicates that Seam was unable to issue this [access method](/use-cases/granting-access/creating-an-access-grant) before its access grant started, so the recipient may be unable to access the space. This usually points to a problem that needs attention, such as an offline or disconnected device. Seam keeps retrying, and this error clears automatically if the access method is eventually issued. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "being_deleted", "message": "Indicates that the access method is being deleted.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ID of the original access method from which this backup access method was split, if applicable. ### `being_deleted` Indicates that the [access method](/use-cases/granting-access/creating-an-access-grant) is being deleted. *** ### `delay_in_issuing` Indicates that Seam has not yet issued this [access method](/use-cases/granting-access/creating-an-access-grant), even though its access grant is about to begin, so access may not be ready when the recipient arrives. Seam is still attempting to issue it, and this warning clears automatically once issuance succeeds. *** ### `pulled_backup_access_code` Indicates that all attempts to create an access code on this device before the start time failed and a backup access code was used to ensure access was provided in time. *** ### `updating_access_times` Indicates that the access times for this [access method](/use-cases/granting-access/creating-an-access-grant) are being updated. *** # Access Method Events Source: https://docs.seam.co/api/access_methods/events Webhook events that Seam emits for the Access Method resource, with example payloads and properties. ## `access_method.issued` An access method was issued. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An access method was issued.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.issued", "is_backup_code": true, "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. The actual PIN code for code access methods (only present when mode is 'code'). Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.issued` Indicates whether the code is a backup code (only present when mode is 'code' and a backup code was used). Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.revoked` An access method was revoked. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An access method was revoked.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.revoked", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.revoked` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.card_encoding_required` An access method representing a physical card requires encoding. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An access method representing a physical card requires encoding.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.card_encoding_required", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.card_encoding_required` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.deleted` An access method was deleted. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An access method was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.reissued` An access method was reissued. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An access method was reissued.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.reissued", "is_backup_code": true, "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. The actual PIN code for code access methods (only present when mode is 'code'). Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.reissued` Indicates whether the code is a backup code (only present when mode is 'code' and a backup code was used). Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.created` An access method was created. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An access method was created.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.created", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.created` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.delay_in_issuing` Seam has not yet issued this access method, even though its access grant is about to begin, so access may not be ready when the recipient arrives. Seam is still attempting to issue it, and the accompanying `delay_in_issuing` warning clears automatically once issuance succeeds. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "Seam has not yet issued this access method, even though its access grant is about to begin, so access may not be ready when the recipient arrives. Seam is still attempting to issue it, and the accompanying `delay_in_issuing` warning clears automatically once issuance succeeds.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.delay_in_issuing", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.delay_in_issuing` Date and time at which the event occurred. ID of the workspace associated with the event. ## `access_method.failed_to_issue` Seam was unable to issue this access method before its access grant started, so the recipient may be unable to access the space. This usually points to a problem that needs attention, such as an offline or disconnected device. Seam keeps retrying, and the accompanying `failed_to_issue` error clears automatically if the access method is eventually issued. ```json Example webhook payload theme={null} { "access_grant_ids": [], "access_grant_keys": [], "access_method_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "Seam was unable to issue this access method before its access grant started, so the recipient may be unable to access the space. This usually points to a problem that needs attention, such as an offline or disconnected device. Seam keeps retrying, and the accompanying `failed_to_issue` error clears automatically if the access method is eventually issued.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "access_method.failed_to_issue", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of the access grants associated with this access method. Keys of the access grants associated with this access method (if present). ID of the affected access method. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `access_method.failed_to_issue` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Access Method Source: https://docs.seam.co/api/access_methods/get /openapi.json post /access_methods/get Gets an access method. # Get related Access Method resources Source: https://docs.seam.co/api/access_methods/get_related /openapi.json post /access_methods/get_related Gets all related resources for one or more Access Methods. # List Access Methods Source: https://docs.seam.co/api/access_methods/list /openapi.json post /access_methods/list Lists all access methods, usually filtered by Access Grant. You must include at least one request parameter. # The Access Method Object Source: https://docs.seam.co/api/access_methods/object Learn how the access_method object describes the modes of access for an Access Grant, such as PIN codes, plastic cards, and mobile keys. ## The access\_method Object Represents an access method for an Access Grant. Access methods describe the modes of access, such as PIN codes, plastic cards, and mobile keys. For a mobile key, the access method also stores the URL for the associated Instant Key. ```json Card Access Method theme={null} { "access_method_id": "27d8ad77-55c2-4e20-b5b3-43555926f0e8", "created_at": "2025-06-14T16:54:17.946612Z", "display_name": "My Card", "is_card_encoding_required": true, "issued_at": "2025-06-14T16:54:17.946612Z", "mode": "card", "workspace_id": "661025d3-c1d2-403c-83a8-af153aaedfbc" } ``` ```json Mobile Key Access Method theme={null} { "access_method_id": "27d8ad77-55c2-4e20-b5b3-43555926f0e8", "created_at": "2025-06-14T16:54:17.946612Z", "display_name": "My Mobile Key", "instant_key_url": "https://ik.seam.co/ABCXYZ", "is_card_encoding_required": false, "mode": "mobile_key", "workspace_id": "661025d3-c1d2-403c-83a8-af153aaedfbc" } ``` ```json PIN Code Access Method theme={null} { "access_method_id": "27d8ad77-55c2-4e20-b5b3-43555926f0e8", "created_at": "2025-06-14T16:54:17.946612Z", "display_name": "My PIN Code", "is_card_encoding_required": false, "mode": "code", "workspace_id": "661025d3-c1d2-403c-83a8-af153aaedfbc" } ``` ```json Cloud Key Access Method theme={null} { "workspace_id": "00000000-0000-0000-0000-000000000000", "access_method_id": "00000000-0000-0000-0000-000000000000", "display_name": "", "mode": "cloud_key", "created_at": "2025-01-01T00:00:00.000Z", "issued_at": "2025-01-01T00:00:00.000Z", "is_issued": false, "warnings": [], "errors": [], "pending_mutations": [] } ``` *** ## Properties ID of the access method. Token of the client session associated with the access method. The actual PIN code for code access methods. Date and time at which the access method was created. ID of the customization profile associated with the access method. Display name of the access method. Errors associated with the [access method](/use-cases/granting-access/creating-an-access-grant). URL of the Instant Key for mobile key access methods. Indicates whether an existing card credential must be assigned to this access method before it can be issued. Only applies to card-mode access methods on systems that support credential assignment. Indicates whether encoding with an card encoder is required to issue or reissue the plastic card associated with the access method. Indicates whether the access method has been issued. Indicates whether the access method is ready for card assignment. This is true when the access method is in card mode, has not yet been issued, and the system supports credential assignment. Indicates whether the access method is ready to be encoded. This is true when the credential has been created and the card has not yet been issued. Date and time at which the access method was issued. Access method mode. Supported values: `code`, `card`, `mobile_key`, `cloud_key`. Pending mutations for the [access method](/use-cases/granting-access/creating-an-access-grant). Indicates operations that are in progress. Warnings associated with the [access method](/use-cases/granting-access/creating-an-access-grant). ID of the Seam workspace associated with the access method. # Unlock a Door with an Access Method Source: https://docs.seam.co/api/access_methods/unlock_door /openapi.json post /access_methods/unlock_door Remotely unlocks a specified [entrance](/low-level-apis/access-systems/retrieving-entrance-details) using the cloud key credential associated with an access method. Returns an action attempt that tracks the progress of the unlock operation. # Get an Unmanaged Access Method Source: https://docs.seam.co/api/access_methods/unmanaged/get /openapi.json post /access_methods/unmanaged/get Gets an unmanaged access method (where is_managed = false). # List Unmanaged Access Methods Source: https://docs.seam.co/api/access_methods/unmanaged/list /openapi.json post /access_methods/unmanaged/list Lists all unmanaged access methods (where is_managed = false), usually filtered by Access Grant. # Add an ACS User to an Access Group Source: https://docs.seam.co/api/acs/access_groups/add_user /openapi.json post /acs/access_groups/add_user Adds a specified [access system user](/low-level-apis/access-systems/user-management) to a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # Delete an Access Group Source: https://docs.seam.co/api/acs/access_groups/delete /openapi.json post /acs/access_groups/delete Deletes a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # Access Group Errors Source: https://docs.seam.co/api/acs/access_groups/errors Errors that Seam reports on the Access Group resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "failed_to_create_on_acs_system", "message": "Indicates that the access group was not created on the access system. This is likely due to an internal unexpected error. Contact Seam support.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. ### `failed_to_create_on_acs_system` Indicates that the [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups) was not created on the [access system](/low-level-apis/access-systems). This is likely due to an internal unexpected error. Contact Seam [support](mailto:support@seam.co). *** # Access Group Events Source: https://docs.seam.co/api/acs/access_groups/events Webhook events that Seam emits for the Access Group resource, with example payloads and properties. ## `acs_access_group.deleted` An ACS access group was deleted. ```json Example webhook payload theme={null} { "acs_access_group_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An ACS access group was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_access_group.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected access group. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_access_group.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Access Group Source: https://docs.seam.co/api/acs/access_groups/get /openapi.json post /acs/access_groups/get Returns a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # List Access Groups Source: https://docs.seam.co/api/acs/access_groups/list /openapi.json post /acs/access_groups/list Returns a list of all [access groups](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # List Entrances Accessible to an Access Group Source: https://docs.seam.co/api/acs/access_groups/list_accessible_entrances /openapi.json post /acs/access_groups/list_accessible_entrances Returns a list of all accessible entrances for a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # List ACS Users in an Access Group Source: https://docs.seam.co/api/acs/access_groups/list_users /openapi.json post /acs/access_groups/list_users Returns a list of all [access system users](/low-level-apis/access-systems/user-management) in an [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # The Access Group Object Source: https://docs.seam.co/api/acs/access_groups/object Learn how the acs_access_group object defines the entrances a set of access system users can reach and, in some systems, their access schedule. ## The acs\_access\_group Object Group that defines the entrances to which a set of users has access and, in some cases, the access schedule for these entrances and users. Some access control systems use [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups), which are sets of users, combined with sets of permissions. These permissions include both the set of areas or assets that the users can access and the schedule during which the users can access these areas or assets. Instead of assigning access rights individually to each access control system user, which can be time-consuming and error-prone, administrators can assign users to an access group, thereby ensuring that the users inherit all the permissions associated with the access group. Using access groups streamlines the process of managing large numbers of access control system users, especially in bigger organizations or complexes. To learn whether your access control system supports access groups, see the corresponding [system integration guide](/device-and-system-integration-guides#access-control-systems). ```json ACS Access Group theme={null} { "access_group_type": "salto_ks_access_group", "access_group_type_display_name": "Salto KS Access Group", "acs_access_group_id": "3f448826-9875-4947-9519-e468090a4f7d", "acs_system_id": "045baa77-6d06-40fe-a2cd-b82eef688f4a", "connected_account_id": "daba7bd0-edb6-4bb9-a70b-f9ae08a0e301", "created_at": "2025-06-15T16:54:17.946453Z", "display_name": "Main Group", "errors": [], "external_type": "salto_ks_access_group", "external_type_display_name": "Salto KS Access Group", "is_managed": true, "name": "My Access Group", "pending_mutations": [], "warnings": [], "workspace_id": "ac19352c-869a-4209-9ce7-44c740a8b5d0" } ``` *** ## Properties **Deprecated**. Use `external_type`. The access group type. **Deprecated**. Use `external_type_display_name`. The access group type display name. `starts_at` and `ends_at` timestamps for the access group's access. Date and time at which the user's access ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Date and time at which the user's access starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the access group. ID of the access control system that contains the access group. ID of the connected account that contains the access group. Date and time at which the access group was created. Display name for the access group. Errors associated with the `acs_access_group`. Brand-specific terminology for the access group type. Display name that corresponds to the brand-specific terminology for the access group type. Indicates whether Seam manages the access group. Name of the access group. Collection of pending mutations for the access group. Represents operations that have been requested but not yet completed on the integrated access system. Warnings associated with the `acs_access_group`. Date and time at which Seam created the warning. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. ID of the workspace that contains the access group. # Remove an ACS User from an Access Group Source: https://docs.seam.co/api/acs/access_groups/remove_user /openapi.json post /acs/access_groups/remove_user Removes a specified [access system user](/low-level-apis/access-systems/user-management) from a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # Assign a Credential to an ACS User Source: https://docs.seam.co/api/acs/credentials/assign /openapi.json post /acs/credentials/assign Assigns a specified [credential](/low-level-apis/access-systems/managing-credentials) to a specified [access system user](/low-level-apis/access-systems/user-management). # Create a Credential for an ACS User Source: https://docs.seam.co/api/acs/credentials/create /openapi.json post /acs/credentials/create Creates a new [credential](/low-level-apis/access-systems/managing-credentials) for a specified [ACS user](/low-level-apis/access-systems/user-management). For granting access, we recommend [Access Grants](/use-cases/granting-access) instead: they create and manage the underlying credentials for you, across access systems and standalone smart locks alike. Use this low-level endpoint only when you need direct control over an individual ACS credential. # Delete a Credential Source: https://docs.seam.co/api/acs/credentials/delete /openapi.json post /acs/credentials/delete Deletes a specified [credential](/low-level-apis/access-systems/managing-credentials). # Credential Warnings Source: https://docs.seam.co/api/acs/credentials/errors Warnings that Seam reports on the Credential resource, each with its code and meaning. ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "waiting_to_be_issued", "message": "Indicates that the credential is waiting to be issued.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `being_deleted` Indicates that the [credential](/low-level-apis/access-systems/managing-credentials) is being deleted. *** ### `needs_to_be_reissued` Access permissions for the [credential](/low-level-apis/access-systems/managing-credentials) have changed. [Reissue](/low-level-apis/access-systems/working-with-card-encoders-and-scanners/creating-and-encoding-card-based-credentials) (re-encode) the credential. This issue may affect the proper functioning of the credential. *** ### `schedule_externally_modified` Indicates that the schedule of one of the [credential](/low-level-apis/access-systems/managing-credentials)'s children was modified externally. *** ### `schedule_modified` Indicates that the schedule of the [credential](/low-level-apis/access-systems/managing-credentials) was modified to avoid creating a credential with a start date in the past. *** ### `unknown_issue_with_acs_credential` An unknown issue occurred while syncing the state of the [credential](/low-level-apis/access-systems/managing-credentials) with the provider. This issue may affect the proper functioning of the credential. *** ### `waiting_to_be_issued` Indicates that the [credential](/low-level-apis/access-systems/managing-credentials) is waiting to be issued. *** # Credential Events Source: https://docs.seam.co/api/acs/credentials/events Webhook events that Seam emits for the Credential resource, with example payloads and properties. ## `acs_credential.deleted` An [access system credential](/low-level-apis/access-systems/managing-credentials) was deleted. ```json Example webhook payload theme={null} { "acs_credential_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system credential](/low-level-apis/access-systems/managing-credentials) was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_credential.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected credential. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_credential.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_credential.issued` An [access system credential](/low-level-apis/access-systems/managing-credentials) was issued. ```json Example webhook payload theme={null} { "acs_credential_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system credential](/low-level-apis/access-systems/managing-credentials) was issued.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_credential.issued", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected credential. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_credential.issued` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_credential.reissued` An [access system credential](/low-level-apis/access-systems/managing-credentials) was reissued. ```json Example webhook payload theme={null} { "acs_credential_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system credential](/low-level-apis/access-systems/managing-credentials) was reissued.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_credential.reissued", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected credential. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_credential.reissued` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_credential.invalidated` An [access system credential](/low-level-apis/access-systems/managing-credentials) was invalidated. That is, the credential cannot be used anymore. ```json Example webhook payload theme={null} { "acs_credential_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system credential](/low-level-apis/access-systems/managing-credentials) was invalidated. That is, the credential cannot be used anymore.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_credential.invalidated", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected credential. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_credential.invalidated` Date and time at which the event occurred. ID of the workspace associated with the event. # Get a Credential Source: https://docs.seam.co/api/acs/credentials/get /openapi.json post /acs/credentials/get Returns a specified [credential](/low-level-apis/access-systems/managing-credentials). # List Credentials Source: https://docs.seam.co/api/acs/credentials/list /openapi.json post /acs/credentials/list Returns a list of all [credentials](/low-level-apis/access-systems/managing-credentials). # List Accessible Entrances Source: https://docs.seam.co/api/acs/credentials/list_accessible_entrances /openapi.json post /acs/credentials/list_accessible_entrances Returns a list of all [entrances](/api/acs/entrances/object) to which a [credential](/api/acs/credentials/object) grants access. # The Credential Object Source: https://docs.seam.co/api/acs/credentials/object Learn how the acs_credential object represents the means—such as key cards, mobile keys, or PIN codes—by which an access system user gains entry. ## The acs\_credential Object Means by which an [access control system user](/low-level-apis/access-systems/user-management) gains access at an [entrance](/low-level-apis/access-systems/retrieving-entrance-details). The `acs_credential` object represents a [credential](/low-level-apis/access-systems/managing-credentials) that provides an ACS user access within an [access control system](/low-level-apis/access-systems). An access control system generally uses digital means of access to authorize a user trying to get through a specific entrance. Examples of credentials include plastic key cards, mobile keys, biometric identifiers, and PIN codes. The electronic nature of these credentials, as well as the fact that access is centralized, enables both the rapid provisioning and rescinding of access and the ability to compile access audit logs. For each `acs_credential`, you define the access method. You can also specify additional properties, such as a PIN code, depending on the credential type. For granting a person access to a space, [Access Grants](/use-cases/granting-access) are the default and recommended approach. Use the lower-level ACS credential API directly only when you specifically need to manage individual credentials. ```json ACS Card Credential theme={null} { "access_method": "card", "acs_credential_id": "73a0a199-024f-454d-a916-9bbda8502c12", "acs_system_id": "b1d03165-2759-474b-a342-e02223f27b39", "acs_user_id": "0fc82df4-391b-4d00-a234-86378f1c3952", "connected_account_id": "daba7bd0-edb6-4bb9-a70b-f9ae08a0e301", "card_number": "164d29dc4a09b65f", "created_at": "2025-06-16T16:54:17.946514Z", "display_name": "Guest Lock 1, Vingcard Lock 2", "ends_at": "2025-07-12T16:54:17.946512Z", "errors": [], "external_type": "visionline_card", "external_type_display_name": "Visionline Card", "is_issued": true, "is_latest_desired_state_synced_with_provider": true, "is_managed": true, "is_multi_phone_sync_credential": false, "issued_at": "2025-06-16T16:54:17.946512Z", "latest_desired_state_synced_with_provider_at": "2025-06-18T16:54:17.946514Z", "starts_at": "2025-07-10T16:54:17.946512Z", "visionline_metadata": { "card_function_type": "guest", "card_id": "5", "common_acs_entrance_ids": [ "5f4e3d2c-1b0a-9f8e-7d6c-5b4a3c2d1e0f" ], "credential_id": "15", "guest_acs_entrance_ids": [ "a1b2c3d4-e5f6-4a3b-2c1d-0e9f8a7b6c5d" ], "is_valid": true }, "warnings": [], "workspace_id": "005f1e54-5360-40db-8c31-4ef6baaad1fd" } ``` ```json ACS Mobile Key Credential theme={null} { "access_method": "mobile_key", "acs_credential_id": "73a0a199-024f-454d-a916-9bbda8502c12", "acs_system_id": "b1d03165-2759-474b-a342-e02223f27b39", "acs_user_id": "0fc82df4-391b-4d00-a234-86378f1c3952", "connected_account_id": "1b9a3e0d-443f-4063-b619-4ca7e2a97751", "created_at": "2025-06-16T16:54:17.946514Z", "display_name": "Front Door", "errors": [], "is_managed": true, "is_multi_phone_sync_credential": true, "is_one_time_use": false, "warnings": [], "workspace_id": "005f1e54-5360-40db-8c31-4ef6baaad1fd" } ``` ```json ACS PIN Code Credential theme={null} { "access_method": "code", "acs_credential_id": "73a0a199-024f-454d-a916-9bbda8502c12", "acs_system_id": "b1d03165-2759-474b-a342-e02223f27b39", "acs_user_id": "0fc82df4-391b-4d00-a234-86378f1c3952", "connected_account_id": "1b9a3e0d-443f-4063-b619-4ca7e2a97751", "code": "123456", "created_at": "2025-06-16T16:54:17.946514Z", "display_name": "FRONT_DOOR", "errors": [], "external_type": "salto_ks_credential", "external_type_display_name": "Salto KS Credential", "is_latest_desired_state_synced_with_provider": true, "is_managed": true, "is_multi_phone_sync_credential": false, "is_one_time_use": false, "latest_desired_state_synced_with_provider_at": "2025-06-18T16:54:17.946514Z", "starts_at": "2025-07-10T16:54:17.946512Z", "warnings": [], "workspace_id": "005f1e54-5360-40db-8c31-4ef6baaad1fd" } ``` *** ## Properties Access method for the [credential](/low-level-apis/access-systems/managing-credentials). Supported values: `code`, `card`, `mobile_key`, `cloud_key`. ID of the [credential](/low-level-apis/access-systems/managing-credentials). ID of the credential pool to which the credential belongs. ID of the [access control system](/low-level-apis/access-systems) that contains the [credential](/low-level-apis/access-systems/managing-credentials). ID of the [ACS user](/low-level-apis/access-systems/user-management) to whom the [credential](/low-level-apis/access-systems/managing-credentials) belongs. Akiles-specific metadata for the [credential](/low-level-apis/access-systems/managing-credentials). ID of the Akiles member PIN. Vostio-specific metadata for the [credential](/low-level-apis/access-systems/managing-credentials). Indicates whether the credential should auto-join. For an auto-join credential, Seam automatically issues an override card if there are no other cards and a joiner card if there are existing cards on the doors. Names of the doors to which to grant access in the Vostio access system. Endpoint ID in the Vostio access system. Key ID in the Vostio access system. Key issuing request ID in the Vostio access system. IDs of the guest entrances to override in the Vostio access system. Number of the card associated with the [credential](/low-level-apis/access-systems/managing-credentials). Access (PIN) code for the [credential](/low-level-apis/access-systems/managing-credentials). ID of the [connected account](/core-concepts/connected-accounts) to which the [credential](/low-level-apis/access-systems/managing-credentials) belongs. Date and time at which the [credential](/low-level-apis/access-systems/managing-credentials) was created. Display name that corresponds to the [credential](/low-level-apis/access-systems/managing-credentials) type. Date and time at which the [credential](/low-level-apis/access-systems/managing-credentials) validity ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Must be a time in the future and after `starts_at`. Errors associated with the [credential](/low-level-apis/access-systems/managing-credentials). Date and time at which Seam created the error. The error code. The message. Brand-specific terminology for the [credential](/low-level-apis/access-systems/managing-credentials) type. Supported values: `pti_card`, `brivo_credential`, `hid_credential`, `visionline_card`. Display name that corresponds to the brand-specific terminology for the [credential](/low-level-apis/access-systems/managing-credentials) type. Indicates whether the [credential](/low-level-apis/access-systems/managing-credentials) has been encoded onto a card. Indicates whether the latest state of the [credential](/low-level-apis/access-systems/managing-credentials) has been synced from Seam to the provider. Indicates whether Seam manages the credential. Indicates whether the [credential](/low-level-apis/access-systems/managing-credentials) is a [multi-phone sync credential](/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system#what-are-multi-phone-sync-credentials). Indicates whether the [credential](/low-level-apis/access-systems/managing-credentials) can only be used once. If `true`, the code becomes invalid after the first use. Date and time at which the [credential](/low-level-apis/access-systems/managing-credentials) was encoded onto a card. Date and time at which the state of the [credential](/low-level-apis/access-systems/managing-credentials) was most recently synced from Seam to the provider. ID of the parent [credential](/low-level-apis/access-systems/managing-credentials). Date and time at which the [credential](/low-level-apis/access-systems/managing-credentials) validity starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [user identity](/api/user_identities/object) to whom the [credential](/low-level-apis/access-systems/managing-credentials) belongs. Visionline-specific metadata for the [credential](/low-level-apis/access-systems/managing-credentials). Indicates whether the credential should auto-join. For an auto-join credential, Seam automatically issues an override card if there are no other cards and a joiner card if there are existing cards on the doors. Card function type in the Visionline access system. ID of the card in the Visionline access system. Common entrance IDs in the Visionline access system. ID of the credential in the Visionline access system. Guest entrance IDs in the Visionline access system. Indicates whether the credential is valid. IDs of the credentials to which you want to join. Warnings associated with the [credential](/low-level-apis/access-systems/managing-credentials). ID of the workspace that contains the [credential](/low-level-apis/access-systems/managing-credentials). # Unassign a Credential from an ACS User Source: https://docs.seam.co/api/acs/credentials/unassign /openapi.json post /acs/credentials/unassign Unassigns a specified [credential](/low-level-apis/access-systems/managing-credentials) from a specified [access system user](/low-level-apis/access-systems/user-management). # Update a Credential Source: https://docs.seam.co/api/acs/credentials/update /openapi.json post /acs/credentials/update Updates the code and ends at date and time for a specified [credential](/low-level-apis/access-systems/managing-credentials). # Encode a Credential Source: https://docs.seam.co/api/acs/encoders/encode_credential /openapi.json post /acs/encoders/encode_credential Encodes an existing [credential](/low-level-apis/access-systems/managing-credentials) onto a plastic card placed on the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). Either provide an `acs_credential_id` or an `access_method_id` # Encoder Events Source: https://docs.seam.co/api/acs/encoders/events Webhook events that Seam emits for the Encoder resource, with example payloads and properties. ## `acs_encoder.added` An [access system encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) was added. ```json Example webhook payload theme={null} { "acs_encoder_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) was added.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_encoder.added", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected encoder. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_encoder.added` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_encoder.removed` An [access system encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) was removed. ```json Example webhook payload theme={null} { "acs_encoder_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) was removed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_encoder.removed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected encoder. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_encoder.removed` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Encoder Source: https://docs.seam.co/api/acs/encoders/get /openapi.json post /acs/encoders/get Returns a specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). # List Encoders Source: https://docs.seam.co/api/acs/encoders/list /openapi.json post /acs/encoders/list Returns a list of all [encoders](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). # The Encoder Object Source: https://docs.seam.co/api/acs/encoders/object Learn how the acs_encoder object represents a hardware device that encodes credential data onto physical key cards within an access control system. ## The acs\_encoder Object Represents a hardware device that encodes [credential](/low-level-apis/access-systems/managing-credentials) data onto physical cards within an [access control system](/low-level-apis/access-systems). Some access control systems require credentials to be encoded onto plastic key cards using a card encoder. This process involves the following two key steps: 1. Credential creation Configure the access parameters for the credential. 2. Card encoding Write the credential data onto the card using a compatible card encoder. Separately, the Seam API also supports card scanning, which enables you to scan and read the encoded data on a card. You can use this action to confirm consistency with access control system records or diagnose discrepancies if needed. See [Working with Card Encoders and Scanners](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). To verify if your access control system requires a card encoder, see the corresponding [system integration guide](/device-and-system-integration-guides#access-control-systems). ```json ACS Encoder theme={null} { "acs_encoder_id": "681da2d6-4ac6-4b33-8c03-86281b761325", "acs_system_id": "c85406d2-214f-4e11-8000-a2e5b5a362a4", "connected_account_id": "1b9a3e0d-443f-4063-b619-4ca7e2a97750", "created_at": "2025-06-16T16:54:17.946527Z", "display_name": "Encoder 1", "errors": [], "workspace_id": "f863ac85-2c4e-49ae-8679-3ec2417f1d62" } ``` *** ## Properties ID of the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). ID of the [access control system](/low-level-apis/access-systems) that contains the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). ID of the connected account that contains the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). Date and time at which the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) was created. Display name for the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). Errors associated with the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. ID of the workspace that contains the [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). # Scan a Credential Source: https://docs.seam.co/api/acs/encoders/scan_credential /openapi.json post /acs/encoders/scan_credential Scans an encoded [acs_credential](/low-level-apis/access-systems/managing-credentials) from a plastic card placed on the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). # Scan to Assign a Credential Source: https://docs.seam.co/api/acs/encoders/scan_to_assign_credential /openapi.json post /acs/encoders/scan_to_assign_credential Scans a physical card placed on the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) and assigns the scanned credential to an ACS user. Provide either an `acs_user_id` or a `user_identity_id`. # Simulate that the Next Credential Encoding Will Fail Source: https://docs.seam.co/api/acs/encoders/simulate/next_credential_encode_will_fail /openapi.json post /acs/encoders/simulate/next_credential_encode_will_fail Simulates that the next attempt to encode a [credential](/low-level-apis/access-systems/managing-credentials) using the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) will fail. You can only perform this action within a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). # Simulate that the Next Credential Encoding Will Succeed Source: https://docs.seam.co/api/acs/encoders/simulate/next_credential_encode_will_succeed /openapi.json post /acs/encoders/simulate/next_credential_encode_will_succeed Simulates that the next attempt to encode a [credential](/low-level-apis/access-systems/managing-credentials) using the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) will succeed. You can only perform this action within a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). # Simulate that the Next Credential Scan Will Fail Source: https://docs.seam.co/api/acs/encoders/simulate/next_credential_scan_will_fail /openapi.json post /acs/encoders/simulate/next_credential_scan_will_fail Simulates that the next attempt to scan a [credential](/low-level-apis/access-systems/managing-credentials) using the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) will fail. You can only perform this action within a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). # Simulate that the Next Credential Scan Will Succeed Source: https://docs.seam.co/api/acs/encoders/simulate/next_credential_scan_will_succeed /openapi.json post /acs/encoders/simulate/next_credential_scan_will_succeed Simulates that the next attempt to scan a [credential](/low-level-apis/access-systems/managing-credentials) using the specified [encoder](/low-level-apis/access-systems/working-with-card-encoders-and-scanners) will succeed. You can only perform this action within a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). # Entrance Warnings Source: https://docs.seam.co/api/acs/entrances/errors Warnings that Seam reports on the Entrance resource, each with its code and meaning. ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "salto_ks_entrance_access_code_support_removed", "message": "Indicates that a change in the reported device model has been detected for this Salto KS entrance, which may occur after an IQ hub reset. Access code support may be affected. See https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support for troubleshooting steps.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `entrance_setup_required` Indicates that this entrance requires additional configuration in the access control system before Seam can fully manage it. *** ### `entrance_shares_zone` Indicates that this entrance shares a zone with other entrances in Avigilon Alta and cannot be added to an access group individually. *** ### `privacy_mode` Indicates that this entrance is in privacy mode. When privacy mode is enabled, access codes, mobile keys, and remote unlocks will not work unless the user has admin access. *** ### `salto_ks_entrance_access_code_support_removed` Indicates that a change in the reported device model has been detected for this Salto KS entrance, which may occur after an IQ hub reset. Access code support may be affected. See [https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support](https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support) for troubleshooting steps. *** ### `salto_ks_privacy_mode` Indicates that this entrance is in privacy mode. When privacy mode is enabled, access codes, mobile keys, and remote unlocks will not work unless the user has admin access. *** # Entrance Events Source: https://docs.seam.co/api/acs/entrances/events Webhook events that Seam emits for the Entrance resource, with example payloads and properties. ## `acs_entrance.added` An [access system entrance](/low-level-apis/access-systems/retrieving-entrance-details) was added. ```json Example webhook payload theme={null} { "acs_entrance_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system entrance](/low-level-apis/access-systems/retrieving-entrance-details) was added.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_entrance.added", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected entrance. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_entrance.added` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_entrance.removed` An [access system entrance](/low-level-apis/access-systems/retrieving-entrance-details) was removed. ```json Example webhook payload theme={null} { "acs_entrance_id": "00000000-0000-0000-0000-000000000000", "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system entrance](/low-level-apis/access-systems/retrieving-entrance-details) was removed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_entrance.removed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected entrance. ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_entrance.removed` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Entrance Source: https://docs.seam.co/api/acs/entrances/get /openapi.json post /acs/entrances/get Returns a specified [access system entrance](/low-level-apis/access-systems/retrieving-entrance-details). # Grant an ACS User Access to an Entrance Source: https://docs.seam.co/api/acs/entrances/grant_access /openapi.json post /acs/entrances/grant_access Grants a specified [access system user](/low-level-apis/access-systems/user-management) access to a specified [access system entrance](/low-level-apis/access-systems/retrieving-entrance-details). # List Entrances Source: https://docs.seam.co/api/acs/entrances/list /openapi.json post /acs/entrances/list Returns a list of all [access system entrances](/low-level-apis/access-systems/retrieving-entrance-details). # List Credentials with Access to an Entrance Source: https://docs.seam.co/api/acs/entrances/list_credentials_with_access /openapi.json post /acs/entrances/list_credentials_with_access Returns a list of all [credentials](/low-level-apis/access-systems/managing-credentials) with access to a specified [entrance](/low-level-apis/access-systems/retrieving-entrance-details). # The Entrance Object Source: https://docs.seam.co/api/acs/entrances/object Learn how the acs_entrance object represents a secured door, gate, or zone within an access control system, and how to list its credentials. ## The acs\_entrance Object Represents an [entrance](/low-level-apis/access-systems/retrieving-entrance-details) within an [access control system](/low-level-apis/access-systems). In an access control system, an entrance is a secured door, gate, zone, or other method of entry. You can list details for all the `acs_entrance` resources in your workspace or get these details for a specific `acs_entrance`. You can also list all entrances associated with a specific credential, and you can list all credentials associated with a specific entrance. ```json ACS Entrance theme={null} { "acs_entrance_id": "f74e4879-5991-4e2f-a368-888983dcfbfc", "acs_system_id": "6a74a969-94ea-4383-b5cf-5e7da8c113d1", "connected_account_id": "1b9a3e0d-443f-4063-b619-4ca7e2a97751", "created_at": "2025-06-15T16:54:17.946495Z", "display_name": "Main Entrance", "errors": [], "space_ids": [], "visionline_metadata": { "door_category": "guest", "door_name": "Main Entrance", "profiles": [ { "visionline_door_profile_id": "7f8e9d0a-1b2c-3d4e-5f6a-7b8c9d0e1f2a", "visionline_door_profile_type": "BLE" } ] }, "warnings": [] } ``` *** ## Properties ID of the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). ID of the [access control system](/low-level-apis/access-systems) that contains the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Akiles-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Actions the gadget exposes (for example, open). ID of the gadget action. Name of the gadget action. ID of the Akiles gadget. ID of the Akiles site the gadget belongs to. Name of the Akiles site the gadget belongs to. ASSA ABLOY Vostio-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Name of the door in the Vostio access system. Number of the door in the Vostio access system. Type of the door in the Vostio access system. PMS ID of the door in the Vostio access system. Indicates whether keys are allowed to set the door in stand open mode in the Vostio access system. Avigilon Alta-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Entry name for an Avigilon Alta system. Total count of entry relays for an Avigilon Alta system. Organization name for an Avigilon Alta system. Site ID for an Avigilon Alta system. Site name for an Avigilon Alta system. Zone ID for an Avigilon Alta system. Zone name for an Avigilon Alta system. Brivo-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). ID of the access point in the Brivo access system. ID of the site that the access point belongs to. Name of the site that the access point belongs to. Indicates whether the ACS entrance can belong to a reservation via an access\_grant.reservation\_key. Indicates whether the ACS entrance can be unlocked with card credentials. Indicates whether the ACS entrance can be unlocked with cloud key credentials. Indicates whether the ACS entrance can be unlocked with pin codes. Indicates whether the ACS entrance can be unlocked with mobile key credentials. ID of the [connected account](/low-level-apis/access-systems/retrieving-entrance-details) associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Date and time at which the [entrance](/low-level-apis/access-systems/retrieving-entrance-details) was created. Display name for the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). dormakaba Ambiance-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Name of the access point in the dormakaba Ambiance access system. dormakaba Community-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Type of access point profile in the dormakaba Community access system. Errors associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Hotek-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Display name of the entrance. Display name of the entrance. Room number of the entrance. Indicates whether the [entrance](/low-level-apis/access-systems/retrieving-entrance-details) is currently locked. Latch-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Accessibility type in the Latch access system. Name of the door in the Latch access system. Type of the door in the Latch access system. Indicates whether the entrance is connected. Salto KS-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Battery level of the door access device. Name of the door in the Salto KS access system. Indicates whether an intrusion alarm is active on the door. Indicates whether the door is left open. Type of the lock in the Salto KS access system. Locked state of the door in the Salto KS access system. Indicates whether the door access device is online. Indicates whether privacy mode is enabled for the lock. Salto Space-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Indicates whether AuditOnKeys is enabled for the door in the Salto Space access system. Description of the door in the Salto Space access system. Door ID in the Salto Space access system. Name of the door in the Salto Space access system. Description of the room in the Salto Space access system. Name of the room in the Salto Space access system. IDs of the spaces that the entrance is in. Visionline-specific metadata associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). Category of the door in the Visionline access system. Name of the door in the Visionline access system. Profile for the door in the Visionline access system. Door profile ID in the Visionline access system. Door profile type in the Visionline access system. Warnings associated with the [entrance](/low-level-apis/access-systems/retrieving-entrance-details). # Unlock an Entrance Source: https://docs.seam.co/api/acs/entrances/unlock /openapi.json post /acs/entrances/unlock Remotely unlocks a specified [entrance](/low-level-apis/access-systems/retrieving-entrance-details) using a cloud_key credential. Returns an action attempt that tracks the progress of the unlock operation. # Access Control Systems Source: https://docs.seam.co/api/acs/object Systems for managing and monitoring access to physical spaces Access control systems centralize access authorization for buildings, which means that you can use a single system to grant users access to one or more entrances. An access control system manages the following elements: * Who has access * The entrances to which users have access * The access schedule for each user and entrance * The access mechanism—PIN codes, mobile keys, or plastic cards—for each access grant To grant access using the Seam access control system API, use the following basic process: 1. Create `acs_user`s. 2. Configure access for these users. For some access control systems, configure the allowed entrances and access schedule. For other systems, use `acs_access_group`s. For details, see the [system integration guide](/device-and-system-integration-guides#access-control-systems) for your access control system. 3. Create `acs_credential`s, which are the digital means of granting access to users, such as PIN codes, mobile keys, and plastic (RFID) cards. If you are developing a mobile app to provide access for your users, you can also use [Seam's iOS and Android SDKs](/capability-guides/mobile-access/mobile-device-sdks) that pair with the Seam API to create and manage mobile keys. ## Resources The Access Control Systems (ACS) namespace contains the following resources: ### [`acs_access_group`](/api/acs/access_groups/object) Group that defines the entrances to which a set of users has access and, in some cases, the access schedule for these entrances and users. Some access control systems use [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups), which are sets of users, combined with sets of permissions. These permissions include both the set of areas or assets that the users can access and the schedule during which the users can access these areas or assets. Instead of assigning access rights individually to each access control system user, which can be time-consuming and error-prone, administrators can assign users to an access group, thereby ensuring that the users inherit all the permissions associated with the access group. Using access groups streamlines the process of managing large numbers of access control system users, especially in bigger organizations or complexes. To learn whether your access control system supports access groups, see the corresponding [system integration guide](/device-and-system-integration-guides#access-control-systems). *** ### [`acs_credential`](/api/acs/credentials/object) Means by which an [access control system user](/low-level-apis/access-systems/user-management) gains access at an [entrance](/low-level-apis/access-systems/retrieving-entrance-details). The `acs_credential` object represents a [credential](/low-level-apis/access-systems/managing-credentials) that provides an ACS user access within an [access control system](/low-level-apis/access-systems). An access control system generally uses digital means of access to authorize a user trying to get through a specific entrance. Examples of credentials include plastic key cards, mobile keys, biometric identifiers, and PIN codes. The electronic nature of these credentials, as well as the fact that access is centralized, enables both the rapid provisioning and rescinding of access and the ability to compile access audit logs. For each `acs_credential`, you define the access method. You can also specify additional properties, such as a PIN code, depending on the credential type. For granting a person access to a space, [Access Grants](/use-cases/granting-access) are the default and recommended approach. Use the lower-level ACS credential API directly only when you specifically need to manage individual credentials. *** ### [`acs_encoder`](/api/acs/encoders/object) Represents a hardware device that encodes [credential](/low-level-apis/access-systems/managing-credentials) data onto physical cards within an [access control system](/low-level-apis/access-systems). Some access control systems require credentials to be encoded onto plastic key cards using a card encoder. This process involves the following two key steps: 1. Credential creation Configure the access parameters for the credential. 2. Card encoding Write the credential data onto the card using a compatible card encoder. Separately, the Seam API also supports card scanning, which enables you to scan and read the encoded data on a card. You can use this action to confirm consistency with access control system records or diagnose discrepancies if needed. See [Working with Card Encoders and Scanners](/low-level-apis/access-systems/working-with-card-encoders-and-scanners). To verify if your access control system requires a card encoder, see the corresponding [system integration guide](/device-and-system-integration-guides#access-control-systems). *** ### [`acs_entrance`](/api/acs/entrances/object) Represents an [entrance](/low-level-apis/access-systems/retrieving-entrance-details) within an [access control system](/low-level-apis/access-systems). In an access control system, an entrance is a secured door, gate, zone, or other method of entry. You can list details for all the `acs_entrance` resources in your workspace or get these details for a specific `acs_entrance`. You can also list all entrances associated with a specific credential, and you can list all credentials associated with a specific entrance. *** ### [`acs_system`](/api/acs/systems/object) Represents an [access control system](/low-level-apis/access-systems). Within an `acs_system`, create [`acs_user`s](/api/acs/users/object) and [`acs_credential`s](/api/acs/credentials/object) to grant access to the `acs_user`s. For details about the resources associated with an access control system, see the [access control systems namespace](/api/acs/object). *** ### [`acs_user`](/api/acs/users/object) Represents a [user](/low-level-apis/access-systems/user-management) in an [access system](/low-level-apis/access-systems). An access system user typically refers to an individual who requires access, like an employee or resident. Each user can possess multiple credentials that serve as their keys or identifiers for access. The type of credential can vary widely. For example, in the Salto system, a user can have a PIN code, a mobile app account, and a fob. In other platforms, it is not uncommon for a user to have more than one of the same credential type, such as multiple key cards. Additionally, these credentials can have a schedule or validity period. For details about how to configure users in your access system, see the corresponding [system integration guide](/device-and-system-integration-guides#access-control-systems). *** # ACS System Errors and Warnings Source: https://docs.seam.co/api/acs/systems/errors Errors and warnings that Seam reports on the ACS System resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "seam_bridge_disconnected", "message": "Indicates that the Seam API cannot communicate with Seam Bridge, for example, if Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline.\nThis error might also occur if Seam Bridge is connected to the wrong workspace.\nSee also Troubleshooting Your Access Control System.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates whether the error is related to the [Seam Bridge](/capability-guides/seam-bridge). ### `account_disconnected` Indicates that the login credentials are invalid. Reconnect the account using a [Connect Webview](/core-concepts/connect-webviews) to restore access. *** ### `acs_system_disconnected` Indicates that the [access control system](/low-level-apis/access-systems) has been disconnected. See [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system) to resolve the issue. *** ### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** ### `insufficient_permissions` Indicates that Seam's integration user does not have sufficient permissions on the provider's system backing this [access control system](/low-level-apis/access-systems). Access cannot be managed until permissions are restored. See the error message for specifics, then either reauthorize the connected account in Seam or grant the integration user the required permissions in the provider's system. *** ### `provider_service_unavailable` Indicates that the access control system provider's service is temporarily unavailable. Seam will automatically retry and reconnect when the service becomes available again. *** ### `salto_ks_certification_expired` Indicates that the [access control system](/low-level-apis/access-systems) has lost its Salto KS certification. Contact [support](mailto:support@seam.co) to regain access. *** ### `salto_ks_subscription_limit_exceeded` Indicates that the maximum number of users allowed for the site has been reached. This means that new access codes cannot be created. Contact Salto support to increase the user limit. *** ### `seam_bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. This error might also occur if Seam Bridge is connected to the wrong [workspace](/core-concepts/workspaces). See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** ### `visionline_instance_unreachable` Indicates that [Seam Bridge](/capability-guides/seam-bridge) is functioning correctly and the Seam API can communicate with Seam Bridge, but the Seam API cannot connect to the on-premises [Visionline access control system](/device-and-system-integration-guides/assa-abloy-visionline-access-control-system). For example, the IP address of the on-premises access control system may be set incorrectly within the Seam [workspace](/core-concepts/workspaces). See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-visionline_instance_unreachable). *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "salto_ks_subscription_limit_almost_reached", "message": "Indicates that the Salto KS site has exceeded 80% of the maximum number of allowed users. Increase your subscription limit or delete some users from your site to rectify the issue.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. The misconfigured acs entrance ids. ### `salto_ks_subscription_limit_almost_reached` Indicates that the Salto KS site has exceeded 80% of the maximum number of allowed users. Increase your subscription limit or delete some users from your site to rectify the issue. *** ### `setup_required` Indicates that the access control system requires additional setup before it can be fully operational. Follow the instructions in the warning message to complete the setup. *** ### `time_zone_does_not_match_location` Indicates the [access control system](/low-level-apis/access-systems) time zone could not be determined because the reported physical location does not match the time zone configured on the physical [ACS entrances](/low-level-apis/access-systems/retrieving-entrance-details). *** # ACS System Events Source: https://docs.seam.co/api/acs/systems/events Webhook events that Seam emits for the ACS System resource, with example payloads and properties. ## `acs_system.connected` An [access system](/low-level-apis/access-systems) was connected. ```json Example webhook payload theme={null} { "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system](/low-level-apis/access-systems) was connected.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_system.connected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_system.connected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_system.added` An [access system](/low-level-apis/access-systems) was added. ```json Example webhook payload theme={null} { "acs_system_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system](/low-level-apis/access-systems) was added.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_system.added", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access system. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_system.added` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_system.disconnected` An [access system](/low-level-apis/access-systems) was disconnected. ```json Example webhook payload theme={null} { "acs_system_errors": [], "acs_system_id": "00000000-0000-0000-0000-000000000000", "acs_system_warnings": [], "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system](/low-level-apis/access-systems) was disconnected.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_system.disconnected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Errors associated with the access control system. ID of the access system. Warnings associated with the access control system. Errors associated with the connected account. ID of the connected account. Warnings associated with the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_system.disconnected` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an ACS System Source: https://docs.seam.co/api/acs/systems/get /openapi.json post /acs/systems/get Returns a specified [access system](/low-level-apis/access-systems). # List ACS Systems Source: https://docs.seam.co/api/acs/systems/list /openapi.json post /acs/systems/list Returns a list of all [access systems](/low-level-apis/access-systems). To filter the list of returned access systems by a specific connected account ID, include the `connected_account_id` in the request body. If you omit the `connected_account_id` parameter, the response includes all access systems connected to your workspace. # List Compatible Credential Manager ACS Systems Source: https://docs.seam.co/api/acs/systems/list_compatible_credential_manager_acs_systems /openapi.json post /acs/systems/list_compatible_credential_manager_acs_systems Returns a list of all credential manager systems that are compatible with a specified [access system](/low-level-apis/access-systems). Specify the access system for which you want to retrieve all compatible credential manager systems by including the corresponding `acs_system_id` in the request body. # The ACS System Object Source: https://docs.seam.co/api/acs/systems/object Learn how the acs_system object represents an access control system in which you create users and credentials to grant them access at entrances. ## The acs\_system Object Represents an [access control system](/low-level-apis/access-systems). Within an `acs_system`, create [`acs_user`s](/api/acs/users/object) and [`acs_credential`s](/api/acs/credentials/object) to grant access to the `acs_user`s. For details about the resources associated with an access control system, see the [access control systems namespace](/api/acs/object). ```json ACS System theme={null} { "acs_access_group_count": 5, "acs_system_id": "dbed811f-a8c7-4dab-a3cb-1a734ebd6ac7", "acs_user_count": 20, "connected_account_id": "a94aeed0-1ae0-4e49-9c23-8444c7ceba09", "connected_account_ids": [ "a94aeed0-1ae0-4e49-9c23-8444c7ceba09" ], "created_at": "2025-06-15T16:54:17.946425Z", "default_credential_manager_acs_system_id": "5dde2def-3507-44f5-9521-7ca96aa4cd18", "errors": [], "external_type": "salto_ks_site", "external_type_display_name": "Salto KS site", "image_alt_text": "Salto KS site Logo", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/acs_systems/salto_ks_site.png&q=75&w=128", "is_credential_manager": false, "location": { "time_zone": "America/New_York" }, "name": "My ACS System", "warnings": [], "workspace_id": "172920be-1f4d-45d4-8519-ecc3bdee638f" } ``` *** ## Properties Number of access groups in the [access control system](/low-level-apis/access-systems). ID of the [access control system](/low-level-apis/access-systems). Number of users in the [access control system](/low-level-apis/access-systems). ID of the connected account associated with the [access control system](/low-level-apis/access-systems). **Deprecated**. Use `connected_account_id`. IDs of the [connected accounts](/core-concepts/connected-accounts) associated with the [access control system](/low-level-apis/access-systems). Date and time at which the [access control system](/low-level-apis/access-systems) was created. ID of the default credential manager `acs_system` for this [access control system](/low-level-apis/access-systems). Errors associated with the [access control system](/low-level-apis/access-systems). Brand-specific terminology for the [access control system](/low-level-apis/access-systems) type. Display name that corresponds to the brand-specific terminology for the [access control system](/low-level-apis/access-systems) type. Alternative text for the [access control system](/low-level-apis/access-systems) image. URL for the image that represents the [access control system](/low-level-apis/access-systems). Indicates whether the `acs_system` is a credential manager. Location information for the [access control system](/low-level-apis/access-systems). Time zone in which the [access control system](/low-level-apis/access-systems) is located. Name of the [access control system](/low-level-apis/access-systems). **Deprecated**. Use `external_type`. The system type. **Deprecated**. Use `external_type_display_name`. The system type display name. Visionline-specific metadata for the [access control system](/low-level-apis/access-systems). IP address or hostname of the main Visionline server relative to [Seam Bridge](/capability-guides/seam-bridge) on the local network. Keyset loaded into a reader. Mobile keys and reader administration tools securely authenticate only with readers programmed with a matching keyset. Unique ID assigned by the ASSA ABLOY licensing team that identifies each hotel in your credential manager. Warnings associated with the [access control system](/low-level-apis/access-systems). ID of the workspace that contains the [access control system](/low-level-apis/access-systems). # Report Devices Source: https://docs.seam.co/api/acs/systems/report_devices /openapi.json post /acs/systems/report_devices Reports ACS system device status including encoders and entrances. # Add an ACS User to an Access Group Source: https://docs.seam.co/api/acs/users/add_to_access_group /openapi.json post /acs/users/add_to_access_group Adds a specified [access system user](/low-level-apis/access-systems/user-management) to a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # Create an ACS User Source: https://docs.seam.co/api/acs/users/create /openapi.json post /acs/users/create Creates a new [access system user](/low-level-apis/access-systems/user-management). # Delete an ACS User Source: https://docs.seam.co/api/acs/users/delete /openapi.json post /acs/users/delete Deletes a specified [access system user](/low-level-apis/access-systems/user-management) and invalidates the access system user's [credentials](/low-level-apis/access-systems/managing-credentials). You must include at least one request parameter. # ACS User Errors and Warnings Source: https://docs.seam.co/api/acs/users/errors Errors and warnings that Seam reports on the ACS User resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "deleted_externally", "message": "Indicates that the access system user was deleted from the access system outside of Seam.", "created_at": "2025-01-01T00:00:00.000Z" } ``` The error code. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. ### `deleted_externally` Indicates that the [access system user](/low-level-apis/access-systems/user-management) was deleted from the [access system](/low-level-apis/access-systems) outside of Seam. *** ### `failed_to_create_on_acs_system` Indicates that the [access system user](/low-level-apis/access-systems/user-management) was not created on the [access system](/low-level-apis/access-systems). This is likely due to an internal unexpected error. Contact Seam [support](mailto:support@seam.co). *** ### `failed_to_delete_on_acs_system` Indicates that the [access system user](/low-level-apis/access-systems/user-management) was not deleted on the [access system](/low-level-apis/access-systems). This is likely due to an internal unexpected error. Contact Seam [support](mailto:support@seam.co). *** ### `failed_to_update_on_acs_system` Indicates that the [access system user](/low-level-apis/access-systems/user-management) was not updated on the [access system](/low-level-apis/access-systems). This is likely due to an internal unexpected error. Contact Seam [support](mailto:support@seam.co). *** ### `latch_conflict_with_resident_user` Indicates that the [access system user](/low-level-apis/access-systems/user-management) was created from the Seam API but also exists on Mission Control. This is unsupported. Contact Seam [support](mailto:support@seam.co). *** ### `salto_ks_subscription_limit_exceeded` Indicates that the [access system user](/low-level-apis/access-systems/user-management) could not be subscribed on Salto KS because the subscription limit has been exceeded. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "being_deleted", "message": "Indicates that the access system user is being deleted from the access system. This is a temporary state, and the access system user will be deleted shortly.", "created_at": "2025-01-01T00:00:00.000Z" } ``` The warning code. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `acs_user_inactive` Indicates that the [access system user](/low-level-apis/access-systems/user-management) exists but is not currently able to gain access—for example, because their access schedule has not started yet or has ended, the access system has reached its limit for active users, or they have been unsubscribed or deactivated. Refer to the warning message for the provider-specific reason. This is distinct from `is_suspended`, which indicates the user has been explicitly blocked. *** ### `being_deleted` Indicates that the [access system user](/low-level-apis/access-systems/user-management) is being deleted from the [access system](/low-level-apis/access-systems). This is a temporary state, and the access system user will be deleted shortly. *** ### `latch_resident_user` Indicates that the [access system user](/low-level-apis/access-systems/user-management) was created on Latch Mission Control. Please use the Latch Mission Control to manage this user. *** ### `salto_ks_user_not_subscribed` Indicates that the [access system user](/low-level-apis/access-systems/user-management) is not subscribed on Salto KS, so they cannot unlock doors or perform any actions. This occurs when the their access schedule hasn’t started yet, if their access schedule has ended, if the site has reached its limit for active users (subscription slots), or if they have been manually unsubscribed. *** ### `unknown_issue_with_acs_user` An unknown issue occurred while syncing the state of this [access system user](/low-level-apis/access-systems/user-management) with the provider. This issue may affect the proper functioning of this user. *** # ACS User Events Source: https://docs.seam.co/api/acs/users/events Webhook events that Seam emits for the ACS User resource, with example payloads and properties. ## `acs_user.created` An [access system user](/low-level-apis/access-systems/user-management) was created. ```json Example webhook payload theme={null} { "acs_system_id": "00000000-0000-0000-0000-000000000000", "acs_user_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system user](/low-level-apis/access-systems/user-management) was created.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_user.created", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access system. ID of the affected access system user. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_user.created` Date and time at which the event occurred. ID of the workspace associated with the event. ## `acs_user.deleted` An [access system user](/low-level-apis/access-systems/user-management) was deleted. ```json Example webhook payload theme={null} { "acs_system_id": "00000000-0000-0000-0000-000000000000", "acs_user_id": "00000000-0000-0000-0000-000000000000", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "An [access system user](/low-level-apis/access-systems/user-management) was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "acs_user.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access system. ID of the affected access system user. ID of the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `acs_user.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an ACS User Source: https://docs.seam.co/api/acs/users/get /openapi.json post /acs/users/get Returns a specified [access system user](/low-level-apis/access-systems/user-management). You must include at least one request parameter. # List ACS Users Source: https://docs.seam.co/api/acs/users/list /openapi.json post /acs/users/list Returns a list of all [access system users](/low-level-apis/access-systems/user-management). # List ACS User-Accessible Entrances Source: https://docs.seam.co/api/acs/users/list_accessible_entrances /openapi.json post /acs/users/list_accessible_entrances Lists the [entrances](/api/acs/entrances/object) to which a specified [access system user](/low-level-apis/access-systems/user-management) has access. You must include at least one request parameter. # The ACS User Object Source: https://docs.seam.co/api/acs/users/object Learn how the acs_user object represents an individual—such as an employee or resident—who holds one or more credentials in an access control system. ## The acs\_user Object Represents a [user](/low-level-apis/access-systems/user-management) in an [access system](/low-level-apis/access-systems). An access system user typically refers to an individual who requires access, like an employee or resident. Each user can possess multiple credentials that serve as their keys or identifiers for access. The type of credential can vary widely. For example, in the Salto system, a user can have a PIN code, a mobile app account, and a fob. In other platforms, it is not uncommon for a user to have more than one of the same credential type, such as multiple key cards. Additionally, these credentials can have a schedule or validity period. For details about how to configure users in your access system, see the corresponding [system integration guide](/device-and-system-integration-guides#access-control-systems). ```json ACS User theme={null} { "access_schedule": { "ends_at": "2025-06-12T11:00:00.000Z", "starts_at": "2025-06-10T15:00:00.000Z" }, "acs_system_id": "62d3384f-267f-4a4a-a946-d35819ec9981", "acs_user_id": "6a5d9697-3cc4-436a-8165-4375ff424870", "connected_account_id": "c0175797-30f0-49f7-a228-2df115443ca7", "created_at": "2025-06-15T16:54:17.946482Z", "display_name": "Jane Doe", "email_address": "jane@example.com", "errors": [], "external_type": "salto_site_user", "external_type_display_name": "Salto site user", "full_name": "Jane Doe", "hid_acs_system_id": "2acbe47f-612c-422a-9205-7af292f74e7f", "is_managed": true, "is_suspended": false, "last_successful_sync_at": "2025-06-18T17:45:00.582Z", "pending_mutations": [ { "to": { "acs_access_group_id": "2c0fb4a0-2b42-4651-926e-1a10bedbf6ce" }, "from": { "acs_access_group_id": "f1e2d3c4-b5a6-4d7c-8e9f-0a1b2c3d4e5f" }, "message": "This user's access membership is being updated.", "created_at": "2025-06-18T17:57:01.867Z", "mutation_code": "updating_group_membership" } ], "phone_number": "+1555551000", "user_identity_email_address": "jane@example.com", "user_identity_full_name": "Jane Doe", "user_identity_id": "a23b3e02-e394-4e5f-b21c-b366b8bc0dd3", "user_identity_phone_number": "+1555551000", "warnings": [], "workspace_id": "8d4868e3-2f95-4f33-8689-19420b3101cd" } ``` *** ## Properties `starts_at` and `ends_at` timestamps for the [access system user's](/low-level-apis/access-systems/user-management) access. Date and time at which the user's access ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Date and time at which the user's access starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [access system](/low-level-apis/access-systems) that contains the [access system user](/low-level-apis/access-systems/user-management). ID of the [access system user](/low-level-apis/access-systems/user-management). The ID of the connected account that is associated with the [access system user](/low-level-apis/access-systems/user-management). Date and time at which the [access system user](/low-level-apis/access-systems/user-management) was created. Display name for the [access system user](/low-level-apis/access-systems/user-management). **Deprecated**. use email\_address. The email. Email address of the [access system user](/low-level-apis/access-systems/user-management). Errors associated with the [access system user](/low-level-apis/access-systems/user-management). Brand-specific terminology for the [access system user](/low-level-apis/access-systems/user-management) type. Display name that corresponds to the brand-specific terminology for the [access system user](/low-level-apis/access-systems/user-management) type. Full name of the [access system user](/low-level-apis/access-systems/user-management). ID of the HID access control system associated with the user. Indicates whether Seam manages the access system user. Indicates whether the [access system user](/low-level-apis/access-systems/user-management) is currently [suspended](/low-level-apis/access-systems/user-management/suspending-and-unsuspending-users). Pending mutations associated with the [access system user](/low-level-apis/access-systems/user-management). Seam is in the process of pushing these mutations to the integrated access system. Phone number of the [access system user](/low-level-apis/access-systems/user-management) in E.164 format (for example, `+15555550100`). Salto KS-specific metadata associated with the [access system user](/low-level-apis/access-systems/user-management). Indicates whether the user holds an active subscription slot on the Salto KS site. Only subscribed users can unlock doors and count against the site's user-subscription limit. A user may not be subscribed because their access schedule has not started or has ended, the site has reached its subscription limit, or they were manually unsubscribed. This is distinct from `is_suspended`, which reflects whether the user has been explicitly blocked. Salto Space-specific metadata associated with the [access system user](/low-level-apis/access-systems/user-management). Indicates whether AuditOpenings is enabled for the user in the Salto Space access system. User ID in the Salto Space access system. Email address of the user identity associated with the [access system user](/low-level-apis/access-systems/user-management). Full name of the user identity associated with the [access system user](/low-level-apis/access-systems/user-management). ID of the user identity associated with the [access system user](/low-level-apis/access-systems/user-management). Phone number of the user identity associated with the [access system user](/low-level-apis/access-systems/user-management) in E.164 format (for example, `+15555550100`). Warnings associated with the [access system user](/low-level-apis/access-systems/user-management). ID of the workspace that contains the [access system user](/low-level-apis/access-systems/user-management). # Remove an ACS User from an Access Group Source: https://docs.seam.co/api/acs/users/remove_from_access_group /openapi.json post /acs/users/remove_from_access_group Removes a specified [access system user](/low-level-apis/access-systems/user-management) from a specified [access group](/low-level-apis/access-systems/user-management/assigning-users-to-access-groups). # Revoke ACS User Access to All Entrances Source: https://docs.seam.co/api/acs/users/revoke_access_to_all_entrances /openapi.json post /acs/users/revoke_access_to_all_entrances Revokes access to all [entrances](/api/acs/entrances/object) for a specified [access system user](/low-level-apis/access-systems/user-management). You must include at least one request parameter. # Suspend an ACS User Source: https://docs.seam.co/api/acs/users/suspend /openapi.json post /acs/users/suspend [Suspends](/low-level-apis/access-systems/user-management/suspending-and-unsuspending-users#suspend-an-acs-user) a specified [access system user](/low-level-apis/access-systems/user-management). Suspending an access system user revokes their access temporarily. To restore an access system user's access, you can [unsuspend](/api/acs/users/unsuspend) them. You must include at least one request parameter. # Unsuspend an ACS User Source: https://docs.seam.co/api/acs/users/unsuspend /openapi.json post /acs/users/unsuspend [Unsuspends](/low-level-apis/access-systems/user-management/suspending-and-unsuspending-users#unsuspend-an-acs-user) a specified suspended [access system user](/low-level-apis/access-systems/user-management). While [suspending an access system user](/api/acs/users/suspend) revokes their access temporarily, unsuspending the access system user restores their access. You must include at least one request parameter. # Update an ACS User Source: https://docs.seam.co/api/acs/users/update /openapi.json post /acs/users/update Updates the properties of a specified [access system user](/low-level-apis/access-systems/user-management). You must include at least one request parameter. # Action Attempt Events Source: https://docs.seam.co/api/action_attempts/events Webhook events that Seam emits for the Action Attempt resource, with example payloads and properties. ## `action_attempt.lock_door.succeeded` A lock door action attempt succeeded. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A lock door action attempt succeeded.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.lock_door.succeeded", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.lock_door.succeeded` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.lock_door.failed` A lock door action attempt failed. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A lock door action attempt failed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.lock_door.failed", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.lock_door.failed` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.unlock_door.succeeded` An unlock door action attempt succeeded. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An unlock door action attempt succeeded.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.unlock_door.succeeded", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.unlock_door.succeeded` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.unlock_door.failed` An unlock door action attempt failed. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An unlock door action attempt failed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.unlock_door.failed", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.unlock_door.failed` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.simulate_keypad_code_entry.succeeded` A simulate keypad code entry action attempt succeeded. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A simulate keypad code entry action attempt succeeded.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.simulate_keypad_code_entry.succeeded", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.simulate_keypad_code_entry.succeeded` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.simulate_keypad_code_entry.failed` A simulate keypad code entry action attempt failed. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A simulate keypad code entry action attempt failed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.simulate_keypad_code_entry.failed", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.simulate_keypad_code_entry.failed` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.simulate_manual_lock_via_keypad.succeeded` A simulate manual lock via keypad action attempt succeeded. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A simulate manual lock via keypad action attempt succeeded.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.simulate_manual_lock_via_keypad.succeeded", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.simulate_manual_lock_via_keypad.succeeded` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. ## `action_attempt.simulate_manual_lock_via_keypad.failed` A simulate manual lock via keypad action attempt failed. ```json Example webhook payload theme={null} { "action_attempt_id": "00000000-0000-0000-0000-000000000000", "action_type": "", "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A simulate manual lock via keypad action attempt failed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "action_attempt.simulate_manual_lock_via_keypad.failed", "occurred_at": "2025-01-01T00:00:00.000Z", "status": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected action attempt. Type of the action. ID of the connected account associated with the action attempt, if applicable. Date and time at which the event was created. ID of the device associated with the action attempt, if applicable. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `action_attempt.simulate_manual_lock_via_keypad.failed` Date and time at which the event occurred. Status of the action. ID of the workspace associated with the event. # Get an Action Attempt Source: https://docs.seam.co/api/action_attempts/get /openapi.json post /action_attempts/get Returns a specified [action attempt](/core-concepts/action-attempts). # List Action Attempts Source: https://docs.seam.co/api/action_attempts/list /openapi.json post /action_attempts/list Returns a list of the [action attempts](/core-concepts/action-attempts) that you specify as an array of `action_attempt_id`s. # The Action Attempt Object Source: https://docs.seam.co/api/action_attempts/object Learn how the action_attempt object tracks an attempt to perform an action against a device, letting you monitor its status and final result. ## The action\_attempt Object Represents an attempt to perform an action against a device. ```json Action Attempt theme={null} { "action_attempt_id": "3f2b1c8d-1b5e-4f8c-9c7d-9a8b7c6d5e4f", "action_type": "LOCK_DOOR", "error": null, "result": {}, "status": "success" } ``` *** ## Properties ID of the action attempt. Status of the action attempt. * `pending` * `success` * `error` Type of the action attempt. * `LOCK_DOOR` * `UNLOCK_DOOR` * `SCAN_CREDENTIAL` * `ENCODE_CREDENTIAL` * `SCAN_TO_ASSIGN_CREDENTIAL` * `ASSIGN_CREDENTIAL` * `RESET_SANDBOX_WORKSPACE` * `SET_FAN_MODE` * `SET_HVAC_MODE` * `ACTIVATE_CLIMATE_PRESET` * `SIMULATE_KEYPAD_CODE_ENTRY` * `SIMULATE_MANUAL_LOCK_VIA_KEYPAD` * `PUSH_THERMOSTAT_PROGRAMS` * `CONFIGURE_AUTO_LOCK` Error associated with the action attempt. Null for pending and successful action attempts. Result of the action attempt. Null for pending and errored action attempts. # Authentication Source: https://docs.seam.co/api/authentication Learn how to authenticate with the Seam API by exporting your API key as an environment variable that the Seam client libraries pick up automatically. Export your API key as an environment variable. Seam client libraries automatically pick up this exported key. For example: ``` $ export SEAM_API_KEY=seam_test2bMS_94SrGUXuNR2JmJkjtvBQDg5c ``` Next, run the following code to confirm that you are correctly authenticated: **Code:** ```javascript theme={null} import { Seam } from 'seam' const seam = new Seam() // Seam automatically uses your exported SEAM_API_KEY. const checkAuth = async () => { const workspace = await seam.workspaces.get() console.log(workspace) } checkAuth() ``` **Output:** ```json theme={null} { workspace_id: '00000000-0000-0000-0000-000000000000', name: 'Sandbox', company_name: 'Acme', connect_partner_name: 'Acme', is_sandbox": true } ``` **Code:** ```bash theme={null} curl -X 'POST' \ 'https://connect.getseam.com/workspaces/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{}' ``` **Output:** ```json theme={null} { "workspace": { "workspace_id": "00000000-0000-0000-0000-000000000000", "name": "Sandbox", "company_name": "Acme", "connect_partner_name": "Acme", "is_sandbox": true }, "ok": true } ``` **Code:** ```python theme={null} from seam import Seam seam = Seam() # Seam automatically uses your exported SEAM_API_KEY. workspace = seam.workspaces.get() pprint(workspace) ``` **Output:** ``` Workspace( workspace_id='00000000-0000-0000-0000-000000000000', name='Sandbox', company_name='Acme', connect_partner_name='Acme', is_sandbox=True ) ``` **Code:** ```ruby theme={null} require "seam" seam = Seam.new() # Seam automatically uses your exported SEAM_API_KEY. workspace = seam.workspaces.get() puts workspace.inspect ``` **Output:** ``` < Seam::Workspace:0x0070328 workspace_id="00000000-0000-0000-0000-000000000000" name="Sandbox" company_name="Acme" connect_partner_name="Acme" is_sandbox=true > ``` **Code:** ```php theme={null} workspaces->get(); echo json_encode($workspace, JSON_PRETTY_PRINT); ``` **Output:** ```json theme={null} { "workspace_id": "00000000-0000-0000-0000-000000000000", "name": "Sandbox", "company_name": "Acme", "connect_partner_name": "Acme", "is_sandbox": true } ``` **Code:** ```csharp theme={null} using Seam.Client; var seam = new SeamClient(apiToken: SEAM_API_KEY); var workspace = seam.Workspaces.Get(); Console.WriteLine(workspace); ``` **Output:** ```json theme={null} { "workspace_id": "00000000-0000-0000-0000-000000000000", "name": "Sandbox", "company_name": "Acme", "connect_partner_name": "Acme", "is_sandbox": true } ``` # Create a Client Session Source: https://docs.seam.co/api/client_sessions/create /openapi.json post /client_sessions/create Creates a new [client session](/core-concepts/authentication/client-session-tokens). # Delete a Client Session Source: https://docs.seam.co/api/client_sessions/delete /openapi.json post /client_sessions/delete Deletes a [client session](/core-concepts/authentication/client-session-tokens). # Client Session Events Source: https://docs.seam.co/api/client_sessions/events Webhook events that Seam emits for the Client Session resource, with example payloads and properties. ## `client_session.deleted` A client session was deleted. ```json Example webhook payload theme={null} { "client_session_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A client session was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "client_session.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected client session. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `client_session.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. # Get a Client Session Source: https://docs.seam.co/api/client_sessions/get /openapi.json post /client_sessions/get Returns a specified [client session](/core-concepts/authentication/client-session-tokens). # Get or Create a Client Session Source: https://docs.seam.co/api/client_sessions/get_or_create /openapi.json post /client_sessions/get_or_create Returns a [client session](/core-concepts/authentication/client-session-tokens) with specific characteristics or creates a new client session with these characteristics if it does not yet exist. # Grant Access to a Client Session Source: https://docs.seam.co/api/client_sessions/grant_access /openapi.json post /client_sessions/grant_access Grants a [client session](/core-concepts/authentication/client-session-tokens) access to one or more resources, such as [Connect Webviews](/core-concepts/connect-webviews), [user identities](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity), and so on. You must include at least one request parameter. # List Client Sessions Source: https://docs.seam.co/api/client_sessions/list /openapi.json post /client_sessions/list Returns a list of all [client sessions](/core-concepts/authentication/client-session-tokens). # The Client Session Object Source: https://docs.seam.co/api/client_sessions/object Learn how the client_session object restricts your users to their own devices using a custom user_identifier_key that scopes Seam API results. ## The client\_session Object Represents a [client session](/core-concepts/authentication/client-session-tokens). If you want to restrict your users' access to their own devices, use client sessions. You create each client session with a custom `user_identifier_key`. Normally, the `user_identifier_key` is a user ID that your application provides. When calling the Seam API from your backend using an API key, you can pass the `user_identifier_key` as a parameter to limit results to the associated client session. For example, `/devices/list?user_identifier_key=123` only returns devices associated with the client session created with the `user_identifier_key` `123`. A client session has a token that you can use with the Seam JavaScript SDK to make requests from the client (browser) directly to the Seam API. The token restricts the user's access to only the devices that they own. See also [Get Started with React](/ui-components/overview/getting-started-with-seam-components/get-started-with-react-components-and-client-session-tokens). ```json Client Session theme={null} { "client_session_id": "c2cbd177-1ace-414b-bb1e-9f129e4a05c1", "connect_webview_ids": [ "550e8400-e29b-41d4-a716-446655440000" ], "connected_account_ids": [ "f47ac10b-58cc-4372-a567-0e02b2c3d479" ], "created_at": "2025-06-15T16:54:17.946309Z", "customer_id": "77eccc4e-c8bc-4c7d-b83c-cb853ed3bade", "device_count": 1, "expires_at": "2025-06-17T16:54:17.946309Z", "token": "seam_cst1891oqCmB_6dBwV8PJ2Fsoe9dWYVyMfVHq", "user_identifier_key": "user_id_1", "user_identity_id": "a6e93f84-565e-47d7-8908-1ca71ada373c", "user_identity_ids": [ "a6e93f84-565e-47d7-8908-1ca71ada373c" ], "workspace_id": "b887bf84-9849-4454-a562-cf84293d9781" } ``` *** ## Properties ID of the client session. IDs of the [Connect Webviews](/core-concepts/connect-webviews) associated with the [client session](/core-concepts/authentication/client-session-tokens). IDs of the [connected accounts](/core-concepts/connected-accounts) associated with the [client session](/core-concepts/authentication/client-session-tokens). Date and time at which the [client session](/core-concepts/authentication/client-session-tokens) was created. Customer key associated with the [client session](/core-concepts/authentication/client-session-tokens). Number of devices associated with the [client session](/core-concepts/authentication/client-session-tokens). Date and time at which the [client session](/core-concepts/authentication/client-session-tokens) expires. Client session token associated with the [client session](/core-concepts/authentication/client-session-tokens). Your user ID for the user associated with the [client session](/core-concepts/authentication/client-session-tokens). ID of the [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) associated with the client session. **Deprecated**. Use `user_identity_id` instead. IDs of the [user identities](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) associated with the client session. ID of the workspace associated with the client session. # Revoke a Client Session Source: https://docs.seam.co/api/client_sessions/revoke /openapi.json post /client_sessions/revoke Revokes a [client session](/core-concepts/authentication/client-session-tokens). Note that [deleting a client session](/api/client_sessions/delete) is a separate action. # Create a Connect Webview Source: https://docs.seam.co/api/connect_webviews/create /openapi.json post /connect_webviews/create Creates a new [Connect Webview](/core-concepts/connect-webviews). To enable a user to connect their devices or systems to Seam, they must sign in to their device or system account. To enable a user to sign in, you create a `connect_webview`. After creating the Connect Webview, you receive a URL that you can use to display the visual component of this Connect Webview for your user. You can open an iframe or new window to display the Connect Webview. You should make a new `connect_webview` for each unique login request. Each `connect_webview` tracks the user that signed in with it. You receive an error if you reuse a Connect Webview for the same user twice or if you use the same Connect Webview for multiple users. See also: [Connect Webview Process](/core-concepts/connect-webviews/connect-webview-process). # Delete a Connect Webview Source: https://docs.seam.co/api/connect_webviews/delete /openapi.json post /connect_webviews/delete Deletes a [Connect Webview](/core-concepts/connect-webviews). You do not need to delete a Connect Webview once a user completes it. Instead, you can simply ignore completed Connect Webviews. # Connect Webview Events Source: https://docs.seam.co/api/connect_webviews/events Webhook events that Seam emits for the Connect Webview resource, with example payloads and properties. ## `connect_webview.login_succeeded` A Connect Webview login succeeded. ```json Example webhook payload theme={null} { "connect_webview_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "event_description": "A Connect Webview login succeeded.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connect_webview.login_succeeded", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Connect Webview. Custom metadata of the connected account; present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with this connect webview, if any. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connect_webview.login_succeeded` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connect_webview.login_failed` A Connect Webview login failed. ```json Example webhook payload theme={null} { "connect_webview_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A Connect Webview login failed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connect_webview.login_failed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the affected Connect Webview. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connect_webview.login_failed` Date and time at which the event occurred. ID of the workspace associated with the event. # Get a Connect Webview Source: https://docs.seam.co/api/connect_webviews/get /openapi.json post /connect_webviews/get Returns a specified [Connect Webview](/core-concepts/connect-webviews). Unless you're using a `custom_redirect_url`, you should poll a newly-created `connect_webview` to find out if the user has signed in or to get details about what devices they've connected. # List Connect Webviews Source: https://docs.seam.co/api/connect_webviews/list /openapi.json post /connect_webviews/list Returns a list of all [Connect Webviews](/core-concepts/connect-webviews). # The Connect Webview Object Source: https://docs.seam.co/api/connect_webviews/object Learn how the connect_webview object embeds a client-side flow that walks your users through linking their device or system accounts to Seam. ## The connect\_webview Object Represents a [Connect Webview](/core-concepts/connect-webviews). Connect Webviews are fully-embedded client-side components that you add to your app. Your users interact with your embedded Connect Webviews to link their IoT device or system accounts to Seam. That is, Connect Webviews walk your users through the process of logging in to their device or system accounts. Seam handles all the authentication steps, and—once your user has completed the authorization through your app—you can access and control their devices or systems using the Seam API. Connect Webviews perform credential validation, multifactor authentication (when applicable), and error handling for each brand that Seam supports. Further, Connect Webviews work across all modern browsers and platforms, including Chrome, Safari, and Firefox. To enable a user to connect their device or system account to Seam through your app, first create a `connect_webview`. Once created, this `connect_webview` includes a URL that you can use to open an [iframe](https://www.w3schools.com/html/html_iframe.asp) or new window containing the Connect Webview for your user. When you create a Connect Webview, specify the desired provider category key in the `provider_category` parameter. Alternately, to specify a list of providers explicitly, use the `accepted_providers` parameter with a list of device provider keys. To list all providers within a category, use `/devices/list_device_providers` with the desired `provider_category` filter. To list all provider keys, use `/devices/list_device_providers` with no filters. ```json Connect Webview theme={null} { "accepted_capabilities": [ "lock", "thermostat" ], "accepted_devices": [], "accepted_providers": [ "schlage", "kwikset", "yale", "smartthings" ], "any_device_allowed": false, "any_provider_allowed": false, "authorized_at": "2025-06-14T16:54:17.946323Z", "automatically_manage_new_devices": true, "connect_webview_id": "c4c30885-ec87-4b31-8d7b-9bc0678fa028", "connected_account_id": "5d2fe05f-4f5b-4b91-909c-96e2601dccbe", "created_at": "2025-06-14T16:54:17.946323Z", "custom_metadata": { "id": "internalId1" }, "custom_redirect_failure_url": "https://example.com/failure-redirect", "custom_redirect_url": "https://example.com/redirect", "device_selection_mode": "single", "login_successful": true, "selected_provider": "schlage", "status": "authorized", "url": "https://connect.getseam.com/connect_webviews/view?connect_webview_id=12345678-1234-1234-1234-123456789012&auth_token=2r2Rn8V5QUtxE79gNsTmLK58KkuqrwU8d", "wait_for_device_creation": true, "workspace_id": "9db95105-e77d-4577-b1b7-0a20b360d5e0" } ``` *** ## Properties High-level device capabilities that the Connect Webview can accept. When creating a Connect Webview, you can specify the types of devices that it can connect to Seam. If you do not set custom `accepted_capabilities`, Seam uses a default set of `accepted_capabilities` for each provider. For example, if you create a Connect Webview that accepts SmartThing devices, without specifying `accepted_capabilities`, Seam accepts only SmartThings locks. To connect SmartThings thermostats and locks to Seam, create a Connect Webview and include both `thermostat` and `lock` in the `accepted_capabilities`. List of accepted [provider keys](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-brands-to-display-in-your-connect-webviews). Indicates whether any provider is allowed. Date and time at which the user authorized (through the Connect Webview) the management of their devices. Indicates whether Seam should [import all new devices](/core-concepts/connect-webviews/customizing-connect-webviews#automatically_manage_new_devices) for the connected account to make these devices available for use and management by the Seam API. ID of the Connect Webview. ID of the connected account associated with the Connect Webview. Date and time at which the Connect Webview was created. Set of key:value pairs. Adding custom metadata to a resource, such as a [Connect Webview](/core-concepts/connect-webviews/attaching-custom-data-to-the-connect-webview), [connected account](/core-concepts/connected-accounts/adding-custom-metadata-to-a-connected-account), or [device](/core-concepts/devices/adding-custom-metadata-to-a-device), enables you to store custom information, like customer details or internal IDs from your application. URL to which the Connect Webview should redirect when an unexpected error occurs. URL to which the Connect Webview should redirect when the user successfully pairs a device or system. If you do not set the `custom_redirect_failure_url`, the Connect Webview redirects to the `custom_redirect_url` when an unexpected error occurs. The customer key associated with this webview, if any. Device selection mode of the Connect Webview. Supported values: `none`, `single`, `multiple`. Indicates whether the user logged in successfully using the Connect Webview. Selected provider of the Connect Webview, one of the [provider keys](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-brands-to-display-in-your-connect-webviews). Status of the Connect Webview. `authorized` indicates that the user has successfully logged into their device or system account, thereby completing the Connect Webview. URL for the Connect Webview. You use the URL to display the Connect Webview flow to your user. Indicates whether Seam should [finish syncing all devices](/core-concepts/connect-webviews/customizing-connect-webviews#wait_for_device_creation) in a newly-connected account before completing the associated Connect Webview. ID of the workspace that contains the Connect Webview. # Delete a Connected Account Source: https://docs.seam.co/api/connected_accounts/delete /openapi.json post /connected_accounts/delete Deletes a specified [connected account](/core-concepts/connected-accounts). Deleting a connected account triggers a `connected_account.deleted` event and removes the connected account and all data associated with the connected account from Seam, including devices, events, access codes, and so on. For every deleted resource, Seam sends a corresponding deleted event, but the resource is not deleted from the provider. For example, if you delete a connected account with a device that has an access code, Seam sends a `connected_account.deleted` event, a `device.deleted` event, and an `access_code.deleted` event, but Seam does not remove the access code from the device. # Connected Account Errors and Warnings Source: https://docs.seam.co/api/connected_accounts/errors Errors and warnings that Seam reports on the Connected Account resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "account_disconnected", "message": "Indicates that the account is disconnected.", "created_at": "2025-01-01T00:00:00.000Z", "is_bridge_error": true, "is_connected_account_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates whether the error is related to [Seam Bridge](/capability-guides/seam-bridge). Indicates whether the error is related specifically to the connected account. Salto KS metadata associated with the connected account that has an error. ### `account_disconnected` Indicates that the account is disconnected. *** ### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if the Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** ### `dormakaba_sites_disconnected` Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. *** ### `salto_ks_subscription_limit_exceeded` Indicates that the maximum number of users allowed for the site has been reached. This means that new access codes cannot be created. Contact Salto support to increase the user limit. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "scheduled_maintenance_window", "message": "Indicates that scheduled downtime is planned for the connected account.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. Salto KS metadata associated with the connected account that has a warning. ### `account_reauthorization_requested` Indicates that the Connected Account requires reauthorization using a new Connect Webview. The account is still connected, but cannot access new features. Delaying reauthorization too long will eventually cause the Connected Account to become disconnected. *** ### `being_deleted` Indicates that the connected account is currently being deleted. All devices, access codes, and other resources associated with this account are in the process of being removed from Seam. *** ### `dormakaba_sites_unapproved` Indicates that one or more dormakaba sites associated with the connected account are not approved. Contact [support@getseam.com](mailto:support@getseam.com) to finish setting up your account. *** ### `provider_service_unavailable` Indicates that the connected account's provider service is temporarily unavailable. Seam will automatically retry and reconnect when the service becomes available again. *** ### `salto_ks_subscription_limit_almost_reached` Indicates that the Salto KS site has exceeded 80% of the maximum number of allowed users. Increase your subscription limit or delete some users from your site. *** ### `scheduled_maintenance_window` Indicates that scheduled downtime is planned for the connected account. *** ### `setup_required` Indicates that the connected account requires additional setup before it can be fully operational. Follow the instructions in the warning message to complete the setup. *** ### `unknown_issue_with_connected_account` Indicates that an unknown issue occurred while syncing the state of the connected account with the provider. This issue may affect the proper functioning of one or more resources in the account. *** # Connected Account Events Source: https://docs.seam.co/api/connected_accounts/events Webhook events that Seam emits for the Connected Account resource, with example payloads and properties. ## `connected_account.connected` A connected account was connected for the first time or was reconnected after being disconnected. ```json Example webhook payload theme={null} { "connect_webview_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "event_description": "A connected account was connected for the first time or was reconnected after being disconnected.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.connected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the Connect Webview associated with the event. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the affected connected account. Date and time at which the event was created. The customer key associated with this connected account, if any. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.connected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.created` A connected account was created. ```json Example webhook payload theme={null} { "connect_webview_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A connected account was created.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.created", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the Connect Webview associated with the event. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the affected connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.created` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.successful_login` A connected account had a successful login using a Connect Webview. ```json Example webhook payload theme={null} { "connect_webview_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A connected account had a successful login using a Connect Webview.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.successful_login", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the Connect Webview associated with the event. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the affected connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.successful_login` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.disconnected` A connected account was disconnected. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A connected account was disconnected.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.disconnected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the affected connected account. Warnings associated with the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.disconnected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.completed_first_sync` A connected account completed the first sync with Seam, and the corresponding devices or systems are now available. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A connected account completed the first sync with Seam, and the corresponding devices or systems are now available.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.completed_first_sync", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the affected connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.completed_first_sync` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.deleted` A connected account was deleted. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "event_description": "A connected account was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the affected connected account. Date and time at which the event was created. The customer key associated with this connected account, if any. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.completed_first_sync_after_reconnection` A connected account completed the first sync after reconnection with Seam, and the corresponding devices or systems are now available. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A connected account completed the first sync after reconnection with Seam, and the corresponding devices or systems are now available.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.completed_first_sync_after_reconnection", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the affected connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.completed_first_sync_after_reconnection` Date and time at which the event occurred. ID of the workspace associated with the event. ## `connected_account.reauthorization_requested` A connected account requires reauthorization using a new Connect Webview. The account is still connected, but cannot access new features. Delaying reauthorization too long will eventually cause the Connected Account to become disconnected. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "event_description": "A connected account requires reauthorization using a new Connect Webview. The account is still connected, but cannot access new features. Delaying reauthorization too long will eventually cause the Connected Account to become disconnected.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "connected_account.reauthorization_requested", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the affected connected account. Warnings associated with the connected account. Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `connected_account.reauthorization_requested` Date and time at which the event occurred. ID of the workspace associated with the event. # Get a Connected Account Source: https://docs.seam.co/api/connected_accounts/get /openapi.json post /connected_accounts/get Returns a specified [connected account](/core-concepts/connected-accounts). You must include at least one request parameter. # List Connected Accounts Source: https://docs.seam.co/api/connected_accounts/list /openapi.json post /connected_accounts/list Returns a list of all [connected accounts](/core-concepts/connected-accounts). # The Connected Account Object Source: https://docs.seam.co/api/connected_accounts/object Learn how the connected_account object represents an external third-party account your user has authorized Seam to access, such as an August account. ## The connected\_account Object Represents a [connected account](/core-concepts/connected-accounts). A connected account is an external third-party account to which your user has authorized Seam to get access, for example, an August account with a list of door locks. ```json Connected Account theme={null} { "account_type": "salto_space", "account_type_display_name": "Salto Space", "display_name": "j**n@example.com", "automatically_manage_new_devices": true, "connected_account_id": "a289aa54-5488-4707-9a4b-eeea4edf311d", "created_at": "2025-06-15T16:54:17.946329Z", "custom_metadata": { "id": "internalId1" }, "errors": [], "user_identifier": { "api_url": "https://example.com/api", "email": "jane_doe@example.com", "exclusive": true, "phone": "+1555551004", "username": "jane_doe" }, "warnings": [], "accepted_capabilities": [ "lock" ] } ``` *** ## Properties List of capabilities that were accepted during the account connection process. Type of connected account. Display name for the connected account type. Indicates whether Seam should [import all new devices](/core-concepts/connect-webviews/customizing-connect-webviews#automatically_manage_new_devices) for the connected account to make these devices available for management by the Seam API. ID of the connected account. Date and time at which the connected account was created. Set of key:value pairs. Adding custom metadata to a resource, such as a [Connect Webview](/core-concepts/connect-webviews/attaching-custom-data-to-the-connect-webview), [connected account](/core-concepts/connected-accounts/adding-custom-metadata-to-a-connected-account), or [device](/core-concepts/devices/adding-custom-metadata-to-a-device), enables you to store custom information, like customer details or internal IDs from your application. Your unique key for the customer associated with this connected account. Default reservation check-in time for this connected account, as `HH:mm` (24-hour). Sourced from the connector configuration — set during the connect\_webview for providers like Lodgify whose API does not expose check-in times. Default reservation check-out time for this connected account, as `HH:mm` (24-hour). Sourced from the connector configuration. Display name for the connected account. Errors associated with the connected account. For iCal connected accounts, the platform that produced the feed (for example, `airbnb`, `vrbo`, or `booking`), or `unknown` when it could not be determined. Intended for rendering the source platform's logo. For iCal connected accounts, the feed URL for the connection. Sourced from the connector configuration. Logo URL for the connected account provider. IANA time zone (e.g. America/Los\_Angeles) for this connected account. Sourced from the connector configuration. **Deprecated**. Use `display_name` instead. User identifier associated with the connected account. API URL for the user identifier associated with the connected account. Email address of the user identifier associated with the connected account. Indicates whether the user identifier associated with the connected account is exclusive. Phone number of the user identifier associated with the connected account. Username of the user identifier associated with the connected account. Warnings associated with the connected account. # Simulate Connected Account Disconnection Source: https://docs.seam.co/api/connected_accounts/simulate/disconnect /openapi.json post /connected_accounts/simulate/disconnect Simulates a connected account becoming disconnected from Seam. Only applicable for [sandbox workspaces](/core-concepts/workspaces#sandbox-workspaces). # Sync a Connected Account Source: https://docs.seam.co/api/connected_accounts/sync /openapi.json post /connected_accounts/sync Request a [connected account](/core-concepts/connected-accounts) sync attempt for the specified `connected_account_id`. # Update a Connected Account Source: https://docs.seam.co/api/connected_accounts/update /openapi.json post /connected_accounts/update Updates a [connected account](/core-concepts/connected-accounts). # Create Customer Portal Source: https://docs.seam.co/api/customers/create_portal /openapi.json post /customers/create_portal Creates a new customer portal magic link with configurable features. # Delete Customer Data Source: https://docs.seam.co/api/customers/delete_data /openapi.json post /customers/delete_data Deletes customer data including resources like spaces, properties, rooms, users, etc. This will delete the partner resources and any related Seam resources (user identities, access grants, spaces). # The Customer Object Source: https://docs.seam.co/api/customers/object Learn how the customer_portal object provides a hosted, customizable interface for managing device access that you can share or embed in your product. ## The customer\_portal Object Represents a Customer Portal. Customer Portal is a hosted, customizable interface for managing device access. It enables you to embed secure, pre-authenticated access flows into your product—either by sharing a link with users or embedding a view in an iframe. With Customer Portal, you no longer need to build out frontend experiences for physical access, thermostats, and sensors. Instead, you can ship enterprise-grade access control experiences in a fraction of the time, while maintaining your product's branding and user experience. Seam hosts these flows, handling everything from account connection and device mapping to full-featured device control. ```json Customer Portal theme={null} { "created_at": "2025-06-16T16:54:17.946594Z", "customer_key": "My Company", "expires_at": "2025-06-17T16:54:17.946594Z", "url": "https://se.am/1234", "workspace_id": "67c58f1f-f148-4415-a63c-dc6c145c6b91" } ``` *** ## Properties Date and time at which the customer portal link was created. Customer key for the customer portal. Date and time at which the customer portal link expires. URL for the customer portal. ID of the workspace associated with the customer portal. # Push Customer Data Source: https://docs.seam.co/api/customers/push_data /openapi.json post /customers/push_data Pushes customer data including resources like spaces, properties, rooms, users, etc. # Device Errors and Warnings Source: https://docs.seam.co/api/devices/errors Errors and warnings that Seam reports on the Device resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "account_disconnected", "message": "Indicates that the account is disconnected.", "created_at": "2025-01-01T00:00:00.000Z", "is_connected_account_error": true, "is_device_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates whether the error is related to [Seam Bridge](/capability-guides/seam-bridge). Indicates that the error is a [connected account](/api/connected_accounts/object) error. Indicates that the error is not a device error. ### `device_disconnected` Indicates that the device is disconnected. *** ### `device_offline` Indicates that the device is offline. *** ### `device_removed` Indicates that the device has been removed. *** ### `hub_disconnected` Indicates that the hub is disconnected. *** ### `missing_device_credentials` Indicates that device credentials are missing. *** ### `subscription_required` Indicates that a subscription is required to connect. *** ### Access Codes #### `empty_backup_access_code_pool` Indicates that the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. *** ### Locks #### `august_lock_not_authorized` Indicates that the user is not authorized to use the August lock. *** ### Thermostats #### `auxiliary_heat_running` Indicates that the auxiliary heat is running. *** ### Connected Account These errors are inherited from the [Connected Account](/api/connected_accounts/errors) resource. When they are set on the parent connected account, they are propagated to this resource's errors list. #### `account_disconnected` Indicates that the account is disconnected. *** #### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if the Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** #### `dormakaba_sites_disconnected` Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. *** #### `insufficient_permissions` Indicates that Seam's integration user does not have sufficient permissions on the provider's system to which this device belongs, so Seam cannot manage access codes or unlock the device. See the error message for specifics, then either reauthorize the connected account in Seam or grant the integration user the required permissions in the provider's system. *** #### `salto_ks_subscription_limit_exceeded` Indicates that the Salto site user limit has been reached. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "partial_backup_access_code_pool", "message": "Indicates that the backup access code is unhealthy.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. Number of active access codes on the device when the warning was set. Maximum number of active access codes supported by the device. ### `device_communication_degraded` Indicates that the device appears to be unresponsive. *** ### `device_has_flaky_connection` Indicates that the device has a flaky connection. *** ### `scheduled_maintenance_window` Indicates that a scheduled maintenance window has been detected. *** ### `third_party_integration_detected` Indicates that a third-party integration has been detected. *** ### Access Codes #### `many_active_backup_codes` Indicates that there are too many backup codes. *** #### `max_access_codes_reached` Indicates that the device has reached its maximum number of active access codes. Delete existing codes before creating new ones. *** #### `partial_backup_access_code_pool` Indicates that the backup access code is unhealthy. *** #### `privacy_mode` Indicates that the lock is in Privacy Mode. Access codes and remote unlock are blocked until Privacy Mode is disabled. *** #### `provider_issue` Indicates a provider-specific issue that may affect device functionality. *** #### `salto_ks_lock_access_code_support_removed` Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See [https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support](https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support) for troubleshooting steps. *** #### `salto_ks_office_mode` Indicates that the Salto KS lock is in Office Mode. Access Codes will not unlock doors. *** #### `salto_ks_privacy_mode` Indicates that the Salto KS lock is in Privacy Mode. Access Codes will not unlock doors. *** ### Locks #### `accessory_keypad_setup_required` Indicates that the accessory keypad exists, but is not linked to the Igloohome Bridge. Online access code programming will fail until the keypad is linked to the Igloohome Bridge in the Igloohome app. *** #### `hub_required_for_additional_capabilities` Indicates that a hub or relay must be connected to unlock additional capabilities such as remote unlock. *** #### `keynest_unsupported_locker` Indicates that the key is in a locker that does not support the access codes API. *** #### `lockly_time_zone_not_configured` Indicates that Seam detected that the Lockly device does not have a time zone configured. Time-bound codes may not work as expected. *** #### `power_saving_mode` Indicates that the device is in power saving mode and may have limited functionality. *** #### `salto_ks_subscription_limit_almost_reached` Indicates that the Salto KS site has exceeded 80% of the maximum number of allowed users. Increase your subscription limit or delete some users from your site. *** #### `time_zone_mismatch` Indicates that the device's configured time zone does not match its hardware UTC offset. Time-bound access codes may activate at the wrong local time. *** #### `time_zone_unknown` Indicates that Seam does not know the device's time zone. Set a time zone to enable time-bound access codes. *** #### `ttlock_lock_gateway_unlocking_not_enabled` Indicates that the Remote Unlock feature is not enabled in the settings." *** #### `ttlock_weak_gateway_signal` Indicates that the gateway signal is weak. *** #### `two_n_device_missing_timezone` Indicates that the 2N device does not have a time zone configured. Configure a time zone on the device to enable access codes. *** #### `ultraloq_time_zone_unknown` Indicates that Seam does not know the time zone of the Ultraloq device. Set a time zone to enable time-bound access codes. *** #### `unreliable_online_status` Indicates that the device may optimistically be reported as online because the provider does not reliably report its online status. *** ### Phones #### `unknown_issue_with_phone` Indicates that an unknown issue occurred while syncing the state of the phone with the provider. This issue may affect the proper functioning of the phone. *** ### Thermostats #### `temperature_threshold_exceeded` Indicates that the temperature threshold has been exceeded. *** # Device Events Source: https://docs.seam.co/api/devices/events Webhook events that Seam emits for the Device resource, with example payloads and properties. ## `device.connected` The status of a device changed from offline to online. That is, the `device.properties.online` property changed from `false` to `true`. Note that some devices operate entirely in offline mode, so Seam never emits a `device.connected` event for these devices. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "The status of a device changed from offline to online. That is, the `device.properties.online` property changed from `false` to `true`. Note that some devices operate entirely in offline mode, so Seam never emits a `device.connected` event for these devices.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.connected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.connected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.added` A device was added to Seam or was re-added to Seam after having been removed. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A device was added to Seam or was re-added to Seam after having been removed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.added", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.added` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.converted_to_unmanaged` A managed device was successfully converted to an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices). ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A managed device was successfully converted to an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices).", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.converted_to_unmanaged", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.converted_to_unmanaged` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.disconnected` The status of a device changed from online to offline. That is, the `device.properties.online` property changed from `true` to `false`. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "error_code": "account_disconnected", "event_description": "The status of a device changed from online to offline. That is, the `device.properties.online` property changed from `true` to `false`.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.disconnected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the event. Warnings associated with the connected account. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the affected device. Warnings associated with the device. Error code associated with the disconnection event, if any. Possible values: `account_disconnected`, `hub_disconnected`, `device_disconnected` Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.disconnected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.tampered` A device detected that it was tampered with, for example, opened or moved. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A device detected that it was tampered with, for example, opened or moved.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.tampered", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.tampered` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.low_battery` A device battery level dropped below the low threshold. ```json Example webhook payload theme={null} { "battery_level": 0, "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A device battery level dropped below the low threshold.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.low_battery", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Number in the range 0 to 1.0 indicating the amount of battery in the affected device, as reported by the device. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.low_battery` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.battery_status_changed` A device battery status changed since the last `battery_status_changed` event. ```json Example webhook payload theme={null} { "battery_level": 0, "battery_status": "critical", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A device battery status changed since the last `battery_status_changed` event.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.battery_status_changed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Number in the range 0 to 1.0 indicating the amount of battery in the affected device, as reported by the device. Battery status of the affected device, calculated from the numeric `battery_level` value. Possible values: `critical`, `low`, `good`, `full` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.battery_status_changed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.removed` A device was removed externally from the connected account. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A device was removed externally from the connected account.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.removed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.removed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.deleted` A device was deleted. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "device_name": "", "event_description": "A device was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Name of the deleted device, captured at deletion time. The device record no longer exists when this event fires, so the name is preserved here. Null when the device had no resolvable name. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.third_party_integration_detected` Seam detected that a device is using a third-party integration that will interfere with Seam device management. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "Seam detected that a device is using a third-party integration that will interfere with Seam device management.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.third_party_integration_detected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.third_party_integration_detected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.third_party_integration_no_longer_detected` Seam detected that a device is no longer using a third-party integration that was interfering with Seam device management. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "Seam detected that a device is no longer using a third-party integration that was interfering with Seam device management.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.third_party_integration_no_longer_detected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.third_party_integration_no_longer_detected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.salto.privacy_mode_activated` A [Salto device](/device-and-system-integration-guides/salto-locks) activated privacy mode. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [Salto device](/device-and-system-integration-guides/salto-locks) activated privacy mode.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.salto.privacy_mode_activated", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.salto.privacy_mode_activated` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.salto.privacy_mode_deactivated` A [Salto device](/device-and-system-integration-guides/salto-locks) deactivated privacy mode. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [Salto device](/device-and-system-integration-guides/salto-locks) deactivated privacy mode.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.salto.privacy_mode_deactivated", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.salto.privacy_mode_deactivated` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.connection_became_flaky` Seam detected a flaky device connection. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "Seam detected a flaky device connection.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.connection_became_flaky", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the event. Warnings associated with the connected account. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the affected device. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.connection_became_flaky` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.connection_stabilized` Seam detected that a previously-flaky device connection stabilized. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "Seam detected that a previously-flaky device connection stabilized.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.connection_stabilized", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.connection_stabilized` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.error.subscription_required` A third-party subscription is required to use all device features. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "A third-party subscription is required to use all device features.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.error.subscription_required", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the event. Warnings associated with the connected account. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the affected device. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.error.subscription_required` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.error.subscription_required.resolved` A third-party subscription is active or no longer required to use all device features. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A third-party subscription is active or no longer required to use all device features.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.error.subscription_required.resolved", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.error.subscription_required.resolved` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.accessory_keypad_connected` An accessory keypad was connected to a device. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An accessory keypad was connected to a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.accessory_keypad_connected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.accessory_keypad_connected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.accessory_keypad_disconnected` An accessory keypad was disconnected from a device. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "event_description": "An accessory keypad was disconnected from a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.accessory_keypad_disconnected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the event. Warnings associated with the connected account. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the affected device. Warnings associated with the device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.accessory_keypad_disconnected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.name_changed` The name of a device was changed. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "device_name": "", "event_description": "The name of a device was changed.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.name_changed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. The new name of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.name_changed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `camera.activated` A camera was activated, for example, by motion detection. ```json Example webhook payload theme={null} { "activation_reason": "motion_detected", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A camera was activated, for example, by motion detection.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "camera.activated", "image_url": "", "motion_sub_type": "human", "occurred_at": "2025-01-01T00:00:00.000Z", "video_url": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` The reason the camera was activated. Possible values: `motion_detected` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `camera.activated` URL to a thumbnail image captured at the time of activation. Sub-type of motion detected, if available. Possible values: `human`, `vehicle`, `package`, `other` Date and time at which the event occurred. URL to a short video clip captured at the time of activation. ID of the workspace associated with the event. ## `device.doorbell_rang` A doorbell button was pressed on a device. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A doorbell button was pressed on a device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.doorbell_rang", "image_url": "", "occurred_at": "2025-01-01T00:00:00.000Z", "video_url": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.doorbell_rang` URL to a thumbnail image captured at the time the doorbell was pressed. Date and time at which the event occurred. URL to a short video clip captured at the time the doorbell was pressed. ID of the workspace associated with the event. # Get a Device Source: https://docs.seam.co/api/devices/get /openapi.json post /devices/get Returns a specified [device](/core-concepts/devices). You must specify either `device_id` or `name`. You must include at least one request parameter. # List Devices Source: https://docs.seam.co/api/devices/list /openapi.json post /devices/list Returns a list of all [devices](/core-concepts/devices). # List Device Providers Source: https://docs.seam.co/api/devices/list_device_providers /openapi.json post /devices/list_device_providers Returns a list of all device providers. The information that this endpoint returns for each provider includes a set of [capability flags](/capability-guides/device-and-system-capabilities#capability-flags), such as `device_provider.can_remotely_unlock`. If at least one supported device from a provider has a specific capability, the corresponding capability flag is `true`. When you create a [Connect Webview](/core-concepts/connect-webviews), you can customize the providers—that is, the brands—that it displays. In the `/connect_webviews/create` request, include the desired set of device provider keys in the `accepted_providers` parameter. See also [Customize the Brands to Display in Your Connect Webviews](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-brands-to-display-in-your-connect-webviews). # The Device Object Source: https://docs.seam.co/api/devices/object Learn how the device object represents a smart lock, thermostat, sensor, or other device connected to Seam, including its properties and events. ## The device Object Represents a [device](/core-concepts/devices) that has been connected to Seam. ```json Lock Device theme={null} { "can_program_online_access_codes": true, "can_remotely_lock": true, "can_remotely_unlock": true, "capabilities_supported": [ "access_code", "lock" ], "connected_account_id": "8e3a4f1b-2c7d-4a9e-8b5f-3d2c1a0b9e8f", "created_at": "2025-03-27T02:08:16.418Z", "space_ids": [], "custom_metadata": { "id": "internalId1" }, "device_id": "a69569e1-133b-4a9d-b883-018641bfe543", "device_type": "schlage_lock", "display_name": "FRONT DOOR", "errors": [], "is_managed": true, "location": { "location_name": "Front Door", "timezone": "America/New_York" }, "nickname": "Front Door", "properties": { "appearance": { "name": "FRONT DOOR" }, "battery": { "level": 0.48, "status": "good" }, "battery_level": 0.48, "code_constraints": [ { "constraint_type": "name_length", "max_length": 9 } ], "has_native_entry_events": true, "image_alt_text": "Schlage Sense Smart Deadbolt with Camelot Trim, Front", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/devices/schlage_sense-smart-deadbolt-with-camelot-trim_front.png&q=75&w=128", "locked": false, "manufacturer": "schlage", "model": { "accessory_keypad_supported": false, "can_connect_accessory_keypad": false, "display_name": "Encode", "has_built_in_keypad": true, "manufacturer_display_name": "Schlage", "offline_access_codes_supported": false, "online_access_codes_supported": true }, "name": "FRONT DOOR", "offline_access_codes_enabled": false, "online": true, "online_access_codes_enabled": true, "schlage_metadata": { "device_id": "a69569e1-133b-4a9d-b883-018641bfe543", "device_name": "FRONT DOOR", "model": "Encode" }, "serial_number": "34000000000531e0", "supported_code_lengths": [ 4, 5, 6, 7, 8 ], "supports_backup_access_code_pool": true, "supports_offline_access_codes": false }, "warnings": [], "workspace_id": "5d7f2e1a-9c8b-4f3e-8d2c-1a0b9e8f7c6d" } ``` ```json Noise Sensor Device theme={null} { "capabilities_supported": [ "noise_detection" ], "connected_account_id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d", "created_at": "2025-05-16T16:54:17.946049Z", "custom_metadata": { "id": "internalId1" }, "device_id": "f1e2d3c4-b5a6-4d7c-8e9f-0a1b2c3d4e5f", "device_type": "minut_sensor", "display_name": "Living Room", "errors": [], "is_managed": true, "space_ids": [], "location": { "location_name": "Jane's Test Home", "timezone": "America/Los_Angeles" }, "nickname": "Living Room", "properties": { "appearance": { "name": "Living Room" }, "battery": { "level": 1, "status": "full" }, "battery_level": 1, "currently_triggering_noise_threshold_ids": [], "image_alt_text": "Minut Sensor", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/devices/minut_gen-3_front.png&q=75&w=128", "manufacturer": "minut", "minut_metadata": { "device_id": "770cd3153deca3dee0fe0614", "device_location": { "latitude": 0, "longitude": 0 }, "device_name": "Living Room", "home_address": { "city": "San Francisco", "country": "US", "notes": "string", "post_code": "44210", "region": "San Francisco County", "street_name1": "2258 24th Street", "street_name2": "" }, "home_id": "2978b6d5dba395ec08300e46", "home_location": { "latitude": 0, "longitude": 0 }, "home_name": "Jane's Test Home", "latest_sensor_values": { "accelerometer_z": { "time": "2025-06-16T16:54:17.946049Z", "value": -1.00390625 }, "humidity": { "time": "2025-06-16T16:54:17.946049Z", "value": 31.110000610351562 }, "pressure": { "time": "2025-06-16T16:54:17.946049Z", "value": 101923 }, "sound": { "time": "2025-06-16T16:54:17.946049Z", "value": 47.7117919921875 }, "temperature": { "time": "2025-06-16T16:54:17.946049Z", "value": 21.270000457763672 } } }, "model": { "display_name": "Noise Sensor", "manufacturer_display_name": "Minut" }, "name": "Living Room", "noise_level_decibels": 47.7117919921875, "online": true }, "warnings": [], "workspace_id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d" } ``` ```json Thermostat Device theme={null} { "can_hvac_cool": true, "can_hvac_heat": true, "can_hvac_heat_cool": true, "can_turn_off_hvac": true, "capabilities_supported": [ "thermostat" ], "connected_account_id": "a0b1c2d3-e4f5-6a7b-8c9d-0e1f2a3b4c5d", "created_at": "2024-10-03T22:12:15.666Z", "custom_metadata": { "id": "internalId1" }, "device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0", "device_type": "ecobee_thermostat", "display_name": "Living Room", "errors": [], "is_managed": true, "space_ids": [], "location": { "location_name": "2948 20th St, San Francisco, CA, 94110, US", "timezone": "America/Los_Angeles" }, "nickname": "Living Room", "properties": { "active_climate_preset": { "can_delete": true, "can_edit": true, "climate_preset_key": "sleep", "cooling_set_point_celsius": 23.88888888888889, "display_name": "Sleep", "fan_mode_setting": "auto", "heating_set_point_celsius": 17.77777777777778, "hvac_mode_setting": "heat_cool", "manual_override_allowed": true }, "appearance": { "name": "Living Room" }, "available_climate_presets": [ { "climate_preset_key": "sleep", "can_edit": true, "can_delete": true, "can_use_with_thermostat_daily_programs": false, "name": "Sleep", "display_name": "Sleep", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "manual_override_allowed": true, "cooling_set_point_celsius": 23.88888888888889, "heating_set_point_celsius": 17.77777777777778, "cooling_set_point_fahrenheit": 75, "heating_set_point_fahrenheit": 64 }, { "climate_preset_key": "home", "can_edit": true, "can_delete": true, "can_use_with_thermostat_daily_programs": false, "name": "Home", "display_name": "Home", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "manual_override_allowed": false, "cooling_set_point_celsius": 23.88888888888889, "heating_set_point_celsius": 17.77777777777778, "cooling_set_point_fahrenheit": 75, "heating_set_point_fahrenheit": 64 }, { "climate_preset_key": "work", "can_edit": true, "can_delete": true, "can_use_with_thermostat_daily_programs": false, "name": "Work", "display_name": "Work", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "manual_override_allowed": false, "cooling_set_point_celsius": 23.88888888888889, "heating_set_point_celsius": 17.77777777777778, "cooling_set_point_fahrenheit": 75, "heating_set_point_fahrenheit": 64 } ], "available_fan_mode_settings": [ "auto", "on" ], "available_hvac_mode_settings": [ "cool", "heat", "heat_cool", "off" ], "current_climate_setting": { "display_name": "Manual Setting", "fan_mode_setting": "auto", "heating_set_point_celsius": 25, "heating_set_point_fahrenheit": 77, "hvac_mode_setting": "heat", "manual_override_allowed": true }, "ecobee_metadata": { "device_name": "Living Room", "ecobee_device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0" }, "fallback_climate_preset_key": "eco", "fan_mode_setting": "auto", "has_direct_power": true, "image_alt_text": "Ecobee 3 Lite Thermostat", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/devices/ecobee_3-lite_front.png&q=75&w=128", "is_cooling": false, "is_fan_running": false, "is_heating": false, "is_temporary_manual_override_active": false, "manufacturer": "ecobee", "max_cooling_set_point_celsius": 33.333333333333336, "max_cooling_set_point_fahrenheit": 92, "max_heating_set_point_celsius": 26.11111111111111, "max_heating_set_point_fahrenheit": 79, "min_cooling_set_point_celsius": 18.333333333333336, "min_cooling_set_point_fahrenheit": 65, "min_heating_cooling_delta_celsius": 2.7777777777777777, "min_heating_cooling_delta_fahrenheit": 5, "min_heating_set_point_celsius": 7.222222222222222, "min_heating_set_point_fahrenheit": 45, "model": { "display_name": "Thermostat", "manufacturer_display_name": "Ecobee" }, "name": "Living Room", "online": true, "relative_humidity": 0.36, "temperature_celsius": 21.11111111111111, "temperature_fahrenheit": 70, "temperature_threshold": { "lower_limit_celsius": 16.66666666666667, "lower_limit_fahrenheit": 62, "upper_limit_celsius": 26.66666666666667, "upper_limit_fahrenheit": 80 }, "thermostat_daily_programs": [ { "thermostat_daily_program_id": "1a2b3c4d-5e6f-7890-1234-56789abcdef1", "device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0", "name": "Weekday Program", "periods": [ { "starts_at_time": "00:00:00", "climate_preset_key": "sleep" }, { "starts_at_time": "07:00:00", "climate_preset_key": "home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "work" }, { "starts_at_time": "18:00:00", "climate_preset_key": "home" }, { "starts_at_time": "22:00:00", "climate_preset_key": "sleep" } ], "workspace_id": "9f8e7d6c-5b4a-3c2d-1e0f-9876543210ab", "created_at": "2025-05-30T04:01:25.455Z" }, { "thermostat_daily_program_id": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f90", "device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0", "name": "Weekend Program", "periods": [ { "starts_at_time": "00:00:00", "climate_preset_key": "sleep" }, { "starts_at_time": "08:00:00", "climate_preset_key": "home" }, { "starts_at_time": "23:00:00", "climate_preset_key": "sleep" } ], "workspace_id": "9f8e7d6c-5b4a-3c2d-1e0f-9876543210ab", "created_at": "2025-05-30T04:02:19.952Z" } ], "thermostat_weekly_program": null }, "warnings": [], "workspace_id": "9f8e7d6c-5b4a-3c2d-1e0f-9876543210ab" } ``` *** ## Properties Indicates whether the lock supports configuring automatic locking. Indicates whether the thermostat supports cooling. Indicates whether the thermostat supports heating. Indicates whether the thermostat supports simultaneous heating and cooling. Indicates whether the device supports programming offline access codes. Indicates whether the device supports programming online access codes. Indicates whether the thermostat supports different climate programs for each day of the week. Indicates whether the thermostat supports a single climate program applied to every day. Indicates whether the thermostat supports weekday/weekend climate programs. Indicates whether the device supports remote locking. Indicates whether the device supports remote unlocking. Indicates whether the thermostat supports running climate programs. Indicates whether the device supports simulating connection in a sandbox. Indicates whether the device supports simulating disconnection in a sandbox. Indicates whether the hub supports simulating connection in a sandbox. Indicates whether the hub supports simulating disconnection in a sandbox. Indicates whether the device supports simulating a paid subscription in a sandbox. Indicates whether the device supports simulating removal in a sandbox. Indicates whether the thermostat can be turned off. Indicates whether the lock supports unlocking with an access code. Collection of capabilities that the device supports when connected to Seam. Values are `access_code`, which indicates that the device can manage and utilize digital PIN codes for secure access; `lock`, which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; `noise_detection`, which indicates that the device supports monitoring and responding to ambient noise levels; `thermostat`, which indicates that the device can regulate and adjust indoor temperatures; `battery`, which indicates that the device can manage battery life and health; and `phone`, which indicates that the device is a mobile device, such as a smartphone. **Important:** Superseded by [capability flags](/capability-guides/device-and-system-capabilities#capability-flags). Unique identifier for the account associated with the device. Date and time at which the device object was created. Set of key:value pairs. Adding custom metadata to a resource, such as a [Connect Webview](/core-concepts/connect-webviews/attaching-custom-data-to-the-connect-webview), [connected account](/core-concepts/connected-accounts/adding-custom-metadata-to-a-connected-account), or [device](/core-concepts/devices/adding-custom-metadata-to-a-device), enables you to store custom information, like customer details or internal IDs from your application. ID of the device. Type of the device. Display name of the device, defaults to nickname (if it is set) or `properties.appearance.name`, otherwise. Enables administrators and users to identify the device easily, especially when there are numerous devices. Array of errors associated with the device. Each error object within the array contains two fields: `error_code` and `message`. `error_code` is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. Indicates whether Seam manages the device. See also [Managed and Unmanaged Devices](/core-concepts/devices/managed-and-unmanaged-devices). Optional nickname to describe the device, settable through Seam. Properties of the device. Accessory keypad properties and state. Keypad battery properties. The level. Indicates if an accessory keypad is connected to the device. Appearance-related properties, as reported by the device. Name of the device as seen from the provider API and application, not settable through Seam. Represents the current status of the battery charge level. Battery charge level as a value between 0 and 1, inclusive. Represents the current status of the battery charge level. Values are `critical`, which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; `low`, which signifies that the battery is under the preferred threshold and should be charged soon; `good`, which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and `full`, which represents a battery that is fully charged, providing the maximum duration of usage. Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. Array of noise threshold IDs that are currently triggering. Indicates whether the device has direct power. Alt text for the device image. Image URL for the device. Manufacturer of the device. When a device, such as a smart lock, is connected through a smart hub, the manufacturer of the device might be different from that of the smart hub. Device model-related properties. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The accessory keypad supported. Indicates whether the device can connect a accessory keypad. Display name of the device model. Indicates whether the device has a built in accessory keypad. Display name that corresponds to the manufacturer-specific terminology for the device. **Deprecated**. use device.can\_program\_offline\_access\_codes. The offline access codes supported. **Deprecated**. use device.can\_program\_online\_access\_codes. The online access codes supported. **Deprecated**. use device.display\_name instead Name of the device. Indicates current noise level in decibels, if the device supports noise detection. **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. Indicates whether the device is online. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. Serial number of the device. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The supports accessory keypad. **Deprecated**. use offline\_access\_codes\_enabled The supports offline access codes. ASSA ABLOY Credential Service metadata for the phone. Endpoints associated with the phone. ID of the associated endpoint. Indicated whether the endpoint is active. Indicates whether the credential service has active endpoints associated with the phone. Salto Space credential service metadata for the phone. Indicates whether the credential service has an active associated phone. Metadata for an Akiles device. Group ID to which to add users for an Akiles device. Gadget ID for an Akiles device. Gadget name for an Akiles device. Product name for an Akiles device. Metadata for an Aqara device. Device name for an Aqara device. Device ID (did) for an Aqara device. Firmware version for an Aqara device. Model identifier for an Aqara device. Model type for an Aqara device. Parent gateway device ID for an Aqara device. Position (room) ID for an Aqara device. Time zone reported for an Aqara device (e.g. GMT-07:00). Metadata for an ASSA ABLOY Vostio system. Encoder name for an ASSA ABLOY Vostio system. Metadata for an August device. Indicates whether an August device has a keypad. House ID for an August device. House name for an August device. Keypad battery level for an August device. Lock ID for an August device. Lock name for an August device. Model for an August device. Metadata for an Avigilon Alta system. Entry name for an Avigilon Alta system. Total count of entry relays for an Avigilon Alta system. Organization name for an Avigilon Alta system. Site ID for an Avigilon Alta system. Site name for an Avigilon Alta system. Zone ID for an Avigilon Alta system. Zone name for an Avigilon Alta system. Metadata for a Brivo device. Indicates whether the Brivo access point has activation (remote unlock) enabled. Device name for a Brivo device. Metadata for a ControlByWeb device. Device ID for a ControlByWeb device. Device name for a ControlByWeb device. Relay name for a ControlByWeb device. Metadata for a dormakaba Oracode device. Device ID for a dormakaba Oracode device. Door ID for a dormakaba Oracode device. Indicates whether a door is wireless for a dormakaba Oracode device. Door name for a dormakaba Oracode device. IANA time zone for a dormakaba Oracode device. Predefined time slots for a dormakaba Oracode device. Check in time for a time slot for a dormakaba Oracode device. Checkout time for a time slot for a dormakaba Oracode device. ID of a user level for a dormakaba Oracode device. Prefix for a user level for a dormakaba Oracode device. Indicates whether a time slot for a dormakaba Oracode device is a 24-hour time slot. Indicates whether a time slot for a dormakaba Oracode device is in biweekly mode. Indicates whether a time slot for a dormakaba Oracode device is a master time slot. Indicates whether a time slot for a dormakaba Oracode device is a one-shot time slot. Name of a time slot for a dormakaba Oracode device. Prefix for a time slot for a dormakaba Oracode device. **Deprecated**. Previously marked as "@DEPRECATED." Site ID for a dormakaba Oracode device. Site name for a dormakaba Oracode device. Metadata for an ecobee device. Device name for an ecobee device. Device ID for an ecobee device. Metadata for a 4SUITES device. Device ID for a 4SUITES device. Device name for a 4SUITES device. Reclose delay, in seconds, for a 4SUITES device. Metadata for a Genie device. Lock name for a Genie device. Door name for a Genie device. Metadata for a Honeywell Resideo device. Device name for a Honeywell Resideo device. Device ID for a Honeywell Resideo device. Metadata for an igloo device. Bridge ID for an igloo device. Device ID for an igloo device. Model for an igloo device. Metadata for an igloohome device. Bridge ID for an igloohome device. Bridge name for an igloohome device. Device ID for an igloohome device. Device name for an igloohome device. Indicates whether a keypad is linked to a bridge for an igloohome device. Keypad ID for an igloohome device. Metadata for a KeyNest device. Address for a KeyNest device. Current or last store ID for a KeyNest device. Current status for a KeyNest device. Current user company for a KeyNest device. Current user email for a KeyNest device. Current user name for a KeyNest device. Current user phone number for a KeyNest device. Default office ID for a KeyNest device. Device name for a KeyNest device. Fob ID for a KeyNest device. Handover method for a KeyNest device. Whether the KeyNest device has a photo. Whether the key is in a locker that does not support the access codes API. Key ID for a KeyNest device. Key notes for a KeyNest device. KeyNest app user for a KeyNest device. Last movement timestamp for a KeyNest device. Property ID for a KeyNest device. Property postcode for a KeyNest device. Status type for a KeyNest device. Subscription plan for a KeyNest device. Metadata for a Kisi device. Description for a Kisi device. Lock ID for a Kisi device. Lock name for a Kisi device. Place name for a Kisi device. Metadata for a Korelock device. Device ID for a Korelock device. Device name for a Korelock device. Firmware version for a Korelock device. Location ID for a Korelock device. Required for timebound access codes. Model code for a Korelock device. Serial number for a Korelock device. WiFi signal strength (0-1) for a Korelock device. Metadata for a Kwikset device. Device ID for a Kwikset device. Device name for a Kwikset device. Model number for a Kwikset device. Metadata for a Lockly device. Device ID for a Lockly device. Device name for a Lockly device. Model for a Lockly device. Metadata for a Minut device. Device ID for a Minut device. Device name for a Minut device. Latest sensor values for a Minut device. Latest accelerometer Z-axis reading for a Minut device. Time of latest accelerometer Z-axis reading for a Minut device. Value of latest accelerometer Z-axis reading for a Minut device. Latest humidity reading for a Minut device. Time of latest humidity reading for a Minut device. Value of latest humidity reading for a Minut device. Latest pressure reading for a Minut device. Time of latest pressure reading for a Minut device. Value of latest pressure reading for a Minut device. Latest sound reading for a Minut device. Time of latest sound reading for a Minut device. Value of latest sound reading for a Minut device. Latest temperature reading for a Minut device. Time of latest temperature reading for a Minut device. Value of latest temperature reading for a Minut device. Metadata for a Google Nest device. Custom device name for a Google Nest device. The device owner sets this value. Device name for a Google Nest device. Google sets this value. Display name for a Google Nest device. Device ID for a Google Nest device. ID of the Google Nest structure containing the device. Name of the Google Nest structure containing the device. The device owner sets this value. Metadata for a NoiseAware device. Device ID for a NoiseAware device. Device model for a NoiseAware device. Device name for a NoiseAware device. Noise level, in decibels, for a NoiseAware device. Noise level, expressed as a Noise Risk Score (NRS), for a NoiseAware device. Metadata for a Nuki device. Device ID for a Nuki device. Device name for a Nuki device. Indicates whether keypad 2 is paired for a Nuki device. Indicates whether the keypad battery is in a critical state for a Nuki device. Indicates whether the keypad is paired for a Nuki device. Metadata for an Omnitec device. Whether the Omnitec lock has a connected gateway for remote operations. Operator-assigned alias for an Omnitec device. Lock ID for an Omnitec device. Bluetooth MAC address for an Omnitec device. Lock name for an Omnitec device. IANA time zone for the Omnitec device, used to schedule time-bound access codes at the correct local time (accounting for DST). Static UTC offset of the Omnitec lock in milliseconds. Does not account for DST. Metadata for a Ring device. Device ID for a Ring device. Device name for a Ring device. Metadata for a Salto KS device. Battery level for a Salto KS device. Customer reference for a Salto KS device. Indicates whether the site has a Salto KS subscription that supports custom PINs. Lock ID for a Salto KS device. Lock type for a Salto KS device. Locked state for a Salto KS device. Model for a Salto KS device. Site ID for the Salto KS site to which the device belongs. Site name for the Salto KS site to which the device belongs. **Deprecated**. Use `salto_ks_metadata` instead. Metada for a Salto device. Battery level for a Salto device. Customer reference for a Salto device. Lock ID for a Salto device. Lock type for a Salto device. Locked state for a Salto device. Model for a Salto device. Site ID for the Salto KS site to which the device belongs. Site name for the Salto KS site to which the device belongs. Metadata for a Schlage device. Device ID for a Schlage device. Device name for a Schlage device. Model for a Schlage device. Metadata for Seam Bridge. Device number for Seam Bridge. Name for Seam Bridge. Unlock method for Seam Bridge. Metadata for a Sensi device. Device ID for a Sensi device. Device name for a Sensi device. Set to true when the device does not support the /dual-setpoints API endpoint. Enforced setpoint range in Celsius for a Sensi device, derived from an OutOfRange API error. Product type for a Sensi device. Metadata for a SmartThings device. Device ID for a SmartThings device. Device name for a SmartThings device. Location ID for a SmartThings device. Model for a SmartThings device. Metadata for a tado° device. Device type for a tado° device. Serial number for a tado° device. Metadata for a Tedee device. Bridge ID for a Tedee device. Bridge name for a Tedee device. Device ID for a Tedee device. Device model for a Tedee device. Device name for a Tedee device. Keypad ID for a Tedee device. Serial number for a Tedee device. Metadata for a TTLock device. Feature value for a TTLock device. Features for a TTLock device. Indicates whether a TTLock device supports auto-lock time configuration. Indicates whether a TTLock device supports an incomplete keyboard passcode. Indicates whether a TTLock device supports the lock command. Indicates whether a TTLock device supports a passcode. Indicates whether a TTLock device supports passcode management. Indicates whether a TTLock device supports unlock via gateway. Indicates whether a TTLock device supports Wi-Fi. Indicates whether a TTLock device has a gateway. Lock alias for a TTLock device. Lock ID for a TTLock device. Lock-side timezone offset in milliseconds east of UTC, as configured in the TTLock app. Source of truth for the lock's wall-clock interpretation of access code start/end times — a misconfigured value here is the typical cause of customer "codes offset by N hours" reports. Diagnostic only; Seam does not convert times based on this value. Wireless keypads for a TTLock device. ID for a wireless keypad for a TTLock device. Name for a wireless keypad for a TTLock device. Metadata for a 2N device. Device ID for a 2N device. Device name for a 2N device. Metadata for an Ultraloq device. Device ID for an Ultraloq device. Device name for an Ultraloq device. Device type for an Ultraloq device. IANA timezone for the Ultraloq device. Metadata for an ASSA ABLOY Visionline system. Encoder ID for an ASSA ABLOY Visionline system. Metadata for a Wyze device. Device ID for a Wyze device. Device information model for a Wyze device. Device name for a Wyze device. Keypad UUID for a Wyze device. Locker status (hardlock) for a Wyze device. Product model for a Wyze device. Product name for a Wyze device. Product type for a Wyze device. The delay in seconds before the lock automatically locks after being unlocked. Indicates whether automatic locking is enabled. Indicates whether the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is currently enabled for the device. To disable it, set this to `false` using [/devices/update](/api/devices/update). Constraints on access codes for the device. Seam represents each constraint as an object with a `constraint_type` property. Depending on the constraint type, there may also be additional properties. Note that some constraints are manufacturer- or device-specific. The constraint type. Maximum name length constraint for access codes. Minimum name length constraint for access codes. Indicates whether the door is open. Indicates whether the device supports native entry events. Keypad battery status. Keypad battery charge level. Indicates whether the lock is locked. Maximum number of active access codes that the device supports. Time frames that may be requested when creating an offline access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Time frames that may be requested when creating an online access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Supported code lengths for access codes. Indicates whether the device supports a [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes). **Deprecated**. Use `active_thermostat_schedule_id` with `/thermostats/schedules/get` instead. Active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) was created. ID of the desired [thermostat](/capability-guides/thermostats) device. Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Errors associated with the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Indicates whether a person at the thermostat can change the thermostat's settings after the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts. Number of minutes for which a person at the thermostat can change the thermostat's settings after the activation of the scheduled [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). See also [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). ID of the workspace that contains the thermostat schedule. ID of the active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Climate preset modes that the thermostat supports, such as "home", "away", "wake", "sleep", "occupied", and "unoccupied". Available [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets) for the thermostat. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Fan mode settings that the thermostat supports. HVAC mode settings that the thermostat supports. Current climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). **Deprecated**. use fallback\_climate\_preset\_key to specify a fallback climate preset instead. The default climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Key of the [fallback climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) for the thermostat. **Deprecated**. Use `current_climate_setting.fan_mode_setting` instead. The fan mode setting. Indicates whether the connected HVAC system is currently cooling, as reported by the thermostat. Indicates whether the fan in the connected HVAC system is currently running, as reported by the thermostat. Indicates whether the connected HVAC system is currently heating, as reported by the thermostat. Indicates whether the current thermostat settings differ from the most recent active program or schedule that Seam activated. For this condition to occur, `current_climate_setting.manual_override_allowed` must also be `true`. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Maximum number of periods that the thermostat can support per day. For example, if the thermostat supports 4 periods per day, this value is 4. Maximum number of climate presets that the thermostat can support for weekly programming. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °C between the cooling and heating set points when in heat-cool (auto) mode. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °F between the cooling and heating set points when in heat-cool (auto) mode. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Reported relative humidity, as a value between 0 and 1, inclusive. Reported temperature in °C. Reported temperature in °F. Current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Precision of the thermostat's period in minutes. For example, if the thermostat supports 15-minute periods, this value is 15. All values are relative to the top of the hour, so for 15 minutes, the periods would be 0, 15, 30, and 45 minutes past the hour. Configured [daily programs](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat daily program was created. ID of the thermostat device on which the thermostat daily program is configured. User-friendly name to identify the thermostat daily program. Array of thermostat daily program periods. Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to activate at the `starts_at_time`. Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the thermostat daily program. ID of the workspace that contains the thermostat daily program. Current [weekly program](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat weekly program was created. ID of the thermostat daily program to run on Fridays. ID of the thermostat daily program to run on Mondays. ID of the thermostat daily program to run on Saturdays. ID of the thermostat daily program to run on Sundays. ID of the thermostat daily program to run on Thursdays. ID of the thermostat daily program to run on Tuesdays. ID of the thermostat daily program to run on Wednesdays. IDs of the spaces the device is in. Array of warnings associated with the device. Each warning object within the array contains two fields: `warning_code` and `message`. `warning_code` is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. Unique identifier for the Seam workspace associated with the device. Manufacturer of the device. Represents the hardware brand, which may differ from the provider. Display name for the manufacturer, such as `August`, `Yale`, `Salto`, and so on. Image URL for the manufacturer logo. Manufacturer identifier, such as `august`, `yale`, `salto`, and so on. Provider of the device. Represents the third-party service through which the device is controlled. Device provider name. Corresponds to the integration type, such as `august`, `schlage`, `yale_access`, and so on. Display name for the device provider type. Image URL for the device provider. Provider category. Indicates the third-party provider type, such as `stable`, for stable integrations, or `internal`, for internal integrations. Location information for the device. Name of the device location. Name of the room within the device location, when the provider reports one. Time zone of the device location. **Deprecated**. Use `time_zone` instead. Time zone of the device location. ## Access Codes **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The supports accessory keypad. **Deprecated**. use offline\_access\_codes\_enabled The supports offline access codes. Indicates whether the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is currently enabled for the device. To disable it, set this to `false` using [/devices/update](/api/devices/update). Constraints on access codes for the device. Seam represents each constraint as an object with a `constraint_type` property. Depending on the constraint type, there may also be additional properties. Note that some constraints are manufacturer- or device-specific. The constraint type. Maximum name length constraint for access codes. Minimum name length constraint for access codes. Indicates whether the device supports native entry events. Keypad battery status. Keypad battery charge level. Maximum number of active access codes that the device supports. Time frames that may be requested when creating an offline access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Time frames that may be requested when creating an online access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Supported code lengths for access codes. Indicates whether the device supports a [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes). ## Hardware Accessory keypad properties and state. Keypad battery properties. The level. Indicates if an accessory keypad is connected to the device. Appearance-related properties, as reported by the device. Name of the device as seen from the provider API and application, not settable through Seam. Represents the current status of the battery charge level. Battery charge level as a value between 0 and 1, inclusive. Represents the current status of the battery charge level. Values are `critical`, which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; `low`, which signifies that the battery is under the preferred threshold and should be charged soon; `good`, which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and `full`, which represents a battery that is fully charged, providing the maximum duration of usage. Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. Indicates whether the device has direct power. Alt text for the device image. Image URL for the device. Manufacturer of the device. When a device, such as a smart lock, is connected through a smart hub, the manufacturer of the device might be different from that of the smart hub. Serial number of the device. ## Locks The delay in seconds before the lock automatically locks after being unlocked. Indicates whether automatic locking is enabled. Indicates whether the door is open. Indicates whether the lock is locked. ## Noise Sensors Array of noise threshold IDs that are currently triggering. Indicates current noise level in decibels, if the device supports noise detection. ## Thermostats **Deprecated**. Use `active_thermostat_schedule_id` with `/thermostats/schedules/get` instead. Active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) was created. ID of the desired [thermostat](/capability-guides/thermostats) device. Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Errors associated with the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Indicates whether a person at the thermostat can change the thermostat's settings after the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts. Number of minutes for which a person at the thermostat can change the thermostat's settings after the activation of the scheduled [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). See also [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). ID of the workspace that contains the thermostat schedule. ID of the active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Climate preset modes that the thermostat supports, such as "home", "away", "wake", "sleep", "occupied", and "unoccupied". Available [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets) for the thermostat. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Fan mode settings that the thermostat supports. HVAC mode settings that the thermostat supports. Current climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). **Deprecated**. use fallback\_climate\_preset\_key to specify a fallback climate preset instead. The default climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Key of the [fallback climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) for the thermostat. **Deprecated**. Use `current_climate_setting.fan_mode_setting` instead. The fan mode setting. Indicates whether the connected HVAC system is currently cooling, as reported by the thermostat. Indicates whether the fan in the connected HVAC system is currently running, as reported by the thermostat. Indicates whether the connected HVAC system is currently heating, as reported by the thermostat. Indicates whether the current thermostat settings differ from the most recent active program or schedule that Seam activated. For this condition to occur, `current_climate_setting.manual_override_allowed` must also be `true`. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Maximum number of periods that the thermostat can support per day. For example, if the thermostat supports 4 periods per day, this value is 4. Maximum number of climate presets that the thermostat can support for weekly programming. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °C between the cooling and heating set points when in heat-cool (auto) mode. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °F between the cooling and heating set points when in heat-cool (auto) mode. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Reported relative humidity, as a value between 0 and 1, inclusive. Reported temperature in °C. Reported temperature in °F. Current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Precision of the thermostat's period in minutes. For example, if the thermostat supports 15-minute periods, this value is 15. All values are relative to the top of the hour, so for 15 minutes, the periods would be 0, 15, 30, and 45 minutes past the hour. Configured [daily programs](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat daily program was created. ID of the thermostat device on which the thermostat daily program is configured. User-friendly name to identify the thermostat daily program. Array of thermostat daily program periods. Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to activate at the `starts_at_time`. Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the thermostat daily program. ID of the workspace that contains the thermostat daily program. Current [weekly program](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat weekly program was created. ID of the thermostat daily program to run on Fridays. ID of the thermostat daily program to run on Mondays. ID of the thermostat daily program to run on Saturdays. ID of the thermostat daily program to run on Sundays. ID of the thermostat daily program to run on Thursdays. ID of the thermostat daily program to run on Tuesdays. ID of the thermostat daily program to run on Wednesdays. ## The device\_provider Object ```json Device Provider theme={null} { "can_program_online_access_codes": true, "can_remotely_unlock": true, "device_provider_name": "akiles", "display_name": "Akiles", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/logos/akiles.png&q=75&w=128", "space_ids": [], "provider_categories": [ "stable", "consumer_smartlocks" ] } ``` *** ## Properties Indicates whether the lock supports configuring automatic locking. Indicates whether the thermostat supports cooling. Indicates whether the thermostat supports heating. Indicates whether the thermostat supports simultaneous heating and cooling. Indicates whether the device supports programming offline access codes. Indicates whether the device supports programming online access codes. Indicates whether the thermostat supports different climate programs for each day of the week. Indicates whether the thermostat supports a single climate program applied to every day. Indicates whether the thermostat supports weekday/weekend climate programs. Indicates whether the device supports remote locking. Indicates whether the device supports remote unlocking. Indicates whether the thermostat supports running climate programs. Indicates whether the device supports simulating connection in a sandbox. Indicates whether the device supports simulating disconnection in a sandbox. Indicates whether the hub supports simulating connection in a sandbox. Indicates whether the hub supports simulating disconnection in a sandbox. Indicates whether the device supports simulating a paid subscription in a sandbox. Indicates whether the device supports simulating removal in a sandbox. Indicates whether the thermostat can be turned off. Indicates whether the lock supports unlocking with an access code. Name of the device provider. Display name for the device provider. Image URL for the device provider. List of provider categories to which the device provider belongs, such as `stable`, `consumer_smartlocks`, `thermostats`, and so on. # Report Provider Metadata Source: https://docs.seam.co/api/devices/report_provider_metadata /openapi.json post /devices/report_provider_metadata Updates provider-specific metadata for devices. # Simulate Device Connection Source: https://docs.seam.co/api/devices/simulate/connect /openapi.json post /devices/simulate/connect Simulates connecting a device to Seam. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your App Against Device Disconnection and Removal](/core-concepts/devices/testing-your-app-against-device-disconnection-and-removal). # Simulate Hub Connection Source: https://docs.seam.co/api/devices/simulate/connect_to_hub /openapi.json post /devices/simulate/connect_to_hub Simulates bringing the Wi‑Fi hub (bridge) back online for a device. Only applicable for sandbox workspaces and currently implemented for August and TTLock locks. This will clear the `hub_disconnected` error on the device. # Simulate Device Disconnection Source: https://docs.seam.co/api/devices/simulate/disconnect /openapi.json post /devices/simulate/disconnect Simulates disconnecting a device from Seam. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your App Against Device Disconnection and Removal](/core-concepts/devices/testing-your-app-against-device-disconnection-and-removal). # Simulate Hub Disconnection Source: https://docs.seam.co/api/devices/simulate/disconnect_from_hub /openapi.json post /devices/simulate/disconnect_from_hub Simulates taking the Wi‑Fi hub (bridge) offline for a device. Only applicable for sandbox workspaces and currently implemented for August, TTLock, and IglooHome devices. This will set the `hub_disconnected` error on the device, or mark the IglooHome bridge offline in sandbox. # Device Simulations Source: https://docs.seam.co/api/devices/simulate/object Use the device simulation endpoints to connect, disconnect, and remove sandbox devices so you can test how your app handles device state changes. ## Endpoints [**`/devices/simulate/connect`**](./connect) Simulates connecting a device to Seam. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your App Against Device Disconnection and Removal](/core-concepts/devices/testing-your-app-against-device-disconnection-and-removal). [**`/devices/simulate/connect_to_hub`**](./connect_to_hub) Simulates bringing the Wi‑Fi hub (bridge) back online for a device. Only applicable for sandbox workspaces and currently implemented for August and TTLock locks. This will clear the `hub_disconnected` error on the device. [**`/devices/simulate/disconnect`**](./disconnect) Simulates disconnecting a device from Seam. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your App Against Device Disconnection and Removal](/core-concepts/devices/testing-your-app-against-device-disconnection-and-removal). [**`/devices/simulate/disconnect_from_hub`**](./disconnect_from_hub) Simulates taking the Wi‑Fi hub (bridge) offline for a device. Only applicable for sandbox workspaces and currently implemented for August, TTLock, and IglooHome devices. This will set the `hub_disconnected` error on the device, or mark the IglooHome bridge offline in sandbox. [**`/devices/simulate/paid_subscription`**](./paid_subscription) Toggle the simulated Nuki Smart Hosting subscription for a device (sandbox only). Send `is_expired: true` to simulate an expired subscription, or `false` to simulate an active subscription. The actual device error is created/cleared by the poller after this state change. [**`/devices/simulate/remove`**](./remove) Simulates removing a device from Seam. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your App Against Device Disconnection and Removal](/core-concepts/devices/testing-your-app-against-device-disconnection-and-removal). # Simulate Paid Subscription Source: https://docs.seam.co/api/devices/simulate/paid_subscription /openapi.json post /devices/simulate/paid_subscription Toggle the simulated Nuki Smart Hosting subscription for a device (sandbox only). Send `is_expired: true` to simulate an expired subscription, or `false` to simulate an active subscription. The actual device error is created/cleared by the poller after this state change. # Simulate Device Removal Source: https://docs.seam.co/api/devices/simulate/remove /openapi.json post /devices/simulate/remove Simulates removing a device from Seam. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your App Against Device Disconnection and Removal](/core-concepts/devices/testing-your-app-against-device-disconnection-and-removal). # Unmanaged Devices Errors and Warnings Source: https://docs.seam.co/api/devices/unmanaged/errors Errors and warnings that Seam reports on the Unmanaged Devices resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "account_disconnected", "message": "Indicates that the account is disconnected.", "created_at": "2025-01-01T00:00:00.000Z", "is_connected_account_error": true, "is_device_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates whether the error is related to [Seam Bridge](/capability-guides/seam-bridge). Indicates that the error is a [connected account](/api/connected_accounts/object) error. Indicates that the error is not a device error. ### `device_disconnected` Indicates that the device is disconnected. *** ### `device_offline` Indicates that the device is offline. *** ### `device_removed` Indicates that the device has been removed. *** ### `hub_disconnected` Indicates that the hub is disconnected. *** ### `missing_device_credentials` Indicates that device credentials are missing. *** ### `subscription_required` Indicates that a subscription is required to connect. *** ### Access Codes #### `empty_backup_access_code_pool` Indicates that the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. *** ### Locks #### `august_lock_not_authorized` Indicates that the user is not authorized to use the August lock. *** ### Thermostats #### `auxiliary_heat_running` Indicates that the auxiliary heat is running. *** ### Connected Account These errors are inherited from the [Connected Account](/api/connected_accounts/errors) resource. When they are set on the parent connected account, they are propagated to this resource's errors list. #### `account_disconnected` Indicates that the account is disconnected. *** #### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](/capability-guides/seam-bridge), for example, if the Seam Bridge executable has stopped or if the computer running the Seam Bridge executable is offline. See also [Troubleshooting Your Access Control System](/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system-errors-seam_bridge_disconnected). *** #### `dormakaba_sites_disconnected` Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. *** #### `insufficient_permissions` Indicates that Seam's integration user does not have sufficient permissions on the provider's system to which this device belongs, so Seam cannot manage access codes or unlock the device. See the error message for specifics, then either reauthorize the connected account in Seam or grant the integration user the required permissions in the provider's system. *** #### `salto_ks_subscription_limit_exceeded` Indicates that the Salto site user limit has been reached. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "partial_backup_access_code_pool", "message": "Indicates that the backup access code is unhealthy.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. Number of active access codes on the device when the warning was set. Maximum number of active access codes supported by the device. ### `device_communication_degraded` Indicates that the device appears to be unresponsive. *** ### `device_has_flaky_connection` Indicates that the device has a flaky connection. *** ### `scheduled_maintenance_window` Indicates that a scheduled maintenance window has been detected. *** ### `third_party_integration_detected` Indicates that a third-party integration has been detected. *** ### Access Codes #### `many_active_backup_codes` Indicates that there are too many backup codes. *** #### `max_access_codes_reached` Indicates that the device has reached its maximum number of active access codes. Delete existing codes before creating new ones. *** #### `partial_backup_access_code_pool` Indicates that the backup access code is unhealthy. *** #### `privacy_mode` Indicates that the lock is in Privacy Mode. Access codes and remote unlock are blocked until Privacy Mode is disabled. *** #### `provider_issue` Indicates a provider-specific issue that may affect device functionality. *** #### `salto_ks_lock_access_code_support_removed` Indicates that a change in the reported device model has been detected for this Salto KS lock, which may occur after an IQ hub reset. Access code support may be affected. See [https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support](https://help.getseam.com/articles/5098842588-salto-ks-lock-loses-access-code-support) for troubleshooting steps. *** #### `salto_ks_office_mode` Indicates that the Salto KS lock is in Office Mode. Access Codes will not unlock doors. *** #### `salto_ks_privacy_mode` Indicates that the Salto KS lock is in Privacy Mode. Access Codes will not unlock doors. *** ### Locks #### `accessory_keypad_setup_required` Indicates that the accessory keypad exists, but is not linked to the Igloohome Bridge. Online access code programming will fail until the keypad is linked to the Igloohome Bridge in the Igloohome app. *** #### `hub_required_for_additional_capabilities` Indicates that a hub or relay must be connected to unlock additional capabilities such as remote unlock. *** #### `keynest_unsupported_locker` Indicates that the key is in a locker that does not support the access codes API. *** #### `lockly_time_zone_not_configured` Indicates that Seam detected that the Lockly device does not have a time zone configured. Time-bound codes may not work as expected. *** #### `power_saving_mode` Indicates that the device is in power saving mode and may have limited functionality. *** #### `salto_ks_subscription_limit_almost_reached` Indicates that the Salto KS site has exceeded 80% of the maximum number of allowed users. Increase your subscription limit or delete some users from your site. *** #### `time_zone_mismatch` Indicates that the device's configured time zone does not match its hardware UTC offset. Time-bound access codes may activate at the wrong local time. *** #### `time_zone_unknown` Indicates that Seam does not know the device's time zone. Set a time zone to enable time-bound access codes. *** #### `ttlock_lock_gateway_unlocking_not_enabled` Indicates that the Remote Unlock feature is not enabled in the settings." *** #### `ttlock_weak_gateway_signal` Indicates that the gateway signal is weak. *** #### `two_n_device_missing_timezone` Indicates that the 2N device does not have a time zone configured. Configure a time zone on the device to enable access codes. *** #### `ultraloq_time_zone_unknown` Indicates that Seam does not know the time zone of the Ultraloq device. Set a time zone to enable time-bound access codes. *** #### `unreliable_online_status` Indicates that the device may optimistically be reported as online because the provider does not reliably report its online status. *** ### Phones #### `unknown_issue_with_phone` Indicates that an unknown issue occurred while syncing the state of the phone with the provider. This issue may affect the proper functioning of the phone. *** ### Thermostats #### `temperature_threshold_exceeded` Indicates that the temperature threshold has been exceeded. *** # Unmanaged Devices Events Source: https://docs.seam.co/api/devices/unmanaged/events Webhook events that Seam emits for the Unmanaged Devices resource, with example payloads and properties. ## `device.unmanaged.converted_to_managed` An [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices) was successfully converted to a managed device. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "An [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices) was successfully converted to a managed device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.unmanaged.converted_to_managed", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.unmanaged.converted_to_managed` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.unmanaged.connected` The status of an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices) changed from offline to online. That is, the `device.properties.online` property changed from `false` to `true`. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "The status of an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices) changed from offline to online. That is, the `device.properties.online` property changed from `false` to `true`.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.unmanaged.connected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.unmanaged.connected` Date and time at which the event occurred. ID of the workspace associated with the event. ## `device.unmanaged.disconnected` The status of an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices) changed from online to offline. That is, the `device.properties.online` property changed from `true` to `false`. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_errors": [], "connected_account_id": "00000000-0000-0000-0000-000000000000", "connected_account_warnings": [], "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_errors": [], "device_id": "00000000-0000-0000-0000-000000000000", "device_warnings": [], "error_code": "account_disconnected", "event_description": "The status of an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices) changed from online to offline. That is, the `device.properties.online` property changed from `true` to `false`.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "device.unmanaged.disconnected", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. Errors associated with the connected account. ID of the connected account associated with the event. Warnings associated with the connected account. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. Errors associated with the device. ID of the affected device. Warnings associated with the device. Error code associated with the disconnection event, if any. Possible values: `account_disconnected`, `hub_disconnected`, `device_disconnected` Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `device.unmanaged.disconnected` Date and time at which the event occurred. ID of the workspace associated with the event. # Get an Unmanaged Device Source: https://docs.seam.co/api/devices/unmanaged/get /openapi.json post /devices/unmanaged/get Returns a specified [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices). An unmanaged device has a limited set of visible properties and a subset of supported events. You cannot control an unmanaged device. Any [access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) on an unmanaged device are unmanaged. To control an unmanaged device with Seam, [convert it to a managed device](/core-concepts/devices/managed-and-unmanaged-devices#convert-an-unmanaged-device-to-managed). You must specify either `device_id` or `name`. You must include at least one request parameter. # List Unmanaged Devices Source: https://docs.seam.co/api/devices/unmanaged/list /openapi.json post /devices/unmanaged/list Returns a list of all [unmanaged devices](/core-concepts/devices/managed-and-unmanaged-devices). An unmanaged device has a limited set of visible properties and a subset of supported events. You cannot control an unmanaged device. Any [access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) on an unmanaged device are unmanaged. To control an unmanaged device with Seam, [convert it to a managed device](/core-concepts/devices/managed-and-unmanaged-devices#convert-an-unmanaged-device-to-managed). # Unmanaged Devices Source: https://docs.seam.co/api/devices/unmanaged/object Learn how the unmanaged_device object exposes a limited set of properties and events for a device you cannot control until you convert it to managed. ## The unmanaged\_device Object Represents an [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices). An unmanaged device has a limited set of visible properties and a subset of supported events. You cannot control an unmanaged device. Any [access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) on an unmanaged device are unmanaged. To control an unmanaged device with Seam, [convert it to a managed device](/core-concepts/devices/managed-and-unmanaged-devices#convert-an-unmanaged-device-to-managed). ```json Unmanaged Device theme={null} { "can_program_offline_access_codes": false, "can_program_online_access_codes": true, "can_remotely_lock": true, "can_remotely_unlock": true, "can_simulate_connection": false, "can_simulate_disconnection": true, "can_simulate_removal": true, "capabilities_supported": [ "access_code", "lock" ], "connected_account_id": "c1a3967f-24a1-4220-a9c7-7fa97c1d5603", "created_at": "2025-06-16T16:54:17.946342Z", "device_id": "f4f40e75-86fc-4896-b958-e1c7e092b2cf", "device_type": "schlage_lock", "errors": [], "is_managed": false, "location": { "location_name": "Front Door", "timezone": "America/New_York" }, "custom_metadata": { "id": "internalId1" }, "properties": { "accessory_keypad": { "battery": { "level": 1 }, "is_connected": true }, "battery": { "level": 1, "status": "full" }, "battery_level": 1, "image_alt_text": "Schlage Sense Smart Deadbolt with Camelot Trim, Front", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/devices/schlage_sense-smart-deadbolt-with-camelot-trim_front.png&q=75&w=128", "manufacturer": "schlage", "model": { "accessory_keypad_supported": true, "can_connect_accessory_keypad": true, "display_name": "Front Door", "has_built_in_keypad": false, "manufacturer_display_name": "Schlage", "offline_access_codes_supported": false, "online_access_codes_supported": true }, "name": "Front Door", "offline_access_codes_enabled": false, "online": true, "online_access_codes_enabled": true }, "warnings": [], "workspace_id": "3cd6ba1c-8a60-4c24-b487-07bf6c0b755b" } ``` *** ## Properties Indicates whether the lock supports configuring automatic locking. Indicates whether the thermostat supports cooling. Indicates whether the thermostat supports heating. Indicates whether the thermostat supports simultaneous heating and cooling. Indicates whether the device supports programming offline access codes. Indicates whether the device supports programming online access codes. Indicates whether the thermostat supports different climate programs for each day of the week. Indicates whether the thermostat supports a single climate program applied to every day. Indicates whether the thermostat supports weekday/weekend climate programs. Indicates whether the device supports remote locking. Indicates whether the device supports remote unlocking. Indicates whether the thermostat supports running climate programs. Indicates whether the device supports simulating connection in a sandbox. Indicates whether the device supports simulating disconnection in a sandbox. Indicates whether the hub supports simulating connection in a sandbox. Indicates whether the hub supports simulating disconnection in a sandbox. Indicates whether the device supports simulating a paid subscription in a sandbox. Indicates whether the device supports simulating removal in a sandbox. Indicates whether the thermostat can be turned off. Indicates whether the lock supports unlocking with an access code. Collection of capabilities that the device supports when connected to Seam. Values are `access_code`, which indicates that the device can manage and utilize digital PIN codes for secure access; `lock`, which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; `noise_detection`, which indicates that the device supports monitoring and responding to ambient noise levels; `thermostat`, which indicates that the device can regulate and adjust indoor temperatures; `battery`, which indicates that the device can manage battery life and health; and `phone`, which indicates that the device is a mobile device, such as a smartphone. **Important:** Superseded by [capability flags](/capability-guides/device-and-system-capabilities#capability-flags). Unique identifier for the account associated with the device. Date and time at which the device object was created. Set of key:value pairs. Adding custom metadata to a resource, such as a [Connect Webview](/core-concepts/connect-webviews/attaching-custom-data-to-the-connect-webview), [connected account](/core-concepts/connected-accounts/adding-custom-metadata-to-a-connected-account), or [device](/core-concepts/devices/adding-custom-metadata-to-a-device), enables you to store custom information, like customer details or internal IDs from your application. ID of the device. Type of the device. Array of errors associated with the device. Each error object within the array contains two fields: `error_code` and `message`. `error_code` is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. Indicates that Seam does not manage the device. properties of the device. Accessory keypad properties and state. Keypad battery properties. The level. Indicates if an accessory keypad is connected to the device. Represents the current status of the battery charge level. Battery charge level as a value between 0 and 1, inclusive. Represents the current status of the battery charge level. Values are `critical`, which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; `low`, which signifies that the battery is under the preferred threshold and should be charged soon; `good`, which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and `full`, which represents a battery that is fully charged, providing the maximum duration of usage. Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. Alt text for the device image. Image URL for the device. Manufacturer of the device. When a device, such as a smart lock, is connected through a smart hub, the manufacturer of the device might be different from that of the smart hub. Device model-related properties. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The accessory keypad supported. Indicates whether the device can connect a accessory keypad. Display name of the device model. Indicates whether the device has a built in accessory keypad. Display name that corresponds to the manufacturer-specific terminology for the device. **Deprecated**. use device.can\_program\_offline\_access\_codes. The offline access codes supported. **Deprecated**. use device.can\_program\_online\_access\_codes. The online access codes supported. **Deprecated**. use device.display\_name instead Name of the device. **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. Indicates whether the device is online. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. Array of warnings associated with the device. Each warning object within the array contains two fields: `warning_code` and `message`. `warning_code` is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. Unique identifier for the Seam workspace associated with the device. Location information for the device. Name of the device location. Name of the room within the device location, when the provider reports one. Time zone of the device location. **Deprecated**. Use `time_zone` instead. Time zone of the device location. ## access codes **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. ## hardware Accessory keypad properties and state. Keypad battery properties. The level. Indicates if an accessory keypad is connected to the device. Represents the current status of the battery charge level. Battery charge level as a value between 0 and 1, inclusive. Represents the current status of the battery charge level. Values are `critical`, which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; `low`, which signifies that the battery is under the preferred threshold and should be charged soon; `good`, which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and `full`, which represents a battery that is fully charged, providing the maximum duration of usage. Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. Alt text for the device image. Image URL for the device. Manufacturer of the device. When a device, such as a smart lock, is connected through a smart hub, the manufacturer of the device might be different from that of the smart hub. # Update an Unmanaged Device Source: https://docs.seam.co/api/devices/unmanaged/update /openapi.json post /devices/unmanaged/update Updates a specified [unmanaged device](/core-concepts/devices/managed-and-unmanaged-devices). To convert an unmanaged device to managed, set `is_managed` to `true`. An unmanaged device has a limited set of visible properties and a subset of supported events. You cannot control an unmanaged device. Any [access codes](/low-level-apis/smart-locks/access-codes/migrating-existing-access-codes) on an unmanaged device are unmanaged. To control an unmanaged device with Seam, [convert it to a managed device](/core-concepts/devices/managed-and-unmanaged-devices#convert-an-unmanaged-device-to-managed). # Update a Device Source: https://docs.seam.co/api/devices/update /openapi.json post /devices/update Updates a specified [device](/core-concepts/devices). You can add or change [custom metadata](/core-concepts/devices/adding-custom-metadata-to-a-device) for a device, change the device's name, or [convert a managed device to unmanaged](/core-concepts/devices/managed-and-unmanaged-devices). # Get an Event Source: https://docs.seam.co/api/events/get /openapi.json post /events/get Returns a specified event. This endpoint returns the same event that would be sent to a [webhook](/developer-tools/webhooks), but it enables you to retrieve an event that already took place. You must include at least one request parameter. # List Events Source: https://docs.seam.co/api/events/list /openapi.json post /events/list Returns a list of all events. This endpoint returns the same events that would be sent to a [webhook](/developer-tools/webhooks), but it enables you to filter or see events that already took place. You must include at least one request parameter. # The Event Object Source: https://docs.seam.co/api/events/object Learn how the event object represents an occurrence in your workspace, such as a device action or status change, that you can list and react to. ## The event Object ```json Event theme={null} { "connected_account_id": "2e3f4a5b-6c7d-8e9f-0a1b-2c3d4e5f6a7b", "created_at": "2025-06-15T16:54:18.000000Z", "device_id": "b3c4d5e6-f7a8-49bc-def1-23456789abcd", "event_description": "The status of a device changed from offline to online. That is, the device.properties.online property changed from false to true. Note that some devices operate entirely in offline mode, so Seam never emits a device.connected event for these devices.", "event_id": "6d7e8f9a-1b2c-3d4e-5f6a-7b8c9d0e1f2a", "event_type": "device.connected", "occurred_at": "2025-06-15T16:54:17.946329Z", "workspace_id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d" } ``` *** ## Properties Date and time at which the event was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. The event type. * `access_code.created` * `access_code.changed` * `access_code.name_changed` * `access_code.code_changed` * `access_code.time_frame_changed` * `access_code.mutations_requested` * `access_code.scheduled_on_device` * `access_code.set_on_device` * `access_code.removed_from_device` * `access_code.delay_in_setting_on_device` * `access_code.failed_to_set_on_device` * `access_code.deleted` * `access_code.delay_in_removing_from_device` * `access_code.failed_to_remove_from_device` * `access_code.modified_external_to_seam` * `access_code.deleted_external_to_seam` * `access_code.backup_access_code_pulled` * `access_code.unmanaged.converted_to_managed` * `access_code.unmanaged.failed_to_convert_to_managed` * `access_code.unmanaged.created` * `access_code.unmanaged.removed` * `access_grant.created` * `access_grant.deleted` * `access_grant.access_granted_to_all_doors` * `access_grant.access_granted_to_door` * `access_grant.access_to_door_lost` * `access_grant.access_times_changed` * `access_grant.could_not_create_requested_access_methods` * `access_method.issued` * `access_method.revoked` * `access_method.card_encoding_required` * `access_method.deleted` * `access_method.reissued` * `access_method.created` * `access_method.delay_in_issuing` * `access_method.failed_to_issue` * `acs_system.connected` * `acs_system.added` * `acs_system.disconnected` * `acs_credential.deleted` * `acs_credential.issued` * `acs_credential.reissued` * `acs_credential.invalidated` * `acs_user.created` * `acs_user.deleted` * `acs_encoder.added` * `acs_encoder.removed` * `acs_access_group.deleted` * `acs_entrance.added` * `acs_entrance.removed` * `client_session.deleted` * `connected_account.connected` * `connected_account.created` * `connected_account.successful_login` * `connected_account.disconnected` * `connected_account.completed_first_sync` * `connected_account.deleted` * `connected_account.completed_first_sync_after_reconnection` * `connected_account.reauthorization_requested` * `action_attempt.lock_door.succeeded` * `action_attempt.lock_door.failed` * `action_attempt.unlock_door.succeeded` * `action_attempt.unlock_door.failed` * `action_attempt.simulate_keypad_code_entry.succeeded` * `action_attempt.simulate_keypad_code_entry.failed` * `action_attempt.simulate_manual_lock_via_keypad.succeeded` * `action_attempt.simulate_manual_lock_via_keypad.failed` * `connect_webview.login_succeeded` * `connect_webview.login_failed` * `device.connected` * `device.added` * `device.converted_to_unmanaged` * `device.unmanaged.converted_to_managed` * `device.unmanaged.connected` * `device.disconnected` * `device.unmanaged.disconnected` * `device.tampered` * `device.low_battery` * `device.battery_status_changed` * `device.removed` * `device.deleted` * `device.third_party_integration_detected` * `device.third_party_integration_no_longer_detected` * `device.salto.privacy_mode_activated` * `device.salto.privacy_mode_deactivated` * `device.connection_became_flaky` * `device.connection_stabilized` * `device.error.subscription_required` * `device.error.subscription_required.resolved` * `device.accessory_keypad_connected` * `device.accessory_keypad_disconnected` * `noise_sensor.noise_threshold_triggered` * `lock.locked` * `lock.unlocked` * `lock.access_denied` * `thermostat.climate_preset_activated` * `thermostat.manually_adjusted` * `thermostat.temperature_threshold_exceeded` * `thermostat.temperature_threshold_no_longer_exceeded` * `thermostat.temperature_reached_set_point` * `thermostat.temperature_changed` * `device.name_changed` * `camera.activated` * `device.doorbell_rang` * `phone.deactivated` * `space.device_membership_changed` * `space.created` * `space.deleted` Date and time at which the event occurred. ID of the workspace associated with the event. # Introduction Source: https://docs.seam.co/api/index The Seam API lets you control smart locks, thermostats, access control systems, and more through a unified REST interface. The Seam API is organized around REST. It accepts JSON request bodies, returns JSON responses, and uses standard HTTP response codes and verbs. You can use the Seam API in a [sandbox workspace](/core-concepts/workspaces) without affecting live devices. The API key you use determines whether the request runs in sandbox or production mode. **Just getting started?** Check out the [quickstart guide](/quickstart). ``` Base URL: https://connect.getseam.com ``` JavaScript, Python, Ruby, PHP, C#, or Go. API keys, client sessions, or personal access tokens. Connect Seam to AI assistants via MCP. *** ## Granting Access Use [Access Grants](/api/access_grants/object) to give people access to physical spaces. Tell Seam *who* should have access, *where*, and *when* — Seam automatically creates the right credential and programs it to the device. The primary API for granting access — create, update, revoke, and manage the full lifecycle. Access Grants support all access methods through a single API: Generate keypad codes for smart locks. Ongoing or time-bound. Encode plastic cards for access control systems. Issue mobile credentials via app or Instant Key URL. Unlock doors remotely via API call. *** ## Devices and Systems Connect and control IoT devices and access control systems. List, get, and update connected devices. Lock and unlock smart locks. Set temperature, HVAC mode, and climate presets. Monitor noise levels and configure thresholds. Manage access control system users, credentials, entrances, and encoders. *** ## Setup Connect device accounts and configure your workspace. Authorization flows to link user device accounts. Manage linked manufacturer accounts. Map your users to Seam for cross-system identity. Sandbox and production workspaces. Scoped sessions for frontend apps. Customer portals and data. Organize devices and entrances into named groups. *** ## Monitoring Track events, subscribe to webhooks, and poll for action completion. Query device and system events. Real-time event notifications. Poll async operations until completion. *** ## Low-Level APIs These APIs let you program credentials directly on devices. For most access-granting workflows, use [Access Grants](/api/access_grants/object) instead — they handle credential creation, device programming, and lifecycle management automatically. Directly program PIN codes on smart lock keypads. Temporary mobile keys without an app install. Manage phones for mobile access credentials. # SDK Installation Source: https://docs.seam.co/api/installation Install a Seam SDK in your preferred language—JavaScript, Python, Ruby, PHP, or C#—to start building integrations with the Seam API in minutes. **Building this integration with Claude?** Install the [Seam Docs MCP server](/api/mcp-installation) first. It connects Claude directly to Seam's API reference, integration guides, and 400+ device models so Claude can guide you through implementation step by step — no copy-pasting from the docs. Install one of the Seam SDKs in the programming language of your choice. Seam supports many programming languages, such as the following: * JavaScript / TypeScript ([npm](https://www.npmjs.com/package/seam), [GitHub](https://github.com/seamapi/javascript)) * Python ([pip](https://pypi.org/project/seam/), [GitHub](https://github.com/seamapi/python)) * Ruby Gem ([rubygem](https://rubygems.org/gems/seam), [GitHub](https://github.com/seamapi/ruby)) * PHP ([packagist](https://packagist.org/packages/seamapi/seam), [GitHub](https://github.com/seamapi/php)) * C# ([nuget](https://www.nuget.org/packages/Seam), [GitHub](https://github.com/seamapi/csharp)) ```bash theme={null} npm i seam ``` ```bash theme={null} pip install seam # For some development environments, use pip3 in this command instead of pip. ``` ```bash theme={null} bundle add seam ``` ```bash theme={null} composer require seamapi/seam ``` Install using [nuget](https://www.nuget.org/packages/Seam). # Delete an Instant Key Source: https://docs.seam.co/api/instant_keys/delete /openapi.json post /instant_keys/delete Deletes a specified [Instant Key](/use-cases/granting-access/using-instant-keys). # Get an Instant Key Source: https://docs.seam.co/api/instant_keys/get /openapi.json post /instant_keys/get Gets an [instant key](/use-cases/granting-access/using-instant-keys). You must include at least one request parameter. # List Instant Keys Source: https://docs.seam.co/api/instant_keys/list /openapi.json post /instant_keys/list Returns a list of all [instant keys](/use-cases/granting-access/using-instant-keys). # The Instant Key Object Source: https://docs.seam.co/api/instant_keys/object Learn how the instant_key object lets you issue a Bluetooth mobile key with one API call and share it by link, text, or email—no app install required. ## The instant\_key Object Represents a Seam Instant Key. For issuing Bluetooth mobile keys, Instant Keys are the fastest way to share access. With a single API call, you can create a mobile key and send it through text or email or embed it in your own app. There’s no app to install, nor account to create. Your user just taps a link and gets a lightweight, native-feeling experience using iOS App Clip or Instant Apps on Android. Further, Instant Keys work offline, so even in areas with poor cellular or Wi-Fi, like elevator banks or concrete-walled hallways, the Instant Keys still work. ```json Instant Key theme={null} { "client_session_id": "bfe3b1c6-fb9e-48b1-9b5b-c762b2983af6", "created_at": "2025-06-14T16:54:17.946559Z", "expires_at": "2025-06-16T16:54:17.946559Z", "instant_key_id": "1d05c2f6-5b6f-4a9c-b80d-1eca26be12b9", "instant_key_url": "https://ik.seam.co/ABCXYZ", "user_identity_id": "e7a94acb-bd8a-4462-b6fb-8612d35cd7c3", "workspace_id": "4d1c24b2-781e-4d1a-8d77-15249ad57c8a" } ``` *** ## Properties ID of the client session associated with the Instant Key. Date and time at which the Instant Key was created. Customization applied to the Instant Key UI. URL of the logo displayed on the Instant Key. Primary color used in the Instant Key UI. Secondary color used in the Instant Key UI. ID of the customization profile associated with the Instant Key. Date and time at which the Instant Key expires. ID of the Instant Key. Shareable URL for the Instant Key. Use the URL to deliver the Instant Key to your user through a link in a text message or email or by embedding it in your web app. ID of the user identity associated with the Instant Key. ID of the workspace that contains the Instant Key. # Configure Auto-Lock Source: https://docs.seam.co/api/locks/configure_auto_lock /openapi.json post /locks/configure_auto_lock Configures the auto-lock setting for a specified [lock](/low-level-apis/smart-locks). # Lock Errors and Warnings Source: https://docs.seam.co/api/locks/errors Errors and warnings that Seam reports on the Lock resource, each with its code and meaning. These are Lock-specific errors and warnings. For errors and warnings common to all devices, see [Device Errors and Warnings](/api/devices/errors). ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "salto_ks_subscription_limit_exceeded", "message": "Indicates that the Salto site user limit has been reached.", "created_at": "2025-01-01T00:00:00.000Z", "is_connected_account_error": true, "is_device_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates that the error is a [connected account](/api/connected_accounts/object) error. Indicates that the error is not a device error. ### `august_lock_not_authorized` Indicates that the user is not authorized to use the August lock. *** ### `dormakaba_sites_disconnected` Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. *** ### `salto_ks_subscription_limit_exceeded` Indicates that the Salto site user limit has been reached. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "ttlock_lock_gateway_unlocking_not_enabled", "message": "Indicates that the Remote Unlock feature is not enabled in the settings.\"", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `accessory_keypad_setup_required` Indicates that the accessory keypad exists, but is not linked to the Igloohome Bridge. Online access code programming will fail until the keypad is linked to the Igloohome Bridge in the Igloohome app. *** ### `hub_required_for_additional_capabilities` Indicates that a hub or relay must be connected to unlock additional capabilities such as remote unlock. *** ### `keynest_unsupported_locker` Indicates that the key is in a locker that does not support the access codes API. *** ### `lockly_time_zone_not_configured` Indicates that Seam detected that the Lockly device does not have a time zone configured. Time-bound codes may not work as expected. *** ### `power_saving_mode` Indicates that the device is in power saving mode and may have limited functionality. *** ### `salto_ks_subscription_limit_almost_reached` Indicates that the Salto KS site has exceeded 80% of the maximum number of allowed users. Increase your subscription limit or delete some users from your site. *** ### `time_zone_mismatch` Indicates that the device's configured time zone does not match its hardware UTC offset. Time-bound access codes may activate at the wrong local time. *** ### `time_zone_unknown` Indicates that Seam does not know the device's time zone. Set a time zone to enable time-bound access codes. *** ### `ttlock_lock_gateway_unlocking_not_enabled` Indicates that the Remote Unlock feature is not enabled in the settings." *** ### `ttlock_weak_gateway_signal` Indicates that the gateway signal is weak. *** ### `two_n_device_missing_timezone` Indicates that the 2N device does not have a time zone configured. Configure a time zone on the device to enable access codes. *** ### `ultraloq_time_zone_unknown` Indicates that Seam does not know the time zone of the Ultraloq device. Set a time zone to enable time-bound access codes. *** ### `unreliable_online_status` Indicates that the device may optimistically be reported as online because the provider does not reliably report its online status. *** # Lock Events Source: https://docs.seam.co/api/locks/events Webhook events that Seam emits for the Lock resource, with example payloads and properties. ## `lock.locked` A [lock](/low-level-apis/smart-locks) was locked. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_is_managed": true, "action_attempt_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [lock](/low-level-apis/smart-locks) was locked.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "lock.locked", "is_via_bluetooth": true, "is_via_nfc": true, "method": "keycode", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access code that was used to lock the device. Whether the access code is managed by Seam (true) or unmanaged (false). Only present when access\_code\_id is set. ID of the Seam action attempt that triggered this lock. Present only when the lock was initiated through Seam (via a `LOCK_DOOR` action attempt). Code (PIN) that was used to lock the device, if known. Taken from the matched managed or unmanaged access code, or from the code reported by the provider when no access code matched. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `lock.locked` Whether the lock action was performed over Bluetooth by a remote client (such as the provider's mobile app), rather than a direct physical interaction or a Seam-initiated remote action. Whether the lock action was performed by an NFC credential tap (such as an Apple Home Key or an NFC key fob) presented to the lock, rather than a direct physical interaction or a Seam-initiated remote action. Method by which the lock was locked. `keycode`: an access code was used (see `access_code_id`). `manual`: a physical action such as a thumbturn or button press. `remote`: a remote action via an app, Bluetooth, or the Seam API (see `action_attempt_id` if Seam-initiated; see `is_via_bluetooth` or `is_via_nfc` for the transport). `automatic`: triggered automatically, for example by an auto-relock timer. `unknown`: could not be determined. Possible values: `keycode`, `manual`, `automatic`, `unknown`, `remote`, `card` Date and time at which the event occurred. ID of the workspace associated with the event. ## `lock.unlocked` A [lock](/low-level-apis/smart-locks) was unlocked. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "access_code_is_managed": true, "action_attempt_id": "00000000-0000-0000-0000-000000000000", "code": "1234", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [lock](/low-level-apis/smart-locks) was unlocked.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "lock.unlocked", "is_via_bluetooth": true, "is_via_nfc": true, "method": "keycode", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access code that was used to unlock the affected device. Whether the access code is managed by Seam (true) or unmanaged (false). Only present when access\_code\_id is set. ID of the Seam action attempt that triggered this unlock. Present only when the unlock was initiated through Seam (via an `UNLOCK_DOOR` action attempt). Code (PIN) that was used to unlock the affected device, if known. Taken from the matched managed or unmanaged access code, or from the code reported by the provider when no access code matched. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `lock.unlocked` Whether the unlock action was performed over Bluetooth by a remote client (such as the provider's mobile app), rather than a direct physical interaction or a Seam-initiated remote action. Whether the unlock action was performed by an NFC credential tap (such as an Apple Home Key or an NFC key fob) presented to the lock, rather than a direct physical interaction or a Seam-initiated remote action. Method by which the lock was unlocked. `keycode`: an [access code](/low-level-apis/smart-locks/access-codes) was used (see `access_code_id`). `manual`: a physical action such as a thumbturn or handle press. `remote`: a remote action via an app, Bluetooth, or the Seam API (see `action_attempt_id` if Seam-initiated; see `is_via_bluetooth` or `is_via_nfc` for the transport). `automatic`: triggered automatically, for example by a time-based schedule. `unknown`: could not be determined. Possible values: `keycode`, `manual`, `automatic`, `unknown`, `remote`, `card` Date and time at which the event occurred. ID of the workspace associated with the event. ## `lock.access_denied` The [lock](/low-level-apis/smart-locks) denied access to a user after one or more consecutive invalid attempts to unlock the device. ```json Example webhook payload theme={null} { "access_code_id": "00000000-0000-0000-0000-000000000000", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "The [lock](/low-level-apis/smart-locks) denied access to a user after one or more consecutive invalid attempts to unlock the device.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "lock.access_denied", "occurred_at": "2025-01-01T00:00:00.000Z", "reason": { "message": "", "reason_code": "unknown_code" }, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` ID of the access code that was used in the unlock attempts. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `lock.access_denied` Date and time at which the event occurred. Why access was denied, when the provider reports a determinable cause. Omitted when unknown. Human-readable explanation of why access was denied. Normalized reason a lock denied access. Provider-agnostic; not all providers report every value. Possible values: `unknown_code`, `expired_code`, `blocklisted_code`, `too_many_attempts`, `blocked_by_privacy_mode`, `credential_error` ID of the workspace associated with the event. # Get a Lock Source: https://docs.seam.co/api/locks/get /openapi.json post /locks/get Deprecated. Use `/devices/get` instead. Returns a specified [lock](/low-level-apis/smart-locks). You must include at least one request parameter. # List Locks Source: https://docs.seam.co/api/locks/list /openapi.json post /locks/list Returns a list of all [locks](/low-level-apis/smart-locks). # Lock a Lock Source: https://docs.seam.co/api/locks/lock_door /openapi.json post /locks/lock_door Locks a [lock](/low-level-apis/smart-locks). See also [Locking and Unlocking Smart Locks](/low-level-apis/smart-locks/lock-and-unlock). # The Lock Object Source: https://docs.seam.co/api/locks/object Learn how the device object represents a smart lock connected to Seam, including its lock-specific properties, capabilities, errors, and events. ## The device Object for Locks Represents a [lock](/low-level-apis/smart-locks). The Seam API enables you to control connected smart locks from a wide variety of manufacturers, including locks that provide online and offline [access code](/low-level-apis/smart-locks/access-codes) programming. Depending on the smart lock brand and model, actions that you can perform include remote unlock, remote lock, and programming access codes. You can also view a lock's properties, capabilities, and status. Further, you can monitor for unlock and lock events. See also [Webhooks](/developer-tools/webhooks). ```json Lock Device theme={null} { "can_program_online_access_codes": true, "can_remotely_lock": true, "can_remotely_unlock": true, "capabilities_supported": [ "access_code", "lock" ], "connected_account_id": "8e3a4f1b-2c7d-4a9e-8b5f-3d2c1a0b9e8f", "created_at": "2025-03-27T02:08:16.418Z", "space_ids": [], "custom_metadata": { "id": "internalId1" }, "device_id": "a69569e1-133b-4a9d-b883-018641bfe543", "device_type": "schlage_lock", "display_name": "FRONT DOOR", "errors": [], "is_managed": true, "location": { "location_name": "Front Door", "timezone": "America/New_York" }, "nickname": "Front Door", "properties": { "appearance": { "name": "FRONT DOOR" }, "battery": { "level": 0.48, "status": "good" }, "battery_level": 0.48, "code_constraints": [ { "constraint_type": "name_length", "max_length": 9 } ], "has_native_entry_events": true, "image_alt_text": "Schlage Sense Smart Deadbolt with Camelot Trim, Front", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/devices/schlage_sense-smart-deadbolt-with-camelot-trim_front.png&q=75&w=128", "locked": false, "manufacturer": "schlage", "model": { "accessory_keypad_supported": false, "can_connect_accessory_keypad": false, "display_name": "Encode", "has_built_in_keypad": true, "manufacturer_display_name": "Schlage", "offline_access_codes_supported": false, "online_access_codes_supported": true }, "name": "FRONT DOOR", "offline_access_codes_enabled": false, "online": true, "online_access_codes_enabled": true, "schlage_metadata": { "device_id": "a69569e1-133b-4a9d-b883-018641bfe543", "device_name": "FRONT DOOR", "model": "Encode" }, "serial_number": "34000000000531e0", "supported_code_lengths": [ 4, 5, 6, 7, 8 ], "supports_backup_access_code_pool": true, "supports_offline_access_codes": false }, "warnings": [], "workspace_id": "5d7f2e1a-9c8b-4f3e-8d2c-1a0b9e8f7c6d" } ``` *** ## Properties Indicates whether the lock supports configuring automatic locking. Indicates whether the thermostat supports cooling. Indicates whether the thermostat supports heating. Indicates whether the thermostat supports simultaneous heating and cooling. Indicates whether the device supports programming offline access codes. Indicates whether the device supports programming online access codes. Indicates whether the thermostat supports different climate programs for each day of the week. Indicates whether the thermostat supports a single climate program applied to every day. Indicates whether the thermostat supports weekday/weekend climate programs. Indicates whether the device supports remote locking. Indicates whether the device supports remote unlocking. Indicates whether the thermostat supports running climate programs. Indicates whether the device supports simulating connection in a sandbox. Indicates whether the device supports simulating disconnection in a sandbox. Indicates whether the hub supports simulating connection in a sandbox. Indicates whether the hub supports simulating disconnection in a sandbox. Indicates whether the device supports simulating a paid subscription in a sandbox. Indicates whether the device supports simulating removal in a sandbox. Indicates whether the thermostat can be turned off. Indicates whether the lock supports unlocking with an access code. Collection of capabilities that the device supports when connected to Seam. Values are `access_code`, which indicates that the device can manage and utilize digital PIN codes for secure access; `lock`, which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; `noise_detection`, which indicates that the device supports monitoring and responding to ambient noise levels; `thermostat`, which indicates that the device can regulate and adjust indoor temperatures; `battery`, which indicates that the device can manage battery life and health; and `phone`, which indicates that the device is a mobile device, such as a smartphone. **Important:** Superseded by [capability flags](/capability-guides/device-and-system-capabilities#capability-flags). Unique identifier for the account associated with the device. Date and time at which the device object was created. Set of key:value pairs. Adding custom metadata to a resource, such as a [Connect Webview](/core-concepts/connect-webviews/attaching-custom-data-to-the-connect-webview), [connected account](/core-concepts/connected-accounts/adding-custom-metadata-to-a-connected-account), or [device](/core-concepts/devices/adding-custom-metadata-to-a-device), enables you to store custom information, like customer details or internal IDs from your application. ID of the device. Type of the device. Display name of the device, defaults to nickname (if it is set) or `properties.appearance.name`, otherwise. Enables administrators and users to identify the device easily, especially when there are numerous devices. Array of errors associated with the device. Each error object within the array contains two fields: `error_code` and `message`. `error_code` is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. Indicates whether Seam manages the device. See also [Managed and Unmanaged Devices](/core-concepts/devices/managed-and-unmanaged-devices). Optional nickname to describe the device, settable through Seam. Properties of the device. Accessory keypad properties and state. Keypad battery properties. The level. Indicates if an accessory keypad is connected to the device. Appearance-related properties, as reported by the device. Name of the device as seen from the provider API and application, not settable through Seam. Represents the current status of the battery charge level. Battery charge level as a value between 0 and 1, inclusive. Represents the current status of the battery charge level. Values are `critical`, which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; `low`, which signifies that the battery is under the preferred threshold and should be charged soon; `good`, which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and `full`, which represents a battery that is fully charged, providing the maximum duration of usage. Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. Array of noise threshold IDs that are currently triggering. Indicates whether the device has direct power. Alt text for the device image. Image URL for the device. Manufacturer of the device. When a device, such as a smart lock, is connected through a smart hub, the manufacturer of the device might be different from that of the smart hub. Device model-related properties. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The accessory keypad supported. Indicates whether the device can connect a accessory keypad. Display name of the device model. Indicates whether the device has a built in accessory keypad. Display name that corresponds to the manufacturer-specific terminology for the device. **Deprecated**. use device.can\_program\_offline\_access\_codes. The offline access codes supported. **Deprecated**. use device.can\_program\_online\_access\_codes. The online access codes supported. **Deprecated**. use device.display\_name instead Name of the device. Indicates current noise level in decibels, if the device supports noise detection. **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. Indicates whether the device is online. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. Serial number of the device. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The supports accessory keypad. **Deprecated**. use offline\_access\_codes\_enabled The supports offline access codes. ASSA ABLOY Credential Service metadata for the phone. Endpoints associated with the phone. ID of the associated endpoint. Indicated whether the endpoint is active. Indicates whether the credential service has active endpoints associated with the phone. Salto Space credential service metadata for the phone. Indicates whether the credential service has an active associated phone. Metadata for an Akiles device. Group ID to which to add users for an Akiles device. Gadget ID for an Akiles device. Gadget name for an Akiles device. Product name for an Akiles device. Metadata for an Aqara device. Device name for an Aqara device. Device ID (did) for an Aqara device. Firmware version for an Aqara device. Model identifier for an Aqara device. Model type for an Aqara device. Parent gateway device ID for an Aqara device. Position (room) ID for an Aqara device. Time zone reported for an Aqara device (e.g. GMT-07:00). Metadata for an ASSA ABLOY Vostio system. Encoder name for an ASSA ABLOY Vostio system. Metadata for an August device. Indicates whether an August device has a keypad. House ID for an August device. House name for an August device. Keypad battery level for an August device. Lock ID for an August device. Lock name for an August device. Model for an August device. Metadata for an Avigilon Alta system. Entry name for an Avigilon Alta system. Total count of entry relays for an Avigilon Alta system. Organization name for an Avigilon Alta system. Site ID for an Avigilon Alta system. Site name for an Avigilon Alta system. Zone ID for an Avigilon Alta system. Zone name for an Avigilon Alta system. Metadata for a Brivo device. Indicates whether the Brivo access point has activation (remote unlock) enabled. Device name for a Brivo device. Metadata for a ControlByWeb device. Device ID for a ControlByWeb device. Device name for a ControlByWeb device. Relay name for a ControlByWeb device. Metadata for a dormakaba Oracode device. Device ID for a dormakaba Oracode device. Door ID for a dormakaba Oracode device. Indicates whether a door is wireless for a dormakaba Oracode device. Door name for a dormakaba Oracode device. IANA time zone for a dormakaba Oracode device. Predefined time slots for a dormakaba Oracode device. Check in time for a time slot for a dormakaba Oracode device. Checkout time for a time slot for a dormakaba Oracode device. ID of a user level for a dormakaba Oracode device. Prefix for a user level for a dormakaba Oracode device. Indicates whether a time slot for a dormakaba Oracode device is a 24-hour time slot. Indicates whether a time slot for a dormakaba Oracode device is in biweekly mode. Indicates whether a time slot for a dormakaba Oracode device is a master time slot. Indicates whether a time slot for a dormakaba Oracode device is a one-shot time slot. Name of a time slot for a dormakaba Oracode device. Prefix for a time slot for a dormakaba Oracode device. **Deprecated**. Previously marked as "@DEPRECATED." Site ID for a dormakaba Oracode device. Site name for a dormakaba Oracode device. Metadata for an ecobee device. Device name for an ecobee device. Device ID for an ecobee device. Metadata for a 4SUITES device. Device ID for a 4SUITES device. Device name for a 4SUITES device. Reclose delay, in seconds, for a 4SUITES device. Metadata for a Genie device. Lock name for a Genie device. Door name for a Genie device. Metadata for a Honeywell Resideo device. Device name for a Honeywell Resideo device. Device ID for a Honeywell Resideo device. Metadata for an igloo device. Bridge ID for an igloo device. Device ID for an igloo device. Model for an igloo device. Metadata for an igloohome device. Bridge ID for an igloohome device. Bridge name for an igloohome device. Device ID for an igloohome device. Device name for an igloohome device. Indicates whether a keypad is linked to a bridge for an igloohome device. Keypad ID for an igloohome device. Metadata for a KeyNest device. Address for a KeyNest device. Current or last store ID for a KeyNest device. Current status for a KeyNest device. Current user company for a KeyNest device. Current user email for a KeyNest device. Current user name for a KeyNest device. Current user phone number for a KeyNest device. Default office ID for a KeyNest device. Device name for a KeyNest device. Fob ID for a KeyNest device. Handover method for a KeyNest device. Whether the KeyNest device has a photo. Whether the key is in a locker that does not support the access codes API. Key ID for a KeyNest device. Key notes for a KeyNest device. KeyNest app user for a KeyNest device. Last movement timestamp for a KeyNest device. Property ID for a KeyNest device. Property postcode for a KeyNest device. Status type for a KeyNest device. Subscription plan for a KeyNest device. Metadata for a Kisi device. Description for a Kisi device. Lock ID for a Kisi device. Lock name for a Kisi device. Place name for a Kisi device. Metadata for a Korelock device. Device ID for a Korelock device. Device name for a Korelock device. Firmware version for a Korelock device. Location ID for a Korelock device. Required for timebound access codes. Model code for a Korelock device. Serial number for a Korelock device. WiFi signal strength (0-1) for a Korelock device. Metadata for a Kwikset device. Device ID for a Kwikset device. Device name for a Kwikset device. Model number for a Kwikset device. Metadata for a Lockly device. Device ID for a Lockly device. Device name for a Lockly device. Model for a Lockly device. Metadata for a Minut device. Device ID for a Minut device. Device name for a Minut device. Latest sensor values for a Minut device. Latest accelerometer Z-axis reading for a Minut device. Time of latest accelerometer Z-axis reading for a Minut device. Value of latest accelerometer Z-axis reading for a Minut device. Latest humidity reading for a Minut device. Time of latest humidity reading for a Minut device. Value of latest humidity reading for a Minut device. Latest pressure reading for a Minut device. Time of latest pressure reading for a Minut device. Value of latest pressure reading for a Minut device. Latest sound reading for a Minut device. Time of latest sound reading for a Minut device. Value of latest sound reading for a Minut device. Latest temperature reading for a Minut device. Time of latest temperature reading for a Minut device. Value of latest temperature reading for a Minut device. Metadata for a Google Nest device. Custom device name for a Google Nest device. The device owner sets this value. Device name for a Google Nest device. Google sets this value. Display name for a Google Nest device. Device ID for a Google Nest device. ID of the Google Nest structure containing the device. Name of the Google Nest structure containing the device. The device owner sets this value. Metadata for a NoiseAware device. Device ID for a NoiseAware device. Device model for a NoiseAware device. Device name for a NoiseAware device. Noise level, in decibels, for a NoiseAware device. Noise level, expressed as a Noise Risk Score (NRS), for a NoiseAware device. Metadata for a Nuki device. Device ID for a Nuki device. Device name for a Nuki device. Indicates whether keypad 2 is paired for a Nuki device. Indicates whether the keypad battery is in a critical state for a Nuki device. Indicates whether the keypad is paired for a Nuki device. Metadata for an Omnitec device. Whether the Omnitec lock has a connected gateway for remote operations. Operator-assigned alias for an Omnitec device. Lock ID for an Omnitec device. Bluetooth MAC address for an Omnitec device. Lock name for an Omnitec device. IANA time zone for the Omnitec device, used to schedule time-bound access codes at the correct local time (accounting for DST). Static UTC offset of the Omnitec lock in milliseconds. Does not account for DST. Metadata for a Ring device. Device ID for a Ring device. Device name for a Ring device. Metadata for a Salto KS device. Battery level for a Salto KS device. Customer reference for a Salto KS device. Indicates whether the site has a Salto KS subscription that supports custom PINs. Lock ID for a Salto KS device. Lock type for a Salto KS device. Locked state for a Salto KS device. Model for a Salto KS device. Site ID for the Salto KS site to which the device belongs. Site name for the Salto KS site to which the device belongs. **Deprecated**. Use `salto_ks_metadata` instead. Metada for a Salto device. Battery level for a Salto device. Customer reference for a Salto device. Lock ID for a Salto device. Lock type for a Salto device. Locked state for a Salto device. Model for a Salto device. Site ID for the Salto KS site to which the device belongs. Site name for the Salto KS site to which the device belongs. Metadata for a Schlage device. Device ID for a Schlage device. Device name for a Schlage device. Model for a Schlage device. Metadata for Seam Bridge. Device number for Seam Bridge. Name for Seam Bridge. Unlock method for Seam Bridge. Metadata for a Sensi device. Device ID for a Sensi device. Device name for a Sensi device. Set to true when the device does not support the /dual-setpoints API endpoint. Enforced setpoint range in Celsius for a Sensi device, derived from an OutOfRange API error. Product type for a Sensi device. Metadata for a SmartThings device. Device ID for a SmartThings device. Device name for a SmartThings device. Location ID for a SmartThings device. Model for a SmartThings device. Metadata for a tado° device. Device type for a tado° device. Serial number for a tado° device. Metadata for a Tedee device. Bridge ID for a Tedee device. Bridge name for a Tedee device. Device ID for a Tedee device. Device model for a Tedee device. Device name for a Tedee device. Keypad ID for a Tedee device. Serial number for a Tedee device. Metadata for a TTLock device. Feature value for a TTLock device. Features for a TTLock device. Indicates whether a TTLock device supports auto-lock time configuration. Indicates whether a TTLock device supports an incomplete keyboard passcode. Indicates whether a TTLock device supports the lock command. Indicates whether a TTLock device supports a passcode. Indicates whether a TTLock device supports passcode management. Indicates whether a TTLock device supports unlock via gateway. Indicates whether a TTLock device supports Wi-Fi. Indicates whether a TTLock device has a gateway. Lock alias for a TTLock device. Lock ID for a TTLock device. Lock-side timezone offset in milliseconds east of UTC, as configured in the TTLock app. Source of truth for the lock's wall-clock interpretation of access code start/end times — a misconfigured value here is the typical cause of customer "codes offset by N hours" reports. Diagnostic only; Seam does not convert times based on this value. Wireless keypads for a TTLock device. ID for a wireless keypad for a TTLock device. Name for a wireless keypad for a TTLock device. Metadata for a 2N device. Device ID for a 2N device. Device name for a 2N device. Metadata for an Ultraloq device. Device ID for an Ultraloq device. Device name for an Ultraloq device. Device type for an Ultraloq device. IANA timezone for the Ultraloq device. Metadata for an ASSA ABLOY Visionline system. Encoder ID for an ASSA ABLOY Visionline system. Metadata for a Wyze device. Device ID for a Wyze device. Device information model for a Wyze device. Device name for a Wyze device. Keypad UUID for a Wyze device. Locker status (hardlock) for a Wyze device. Product model for a Wyze device. Product name for a Wyze device. Product type for a Wyze device. The delay in seconds before the lock automatically locks after being unlocked. Indicates whether automatic locking is enabled. Indicates whether the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is currently enabled for the device. To disable it, set this to `false` using [/devices/update](/api/devices/update). Constraints on access codes for the device. Seam represents each constraint as an object with a `constraint_type` property. Depending on the constraint type, there may also be additional properties. Note that some constraints are manufacturer- or device-specific. The constraint type. Maximum name length constraint for access codes. Minimum name length constraint for access codes. Indicates whether the door is open. Indicates whether the device supports native entry events. Keypad battery status. Keypad battery charge level. Indicates whether the lock is locked. Maximum number of active access codes that the device supports. Time frames that may be requested when creating an offline access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Time frames that may be requested when creating an online access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Supported code lengths for access codes. Indicates whether the device supports a [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes). **Deprecated**. Use `active_thermostat_schedule_id` with `/thermostats/schedules/get` instead. Active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) was created. ID of the desired [thermostat](/capability-guides/thermostats) device. Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Errors associated with the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Indicates whether a person at the thermostat can change the thermostat's settings after the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts. Number of minutes for which a person at the thermostat can change the thermostat's settings after the activation of the scheduled [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). See also [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). ID of the workspace that contains the thermostat schedule. ID of the active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Climate preset modes that the thermostat supports, such as "home", "away", "wake", "sleep", "occupied", and "unoccupied". Available [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets) for the thermostat. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Fan mode settings that the thermostat supports. HVAC mode settings that the thermostat supports. Current climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). **Deprecated**. use fallback\_climate\_preset\_key to specify a fallback climate preset instead. The default climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Key of the [fallback climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) for the thermostat. **Deprecated**. Use `current_climate_setting.fan_mode_setting` instead. The fan mode setting. Indicates whether the connected HVAC system is currently cooling, as reported by the thermostat. Indicates whether the fan in the connected HVAC system is currently running, as reported by the thermostat. Indicates whether the connected HVAC system is currently heating, as reported by the thermostat. Indicates whether the current thermostat settings differ from the most recent active program or schedule that Seam activated. For this condition to occur, `current_climate_setting.manual_override_allowed` must also be `true`. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Maximum number of periods that the thermostat can support per day. For example, if the thermostat supports 4 periods per day, this value is 4. Maximum number of climate presets that the thermostat can support for weekly programming. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °C between the cooling and heating set points when in heat-cool (auto) mode. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °F between the cooling and heating set points when in heat-cool (auto) mode. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Reported relative humidity, as a value between 0 and 1, inclusive. Reported temperature in °C. Reported temperature in °F. Current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Precision of the thermostat's period in minutes. For example, if the thermostat supports 15-minute periods, this value is 15. All values are relative to the top of the hour, so for 15 minutes, the periods would be 0, 15, 30, and 45 minutes past the hour. Configured [daily programs](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat daily program was created. ID of the thermostat device on which the thermostat daily program is configured. User-friendly name to identify the thermostat daily program. Array of thermostat daily program periods. Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to activate at the `starts_at_time`. Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the thermostat daily program. ID of the workspace that contains the thermostat daily program. Current [weekly program](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat weekly program was created. ID of the thermostat daily program to run on Fridays. ID of the thermostat daily program to run on Mondays. ID of the thermostat daily program to run on Saturdays. ID of the thermostat daily program to run on Sundays. ID of the thermostat daily program to run on Thursdays. ID of the thermostat daily program to run on Tuesdays. ID of the thermostat daily program to run on Wednesdays. IDs of the spaces the device is in. Array of warnings associated with the device. Each warning object within the array contains two fields: `warning_code` and `message`. `warning_code` is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. Unique identifier for the Seam workspace associated with the device. ## Access Codes **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The supports accessory keypad. **Deprecated**. use offline\_access\_codes\_enabled The supports offline access codes. Indicates whether the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is currently enabled for the device. To disable it, set this to `false` using [/devices/update](/api/devices/update). Constraints on access codes for the device. Seam represents each constraint as an object with a `constraint_type` property. Depending on the constraint type, there may also be additional properties. Note that some constraints are manufacturer- or device-specific. The constraint type. Maximum name length constraint for access codes. Minimum name length constraint for access codes. Indicates whether the device supports native entry events. Keypad battery status. Keypad battery charge level. Maximum number of active access codes that the device supports. Time frames that may be requested when creating an offline access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Time frames that may be requested when creating an online access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Supported code lengths for access codes. Indicates whether the device supports a [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes). ## Locks The delay in seconds before the lock automatically locks after being unlocked. Indicates whether automatic locking is enabled. Indicates whether the door is open. Indicates whether the lock is locked. # Simulate a Keypad Code Entry Source: https://docs.seam.co/api/locks/simulate/keypad_code_entry /openapi.json post /locks/simulate/keypad_code_entry Simulates the entry of a code on a keypad. You can only perform this action for [August](/device-and-system-integration-guides/august-locks) devices within [sandbox workspaces](/core-concepts/workspaces#sandbox-workspaces). # Simulate a Manual Lock Action Using a Keypad Source: https://docs.seam.co/api/locks/simulate/manual_lock_via_keypad /openapi.json post /locks/simulate/manual_lock_via_keypad Simulates a manual lock action using a keypad. You can only perform this action for [August](/device-and-system-integration-guides/august-locks) devices within [sandbox workspaces](/core-concepts/workspaces#sandbox-workspaces). # Unlock a Lock Source: https://docs.seam.co/api/locks/unlock_door /openapi.json post /locks/unlock_door Unlocks a [lock](/low-level-apis/smart-locks). See also [Locking and Unlocking Smart Locks](/low-level-apis/smart-locks/lock-and-unlock). # MCP Installation Source: https://docs.seam.co/api/mcp-installation Connect the Seam Docs MCP server to Claude to search Seam's API reference and device database from inside your conversations. The **Seam Docs MCP Server** is a public, read-only [Model Context Protocol](https://modelcontextprotocol.io/) server that gives Claude and other MCP-compatible clients access to Seam's developer documentation and device database. Connect it once, then ask Claude questions about the Seam API, capabilities, webhooks, SDK usage, and the 400+ supported device models — across smart locks, thermostats, access control systems, and noise sensors. Claude grounds its answers in the most up-to-date Seam docs. The server is intended for developers integrating with Seam who want Claude to answer Seam questions accurately, whether they're looking up an API endpoint, checking which lock models support mobile keys, or finding the right integration guide. It is read-only: it cannot control devices, manage access codes, create resources, or perform any other write operations against the Seam API. ## Server Details | Property | Value | | -------------- | --------------------------- | | Server URL | `https://mcp.seam.co/mcp` | | Transport | Streamable HTTP | | Authentication | None — the server is public | No API key, account, or sign-up is required to use the Seam Docs MCP server. It only reads and returns Seam's public documentation. ## What You Can Ask Once connected, you can ask Claude questions like the following, and Claude will fetch the answer from the Seam docs and device database: * "How do I unlock a Schlage Encode lock with the Seam API?" * "Show me the webhook payload for `lock.locked`." * "What's the difference between an access code and an access grant?" * "Which smart lock models support mobile keys and remote unlock?" * "Compare August and Yale lock features for a hospitality deployment." * "Find the right integration guide for property management workflows." * "Does Seam support Salto KS access control systems?" * "How do I create a Connect Webview from the Python SDK?" ## Connect From Claude.ai 1. Sign in to [claude.ai](https://claude.ai). 2. Open **Settings → Connectors**. 3. Click **Add custom connector**. 4. Set the **URL** to `https://mcp.seam.co/mcp`. 5. Set the **Name** to `Seam Docs`. 6. Save. No authentication is required. The connector is now available to Claude in any new conversation. ## Connect From Claude Desktop 1. Open Claude Desktop and go to **Settings → Connectors**. 2. Click **Add custom connector**. 3. Set the **URL** to `https://mcp.seam.co/mcp`. 4. Set the **Name** to `Seam Docs`. 5. Save and restart Claude Desktop if prompted. ## Connect From Claude Code Run the following command from your terminal: ```bash theme={null} claude mcp add --transport http seam-docs https://mcp.seam.co/mcp ``` Or add the following entry to your Claude Code MCP configuration file: ```json theme={null} { "mcpServers": { "seam-docs": { "type": "http", "url": "https://mcp.seam.co/mcp" } } } ``` ## Available Tools The Seam Docs MCP server exposes three read-only tools: | Tool | Display Name | Description | | ------------------- | ----------------- | -------------------------------------------------------------------------------------------------------- | | `search_docs` | Search Seam Docs | Semantic search across all Seam documentation and the 400+ supported device models, ranked by relevance. | | `get_doc` | Get Doc Page | Fetch the full content of any Seam documentation or device page. | | `list_doc_sections` | List Doc Sections | Browse the Seam documentation tree to discover available content. | Claude selects the appropriate tool automatically based on your prompt. ## Troubleshooting * **403 Forbidden on connection** — The server only accepts requests from approved origins (`mcp.seam.co`, `claude.ai`, `app.claude.ai`, and `localhost`). Requests from other origins are rejected. * **Empty search results** — If `search_docs` returns nothing, broaden your query. Use Seam API resource names (for example, `access_codes`) rather than SDK-specific method names, and use generic capability terms (for example, "mobile keys") when searching for devices. * **Connection refused** — Confirm that your network allows outbound HTTPS to `mcp.seam.co`. Some corporate firewalls block custom MCP endpoints. ## Support For questions or issues with the Seam Docs MCP server, contact [support@seam.co](mailto:support@seam.co). # List Noise Sensors Source: https://docs.seam.co/api/noise_sensors/list /openapi.json post /noise_sensors/list Returns a list of all [noise sensors](/capability-guides/noise-sensors). # Create a Noise Threshold Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/create /openapi.json post /noise_sensors/noise_thresholds/create Creates a new [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). Thresholds represent the limits of noise tolerated at a property, which can be customized for each hour of the day. Each device has its own default thresholds, but you can use the Seam API to modify them. # Delete a Noise Threshold Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/delete /openapi.json post /noise_sensors/noise_thresholds/delete Deletes a [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) from a [noise sensor](/capability-guides/noise-sensors). # Noise Thresholds Events Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/events Webhook events that Seam emits for the Noise Thresholds resource, with example payloads and properties. ## `noise_sensor.noise_threshold_triggered` Extended periods of noise or noise exceeding a [threshold](/capability-guides/noise-sensors#what-is-a-threshold) were detected. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "Extended periods of noise or noise exceeding a [threshold](/capability-guides/noise-sensors#what-is-a-threshold) were detected.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "noise_sensor.noise_threshold_triggered", "minut_metadata": {}, "noise_level_decibels": 0, "noise_level_nrs": 0, "noise_threshold_id": "00000000-0000-0000-0000-000000000000", "noise_threshold_name": "", "noiseaware_metadata": {}, "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `noise_sensor.noise_threshold_triggered` Metadata from Minut. Detected noise level in decibels. Detected noise level in Noiseaware Noise Risk Score (NRS). ID of the noise threshold that was triggered. Name of the noise threshold that was triggered. Metadata from Noiseaware. Date and time at which the event occurred. ID of the workspace associated with the event. # Get a Noise Threshold Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/get /openapi.json post /noise_sensors/noise_thresholds/get Returns a specified [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). # List Noise Thresholds Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/list /openapi.json post /noise_sensors/noise_thresholds/list Returns a list of all [noise thresholds](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). # Noise Thresholds Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/object Learn how the noise_threshold object sets the limits of noise tolerated at a property, customizable for each hour of the day on a noise sensor. ## The noise\_threshold Object Represents a [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). Thresholds represent the limits of noise tolerated at a property, which can be customized for each hour of the day. Each device has its own default thresholds, but you can use the Seam API to modify them. ```json Noise Threshold theme={null} { "device_id": "69b9e908-039b-413a-904e-5edee653ca27", "ends_daily_at": "09:00:00[America/Los_Angeles]", "name": "My Noise Threshold", "noise_threshold_decibels": 21, "noise_threshold_id": "f8cef69d-625f-464c-aed4-287c06e0d7fe", "noise_threshold_nrs": 5, "starts_daily_at": "07:00:00[America/Los_Angeles]" } ``` *** ## Properties Unique identifier for the device that contains the noise threshold. Time at which the noise threshold should become inactive daily. Name of the noise threshold. Noise level in decibels for the noise threshold. Unique identifier for the noise threshold. Noise level in Noiseaware Noise Risk Score (NRS) for the noise threshold. This parameter is only relevant for [Noiseaware sensors](/device-and-system-integration-guides/noiseaware-sensors). Time at which the noise threshold should become active daily. # Update a Noise Threshold Source: https://docs.seam.co/api/noise_sensors/noise_thresholds/update /openapi.json post /noise_sensors/noise_thresholds/update Updates a [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors). # The Noise Sensor Object Source: https://docs.seam.co/api/noise_sensors/object Learn how the device object represents a noise sensor that measures sound levels, lets you configure thresholds, and emits disturbance events. ## The device Object for Noise Sensors Represents a [noise sensor](/capability-guides/noise-sensors). Noise sensors are devices that measure that sound level in a given area. You can use noise sensors to monitor noise levels remotely and receive notifications when the noise volume is too loud. The Seam API enables you to configure the [noise thresholds](/capability-guides/noise-sensors/configure-noise-threshold-settings) of a noise sensor and receive events when a disturbance is detected. You can also [simulate triggering a noise threshold](/api/noise_sensors/simulate/trigger_noise_threshold). The Seam API represents a noise sensor as a `device` resource that includes both basic device properties and noise sensor-specific properties. *** ## Endpoints [**`/noise_sensors/list`**](./list) Returns a list of all [noise sensors](/capability-guides/noise-sensors). # Simulate Triggering a Noise Threshold Source: https://docs.seam.co/api/noise_sensors/simulate/trigger_noise_threshold /openapi.json post /noise_sensors/simulate/trigger_noise_threshold Simulates the triggering of a [noise threshold](/capability-guides/noise-sensors/configure-noise-threshold-settings) for a [noise sensor](/capability-guides/noise-sensors) in a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). # Pagination Source: https://docs.seam.co/api/pagination Learn how to paginate Seam API list endpoints using the limit and page_cursor parameters and the pagination response object for faster, efficient apps. For endpoints that can return long lists of resources, using pagination makes your app faster and more efficient. The Seam API and our JavaScript, Python, PHP, and Ruby SDKs support pagination for `list` endpoints. Currently, we support pagination for access codes, access system users, Connect Webviews, connected accounts, and devices. To fetch and process resources across multiple pages in the Seam API, use the `limit` and `page_cursor` parameters, along with the `pagination` response object. The `pagination` object provides the following information:
Property Type Description
next\_page\_cursor String Opaque value that you use to select the next page of results through the page\_cursor parameter.
has\_next\_page Boolean Indicates whether there is another page of results after this one.
next\_page\_url String (URI) URL to get the next page of results.
For pagination in the Seam SDKs, use the corresponding paginator class, for example, `SeamPaginator` in the Seam JavaScript and Python SDKs and `Paginator` in the Seam PHP and Ruby SDKs. The following examples show you how to use pagination in a variety of scenarios: ## Manually Fetch Pages You can specify the number of records per page and the desired page of results. The first `list` request returns the first set of records, as well as the `pagination` object. If `pagination.has_next_page` is `true`, you can request an additional page of records. For all `list` requests after the first, use the `pagination.next_page_cursor` as the value for the `page_cursor` parameter. The following example gets the first page of 20 devices and then the second page of 20 devices: **Code:** ```javascript theme={null} const pages = seam.createPaginator( seam.devices.list({ limit: 20, }), ) const [devices, { hasNextPage, nextPageCursor }] = await pages.firstPage() if (hasNextPage) { const [moreDevices] = await pages.nextPage(nextPageCursor) } ``` **Output:** ```json theme={null} [ { device_id: '11111111-1111-1111-1111-444444444444', ... }, ... ] ``` **Request:** ```bash theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "limit": 20 }' curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"limit\": 20 \"page_cursor\": \"${next_page_cursor}\" }" ``` **Response:** ```json theme={null} { "devices": [ { "device_id": "11111111-1111-1111-1111-444444444444", ... }, ... ], "pagination": { "next_page_cursor": "[string]", "has_next_page": true, "next_page_url": "[URI]" }, "ok": true } ``` **Code:** ```python theme={null} paginator = seam.create_paginator(seam.devices.list, {"limit": 20}) devices, pagination = paginator.first_page() if pagination.has_next_page: more_devices, _ = paginator.next_page(pagination.next_page_cursor) ``` **Output:** ``` [ Device( device_id='11111111-1111-1111-1111-444444444444', ... ), ... ] ``` **Code:** ```ruby theme={null} paginator = seam.create_paginator(seam.devices.method(:list), {limit: 20}) devices, pagination = paginator.first_page if pagination.has_next_page? more_devices, _ = paginator.next_page(pagination.next_page_cursor) end ``` **Output:** ``` [ , ... ] ``` **Code:** ```php theme={null} $pages = $seam->createPaginator( fn($params) => $seam->devices->list(...$params), ["limit" => 2] ); [$devices, $pagination] = $pages->firstPage(); if ($pagination->has_next_page) { [$moreDevices] = $pages->nextPage($pagination->next_page_cursor); } ``` **Output:** ```json theme={null} [ { "device_id": "11111111-1111-1111-1111-444444444444", ... }, ... ] ``` **Code:** ```csharp theme={null} // Coming soon! ``` **Output:** ```json theme={null} // Coming soon! ``` *** ## Resume Pagination You can get the first page on initial load, store the state, and then get the next page at a later time using the stored state. The following example gets the first page of 20 records from the list of devices and, later, gets the next page of 20 devices: **Code:** ```javascript theme={null} // Get the first page of devices. const params = { limit: 20 } const pages = seam.createPaginator(seam.devices.list(params)) const [devices, pagination] = await pages.firstPage() // Store the state, for example, in memory, a file, or a database. localStorage.setItem('/seam/devices/list', JSON.stringify([params, pagination])) // Later, get the next page of devices. const [params = {}, { hasNextPage = false, nextPageCursor = null } = {}] = JSON.parse(localStorage.getItem('/seam/devices/list') ?? '[]') if (hasNextPage) { const pages = seam.createPaginator(seam.devices.list(params)) const [moreDevices] = await pages.nextPage(nextPageCursor) } ``` **Output:** ```json theme={null} [ { device_id: '11111111-1111-1111-1111-444444444444', ... }, ... ] [ { device_id: '11111111-1111-1111-2222-444444444444', ... }, ... ] ``` **Request:** ```bash theme={null} # Get the first page. # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "limit": 20 }' # Store the state, for example, in memory, a file, or a database. # At a later time, retrieve the stored state. # Then, get the next page using the stored state. curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"limit\": 20 \"page_cursor\": \"${next_page_cursor}\" }" ``` **Response:** ```json theme={null} { "devices": [ { "device_id": "11111111-1111-1111-1111-444444444444", ... }, ... ], "pagination": { "next_page_cursor": "[string]", "has_next_page": true, "next_page_url": "[URI]" }, "ok": true } { "devices": [ { "device_id": "11111111-1111-1111-2222-444444444444", ... }, ... ], "pagination": { "next_page_cursor": "[string]", "has_next_page": true, "next_page_url": "[URI]" }, "ok": true } ``` **Code:** ```python theme={null} # Get the first page. params = {"limit": 20} paginator = seam.create_paginator(seam.devices.list, params) devices, pagination = paginator.first_page() # Store the state, for example, in memory, a file, or a database. pagination_state = { "params": params, "next_page_cursor": pagination.next_page_cursor, "has_next_page": pagination.has_next_page, } with open("/tmp/seam_devices_list.json", "w") as f: json.dump(pagination_state, f) # Get the next page at a later time using the stored state. with open("/tmp/seam_devices_list.json", "r") as f: pagination_state = json.load(f) if pagination_state.get("has_next_page"): paginator = seam.create_paginator( seam.devices.list, pagination_state["params"] ) more_devices, _ = paginator.next_page( pagination_state["next_page_cursor"] ) ``` **Output:** ``` [ Device( device_id='11111111-1111-1111-1111-444444444444', ... ), ... ] [ Device( device_id='11111111-1111-1111-2222-444444444444', ... ), ... ] ``` **Code:** ```ruby theme={null} # Get the first page. params = {limit: 20} paginator = seam.create_paginator(seam.devices.method(:list), params) devices, pagination = paginator.first_page # Store the state, for example, in memory, a file, or a database. pagination_state = { "params" => params, "next_page_cursor" => pagination.next_page_cursor, "has_next_page" => pagination.has_next_page? } File.write("/tmp/seam_devices_list.json", JSON.dump(pagination_state)) # Get the next page at a later time using the stored state. pagination_state_json = File.read("/tmp/seam_devices_list.json") pagination_state = JSON.parse(pagination_state_json) if pagination_state["has_next_page"] paginator = seam.create_paginator( seam.devices.method(:list), pagination_state["params"] ) more_devices, _ = paginator.next_page( pagination_state["next_page_cursor"] ) ``` **Output:** ``` [ , ... ] [ , ... ] ``` **Code:** ```php theme={null} // Get the first page. $params = ["limit" => 20]; $pages = $seam->createPaginator( fn($p) => $seam->devices->list(...$p), $params ); [$devices, $pagination] = $pages->firstPage(); // Store the state, for example, in memory, a file, or a database. file_put_contents( "/tmp/seam_devices_list.json", json_encode([$params, $pagination]) ); // Get the next page at a later time using the stored state. $stored_data = json_decode( file_get_contents("/tmp/seam_devices_list.json") ?: "[]", false ); $params = $stored_data[0] ?? []; $pagination = $stored_data[1] ?? (object) ["has_next_page" => false, "next_page_cursor" => null]; if ($pagination->has_next_page) { $pages = $seam->createPaginator( fn($p) => $seam->devices->list(...$p), $params ); [$moreDevices] = $pages->nextPage($pagination->next_page_cursor); } ``` **Output:** ```json theme={null} [ { "device_id": "11111111-1111-1111-1111-444444444444", ... }, ... ] [ { "device_id": "11111111-1111-1111-2222-444444444444", ... }, ... ] ``` **Code:** ```csharp theme={null} // Coming soon! ``` **Output:** ```json theme={null} // Coming soon! ``` *** ## Iterate Over All Pages You can iterate over all pages of records. The following example uses a loop to get all pages of records for a list of 65 devices, at 20 records per page: **Code:** ```javascript theme={null} const pages = seam.createPaginator( seam.devices.list({ limit: 20, }), ) for await (const devices of pages) { console.log(`There are ${devices.length} devices on this page.`) } ``` **Output:** ``` There are 20 devices on this page. There are 20 devices on this page. There are 20 devices on this page. There are 5 devices on this page. ``` **Request:** ```bash theme={null} # Get the first page. # Use GET or POST. response=$(curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "limit": 20 }') echo "$response" | jq -r '.devices | length' | xargs -I {} echo "There are {} devices on this page." # Extract pagination info. next_cursor=$(echo "$response" | jq -r '.pagination.next_page_cursor') has_next=$(echo "$response" | jq -r '.pagination.has_next_page') # Process subsequent pages. while [ "$has_next" = "true" ] && [ ! -z "$next_cursor" ]; do response=$(curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"limit\": 20, \"page_cursor\": \"${next_cursor}\" }") echo "$response" | jq -r '.devices | length' | xargs -I {} echo "There are {} devices on this page." # Update pagination info. next_cursor=$(echo "$response" | jq -r '.pagination.next_page_cursor') has_next=$(echo "$response" | jq -r '.pagination.has_next_page') done ``` **Response:** ``` There are 20 devices on this page. There are 20 devices on this page. There are 20 devices on this page. There are 5 devices on this page. ``` **Code:** ```python theme={null} pages = seam.create_paginator( seam.devices.list( limit=20 ) ) for devices in pages: pprint(f"There are {len(devices)} devices on this page.") ``` **Output:** ``` There are 20 devices on this page. There are 20 devices on this page. There are 20 devices on this page. There are 5 devices on this page. ``` **Code:** ```ruby theme={null} params = {limit: 20} pages = seam.create_paginator(seam.devices.method(:list), params) pages.each do |devices| puts "There are #{devices.length} devices on this page." end ``` **Output:** ``` There are 20 devices on this page. There are 20 devices on this page. There are 20 devices on this page. There are 5 devices on this page. ``` **Code:** ```php theme={null} $params = ["limit" => 20]; $paginator = $seam->createPaginator( fn($p) => $seam->devices->list(...$p), $params ); foreach ($paginator as $page) { $devices = $page->devices; echo "There are " . count($devices) . " devices on this page." . PHP_EOL; } ``` **Output:** ``` There are 20 devices on this page. There are 20 devices on this page. There are 20 devices on this page. There are 5 devices on this page. ``` **Code:** ```csharp theme={null} // Coming soon! ``` **Output:** ```json theme={null} // Coming soon! ``` *** ## Iterate Over All Resources You can iterate over all resources within all pages. The following example uses a loop to get all records for a list of devices, at 20 records per page, and then prints out the device ID for each record: **Code:** ```javascript theme={null} const pages = seam.createPaginator( seam.devices.list({ limit: 20, }), ) for await (const device of pages.flatten()) { console.log(device.device_id) } ``` **Output:** ``` '11111111-1111-1111-1111-444444444444' '11111111-1111-1111-2222-444444444444' ... ``` **Request:** ```bash theme={null} # Get the first page. # Use GET or POST. response=$(curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "limit": 20 }') # Process all pages. while true; do # Extract and print the device IDs from the current page. echo "$response" | jq -r '.devices[].device_id' # Check whether there are more pages. has_next=$(echo "$response" | jq -r '.pagination.has_next_page') if [ "$has_next" != "true" ]; then break fi # Get the next page cursor. next_cursor=$(echo "$response" | jq -r '.pagination.next_page_cursor') if [ -z "$next_cursor" ] || [ "$next_cursor" = "null" ]; then break fi # Fetch the next page. response=$(curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"limit\": 20, \"page_cursor\": \"${next_cursor}\" }") done ``` **Response:** ``` "11111111-1111-1111-1111-444444444444" "11111111-1111-1111-2222-444444444444" ... ``` **Code:** ```python theme={null} paginator = seam.create_paginator(seam.devices.list, {"limit": 20}) for device in paginator.flatten(): print(device.device_id) ``` **Output:** ``` '11111111-1111-1111-1111-444444444444' '11111111-1111-1111-2222-444444444444' ... ``` **Code:** ```ruby theme={null} paginator = seam.create_paginator(seam.devices.method(:list), {limit: 20}) paginator.flatten.each do |device| puts device.device_id end ``` **Output:** ``` "11111111-1111-1111-1111-444444444444" "11111111-1111-1111-2222-444444444444" ... ``` **Code:** ```php theme={null} $pages = $seam->createPaginator( fn($p) => $seam->devices->list(...$p), ["limit" => 20] ); foreach ($pages->flatten() as $device) { print $device->device_id . "\n"; } ``` **Output:** ```json theme={null} "11111111-1111-1111-1111-444444444444" "11111111-1111-1111-2222-444444444444" ... ``` **Code:** ```csharp theme={null} // Coming soon! ``` **Output:** ```json theme={null} // Coming soon! ``` *** ## Return All Resources Across All Pages as an Array You can iterate over all resources within all pages and return a single array or list. The following example returns an array containing all devices: **Code:** ```javascript theme={null} const pages = seam.createPaginator( seam.devices.list({ limit: 20, }), ) const devices = await pages.flattenToArray() ``` **Output:** ```json theme={null} [ { device_id: '11111111-1111-1111-1111-444444444444', ... }, { device_id: '11111111-1111-1111-2222-444444444444', ... }, ... ] ``` **Request:** ```bash theme={null} # Get the first page. # Use GET or POST. response=$(curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "limit": 20 }') # Process all pages. while true; do # Extract all devices from the current page and add them # the all_devices array. devices=$(echo "$response" | jq -c '.devices[]') while IFS= read -r device; do [ -n "$device" ] && all_devices+=("$device") done <<< "$devices" # Check whether there are more pages. has_next=$(echo "$response" | jq -r '.pagination.has_next_page') if [ "$has_next" != "true" ]; then break fi # Get the next page cursor. next_cursor=$(echo "$response" | jq -r '.pagination.next_page_cursor') if [ -z "$next_cursor" ] || [ "$next_cursor" = "null" ]; then break fi # Fetch the next page. response=$(curl -X 'GET' \ 'https://connect.getseam.com/devices/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"limit\": 20, \"page_cursor\": \"${next_cursor}\" }") done ``` **Response:** ```json theme={null} [ { device_id: '11111111-1111-1111-1111-444444444444', ... }, { device_id: '11111111-1111-1111-2222-444444444444', ... }, ... ] ``` **Code:** ```python theme={null} paginator = seam.create_paginator(seam.devices.list, {"limit": 20}) all_devices = paginator.flatten_to_list() ``` **Output:** ``` [ Device( device_id='11111111-1111-1111-1111-444444444444', ... ), Device( device_id='11111111-1111-1111-2222-444444444444', ... ), ... ] ``` **Code:** ```ruby theme={null} paginator = seam.create_paginator(seam.devices.method(:list), {limit: 20}) all_devices = paginator.flatten_to_list ``` **Output:** ``` [ , , ... ] ``` **Code:** ```php theme={null} $pages = $seam->createPaginator( fn($p) => $seam->devices->list(...$p), ["limit" => 20] ); $deviecs = $pages->flattenToArray(); ``` **Output:** ```json theme={null} [ { "device_id": "11111111-1111-1111-1111-444444444444", ... }, { "device_id": "11111111-1111-1111-2222-444444444444", ... }, ... ] ``` **Code:** ```csharp theme={null} // Coming soon! ``` **Output:** ```json theme={null} // Coming soon! ``` # Deactivate a Phone Source: https://docs.seam.co/api/phones/deactivate /openapi.json post /phones/deactivate Deactivates a phone, which is useful, for example, if a user has lost their phone. For more information, see [App User Lost Phone Process](/capability-guides/mobile-access/managing-phones-for-a-user-identity#app-user-lost-phone-process). # Phone Warnings Source: https://docs.seam.co/api/phones/errors Warnings that Seam reports on the Phone resource, each with its code and meaning. ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "unknown_issue_with_phone", "message": "Indicates that an unknown issue occurred while syncing the state of the phone with the provider. This issue may affect the proper functioning of the phone.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `unknown_issue_with_phone` Indicates that an unknown issue occurred while syncing the state of the phone with the provider. This issue may affect the proper functioning of the phone. *** # Phone Events Source: https://docs.seam.co/api/phones/events Webhook events that Seam emits for the Phone resource, with example payloads and properties. ## `phone.deactivated` A phone device was deactivated. ```json Example webhook payload theme={null} { "created_at": "2025-01-01T00:00:00.000Z", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A phone device was deactivated.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "phone.deactivated", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Date and time at which the event was created. Custom metadata of the device; present when device\_id is provided. ID of the affected phone device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `phone.deactivated` Date and time at which the event occurred. ID of the workspace associated with the event. # Get a Phone Source: https://docs.seam.co/api/phones/get /openapi.json post /phones/get Returns a specified [phone](/capability-guides/mobile-access/managing-phones-for-a-user-identity). # List Phones Source: https://docs.seam.co/api/phones/list /openapi.json post /phones/list Returns a list of all [phones](/capability-guides/mobile-access/managing-phones-for-a-user-identity). To filter the list of returned phones by a specific owner user identity or credential, include the `owner_user_identity_id` or `acs_credential_id`, respectively, in the request body. # The Phone Object Source: https://docs.seam.co/api/phones/object Learn how the phone object represents an app user mobile phone that holds mobile credentials, including its properties and lifecycle events. ## The phone Object Represents an app user's mobile phone. ```json Phone theme={null} { "created_at": "2025-06-14T16:54:17.946540Z", "custom_metadata": { "id": "internalId1" }, "device_id": "e452f665-a635-4c65-922b-9feab0e0f84f", "device_type": "ios_phone", "display_name": "My Phone", "errors": [], "nickname": "My Phone", "properties": { "assa_abloy_credential_service_metadata": { "endpoints": [ { "endpoint_id": "c7d8e9f0-1a2b-3c4d-5e6f-7a8b9c0d1e2f", "is_active": true } ], "has_active_endpoint": true } }, "warnings": [], "workspace_id": "da8639a4-28a2-4884-a4f9-b7691f4cf336" } ``` *** ## Properties Date and time at which the phone was created. Optional [custom metadata](/core-concepts/devices/adding-custom-metadata-to-a-device) for the phone. ID of the phone. Type of the phone device, such as `ios_phone` or `android_phone`. Display name of the phone. Defaults to `nickname` (if it is set) or `properties.appearance.name`, otherwise. Enables administrators and users to identify the phone easily, especially when there are numerous phones. Errors associated with the phone. Date and time at which Seam created the error. Unique identifier of the type of error. Detailed description of the error. Optional nickname to describe the phone, settable through Seam. Properties of the phone. ASSA ABLOY Credential Service metadata for the phone. Endpoints associated with the phone. ID of the associated endpoint. Indicated whether the endpoint is active. Indicates whether the credential service has active endpoints associated with the phone. Salto Space credential service metadata for the phone. Indicates whether the credential service has an active associated phone. Warnings associated with the phone. Date and time at which Seam created the warning. Detailed description of the warning. Unique identifier of the type of warning. ID of the workspace that contains the phone. ## phone.properties ASSA ABLOY Credential Service metadata for the phone. Endpoints associated with the phone. ID of the associated endpoint. Indicated whether the endpoint is active. Indicates whether the credential service has active endpoints associated with the phone. Salto Space credential service metadata for the phone. Indicates whether the credential service has an active associated phone. # Create a Sandbox Phone Source: https://docs.seam.co/api/phones/simulate/create_sandbox_phone /openapi.json post /phones/simulate/create_sandbox_phone Creates a new simulated phone in a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). See also [Creating a Simulated Phone for a User Identity](/capability-guides/mobile-access/developing-in-a-sandbox-workspace#creating-a-simulated-phone-for-a-user-identity). # Rate Limits and Guardrails Source: https://docs.seam.co/api/rate-limits-and-guardrails Learn the Seam API rate limits and guardrails, how 429 Too Many Requests responses work, and how to retry requests for reliable device load. In order to provide reliable service for all of our customers and API load predictability for our device partners, we have a number of rate limits and guardrails in place. ## Rate Limits For requests with rate limits, exceeding these limits results in the corresponding API calls failing with a `429 Too Many Requests` response. You must then retry your request after the appropriate amount of time. We enforce the following rate limits on a per-device basis:
Operation Limit
Create an access code 10 access code creations per minute
Update an access code 10 access code updates per minute
Delete an access code 20 access code deletions per minute
Lock a lock 15 lock requests per minute
Unlock a lock 15 unlock requests per minute
# Add Entrances to a Space Source: https://docs.seam.co/api/spaces/add_acs_entrances /openapi.json post /spaces/add_acs_entrances Adds [entrances](/low-level-apis/access-systems/retrieving-entrance-details) to a specific space. # Add a Connected Account to a Space Source: https://docs.seam.co/api/spaces/add_connected_account /openapi.json post /spaces/add_connected_account Adds a [connected account](/core-concepts/connected-accounts) to a specific space. # Add Devices to a Space Source: https://docs.seam.co/api/spaces/add_devices /openapi.json post /spaces/add_devices Adds devices to a specific space. # Create a Space Source: https://docs.seam.co/api/spaces/create /openapi.json post /spaces/create Creates a new space. # Delete a Space Source: https://docs.seam.co/api/spaces/delete /openapi.json post /spaces/delete Deletes a space. # Space Events Source: https://docs.seam.co/api/spaces/events Webhook events that Seam emits for the Space resource, with example payloads and properties. ## `space.device_membership_changed` A device was added or removed from a space. ```json Example webhook payload theme={null} { "acs_entrance_ids": [], "created_at": "2025-01-01T00:00:00.000Z", "device_ids": [], "event_description": "A device was added or removed from a space.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "space.device_membership_changed", "occurred_at": "2025-01-01T00:00:00.000Z", "space_id": "00000000-0000-0000-0000-000000000000", "space_key": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of all ACS entrances currently attached to the space. Date and time at which the event was created. IDs of all devices currently attached to the space. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `space.device_membership_changed` Date and time at which the event occurred. ID of the affected space. Unique key for the space within the workspace. ID of the workspace associated with the event. ## `space.created` A space was created. ```json Example webhook payload theme={null} { "acs_entrance_ids": [], "created_at": "2025-01-01T00:00:00.000Z", "device_ids": [], "event_description": "A space was created.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "space.created", "occurred_at": "2025-01-01T00:00:00.000Z", "space_id": "00000000-0000-0000-0000-000000000000", "space_key": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of all ACS entrances attached to the space when it was created. Date and time at which the event was created. IDs of all devices attached to the space when it was created. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `space.created` Date and time at which the event occurred. ID of the affected space. Unique key for the space within the workspace. ID of the workspace associated with the event. ## `space.deleted` A space was deleted. ```json Example webhook payload theme={null} { "acs_entrance_ids": [], "created_at": "2025-01-01T00:00:00.000Z", "device_ids": [], "event_description": "A space was deleted.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "space.deleted", "occurred_at": "2025-01-01T00:00:00.000Z", "space_id": "00000000-0000-0000-0000-000000000000", "space_key": "", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` IDs of all ACS entrances currently attached to the space when it was deleted. Date and time at which the event was created. IDs of all devices attached to the space when it was deleted. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `space.deleted` Date and time at which the event occurred. ID of the affected space. Unique key for the space within the workspace. ID of the workspace associated with the event. # Get a Space Source: https://docs.seam.co/api/spaces/get /openapi.json post /spaces/get Gets a space. You must include at least one request parameter. # Get related Space resources Source: https://docs.seam.co/api/spaces/get_related /openapi.json post /spaces/get_related Gets all related resources for one or more Spaces. You must include at least one request parameter. # List Spaces Source: https://docs.seam.co/api/spaces/list /openapi.json post /spaces/list Returns a list of all spaces. # The Space Object Source: https://docs.seam.co/api/spaces/object Learn how the space object groups devices and entrances together so you can assign access to an entire space and grant access more efficiently. ## The space Object Represents a space that is a logical grouping of devices and entrances. You can assign access to an entire space, thereby making granting access more efficient. ```json Space theme={null} { "created_at": "2025-06-16T16:54:17.946600Z", "display_name": "My Space", "name": "My Space", "space_id": "5afeb047-3277-4102-b8c4-99edf05b91d2", "workspace_id": "96bd12f9-6def-4bf4-b517-760417451ae9" } ``` *** ## Properties Number of entrances in the space. Date and time at which the space was created. Reservation/stay-related defaults for the space. Also carries the provider/PMS-supplied name under a `_name` key (e.g. `guesty_name`), which Seam preserves when you rename the space (read-only — managed by Seam). Postal address for the space. Default check-in time for reservations at the space, as HH:mm or HH:mm:ss. Default check-out time for reservations at the space, as HH:mm or HH:mm:ss. IANA time zone for the space, e.g. America/Los\_Angeles. Customer key associated with the space. Number of devices in the space. Display name for the space. Geographic coordinates (latitude and longitude) of the space. Latitude of the space, in decimal degrees. Longitude of the space, in decimal degrees. Name of the space. ID of the space. Unique key for the space within the workspace. ID of the workspace associated with the space. # Remove Entrances from a Space Source: https://docs.seam.co/api/spaces/remove_acs_entrances /openapi.json post /spaces/remove_acs_entrances Removes [entrances](/low-level-apis/access-systems/retrieving-entrance-details) from a specific space. # Remove a Connected Account from a Space Source: https://docs.seam.co/api/spaces/remove_connected_account /openapi.json post /spaces/remove_connected_account Removes a [connected account](/core-concepts/connected-accounts) from a specific space. # Remove Devices from a Space Source: https://docs.seam.co/api/spaces/remove_devices /openapi.json post /spaces/remove_devices Removes devices from a specific space. # Update a Space Source: https://docs.seam.co/api/spaces/update /openapi.json post /spaces/update Updates an existing space. # Activate a Climate Preset Source: https://docs.seam.co/api/thermostats/activate_climate_preset /openapi.json post /thermostats/activate_climate_preset Activates a specified [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) for a specified [thermostat](/capability-guides/thermostats). # Set to Cool Mode Source: https://docs.seam.co/api/thermostats/cool /openapi.json post /thermostats/cool Sets a specified [thermostat](/capability-guides/thermostats) to [cool mode](/capability-guides/thermostats/configure-current-climate-settings). # Create a Climate Preset Source: https://docs.seam.co/api/thermostats/create_climate_preset /openapi.json post /thermostats/create_climate_preset Creates a [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) for a specified [thermostat](/capability-guides/thermostats). # Create a Thermostat Daily Program Source: https://docs.seam.co/api/thermostats/daily_programs/create /openapi.json post /thermostats/daily_programs/create Creates a new thermostat daily program. A daily program consists of a set of periods, where each period includes a start time and the key of a configured climate preset. Once you have defined a daily program, you can assign it to one or more days within a weekly program. # Delete a Thermostat Daily Program Source: https://docs.seam.co/api/thermostats/daily_programs/delete /openapi.json post /thermostats/daily_programs/delete Deletes a thermostat daily program. # Daily Programs Source: https://docs.seam.co/api/thermostats/daily_programs/object Learn how the thermostat_daily_program object defines periods that each apply a climate preset at a starting time to automate a thermostat day. ## The thermostat\_daily\_program Object Represents a thermostat daily program, consisting of a set of periods, each of which has a starting time and the key that identifies the climate preset to apply at the starting time. ```json Thermostat Daily Program theme={null} { "created_at": "2025-06-14T16:54:17.946642Z", "device_id": "58437d45-47ac-4ee6-ab27-7b2d1f2947d1", "name": "Weekday Program", "periods": [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Away" }, { "starts_at_time": "16:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ], "thermostat_daily_program_id": "ab8ef74c-c7cd-4100-aa32-0ef960c0080d", "workspace_id": "8da8d923-e55b-45cd-84a3-6c96b3d3d454" } ``` *** ## Properties Date and time at which the thermostat daily program was created. ID of the thermostat device on which the thermostat daily program is configured. User-friendly name to identify the thermostat daily program. Array of thermostat daily program periods. Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to activate at the `starts_at_time`. Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the thermostat daily program. ID of the workspace that contains the thermostat daily program. # Update a Thermostat Daily Program Source: https://docs.seam.co/api/thermostats/daily_programs/update /openapi.json post /thermostats/daily_programs/update Updates a specified thermostat daily program. The periods that you specify overwrite any existing periods for the daily program. # Delete a Climate Preset Source: https://docs.seam.co/api/thermostats/delete_climate_preset /openapi.json post /thermostats/delete_climate_preset Deletes a specified [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) for a specified [thermostat](/capability-guides/thermostats). # Thermostat Errors and Warnings Source: https://docs.seam.co/api/thermostats/errors Errors and warnings that Seam reports on the Thermostat resource, each with its code and meaning. These are Thermostat-specific errors and warnings. For errors and warnings common to all devices, see [Device Errors and Warnings](/api/devices/errors). ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "auxiliary_heat_running", "message": "Indicates that the auxiliary heat is running.", "created_at": "2025-01-01T00:00:00.000Z", "is_device_error": true } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. Indicates that the error is a device error. ### `auxiliary_heat_running` Indicates that the auxiliary heat is running. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "temperature_threshold_exceeded", "message": "Indicates that the temperature threshold has been exceeded.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `temperature_threshold_exceeded` Indicates that the temperature threshold has been exceeded. *** # Thermostat Events Source: https://docs.seam.co/api/thermostats/events Webhook events that Seam emits for the Thermostat resource, with example payloads and properties. ## `thermostat.climate_preset_activated` A thermostat [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) was activated. ```json Example webhook payload theme={null} { "climate_preset_key": "", "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A thermostat [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) was activated.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "thermostat.climate_preset_activated", "is_fallback_climate_preset": true, "occurred_at": "2025-01-01T00:00:00.000Z", "thermostat_schedule_id": "00000000-0000-0000-0000-000000000000", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Key of the climate preset that was activated. Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `thermostat.climate_preset_activated` Indicates whether the climate preset that was activated is the fallback climate preset for the thermostat. Date and time at which the event occurred. ID of the thermostat schedule that prompted the affected climate preset to be activated. ID of the workspace associated with the event. ## `thermostat.manually_adjusted` A [thermostat](/capability-guides/thermostats) was adjusted manually. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "cooling_set_point_celsius": 0, "cooling_set_point_fahrenheit": 0, "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [thermostat](/capability-guides/thermostats) was adjusted manually.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "thermostat.manually_adjusted", "fan_mode_setting": "auto", "heating_set_point_celsius": 0, "heating_set_point_fahrenheit": 0, "hvac_mode_setting": "off", "method": "seam", "occurred_at": "2025-01-01T00:00:00.000Z", "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `thermostat.manually_adjusted` Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Possible values: `auto`, `on`, `circulate` Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. Possible values: `off`, `heat`, `cool`, `heat_cool`, `eco` Method used to adjust the affected thermostat manually. `seam` indicates that the Seam API, Seam CLI, or Seam Console was used to adjust the thermostat. Possible values: `seam`, `external` Date and time at which the event occurred. ID of the workspace associated with the event. ## `thermostat.temperature_threshold_exceeded` A [thermostat's](/capability-guides/thermostats) temperature reading exceeded the set [threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds). ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [thermostat's](/capability-guides/thermostats) temperature reading exceeded the set [threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds).", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "thermostat.temperature_threshold_exceeded", "lower_limit_celsius": 0, "lower_limit_fahrenheit": 0, "occurred_at": "2025-01-01T00:00:00.000Z", "temperature_celsius": 0, "temperature_fahrenheit": 0, "upper_limit_celsius": 0, "upper_limit_fahrenheit": 0, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `thermostat.temperature_threshold_exceeded` Lower temperature limit, in °C, defined by the set threshold. Lower temperature limit, in °F, defined by the set threshold. Date and time at which the event occurred. Temperature, in °C, reported by the affected thermostat. Temperature, in °F, reported by the affected thermostat. Upper temperature limit, in °C, defined by the set threshold. Upper temperature limit, in °F, defined by the set threshold. ID of the workspace associated with the event. ## `thermostat.temperature_threshold_no_longer_exceeded` A [thermostat's](/capability-guides/thermostats) temperature reading no longer exceeds the set [threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds). ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [thermostat's](/capability-guides/thermostats) temperature reading no longer exceeds the set [threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds).", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "thermostat.temperature_threshold_no_longer_exceeded", "lower_limit_celsius": 0, "lower_limit_fahrenheit": 0, "occurred_at": "2025-01-01T00:00:00.000Z", "temperature_celsius": 0, "temperature_fahrenheit": 0, "upper_limit_celsius": 0, "upper_limit_fahrenheit": 0, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `thermostat.temperature_threshold_no_longer_exceeded` Lower temperature limit, in °C, defined by the set threshold. Lower temperature limit, in °F, defined by the set threshold. Date and time at which the event occurred. Temperature, in °C, reported by the affected thermostat. Temperature, in °F, reported by the affected thermostat. Upper temperature limit, in °C, defined by the set threshold. Upper temperature limit, in °F, defined by the set threshold. ID of the workspace associated with the event. ## `thermostat.temperature_reached_set_point` A [thermostat's](/capability-guides/thermostats) temperature reading is within 1 °C of the configured cooling or heating [set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "desired_temperature_celsius": 0, "desired_temperature_fahrenheit": 0, "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [thermostat's](/capability-guides/thermostats) temperature reading is within 1 °C of the configured cooling or heating [set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points).", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "thermostat.temperature_reached_set_point", "occurred_at": "2025-01-01T00:00:00.000Z", "temperature_celsius": 0, "temperature_fahrenheit": 0, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Desired temperature, in °C, defined by the affected thermostat's cooling or heating set point. Desired temperature, in °F, defined by the affected thermostat's cooling or heating set point. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `thermostat.temperature_reached_set_point` Date and time at which the event occurred. Temperature, in °C, reported by the affected thermostat. Temperature, in °F, reported by the affected thermostat. ID of the workspace associated with the event. ## `thermostat.temperature_changed` A [thermostat's](/capability-guides/thermostats) reported temperature changed by at least 1 °C. ```json Example webhook payload theme={null} { "connected_account_custom_metadata": {}, "connected_account_id": "00000000-0000-0000-0000-000000000000", "created_at": "2025-01-01T00:00:00.000Z", "customer_key": "", "device_custom_metadata": {}, "device_id": "00000000-0000-0000-0000-000000000000", "event_description": "A [thermostat's](/capability-guides/thermostats) reported temperature changed by at least 1 °C.", "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "thermostat.temperature_changed", "occurred_at": "2025-01-01T00:00:00.000Z", "temperature_celsius": 0, "temperature_fahrenheit": 0, "workspace_id": "00000000-0000-0000-0000-000000000000" } ``` Custom metadata of the connected account, present when connected\_account\_id is provided. ID of the connected account associated with the event. Date and time at which the event was created. The customer key associated with the device, if any. Custom metadata of the device, present when device\_id is provided. ID of the affected device. Human-readable description of the event. Persisted when the event is created (so the creating code, including a provider, can supply a tailored description) and otherwise derived from the event. ID of the event. Value: `thermostat.temperature_changed` Date and time at which the event occurred. Temperature, in °C, reported by the affected thermostat. Temperature, in °F, reported by the affected thermostat. ID of the workspace associated with the event. # Set to Heat Mode Source: https://docs.seam.co/api/thermostats/heat /openapi.json post /thermostats/heat Sets a specified [thermostat](/capability-guides/thermostats) to [heat mode](/capability-guides/thermostats/configure-current-climate-settings). # Set to Heat-Cool (Auto) Mode Source: https://docs.seam.co/api/thermostats/heat_cool /openapi.json post /thermostats/heat_cool Sets a specified [thermostat](/capability-guides/thermostats) to [heat-cool ("auto") mode](/capability-guides/thermostats/configure-current-climate-settings). # List Thermostats Source: https://docs.seam.co/api/thermostats/list /openapi.json post /thermostats/list Returns a list of all [thermostats](/capability-guides/thermostats). # The Thermostat Object Source: https://docs.seam.co/api/thermostats/object Learn how the device object represents a thermostat connected to Seam, including its climate properties, capabilities, errors, warnings, and events. ## The device Object for Thermostats Represents a [thermostat](/capability-guides/thermostats). You can use the Seam API to perform the following management and monitoring actions for thermostats: * Monitor current thermostat settings and readings. * Configure [temperature thresholds](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds). If the thermostat reports a temperature outside these thresholds, Seam automatically alerts you. * Make immediate changes to [thermostat climate settings](/capability-guides/thermostats/configure-current-climate-settings), such as the HVAC mode and fan mode. * [Create](/capability-guides/thermostats/creating-and-managing-climate-presets) and [schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) climate presets, including a fallback climate preset. * Create daily and weekly [thermostat programs](/capability-guides/thermostats/creating-and-managing-thermostat-programs). The Seam API represents a thermostat as a `device` resource that includes both basic device properties and thermostat-specific properties. *** ```json Thermostat Device theme={null} { "can_hvac_cool": true, "can_hvac_heat": true, "can_hvac_heat_cool": true, "can_turn_off_hvac": true, "capabilities_supported": [ "thermostat" ], "connected_account_id": "a0b1c2d3-e4f5-6a7b-8c9d-0e1f2a3b4c5d", "created_at": "2024-10-03T22:12:15.666Z", "custom_metadata": { "id": "internalId1" }, "device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0", "device_type": "ecobee_thermostat", "display_name": "Living Room", "errors": [], "is_managed": true, "space_ids": [], "location": { "location_name": "2948 20th St, San Francisco, CA, 94110, US", "timezone": "America/Los_Angeles" }, "nickname": "Living Room", "properties": { "active_climate_preset": { "can_delete": true, "can_edit": true, "climate_preset_key": "sleep", "cooling_set_point_celsius": 23.88888888888889, "display_name": "Sleep", "fan_mode_setting": "auto", "heating_set_point_celsius": 17.77777777777778, "hvac_mode_setting": "heat_cool", "manual_override_allowed": true }, "appearance": { "name": "Living Room" }, "available_climate_presets": [ { "climate_preset_key": "sleep", "can_edit": true, "can_delete": true, "can_use_with_thermostat_daily_programs": false, "name": "Sleep", "display_name": "Sleep", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "manual_override_allowed": true, "cooling_set_point_celsius": 23.88888888888889, "heating_set_point_celsius": 17.77777777777778, "cooling_set_point_fahrenheit": 75, "heating_set_point_fahrenheit": 64 }, { "climate_preset_key": "home", "can_edit": true, "can_delete": true, "can_use_with_thermostat_daily_programs": false, "name": "Home", "display_name": "Home", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "manual_override_allowed": false, "cooling_set_point_celsius": 23.88888888888889, "heating_set_point_celsius": 17.77777777777778, "cooling_set_point_fahrenheit": 75, "heating_set_point_fahrenheit": 64 }, { "climate_preset_key": "work", "can_edit": true, "can_delete": true, "can_use_with_thermostat_daily_programs": false, "name": "Work", "display_name": "Work", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "manual_override_allowed": false, "cooling_set_point_celsius": 23.88888888888889, "heating_set_point_celsius": 17.77777777777778, "cooling_set_point_fahrenheit": 75, "heating_set_point_fahrenheit": 64 } ], "available_fan_mode_settings": [ "auto", "on" ], "available_hvac_mode_settings": [ "cool", "heat", "heat_cool", "off" ], "current_climate_setting": { "display_name": "Manual Setting", "fan_mode_setting": "auto", "heating_set_point_celsius": 25, "heating_set_point_fahrenheit": 77, "hvac_mode_setting": "heat", "manual_override_allowed": true }, "ecobee_metadata": { "device_name": "Living Room", "ecobee_device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0" }, "fallback_climate_preset_key": "eco", "fan_mode_setting": "auto", "has_direct_power": true, "image_alt_text": "Ecobee 3 Lite Thermostat", "image_url": "https://connect.getseam.com/_next/image?url=https://connect.getseam.com/assets/images/devices/ecobee_3-lite_front.png&q=75&w=128", "is_cooling": false, "is_fan_running": false, "is_heating": false, "is_temporary_manual_override_active": false, "manufacturer": "ecobee", "max_cooling_set_point_celsius": 33.333333333333336, "max_cooling_set_point_fahrenheit": 92, "max_heating_set_point_celsius": 26.11111111111111, "max_heating_set_point_fahrenheit": 79, "min_cooling_set_point_celsius": 18.333333333333336, "min_cooling_set_point_fahrenheit": 65, "min_heating_cooling_delta_celsius": 2.7777777777777777, "min_heating_cooling_delta_fahrenheit": 5, "min_heating_set_point_celsius": 7.222222222222222, "min_heating_set_point_fahrenheit": 45, "model": { "display_name": "Thermostat", "manufacturer_display_name": "Ecobee" }, "name": "Living Room", "online": true, "relative_humidity": 0.36, "temperature_celsius": 21.11111111111111, "temperature_fahrenheit": 70, "temperature_threshold": { "lower_limit_celsius": 16.66666666666667, "lower_limit_fahrenheit": 62, "upper_limit_celsius": 26.66666666666667, "upper_limit_fahrenheit": 80 }, "thermostat_daily_programs": [ { "thermostat_daily_program_id": "1a2b3c4d-5e6f-7890-1234-56789abcdef1", "device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0", "name": "Weekday Program", "periods": [ { "starts_at_time": "00:00:00", "climate_preset_key": "sleep" }, { "starts_at_time": "07:00:00", "climate_preset_key": "home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "work" }, { "starts_at_time": "18:00:00", "climate_preset_key": "home" }, { "starts_at_time": "22:00:00", "climate_preset_key": "sleep" } ], "workspace_id": "9f8e7d6c-5b4a-3c2d-1e0f-9876543210ab", "created_at": "2025-05-30T04:01:25.455Z" }, { "thermostat_daily_program_id": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f90", "device_id": "a1b2c3d4-e5f6-7890-1234-56789abcdef0", "name": "Weekend Program", "periods": [ { "starts_at_time": "00:00:00", "climate_preset_key": "sleep" }, { "starts_at_time": "08:00:00", "climate_preset_key": "home" }, { "starts_at_time": "23:00:00", "climate_preset_key": "sleep" } ], "workspace_id": "9f8e7d6c-5b4a-3c2d-1e0f-9876543210ab", "created_at": "2025-05-30T04:02:19.952Z" } ], "thermostat_weekly_program": null }, "warnings": [], "workspace_id": "9f8e7d6c-5b4a-3c2d-1e0f-9876543210ab" } ``` *** ## Properties Indicates whether the lock supports configuring automatic locking. Indicates whether the thermostat supports cooling. Indicates whether the thermostat supports heating. Indicates whether the thermostat supports simultaneous heating and cooling. Indicates whether the device supports programming offline access codes. Indicates whether the device supports programming online access codes. Indicates whether the thermostat supports different climate programs for each day of the week. Indicates whether the thermostat supports a single climate program applied to every day. Indicates whether the thermostat supports weekday/weekend climate programs. Indicates whether the device supports remote locking. Indicates whether the device supports remote unlocking. Indicates whether the thermostat supports running climate programs. Indicates whether the device supports simulating connection in a sandbox. Indicates whether the device supports simulating disconnection in a sandbox. Indicates whether the hub supports simulating connection in a sandbox. Indicates whether the hub supports simulating disconnection in a sandbox. Indicates whether the device supports simulating a paid subscription in a sandbox. Indicates whether the device supports simulating removal in a sandbox. Indicates whether the thermostat can be turned off. Indicates whether the lock supports unlocking with an access code. Collection of capabilities that the device supports when connected to Seam. Values are `access_code`, which indicates that the device can manage and utilize digital PIN codes for secure access; `lock`, which indicates that the device controls a door locking mechanism, enabling the remote opening and closing of doors and other entry points; `noise_detection`, which indicates that the device supports monitoring and responding to ambient noise levels; `thermostat`, which indicates that the device can regulate and adjust indoor temperatures; `battery`, which indicates that the device can manage battery life and health; and `phone`, which indicates that the device is a mobile device, such as a smartphone. **Important:** Superseded by [capability flags](/capability-guides/device-and-system-capabilities#capability-flags). Unique identifier for the account associated with the device. Date and time at which the device object was created. Set of key:value pairs. Adding custom metadata to a resource, such as a [Connect Webview](/core-concepts/connect-webviews/attaching-custom-data-to-the-connect-webview), [connected account](/core-concepts/connected-accounts/adding-custom-metadata-to-a-connected-account), or [device](/core-concepts/devices/adding-custom-metadata-to-a-device), enables you to store custom information, like customer details or internal IDs from your application. ID of the device. Type of the device. Display name of the device, defaults to nickname (if it is set) or `properties.appearance.name`, otherwise. Enables administrators and users to identify the device easily, especially when there are numerous devices. Array of errors associated with the device. Each error object within the array contains two fields: `error_code` and `message`. `error_code` is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. Indicates whether Seam manages the device. See also [Managed and Unmanaged Devices](/core-concepts/devices/managed-and-unmanaged-devices). Optional nickname to describe the device, settable through Seam. Properties of the device. Accessory keypad properties and state. Keypad battery properties. The level. Indicates if an accessory keypad is connected to the device. Appearance-related properties, as reported by the device. Name of the device as seen from the provider API and application, not settable through Seam. Represents the current status of the battery charge level. Battery charge level as a value between 0 and 1, inclusive. Represents the current status of the battery charge level. Values are `critical`, which indicates an extremely low level, suggesting imminent shutdown or an urgent need for charging; `low`, which signifies that the battery is under the preferred threshold and should be charged soon; `good`, which denotes a satisfactory charge level, adequate for normal use without the immediate need for recharging; and `full`, which represents a battery that is fully charged, providing the maximum duration of usage. Indicates the battery level of the device as a decimal value between 0 and 1, inclusive. Array of noise threshold IDs that are currently triggering. Indicates whether the device has direct power. Alt text for the device image. Image URL for the device. Manufacturer of the device. When a device, such as a smart lock, is connected through a smart hub, the manufacturer of the device might be different from that of the smart hub. Device model-related properties. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The accessory keypad supported. Indicates whether the device can connect a accessory keypad. Display name of the device model. Indicates whether the device has a built in accessory keypad. Display name that corresponds to the manufacturer-specific terminology for the device. **Deprecated**. use device.can\_program\_offline\_access\_codes. The offline access codes supported. **Deprecated**. use device.can\_program\_online\_access\_codes. The online access codes supported. **Deprecated**. use device.display\_name instead Name of the device. Indicates current noise level in decibels, if the device supports noise detection. **Deprecated**. use device.can\_program\_offline\_access\_codes Indicates whether it is currently possible to use offline access codes for the device. Indicates whether the device is online. **Deprecated**. use device.can\_program\_online\_access\_codes Indicates whether it is currently possible to use online access codes for the device. Serial number of the device. **Deprecated**. use device.properties.model.can\_connect\_accessory\_keypad The supports accessory keypad. **Deprecated**. use offline\_access\_codes\_enabled The supports offline access codes. ASSA ABLOY Credential Service metadata for the phone. Endpoints associated with the phone. ID of the associated endpoint. Indicated whether the endpoint is active. Indicates whether the credential service has active endpoints associated with the phone. Salto Space credential service metadata for the phone. Indicates whether the credential service has an active associated phone. Metadata for an Akiles device. Group ID to which to add users for an Akiles device. Gadget ID for an Akiles device. Gadget name for an Akiles device. Product name for an Akiles device. Metadata for an Aqara device. Device name for an Aqara device. Device ID (did) for an Aqara device. Firmware version for an Aqara device. Model identifier for an Aqara device. Model type for an Aqara device. Parent gateway device ID for an Aqara device. Position (room) ID for an Aqara device. Time zone reported for an Aqara device (e.g. GMT-07:00). Metadata for an ASSA ABLOY Vostio system. Encoder name for an ASSA ABLOY Vostio system. Metadata for an August device. Indicates whether an August device has a keypad. House ID for an August device. House name for an August device. Keypad battery level for an August device. Lock ID for an August device. Lock name for an August device. Model for an August device. Metadata for an Avigilon Alta system. Entry name for an Avigilon Alta system. Total count of entry relays for an Avigilon Alta system. Organization name for an Avigilon Alta system. Site ID for an Avigilon Alta system. Site name for an Avigilon Alta system. Zone ID for an Avigilon Alta system. Zone name for an Avigilon Alta system. Metadata for a Brivo device. Indicates whether the Brivo access point has activation (remote unlock) enabled. Device name for a Brivo device. Metadata for a ControlByWeb device. Device ID for a ControlByWeb device. Device name for a ControlByWeb device. Relay name for a ControlByWeb device. Metadata for a dormakaba Oracode device. Device ID for a dormakaba Oracode device. Door ID for a dormakaba Oracode device. Indicates whether a door is wireless for a dormakaba Oracode device. Door name for a dormakaba Oracode device. IANA time zone for a dormakaba Oracode device. Predefined time slots for a dormakaba Oracode device. Check in time for a time slot for a dormakaba Oracode device. Checkout time for a time slot for a dormakaba Oracode device. ID of a user level for a dormakaba Oracode device. Prefix for a user level for a dormakaba Oracode device. Indicates whether a time slot for a dormakaba Oracode device is a 24-hour time slot. Indicates whether a time slot for a dormakaba Oracode device is in biweekly mode. Indicates whether a time slot for a dormakaba Oracode device is a master time slot. Indicates whether a time slot for a dormakaba Oracode device is a one-shot time slot. Name of a time slot for a dormakaba Oracode device. Prefix for a time slot for a dormakaba Oracode device. **Deprecated**. Previously marked as "@DEPRECATED." Site ID for a dormakaba Oracode device. Site name for a dormakaba Oracode device. Metadata for an ecobee device. Device name for an ecobee device. Device ID for an ecobee device. Metadata for a 4SUITES device. Device ID for a 4SUITES device. Device name for a 4SUITES device. Reclose delay, in seconds, for a 4SUITES device. Metadata for a Genie device. Lock name for a Genie device. Door name for a Genie device. Metadata for a Honeywell Resideo device. Device name for a Honeywell Resideo device. Device ID for a Honeywell Resideo device. Metadata for an igloo device. Bridge ID for an igloo device. Device ID for an igloo device. Model for an igloo device. Metadata for an igloohome device. Bridge ID for an igloohome device. Bridge name for an igloohome device. Device ID for an igloohome device. Device name for an igloohome device. Indicates whether a keypad is linked to a bridge for an igloohome device. Keypad ID for an igloohome device. Metadata for a KeyNest device. Address for a KeyNest device. Current or last store ID for a KeyNest device. Current status for a KeyNest device. Current user company for a KeyNest device. Current user email for a KeyNest device. Current user name for a KeyNest device. Current user phone number for a KeyNest device. Default office ID for a KeyNest device. Device name for a KeyNest device. Fob ID for a KeyNest device. Handover method for a KeyNest device. Whether the KeyNest device has a photo. Whether the key is in a locker that does not support the access codes API. Key ID for a KeyNest device. Key notes for a KeyNest device. KeyNest app user for a KeyNest device. Last movement timestamp for a KeyNest device. Property ID for a KeyNest device. Property postcode for a KeyNest device. Status type for a KeyNest device. Subscription plan for a KeyNest device. Metadata for a Kisi device. Description for a Kisi device. Lock ID for a Kisi device. Lock name for a Kisi device. Place name for a Kisi device. Metadata for a Korelock device. Device ID for a Korelock device. Device name for a Korelock device. Firmware version for a Korelock device. Location ID for a Korelock device. Required for timebound access codes. Model code for a Korelock device. Serial number for a Korelock device. WiFi signal strength (0-1) for a Korelock device. Metadata for a Kwikset device. Device ID for a Kwikset device. Device name for a Kwikset device. Model number for a Kwikset device. Metadata for a Lockly device. Device ID for a Lockly device. Device name for a Lockly device. Model for a Lockly device. Metadata for a Minut device. Device ID for a Minut device. Device name for a Minut device. Latest sensor values for a Minut device. Latest accelerometer Z-axis reading for a Minut device. Time of latest accelerometer Z-axis reading for a Minut device. Value of latest accelerometer Z-axis reading for a Minut device. Latest humidity reading for a Minut device. Time of latest humidity reading for a Minut device. Value of latest humidity reading for a Minut device. Latest pressure reading for a Minut device. Time of latest pressure reading for a Minut device. Value of latest pressure reading for a Minut device. Latest sound reading for a Minut device. Time of latest sound reading for a Minut device. Value of latest sound reading for a Minut device. Latest temperature reading for a Minut device. Time of latest temperature reading for a Minut device. Value of latest temperature reading for a Minut device. Metadata for a Google Nest device. Custom device name for a Google Nest device. The device owner sets this value. Device name for a Google Nest device. Google sets this value. Display name for a Google Nest device. Device ID for a Google Nest device. ID of the Google Nest structure containing the device. Name of the Google Nest structure containing the device. The device owner sets this value. Metadata for a NoiseAware device. Device ID for a NoiseAware device. Device model for a NoiseAware device. Device name for a NoiseAware device. Noise level, in decibels, for a NoiseAware device. Noise level, expressed as a Noise Risk Score (NRS), for a NoiseAware device. Metadata for a Nuki device. Device ID for a Nuki device. Device name for a Nuki device. Indicates whether keypad 2 is paired for a Nuki device. Indicates whether the keypad battery is in a critical state for a Nuki device. Indicates whether the keypad is paired for a Nuki device. Metadata for an Omnitec device. Whether the Omnitec lock has a connected gateway for remote operations. Operator-assigned alias for an Omnitec device. Lock ID for an Omnitec device. Bluetooth MAC address for an Omnitec device. Lock name for an Omnitec device. IANA time zone for the Omnitec device, used to schedule time-bound access codes at the correct local time (accounting for DST). Static UTC offset of the Omnitec lock in milliseconds. Does not account for DST. Metadata for a Ring device. Device ID for a Ring device. Device name for a Ring device. Metadata for a Salto KS device. Battery level for a Salto KS device. Customer reference for a Salto KS device. Indicates whether the site has a Salto KS subscription that supports custom PINs. Lock ID for a Salto KS device. Lock type for a Salto KS device. Locked state for a Salto KS device. Model for a Salto KS device. Site ID for the Salto KS site to which the device belongs. Site name for the Salto KS site to which the device belongs. **Deprecated**. Use `salto_ks_metadata` instead. Metada for a Salto device. Battery level for a Salto device. Customer reference for a Salto device. Lock ID for a Salto device. Lock type for a Salto device. Locked state for a Salto device. Model for a Salto device. Site ID for the Salto KS site to which the device belongs. Site name for the Salto KS site to which the device belongs. Metadata for a Schlage device. Device ID for a Schlage device. Device name for a Schlage device. Model for a Schlage device. Metadata for Seam Bridge. Device number for Seam Bridge. Name for Seam Bridge. Unlock method for Seam Bridge. Metadata for a Sensi device. Device ID for a Sensi device. Device name for a Sensi device. Set to true when the device does not support the /dual-setpoints API endpoint. Enforced setpoint range in Celsius for a Sensi device, derived from an OutOfRange API error. Product type for a Sensi device. Metadata for a SmartThings device. Device ID for a SmartThings device. Device name for a SmartThings device. Location ID for a SmartThings device. Model for a SmartThings device. Metadata for a tado° device. Device type for a tado° device. Serial number for a tado° device. Metadata for a Tedee device. Bridge ID for a Tedee device. Bridge name for a Tedee device. Device ID for a Tedee device. Device model for a Tedee device. Device name for a Tedee device. Keypad ID for a Tedee device. Serial number for a Tedee device. Metadata for a TTLock device. Feature value for a TTLock device. Features for a TTLock device. Indicates whether a TTLock device supports auto-lock time configuration. Indicates whether a TTLock device supports an incomplete keyboard passcode. Indicates whether a TTLock device supports the lock command. Indicates whether a TTLock device supports a passcode. Indicates whether a TTLock device supports passcode management. Indicates whether a TTLock device supports unlock via gateway. Indicates whether a TTLock device supports Wi-Fi. Indicates whether a TTLock device has a gateway. Lock alias for a TTLock device. Lock ID for a TTLock device. Lock-side timezone offset in milliseconds east of UTC, as configured in the TTLock app. Source of truth for the lock's wall-clock interpretation of access code start/end times — a misconfigured value here is the typical cause of customer "codes offset by N hours" reports. Diagnostic only; Seam does not convert times based on this value. Wireless keypads for a TTLock device. ID for a wireless keypad for a TTLock device. Name for a wireless keypad for a TTLock device. Metadata for a 2N device. Device ID for a 2N device. Device name for a 2N device. Metadata for an Ultraloq device. Device ID for an Ultraloq device. Device name for an Ultraloq device. Device type for an Ultraloq device. IANA timezone for the Ultraloq device. Metadata for an ASSA ABLOY Visionline system. Encoder ID for an ASSA ABLOY Visionline system. Metadata for a Wyze device. Device ID for a Wyze device. Device information model for a Wyze device. Device name for a Wyze device. Keypad UUID for a Wyze device. Locker status (hardlock) for a Wyze device. Product model for a Wyze device. Product name for a Wyze device. Product type for a Wyze device. The delay in seconds before the lock automatically locks after being unlocked. Indicates whether automatic locking is enabled. Indicates whether the [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes) is currently enabled for the device. To disable it, set this to `false` using [/devices/update](/api/devices/update). Constraints on access codes for the device. Seam represents each constraint as an object with a `constraint_type` property. Depending on the constraint type, there may also be additional properties. Note that some constraints are manufacturer- or device-specific. The constraint type. Maximum name length constraint for access codes. Minimum name length constraint for access codes. Indicates whether the door is open. Indicates whether the device supports native entry events. Keypad battery status. Keypad battery charge level. Indicates whether the lock is locked. Maximum number of active access codes that the device supports. Time frames that may be requested when creating an offline access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Time frames that may be requested when creating an online access code, expressed as a list of options. The caller picks one option (by matching the requested duration when the options' duration ranges do not overlap, or by `display_name` when they do) and satisfies that one option's rules. When `undefined`, any time frame works. Label for this option. For a single-option device, the product name (for example, `algoPIN` or `SmartPIN`); for a multi-option device, a label that distinguishes it (for example, `Hourly` or `Fixed start times`). iCalendar recurrence rule (RRULE) that the end date must fall on. Constrains which calendar dates are selectable, independent of the time-of-day rules. When `true`, the start and end must fall at the same time of day (the caller picks which). Mutually exclusive with `time_pairs`. Maximum duration this option covers, as an ISO 8601 duration (for example, `PT672H` or `P367D`). Omitted when there is no maximum. Minimum duration this option covers, as an ISO 8601 duration (for example, `PT1H` or `P29D`). Omitted when there is no minimum. iCalendar recurrence rule (RRULE) that the start date must fall on (for example, `FREQ=MONTHLY;BYDAY=1MO,3MO`). Constrains which calendar dates are selectable, independent of the time-of-day rules. Fixed start/end time pairings the caller chooses from. Mutually exclusive with `matching_start_end_time`. Label for the start/end time pairing. End time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. An `end_time` earlier on the clock than `start_time` means the end falls on a later date. Start time of day as a 24-hour `HH:MM` value, interpreted in the option's `time_zone`. IANA time zone for interpreting `time_pairs` and the date recurrence rules. Present only when the option fixes times or dates. Supported code lengths for access codes. Indicates whether the device supports a [backup access code pool](/low-level-apis/smart-locks/access-codes/backup-access-codes). **Deprecated**. Use `active_thermostat_schedule_id` with `/thermostats/schedules/get` instead. Active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) was created. ID of the desired [thermostat](/capability-guides/thermostats) device. Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Errors associated with the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Indicates whether a person at the thermostat can change the thermostat's settings after the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts. Number of minutes for which a person at the thermostat can change the thermostat's settings after the activation of the scheduled [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). See also [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). ID of the workspace that contains the thermostat schedule. ID of the active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Climate preset modes that the thermostat supports, such as "home", "away", "wake", "sleep", "occupied", and "unoccupied". Available [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets) for the thermostat. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Fan mode settings that the thermostat supports. HVAC mode settings that the thermostat supports. Current climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). **Deprecated**. use fallback\_climate\_preset\_key to specify a fallback climate preset instead. The default climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Key of the [fallback climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) for the thermostat. **Deprecated**. Use `current_climate_setting.fan_mode_setting` instead. The fan mode setting. Indicates whether the connected HVAC system is currently cooling, as reported by the thermostat. Indicates whether the fan in the connected HVAC system is currently running, as reported by the thermostat. Indicates whether the connected HVAC system is currently heating, as reported by the thermostat. Indicates whether the current thermostat settings differ from the most recent active program or schedule that Seam activated. For this condition to occur, `current_climate_setting.manual_override_allowed` must also be `true`. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Maximum number of periods that the thermostat can support per day. For example, if the thermostat supports 4 periods per day, this value is 4. Maximum number of climate presets that the thermostat can support for weekly programming. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °C between the cooling and heating set points when in heat-cool (auto) mode. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °F between the cooling and heating set points when in heat-cool (auto) mode. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Reported relative humidity, as a value between 0 and 1, inclusive. Reported temperature in °C. Reported temperature in °F. Current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Precision of the thermostat's period in minutes. For example, if the thermostat supports 15-minute periods, this value is 15. All values are relative to the top of the hour, so for 15 minutes, the periods would be 0, 15, 30, and 45 minutes past the hour. Configured [daily programs](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat daily program was created. ID of the thermostat device on which the thermostat daily program is configured. User-friendly name to identify the thermostat daily program. Array of thermostat daily program periods. Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to activate at the `starts_at_time`. Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the thermostat daily program. ID of the workspace that contains the thermostat daily program. Current [weekly program](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat weekly program was created. ID of the thermostat daily program to run on Fridays. ID of the thermostat daily program to run on Mondays. ID of the thermostat daily program to run on Saturdays. ID of the thermostat daily program to run on Sundays. ID of the thermostat daily program to run on Thursdays. ID of the thermostat daily program to run on Tuesdays. ID of the thermostat daily program to run on Wednesdays. IDs of the spaces the device is in. Array of warnings associated with the device. Each warning object within the array contains two fields: `warning_code` and `message`. `warning_code` is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. `message` provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. Unique identifier for the Seam workspace associated with the device. ## Thermostats **Deprecated**. Use `active_thermostat_schedule_id` with `/thermostats/schedules/get` instead. Active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) was created. ID of the desired [thermostat](/capability-guides/thermostats) device. Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Errors associated with the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Indicates whether a person at the thermostat can change the thermostat's settings after the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts. Number of minutes for which a person at the thermostat can change the thermostat's settings after the activation of the scheduled [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). See also [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). ID of the workspace that contains the thermostat schedule. ID of the active [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Climate preset modes that the thermostat supports, such as "home", "away", "wake", "sleep", "occupied", and "unoccupied". Available [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets) for the thermostat. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Fan mode settings that the thermostat supports. HVAC mode settings that the thermostat supports. Current climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). **Deprecated**. use fallback\_climate\_preset\_key to specify a fallback climate preset instead. The default climate setting. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be deleted. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be edited. Indicates whether the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) key can be programmed in a thermostat daily program. Unique key to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). The climate preset mode for the thermostat, based on the available climate preset modes reported by the device. Temperature to which the thermostat should cool (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should cool (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Display name for the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Metadata specific to the Ecobee climate, if applicable. Reference to the Ecobee climate, if applicable. Indicates if the climate preset is optimized by Ecobee. Indicates whether the climate preset is owned by the user or the system. Desired [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings), such as `on`, `auto`, or `circulate`. Temperature to which the thermostat should heat (in °C). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Temperature to which the thermostat should heat (in °F). See also [Set Points](/capability-guides/thermostats/understanding-thermostat-concepts/set-points). Desired [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) setting, such as `heat`, `cool`, `heat_cool`, or `off`. **Deprecated**. Use 'thermostat\_schedule.is\_override\_allowed' Indicates whether a person at the thermostat can change the thermostat's settings. See [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). Key of the [fallback climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) for the thermostat. **Deprecated**. Use `current_climate_setting.fan_mode_setting` instead. The fan mode setting. Indicates whether the connected HVAC system is currently cooling, as reported by the thermostat. Indicates whether the fan in the connected HVAC system is currently running, as reported by the thermostat. Indicates whether the connected HVAC system is currently heating, as reported by the thermostat. Indicates whether the current thermostat settings differ from the most recent active program or schedule that Seam activated. For this condition to occur, `current_climate_setting.manual_override_allowed` must also be `true`. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Maximum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Maximum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Maximum number of periods that the thermostat can support per day. For example, if the thermostat supports 4 periods per day, this value is 4. Maximum number of climate presets that the thermostat can support for weekly programming. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °C. Minimum [cooling set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#cooling-set-point) in °F. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °C between the cooling and heating set points when in heat-cool (auto) mode. Minimum [temperature difference](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#minimum-heating-cooling-temperature-delta) in °F between the cooling and heating set points when in heat-cool (auto) mode. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °C. Minimum [heating set point](/capability-guides/thermostats/understanding-thermostat-concepts/set-points#heating-set-point) in °F. Reported relative humidity, as a value between 0 and 1, inclusive. Reported temperature in °C. Reported temperature in °F. Current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Lower limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °C within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Upper limit in °F within the current [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) set for the thermostat. Precision of the thermostat's period in minutes. For example, if the thermostat supports 15-minute periods, this value is 15. All values are relative to the top of the hour, so for 15 minutes, the periods would be 0, 15, 30, and 45 minutes past the hour. Configured [daily programs](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat daily program was created. ID of the thermostat device on which the thermostat daily program is configured. User-friendly name to identify the thermostat daily program. Array of thermostat daily program periods. Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to activate at the `starts_at_time`. Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the thermostat daily program. ID of the workspace that contains the thermostat daily program. Current [weekly program](/capability-guides/thermostats/creating-and-managing-thermostat-programs) for the thermostat. Date and time at which the thermostat weekly program was created. ID of the thermostat daily program to run on Fridays. ID of the thermostat daily program to run on Mondays. ID of the thermostat daily program to run on Saturdays. ID of the thermostat daily program to run on Sundays. ID of the thermostat daily program to run on Thursdays. ID of the thermostat daily program to run on Tuesdays. ID of the thermostat daily program to run on Wednesdays. # Set to Off Mode Source: https://docs.seam.co/api/thermostats/off /openapi.json post /thermostats/off Sets a specified [thermostat](/capability-guides/thermostats) to ["off" mode](/capability-guides/thermostats/configure-current-climate-settings). # Create a Thermostat Schedule Source: https://docs.seam.co/api/thermostats/schedules/create /openapi.json post /thermostats/schedules/create Creates a new [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) for a specified [thermostat](/capability-guides/thermostats). # Delete a Thermostat Schedule Source: https://docs.seam.co/api/thermostats/schedules/delete /openapi.json post /thermostats/schedules/delete Deletes a [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) for a specified [thermostat](/capability-guides/thermostats). # Get a Thermostat Schedule Source: https://docs.seam.co/api/thermostats/schedules/get /openapi.json post /thermostats/schedules/get Returns a specified [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). # List Thermostat Schedules Source: https://docs.seam.co/api/thermostats/schedules/list /openapi.json post /thermostats/schedules/list Returns a list of all [thermostat schedules](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) for a specified [thermostat](/capability-guides/thermostats). # Thermostat Schedules Source: https://docs.seam.co/api/thermostats/schedules/object Learn how the thermostat_schedule object activates a climate preset on a thermostat at a starting time and deactivates it at a specified ending time. ## The thermostat\_schedule Object Represents a [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) that activates a configured [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) on a [thermostat](/capability-guides/thermostats) at a specified starting time and deactivates the climate preset at a specified ending time. ```json Thermostat Schedule theme={null} { "climate_preset_key": "eco", "created_at": "2025-06-14T16:54:17.946316Z", "device_id": "dc1dfc4b-8082-453f-a953-276941af8650", "ends_at": "2025-07-14T16:54:17.946313Z", "errors": [], "is_override_allowed": true, "max_override_period_minutes": 90, "name": "My Thermostat Schedule", "starts_at": "2025-07-12T16:54:17.946313Z", "thermostat_schedule_id": "af2cb7f7-9f28-40da-a0a0-e7a008ef7a35", "workspace_id": "58419b36-6103-44e5-aa83-2163e90cce01" } ``` *** ## Properties Key of the [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) to use for the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) was created. ID of the desired [thermostat](/capability-guides/thermostats) device. Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) ends, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. Errors associated with the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which Seam created the error. Unique identifier of the type of error. Enables quick recognition and categorization of the issue. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Indicates whether a person at the thermostat can change the thermostat's settings after the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts. Number of minutes for which a person at the thermostat can change the thermostat's settings after the activation of the scheduled [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets). See also [Specifying Manual Override Permissions](/capability-guides/thermostats/creating-and-managing-thermostat-schedules#specifying-manual-override-permissions). User-friendly name to identify the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). Date and time at which the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules) starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. ID of the [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). ID of the workspace that contains the thermostat schedule. # Update a Thermostat Schedule Source: https://docs.seam.co/api/thermostats/schedules/update /openapi.json post /thermostats/schedules/update Updates a specified [thermostat schedule](/capability-guides/thermostats/creating-and-managing-thermostat-schedules). # Set the Fallback Climate Preset Source: https://docs.seam.co/api/thermostats/set_fallback_climate_preset /openapi.json post /thermostats/set_fallback_climate_preset Sets a specified [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) as the ["fallback"](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) preset for a specified [thermostat](/capability-guides/thermostats). # Set the Fan Mode Setting Source: https://docs.seam.co/api/thermostats/set_fan_mode /openapi.json post /thermostats/set_fan_mode Sets the [fan mode setting](/capability-guides/thermostats/configure-current-climate-settings#fan-mode-settings) for a specified [thermostat](/capability-guides/thermostats). # Set the HVAC Mode Source: https://docs.seam.co/api/thermostats/set_hvac_mode /openapi.json post /thermostats/set_hvac_mode Sets the [HVAC mode](/capability-guides/thermostats/configure-current-climate-settings) for a specified [thermostat](/capability-guides/thermostats). # Set a Temperature Threshold Source: https://docs.seam.co/api/thermostats/set_temperature_threshold /openapi.json post /thermostats/set_temperature_threshold Sets a [temperature threshold](/capability-guides/thermostats/setting-and-monitoring-temperature-thresholds) for a specified thermostat. Seam emits a `thermostat.temperature_threshold_exceeded` event and adds a warning on a thermostat if it reports a temperature outside the threshold range. # HVAC Mode Adjusted Source: https://docs.seam.co/api/thermostats/simulate/hvac_mode_adjusted /openapi.json post /thermostats/simulate/hvac_mode_adjusted Simulates having adjusted the [HVAC mode](/capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) for a [thermostat](/capability-guides/thermostats). Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your Thermostat App with Simulate Endpoints](/capability-guides/thermostats/testing-your-thermostat-app-with-simulate-endpoints). # Temperature Reached Source: https://docs.seam.co/api/thermostats/simulate/temperature_reached /openapi.json post /thermostats/simulate/temperature_reached Simulates a [thermostat](/capability-guides/thermostats) reaching a specified temperature. Only applicable for [sandbox devices](/core-concepts/workspaces#sandbox-workspaces). See also [Testing Your Thermostat App with Simulate Endpoints](/capability-guides/thermostats/testing-your-thermostat-app-with-simulate-endpoints). # Update a Climate Preset Source: https://docs.seam.co/api/thermostats/update_climate_preset /openapi.json post /thermostats/update_climate_preset Updates a specified [climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets) for a specified [thermostat](/capability-guides/thermostats). # Update the Thermostat Weekly Program Source: https://docs.seam.co/api/thermostats/update_weekly_program /openapi.json post /thermostats/update_weekly_program Updates the thermostat weekly program for a thermostat device. To configure a weekly program, specify the ID of the daily program that you want to use for each day of the week. When you update a weekly program, the set of programs that you specify overwrites any previous weekly program for the thermostat. # Add an ACS User to a User Identity Source: https://docs.seam.co/api/user_identities/add_acs_user /openapi.json post /user_identities/add_acs_user Adds a specified [access system user](/low-level-apis/access-systems/user-management) to a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). You must specify either `user_identity_id` or `user_identity_key` to identify the user identity. If `user_identity_key` is provided, but the user identity doesn't exist, a new user identity will be created automatically using information from the ACS user. # Create a User Identity Source: https://docs.seam.co/api/user_identities/create /openapi.json post /user_identities/create Creates a new [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # Delete a User Identity Source: https://docs.seam.co/api/user_identities/delete /openapi.json post /user_identities/delete Deletes a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). This deletes the user identity and all associated resources, including any [credentials](/api/acs/credentials/object), [acs users](/api/acs/users/object) and [client sessions](/api/client_sessions/object). # User Identity Errors and Warnings Source: https://docs.seam.co/api/user_identities/errors Errors and warnings that Seam reports on the User Identity resource, each with its code and meaning. ## Errors Each error is an object with the following shape: ```json Example error theme={null} { "error_code": "issue_with_acs_user", "message": "Indicates that there is an issue with an access system user associated with this user identity.", "created_at": "2025-01-01T00:00:00.000Z", "acs_system_id": "00000000-0000-0000-0000-000000000000", "acs_user_id": "00000000-0000-0000-0000-000000000000" } ``` Unique identifier of the type of error. Enables quick recognition and categorization of the issue. One of the error codes listed below. Detailed description of the error. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the error. ID of the access system that the user identity is associated with. ID of the access system user that has an issue. ### `issue_with_acs_user` Indicates that there is an issue with an access system user associated with this user identity. *** ## Warnings Each warning is an object with the following shape: ```json Example warning theme={null} { "warning_code": "being_deleted", "message": "Indicates that the user identity is currently being deleted.", "created_at": "2025-01-01T00:00:00.000Z" } ``` Unique identifier of the type of warning. Enables quick recognition and categorization of the issue. One of the warning codes listed below. Detailed description of the warning. Provides insights into the issue and potentially how to rectify it. Date and time at which Seam created the warning. ### `acs_user_profile_does_not_match_user_identity` Indicates that the ACS user's profile does not match the user identity's profile *** ### `being_deleted` Indicates that the user identity is currently being deleted. *** # Generate an Instant Key Source: https://docs.seam.co/api/user_identities/generate_instant_key /openapi.json post /user_identities/generate_instant_key Generates a new [instant key](/use-cases/granting-access/using-instant-keys) for a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # Get a User Identity Source: https://docs.seam.co/api/user_identities/get /openapi.json post /user_identities/get Returns a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). You must include at least one request parameter. # Grant a User Identity Access to a Device Source: https://docs.seam.co/api/user_identities/grant_access_to_device /openapi.json post /user_identities/grant_access_to_device Grants a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) access to a specified [device](/core-concepts/devices). # List User Identities Source: https://docs.seam.co/api/user_identities/list /openapi.json post /user_identities/list Returns a list of all [user identities](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # List Accessible Devices for a User Identity Source: https://docs.seam.co/api/user_identities/list_accessible_devices /openapi.json post /user_identities/list_accessible_devices Returns a list of all [devices](/core-concepts/devices) associated with a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). This includes devices derived from the access grants assigned to the user identity and devices directly linked to the user identity. # List Accessible Entrances for a User Identity Source: https://docs.seam.co/api/user_identities/list_accessible_entrances /openapi.json post /user_identities/list_accessible_entrances Returns a list of all [ACS entrances](/api/acs/entrances/object) accessible to a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). This includes entrances derived from the access grants assigned to the user identity and entrances accessible through ACS users linked to the user identity. # List ACS Systems Associated with a User Identity Source: https://docs.seam.co/api/user_identities/list_acs_systems /openapi.json post /user_identities/list_acs_systems Returns a list of all [access systems](/low-level-apis/access-systems) associated with a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # List ACS Users Associated with a User Identity Source: https://docs.seam.co/api/user_identities/list_acs_users /openapi.json post /user_identities/list_acs_users Returns a list of all [access system users](/low-level-apis/access-systems/user-management) assigned to a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # The User Identity Object Source: https://docs.seam.co/api/user_identities/object Learn how the user_identity object links a person to their application user account so you can manage their mobile credentials and access in Seam. ## The user\_identity Object Represents a [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) associated with an application user account. ```json User Identity theme={null} { "created_at": "2025-06-16T16:54:17.946546Z", "display_name": "Jane Doe", "email_address": "jane@example.com", "errors": [], "full_name": "Jane Doe", "phone_number": "+1555551002", "user_identity_id": "43947360-cdc8-4db6-8b22-e079416d1d8b", "user_identity_key": "jane_doe", "acs_user_ids": [ "0fc82df4-391b-4d00-a234-86378f1c3952" ], "warnings": [], "workspace_id": "b7e0a4e0-1044-4319-9a0b-42b642b68c7f" } ``` *** ## Properties Array of access system user IDs associated with the user identity. Date and time at which the user identity was created. Display name for the user identity. Unique email address for the user identity. Array of errors associated with the user identity. Each error object within the array contains fields like "error\_code" and "message." "error\_code" is a string that uniquely identifies the type of error, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the error, offering insights into the issue and potentially how to rectify it. Full name of the user associated with the user identity. Unique phone number for the user identity in [E.164 format](https://www.itu.int/rec/T-REC-E.164/en) (for example, +15555550100). ID of the user identity. Unique key for the user identity. Array of warnings associated with the user identity. Each warning object within the array contains two fields: "warning\_code" and "message." "warning\_code" is a string that uniquely identifies the type of warning, enabling quick recognition and categorization of the issue. "message" provides a more detailed description of the warning, offering insights into the issue and potentially how to rectify it. ID of the workspace that contains the user identity. # Remove an ACS User from a User Identity Source: https://docs.seam.co/api/user_identities/remove_acs_user /openapi.json post /user_identities/remove_acs_user Removes a specified [access system user](/low-level-apis/access-systems/user-management) from a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # Revoke Access to a Device from a User Identity Source: https://docs.seam.co/api/user_identities/revoke_access_to_device /openapi.json post /user_identities/revoke_access_to_device Revokes access to a specified [device](/core-concepts/devices) from a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # Get an Unmanaged User Identity Source: https://docs.seam.co/api/user_identities/unmanaged/get /openapi.json post /user_identities/unmanaged/get Returns a specified unmanaged [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) (where is_managed = false). # List Unmanaged User Identities Source: https://docs.seam.co/api/user_identities/unmanaged/list /openapi.json post /user_identities/unmanaged/list Returns a list of all unmanaged [user identities](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) (where is_managed = false). # Update an Unmanaged User Identity Source: https://docs.seam.co/api/user_identities/unmanaged/update /openapi.json post /user_identities/unmanaged/update Updates an unmanaged [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) to make it managed. This endpoint can only be used to convert unmanaged user identities to managed ones by setting `is_managed` to `true`. It cannot be used to convert managed user identities back to unmanaged. # Update a User Identity Source: https://docs.seam.co/api/user_identities/update /openapi.json post /user_identities/update Updates a specified [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). # Create a Webhook Source: https://docs.seam.co/api/webhooks/create /openapi.json post /webhooks/create Creates a new [webhook](/developer-tools/webhooks). # Delete a Webhook Source: https://docs.seam.co/api/webhooks/delete /openapi.json post /webhooks/delete Deletes a specified [webhook](/developer-tools/webhooks). # Get a Webhook Source: https://docs.seam.co/api/webhooks/get /openapi.json post /webhooks/get Gets a specified [webhook](/developer-tools/webhooks). # List Webhooks Source: https://docs.seam.co/api/webhooks/list /openapi.json post /webhooks/list Returns a list of all [webhooks](/developer-tools/webhooks). # The Webhook Object Source: https://docs.seam.co/api/webhooks/object Learn how the webhook object lets you receive event notifications at an endpoint URL you specify, for the set of event types you choose to subscribe to. ## The webhook Object Represents a [webhook](/developer-tools/webhooks) that enables you to receive notifications of events. When you create a webhook, specify the endpoint URL at which you want to receive events and the set of event types that you want to receive. ```json Webhook theme={null} { "event_types": [ "device.connected", "device.disconnected" ], "secret": "mySecret", "url": "https://example.com/webhook", "webhook_id": "ffe5cc3c-f3f4-48e8-b377-6f76c05d09a1" } ``` *** ## Properties Types of events that the [webhook](/developer-tools/webhooks) should receive. Secret associated with the [webhook](/developer-tools/webhooks). URL for the [webhook](/developer-tools/webhooks). ID of the webhook. # Update a Webhook Source: https://docs.seam.co/api/webhooks/update /openapi.json post /webhooks/update Updates a specified [webhook](/developer-tools/webhooks). # Create a Workspace Source: https://docs.seam.co/api/workspaces/create /openapi.json post /workspaces/create Creates a new [workspace](/core-concepts/workspaces). # Get a Workspace Source: https://docs.seam.co/api/workspaces/get /openapi.json post /workspaces/get Returns the [workspace](/core-concepts/workspaces) associated with the authentication value. # List Workspaces Source: https://docs.seam.co/api/workspaces/list /openapi.json post /workspaces/list Returns a list of [workspaces](/core-concepts/workspaces) associated with the authentication value. # The Workspace Object Source: https://docs.seam.co/api/workspaces/object Learn how the workspace object represents an isolated Seam environment that holds your devices, connected accounts, and resources, with sandbox support. ## The workspace Object Represents a Seam [workspace](/core-concepts/workspaces). A workspace is a top-level entity that encompasses all other resources below it, such as devices, connected accounts, and Connect Webviews. Seam provides two types of workspaces. A [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces) is a special type of workspace designed for testing code. Sandbox workspaces offer test device accounts and virtual devices that you can connect and control. This ability to work with virtual devices is quite handy because it removes the need to own physical devices from multiple brands. To connect real devices and systems to Seam, use a [production workspace](/core-concepts/workspaces#production-workspaces). ```json Production Workspace theme={null} { "company_name": "Acme", "connect_partner_name": "Acme", "connect_webview_customization": { "inviter_logo_url": "https://connect.getseam.com/internal/images/view?image_id=1de135fa-f0c2-4e57-90d0-6b9a7d090a0c", "logo_shape": "circle", "primary_button_color": "#232426", "primary_button_text_color": "#FFFDE7", "success_message": "Your account has been successfully connected to Acme!" }, "is_sandbox": false, "is_suspended": false, "is_publishable_key_auth_enabled": true, "publishable_key": "seam_pk1fGd41X_zKs0ZELRTEc8nWxiBsEXAMPLE", "name": "My Production Workspace", "organization_id": "8f9c4d2e-1a3b-4c5d-6e7f-8a9b0c1d2e3f", "workspace_id": "6a0b6282-6a98-4fef-811e-0904c485ac7a" } ``` ```json Sandbox Workspace theme={null} { "company_name": "Acme", "connect_partner_name": "Acme", "connect_webview_customization": { "inviter_logo_url": "https://connect.getseam.com/internal/images/view?image_id=1de135fa-f0c2-4e57-90d0-6b9a7d090a0c", "logo_shape": "circle", "primary_button_color": "#232426", "primary_button_text_color": "#FFFDE7", "success_message": "Your account has been successfully connected to Acme!" }, "is_sandbox": true, "is_suspended": false, "is_publishable_key_auth_enabled": true, "publishable_key": "seam_pk1fGd41X_zKs0ZELRTEc8nWxiBsEXAMPLE", "name": "My Sandbox Workspace", "organization_id": "8f9c4d2e-1a3b-4c5d-6e7f-8a9b0c1d2e3f", "workspace_id": "6a0b6282-6a98-4fef-811e-0904c485ac7a" } ``` ```json Workspace theme={null} { "company_name": "Acme", "connect_partner_name": "Acme", "connect_webview_customization": { "inviter_logo_url": "https://connect.getseam.com/internal/images/view?image_id=1de135fa-f0c2-4e57-90d0-6b9a7d090a0c", "logo_shape": "circle", "primary_button_color": "#232426", "primary_button_text_color": "#FFFDE7", "success_message": "Your account has been successfully connected to Acme!" }, "is_sandbox": true, "is_suspended": false, "is_publishable_key_auth_enabled": true, "publishable_key": "seam_pk1fGd41X_zKs0ZELRTEc8nWxiBsEXAMPLE", "name": "My Sandbox Workspace", "organization_id": null, "workspace_id": "6a0b6282-6a98-4fef-811e-0904c485ac7a" } ``` *** ## Properties Company name associated with the [workspace](/core-concepts/workspaces). **Deprecated**. Use `company_name` instead. The connect partner name. The connect webview customization. URL of the inviter logo for [Connect Webviews](/core-concepts/connect-webviews) in the workspace. See also [Customize the Look and Feel of Your Connect Webviews](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-look-and-feel-of-your-connect-webviews). Logo shape for [Connect Webviews](/core-concepts/connect-webviews) in the workspace. See also [Customize the Look and Feel of Your Connect Webviews](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-look-and-feel-of-your-connect-webviews). Primary button color for [Connect Webviews](/core-concepts/connect-webviews) in the workspace. See also [Customize the Look and Feel of Your Connect Webviews](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-look-and-feel-of-your-connect-webviews). Primary button text color for [Connect Webviews](/core-concepts/connect-webviews) in the workspace. See also [Customize the Look and Feel of Your Connect Webviews](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-look-and-feel-of-your-connect-webviews). Success message for [Connect Webviews](/core-concepts/connect-webviews) in the workspace. See also [Customize the Look and Feel of Your Connect Webviews](/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-look-and-feel-of-your-connect-webviews). Indicates whether publishable key authentication is enabled for this workspace. Indicates whether the workspace is a [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces). Indicates whether the [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces) is suspended. Seam suspends sandbox workspaces that have not been accessed in 14 days. Name of the [workspace](/core-concepts/workspaces). ID of the organization to which the workspace belongs, or `null` if the workspace is not assigned to an organization. Publishable key for the [workspace](/core-concepts/workspaces). This key is used to identify the workspace in client-side applications. ID of the workspace. # Reset a Sandbox Workspace Source: https://docs.seam.co/api/workspaces/reset_sandbox /openapi.json post /workspaces/reset_sandbox Resets the [sandbox workspace](/core-concepts/workspaces#sandbox-workspaces) associated with the authentication value. Note that this endpoint is only available for sandbox workspaces. # Update a Workspace Source: https://docs.seam.co/api/workspaces/update /openapi.json post /workspaces/update Updates the [workspace](/core-concepts/workspaces) associated with the authentication value. # Customers Source: https://docs.seam.co/capability-guides/customer-portals/customers Link your customers to Seam with customer_key. A customer in Seam represents one of your end customers — for example, a hotel operator, property manager, gym owner, or office admin. Customers link the systems and devices they control (via Seam Connect) to your application. Seam gives you a way to tag each customer with your own identifier through the `customer_key`. This makes it easy to keep Seam’s records aligned with your own database. *** ### What is `customer_key`? `customer_key` is your unique identifier for a customer. You assign it when creating resources that belong to that customer. Seam then copies the same key to related resources, so you always have a reliable way to look them up. *** #### Key uses: * Connect Webviews: Tag a Webview with `customer_key`. When the customer connects their account, the resulting Connected Account inherits that key. * Customer Portals: Initialize a portal with `customer_key` so the portal shows only the devices, spaces, and accounts for that customer. * Lookups: Use `customer_key` to fetch all Connected Accounts, devices, or systems associated with a specific customer. *** ### Next step: set up a Customer Portal Once you’ve defined a customer with `customer_key`, you can set up a Customer Portal to give them self-service access to their systems and devices. In the next section, we’ll walk through how to configure a Customer Portal in the Console and initialize it with your `customer_key`. # Filtering Portal Resources by Custom Metadata Source: https://docs.seam.co/capability-guides/customer-portals/filtering-portal-resources-by-custom-metadata Use customer_resources_filters to control which resources are visible to customers in a portal, based on custom_metadata on property_listings and reservations. When creating a customer portal, you can use the `customer_resources_filters` parameter to control which resources (property listings, reservations) are visible to the customer. Filters match against the `custom_metadata` you set on resources in `customer_data`. *** ### How It Works 1. **Tag resources with `custom_metadata`** — when passing `property_listings` or `reservations` in `customer_data`, include a `custom_metadata` object with key-value pairs on each resource. 2. **Set `customer_resources_filters` when creating the portal** — provide an array of filter objects that specify which `custom_metadata` values a resource must have to be visible. 3. **Filtering is enforced server-side** — the customer portal only returns resources whose `custom_metadata` matches all specified filters. *** ### Filter Structure Reference Each filter in the `customer_resources_filters` array is an object with the following fields: | Field | Type | Description | | ----------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `field` | String | The `custom_metadata` field name to filter on. Must start with a letter or underscore and contain only alphanumeric characters and underscores. | | `operation` | String | The comparison operation. Currently only `"="` (equals) is supported. | | `value` | String or Boolean | The value to compare against. | *** ### Key Behaviors * **AND logic** — when multiple filters are provided, a resource must match *all* of them to be visible. * **Exact match** — the `=` operation performs an exact match against the `custom_metadata` value. * **Server-side enforcement** — filtering happens on the server. The customer portal API only returns matching resources. * **Field name rules** — field names must match the regex `^[a-zA-Z_]\w*$` (start with a letter or underscore, followed by alphanumeric characters or underscores). *** ### Examples #### Example 1: Filtering Property Listings by Region Create property listings with a `region` field in `custom_metadata`, then filter to show only European properties. ```javascript JavaScript theme={null} const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: 'customer_123', property_listings: [ { name: 'Lisbon Apartment', property_listing_key: 'lisbon_apt', custom_metadata: { region: 'europe' }, }, { name: 'NYC Loft', property_listing_key: 'nyc_loft', custom_metadata: { region: 'north_america' }, }, ], }, customer_resources_filters: [ { field: 'region', operation: '=', value: 'europe' }, ], }) // The portal will only show "Lisbon Apartment" console.log(customer_portal.url) ``` ```bash cURL theme={null} curl -X POST \ 'https://connect.getseam.com/customers/create_portal' \ -H 'Authorization: Bearer ${SEAM_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "customer_data": { "customer_key": "customer_123", "property_listings": [ { "name": "Lisbon Apartment", "property_listing_key": "lisbon_apt", "custom_metadata": { "region": "europe" } }, { "name": "NYC Loft", "property_listing_key": "nyc_loft", "custom_metadata": { "region": "north_america" } } ] }, "customer_resources_filters": [ { "field": "region", "operation": "=", "value": "europe" } ] }' ``` #### Example 2: Multiple Filters (AND Logic) When you provide multiple filters, a resource must match all of them. Here, only property listings that are both premium and in Europe are shown. ```javascript JavaScript theme={null} const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: 'customer_123', property_listings: [ { name: 'Premium Villa', property_listing_key: 'premium_villa', custom_metadata: { is_premium: true, region: 'europe' }, }, { name: 'Standard Apartment', property_listing_key: 'standard_apt', custom_metadata: { is_premium: false, region: 'europe' }, }, { name: 'Premium Condo', property_listing_key: 'premium_condo', custom_metadata: { is_premium: true, region: 'north_america' }, }, ], }, customer_resources_filters: [ { field: 'is_premium', operation: '=', value: true }, { field: 'region', operation: '=', value: 'europe' }, ], }) // Only "Premium Villa" is visible in the portal console.log(customer_portal.url) ``` ```bash cURL theme={null} curl -X POST \ 'https://connect.getseam.com/customers/create_portal' \ -H 'Authorization: Bearer ${SEAM_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "customer_data": { "customer_key": "customer_123", "property_listings": [ { "name": "Premium Villa", "property_listing_key": "premium_villa", "custom_metadata": { "is_premium": true, "region": "europe" } }, { "name": "Standard Apartment", "property_listing_key": "standard_apt", "custom_metadata": { "is_premium": false, "region": "europe" } }, { "name": "Premium Condo", "property_listing_key": "premium_condo", "custom_metadata": { "is_premium": true, "region": "north_america" } } ] }, "customer_resources_filters": [ { "field": "is_premium", "operation": "=", "value": true }, { "field": "region", "operation": "=", "value": "europe" } ] }' ``` #### Example 3: Boolean Filters Filter by a boolean `custom_metadata` value, such as showing only premium listings. ```javascript JavaScript theme={null} const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: 'customer_123', property_listings: [ { name: 'Premium Villa', property_listing_key: 'premium_villa', custom_metadata: { is_premium: true }, }, { name: 'Standard Apartment', property_listing_key: 'standard_apt', custom_metadata: { is_premium: false }, }, ], }, customer_resources_filters: [ { field: 'is_premium', operation: '=', value: true }, ], }) // Only "Premium Villa" is visible console.log(customer_portal.url) ``` ```bash cURL theme={null} curl -X POST \ 'https://connect.getseam.com/customers/create_portal' \ -H 'Authorization: Bearer ${SEAM_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "customer_data": { "customer_key": "customer_123", "property_listings": [ { "name": "Premium Villa", "property_listing_key": "premium_villa", "custom_metadata": { "is_premium": true } }, { "name": "Standard Apartment", "property_listing_key": "standard_apt", "custom_metadata": { "is_premium": false } } ] }, "customer_resources_filters": [ { "field": "is_premium", "operation": "=", "value": true } ] }' ``` #### Example 4: Filtering Reservations Filters also apply to reservations. Here, only reservations that are both premium and in Europe are shown. ```javascript JavaScript theme={null} const { customer_portal } = await seam.customers.createPortal({ customer_data: { customer_key: 'customer_123', property_listings: [ { name: 'Premium Villa', property_listing_key: 'premium_villa', }, ], reservations: [ { name: 'Premium EU Reservation', reservation_key: 'premium_eu_res', space_keys: ['premium_villa'], custom_metadata: { is_premium: true, region: 'europe' }, }, { name: 'Standard EU Reservation', reservation_key: 'standard_eu_res', space_keys: ['premium_villa'], custom_metadata: { is_premium: false, region: 'europe' }, }, { name: 'Premium US Reservation', reservation_key: 'premium_us_res', space_keys: ['premium_villa'], custom_metadata: { is_premium: true, region: 'north_america' }, }, ], }, customer_resources_filters: [ { field: 'is_premium', operation: '=', value: true }, { field: 'region', operation: '=', value: 'europe' }, ], }) // Only "Premium EU Reservation" is visible in the portal console.log(customer_portal.url) ``` ```bash cURL theme={null} curl -X POST \ 'https://connect.getseam.com/customers/create_portal' \ -H 'Authorization: Bearer ${SEAM_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "customer_data": { "customer_key": "customer_123", "property_listings": [ { "name": "Premium Villa", "property_listing_key": "premium_villa" } ], "reservations": [ { "name": "Premium EU Reservation", "reservation_key": "premium_eu_res", "space_keys": ["premium_villa"], "custom_metadata": { "is_premium": true, "region": "europe" } }, { "name": "Standard EU Reservation", "reservation_key": "standard_eu_res", "space_keys": ["premium_villa"], "custom_metadata": { "is_premium": false, "region": "europe" } }, { "name": "Premium US Reservation", "reservation_key": "premium_us_res", "space_keys": ["premium_villa"], "custom_metadata": { "is_premium": true, "region": "north_america" } } ] }, "customer_resources_filters": [ { "field": "is_premium", "operation": "=", "value": true }, { "field": "region", "operation": "=", "value": "europe" } ] }' ``` *** ### Verifying Filters After creating a portal, you can verify the configured filters by retrieving the portal via the customer API. The response includes `customer_resources_filters` in the portal configuration. ```bash theme={null} curl -X GET \ 'https://connect.getseam.com/seam/customer/v1/portals/get?customer_portal_id=PORTAL_ID' \ -H 'Authorization: Bearer ${API_KEY}' \ -H 'Content-Type: application/json' ``` The response will include the filters you configured: ```json theme={null} { "customer_portal": { "customer_resources_filters": [ { "field": "is_premium", "operation": "=", "value": true } ] } } ``` # Customer Portals Source: https://docs.seam.co/capability-guides/customer-portals/index Allow your customers to manage their own devices and systems. Provide self-service functions to your customers by setting up a customer portal. You can configure it entirely in the Console, or use our API to automate generating the portal. You can extend the portal experience with [Seam access and climate automations](../reservation-automations). When a customer books a stay, reserves a gym slot, or schedules a visit, automations automatically issue and revoke access or adjust climate settings. You create and manage them in the Console. ### Get started with the customer portal *** ### Customer portal features A customer portal allows your customers to self-manage connecting devices, manage their devices, and handle day-to-day management in one place.
Feature Description
Customer management

Offer your customers a self-serve method to:
:hyphen: Connect existing smart lock, thermostat, or access control accounts
:hyphen: Organize devices to match their property structure
:hyphen: Manage and troubleshoot their devices

:hyphen: Control Access or Climate features that you’ve configured for them.

Interoperability Works seamlessly with other Seam products, including Access and Climate.
Customized branding Configure the portal with your branding, including your logo, colors, and business information.
Ephemeral sessions Portal sessions are temporary. New portal sessions expire after 7 days period. They should be regenerated every time a customer needs to access the portal, whether from a new browser, a new device, or after the previous session has expired.
*** # Integrate customer portal into your application Source: https://docs.seam.co/capability-guides/customer-portals/integrate-customer-portal-into-your-application Generate Customer Portals programmatically with the create_portal endpoint, or grab a ready-made code snippet from the Seam Console. Use the `create_portal` endpoint to generate Customer Portals programmatically. *** **Grab a ready-made snippet from Console** 1. Go to **Developer** → **Customer Portals**. 2. Configure the portal (features, embedded, landing page) and enter your `customer_key` (and Spaces, if using Organize). 3. In Generate Portal → **Create Portal Programmatically**, open the code panel. 4. Copy the prefilled request (cURL). Replace placeholders like the Seam API key. ```bash theme={null} curl -X POST \ https://connect.getseam.com/customers/create_portal \ -H "Authorization: Bearer $SEAM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "is_embedded": false, "features": { "connect": { "exclude": false }, "organize": { "exclude": false }, "manage_devices": { "exclude": false } }, "customer_data": { "customer_key": "sample_customer_key", "property_listings": [ { "name": "Property 1", "property_listing_key": "property_1_id" } ] } }' ``` 5. Send the request from your app or API client. *** **Notes** * Customize features: All features are enabled by default; set `"exclude": true` to turn any off. * Embedded or standalone: Set `"is_embedded": true` to embed in an iframe; otherwise it’s standalone. * Scope by customer: `customer_key` ties the portal to a single customer in your system. * Use your own IDs: Use `space_key` values that match your internal identifiers. * Session lifetime: All portal links expire after 7 days. Generate a new portal programmatically each time a customer needs access. *** ## Embedding the Customer Portal as an iFrame The Seam Customer Portal is a hosted, pre-authenticated interface for managing devices, access codes, reservations, and more. Instead of sharing a magic link with your end-users, you can embed the portal directly inside your own application using an iFrame. This gives your users a seamless experience without leaving your product. ### How it works When you create a customer portal via the API, Seam returns a `customer_portal` URL. This URL can be loaded in a standard HTML ` ``` In practice, your backend generates the `customer_portal.url` and passes it to your frontend, which sets it as the iFrame `src`. Don't hardcode the URL — it contains a session token that expires. ### Step 3: Refresh the link before it expires Portal links are valid for 7 days. If your user keeps a page open for a long time, the embedded portal will eventually expire. Handle this by: 1. **Generating a fresh link on each page load.** This is the simplest approach. Each time your user navigates to the page containing the portal, your backend calls `/customers/create_portal` and returns a new URL. 2. **Tracking expiration client-side.** Store the `expires_at` timestamp and proactively refresh the iFrame `src` before it expires. You can also use the `/customers/open_portal` endpoint, which reuses an existing portal session if it hasn't expired yet, and creates a new one if it has. ### Configuring which features are visible The `features` object in the request body controls which sections of the portal your customer sees. Each feature can be included or excluded: | Feature | What it controls | | ---------------- | --------------------------------------------------------------------------- | | `connect` | Connecting new device accounts (e.g., linking an August or Schlage account) | | `manage` | Managing reservations and staff for properties | | `organize` | Organizing devices into spaces and groups | | `configure` | Configuring automation rules for access, climate, and Instant Key | | `manage_devices` | Legacy device management (use `manage` instead) | For example, if your product only needs reservation management, you can exclude everything else: ```json theme={null} { "features": { "connect": { "exclude": true }, "manage": { "exclude": false, "exclude_reservation_management": false, "exclude_staff_management": true }, "organize": { "exclude": true }, "configure": { "exclude": true } } } ``` ### Embedding a single reservation view (deep links) If you want to embed a portal that shows a single reservation — for example, inside a reservation detail page in your PMS — use the `/customers/reservations/create_deep_link` endpoint instead. ```bash theme={null} curl -X POST https://connect.getseam.com/customers/reservations/create_deep_link \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "customer_key": "my-customer-123", "reservation_key": "res-456" }' ``` This returns a `deep_link.url` that you embed the same way. The portal navigates directly to the reservation page with the navigation UI hidden, so it feels like a native part of your application. Deep links automatically set `is_embedded: true` and `navigation_mode: "restricted"`. ### Localization Set the `locale` parameter when creating the portal to display it in a different language: * `en-US` (default) * `pt-PT` — Portuguese * `fr-FR` — French * `it-IT` — Italian * `es-ES` — Spanish ```json theme={null} { "is_embedded": true, "locale": "fr-FR", "customer_data": { "..." } } ``` ### Branding and customization If you have a customization profile set up, pass the `customization_profile_id` when creating the portal to apply it. ```json theme={null} { "is_embedded": true, "customization_profile_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "customer_data": { "..." } } ``` A customization profile controls two things: * **Visual branding** — colors, logos, and fonts. * **Labels and terminology** — the wording the portal uses, so it matches what your own product calls things. You configure profiles in [Seam Console](https://console.seam.co) under **Developer > Customization Profiles**. ### Customizing labels and terminology Your users may not think of a rental unit as a "space" or a booking as a "reservation." A customization profile lets you override the portal's wording so the embedded portal reads like part of your product rather than like Seam. For example, you might rename **Space** to **Studio**, or **Reservation** to **Booking**. Overrides are set per language, and any string you leave alone keeps Seam's default wording — so you can rename a handful of terms without translating the whole portal. Strings are organized into namespaces, addressed as `Namespace.key`: | Namespace | Covers | | ------------------- | ---------------------------------------------------------------------------- | | `Common` | Shared UI text: buttons, states, and prompts such as **Save** and **Search** | | `Navigation` | Nav labels such as **Connect** and **Settings** | | `ConnectedAccounts` | Account connection, disconnection, and reconnection copy | | `Spaces` | Spaces, properties, rooms, facilities, and their setup flows | | `Devices` | Device lists, details, capabilities, and status | | `AccessCodes` | Access code management | | `AccessGrants` | Access grants | | `Reservations` | Reservations | | `StaffMembers` | Staff member management | | `Settings` | Portal settings | | `Thermostat` | Thermostat controls | | `Events` | Activity and event history | | `Errors` | Error messages | | `DeviceIssues` | Device issue descriptions | Overrides fall back gracefully. Any key you do not override — and any override you leave blank — uses Seam's built-in wording for that language, so a partial set of overrides is perfectly valid and a blank field never blanks out portal copy. Labels can be customized in each language the portal supports: English, Português, Español, Italiano, Français, Deutsch, Nederlands, Ελληνικά, Polski, and Русский. Pair this with the [`locale`](#localization) parameter to control which language a given portal session renders in. ### Frequently asked questions **Do I need to set any special headers or CSP rules on my side?** No. The portal is designed to be embedded and does not set `frame-ancestors` restrictions. As long as your own site doesn't block iFrames in its Content Security Policy, it will work out of the box. **Can my user interact with the portal inside the iFrame?** Yes. The portal is fully interactive — users can connect accounts, view device status, manage reservations, copy access codes, and everything else the portal supports. Adding `allow="clipboard-write"` to your iFrame tag enables the copy-to-clipboard functionality for access codes. **What happens when the portal link expires?** The portal will show an error state. Your application should detect this (either by tracking the `expires_at` timestamp or by listening for a page error in the iFrame) and generate a fresh link. **Can I scope the portal to specific properties or devices?** Yes. Pass `customer_resources_filters` when creating the portal to filter which resources are visible based on their `custom_metadata`. For example, you could show only properties in a specific region or managed by a specific team. ```json theme={null} { "customer_resources_filters": [ { "field": "region", "operation": "=", "value": "us-west" } ] } ``` # Preview the customer portal in Console Source: https://docs.seam.co/capability-guides/customer-portals/preview-the-customer-portal-in-console Preview how Customer Portals work and experiment with the API by setting up a temporary portal directly from the Seam Console. You can set up a customer portal directly from the Seam Console. These Console-generated portals are intended as an **API exploration playground** — they let you preview how portals work and experiment with the API before building your integration. **Important:** Portal links created in Console are temporary. They expire after 7 days and should not be used in production. For real-world usage, always generate portals programmatically using the API. *** ### 1. Open the Customer Portals page From the Console, navigate to **Developer** → **Customer Portals** from the top navigation bar. *** ### 2. Select your business verticals Choose the vertical that best matches your product (for example, *Short Term Rental*). This setting does two things: 1. Preconfigures recommended defaults for your use case. 2. Updates the labels in the portal UI so they use industry-specific terms your customers expect. For example: * In the Hospitality vertical, the generic Seam concept of a *Space* appears in the portal as a *Room*. * In Multi-family, *Spaces* appear as *Units*. * In Gym Management, they appear as *Facilities*. Example: In the Hospitality vertical, Spaces are shown as “Rooms” in the
portal UI. Here's a complete reference of how Seam concepts map to industry-specific labels across verticals: | Vertical | User Identity | Spaces | Bookings | | --------------------- | ------------- | ------------------- | ------------ | | **Short Term Rental** | Guest | Property listings | Reservations | | **Multi-family** | Tenant | Units, Common areas | Leases | | **Hospitality** | Guest | Rooms, Common areas | Bookings | | **Gym Management** | Member | Facilities | Memberships | | **Property Tours** | Visitor | Tour spaces | Bookings | | **Neutral** | User Identity | Spaces | Bookings | *** ### 3. Configure portal features Under **Portal Configuration**, select which features to enable: * **Connect** – allow customers to connect their device accounts. * **Organize** – let customers map devices to rental units, rooms, or spaces. * **Manage Devices** – give customers tools to manage devices, troubleshoot, and view logs. * **Configure** – allow customers to set automation rules and customize Instant Key branding. *** ### 4. Enter your `customer_key` Add the customer\_key for the customer this portal belongs to. Seam uses this key to scope the portal to only that customer’s devices and accounts. *** ### 5. (Optional) Set up Spaces This step is required only if you enable the Organize feature. * Spaces represent the real-world units your customer manages—for example, *Room 101* in a hotel, *Unit A* in an apartment building, or *Studio 3* in a gym. * Create a Space for each unit your customer manages. * Use a `space_key` that matches your own system’s identifier (for example, `room-101-id`). **Reminder:** Even if the portal shows “Rooms” or “Units,” these all map back to Spaces in Seam. *** ### 6. Generate the portal Click **Create Portal**. Seam generates a temporary portal URL you can use to preview the portal. **Note:** All portal links expire after 7 days. For production, always generate portals programmatically, each time a customer needs access. *** ### Next step: Generate portals programmatically with the API In production, portals must be generated with the API so that they can be refreshed whenever a customer needs access. On the next page, we’ll cover how to create portals programmatically using the `create_portal` endpoint. # Device and System Capabilities Source: https://docs.seam.co/capability-guides/device-and-system-capabilities Learn about device and system capabilities, as well as capability flags. In the Seam API, capability flags inform your application about what features and behaviors each device supports. Each device that you connect to Seam has a specific set of capabilities. These capabilities define the Seam API actions that you can use. For example, some devices support [remote unlock actions](../low-level-apis/smart-locks/lock-and-unlock), while others support [programming access codes](/low-level-apis/smart-locks/access-codes/index). Some devices support both of these capabilities. When developing your application, it is imperative to be able to identify the capabilities of each device. For example, if a device supports programming online access codes, your app can present the [`CreateAccessCodeForm` Seam Component](../ui-components/overview/react-components/create-access-code-form) to your user. On the other hand, if a connected device does not support the remote unlock action, you'll likely want to disable or not display the unlock functionality for your app user. ## Capability Flags Capability flags inform your application about what features and behaviors each device supports. That is, you can use capability flags to match devices to the requirements for operations within your app. These flags also compare the capabilities of a specific device instance with those of the device model in general. Capability flags help you to understand which actions a device can
perform. All capability flags share the following behavior: * If `true`, the device has this capability, and this capability is functional on this device instance. * If `false`, the device has this capability, but the capability is not currently functional. See the device [errors and warnings](/api/devices/errors) for more details about the cause of this issue. You can also examine the [properties](/api/devices/object) of the device and [events](/api/devices/events) related to the device to learn more about the cause of this issue. * If not present, the device does not have this capability. Reasons why a capability flag might be `false` could include that a required hardware accessory is not connected to the device. For example, if a lock needs a Wi-Fi bridge for connectivity and is currently not connected to a bridge, the lock cannot be remotely unlocked. If a lock is missing an accessory keypad, access codes cannot be programmed on the lock. With respect to the ability to program online access codes, as long as a lock has the required hardware, Seam assumes that any offline status is temporary and will be resolved before [it's time to set the access code on the device](../low-level-apis/smart-locks/access-codes/lifecycle-of-access-codes). Consequently, in this case, Seam maintains `can_program_online_access_codes` as `true`. Capability flags help you to understand why a device cannot currently
perform an action. Seam recommends adding capability checks before performing specific actions in your app. For example, before performing a [remote unlock](../low-level-apis/smart-locks/lock-and-unlock#unlocking-a-door) operation, you can check to make sure that the target device supports remote unlocking. For details and code samples, see the corresponding capability guides. In addition to viewing the capabilities for a specific device, you can also view the capabilities for a provider using [List Device Providers](/api/devices/list_device_providers). If at least one supported device from a provider has a specific capability, the corresponding capability flag is `true`.
Property Type Description
device.can\_remotely\_unlock Boolean
Optional
Indicates whether the device can perform a remote unlock operation .
device.can\_remotely\_lock Boolean
Optional
Indicates whether the device can perform a remote lock operation .
device.can\_program\_online\_access\_codes Boolean
Optional
Indicates whether the device can program online access codes .
If true, it is currently possible to create new online access codes for the device, and Seam programs the device the next time it's online.
device.can\_program\_offline\_access\_codes Boolean
Optional
Indicates whether the device can program offline access codes .
When this flag is true, Seam can generate an offline code for this device, regardless of the current online status of the device.
device.can\_hvac\_heat Boolean
Optional
Indicates whether the thermostat device (in conjunction with the associated HVAC system) supports heat mode .
When this flag is true, you can set the thermostat to heat mode .
device.can\_hvac\_cool Boolean
Optional
Indicates whether the thermostat device (in conjunction with the associated HVAC system) supports cool mode .
When this flag is true, you can set the thermostat to cool mode .
device.can\_hvac\_heat\_cool Boolean
Optional
Indicates whether the thermostat device (in conjunction with the associated HVAC system) supports heat-cool (auto) mode .
When this flag is true, you can set the thermostat to heat-cool mode .
device.can\_turn\_off\_hvac Boolean
Optional
Indicates whether the thermostat device (in conjunction with the associated HVAC system) supports off mode .
When this flag is true, you can set the thermostat to "off" mode , which turns off both the heating and cooling systems for the space.
Seam is actively developing additional capability flags to provide you with even more robust capability checking abilities for your app. If you would like us to add a specific capability flag, contact [support@seam.co](mailto:support@seam.co). *** ## Next Steps To learn about the actions that you can perform using the Seam API, see the Seam capability guides. These guides provide helpful tutorials and code samples, categorized by capability types. * [Smart locks](/low-level-apis/smart-locks/index), including [locking/unlocking](../low-level-apis/smart-locks/lock-and-unlock) and [managing access codes](/low-level-apis/smart-locks/access-codes/index) * [Access control systems](/low-level-apis/access-systems/index) * [Thermostats](/capability-guides/thermostats/index) * [Noise sensors](/capability-guides/noise-sensors/index) * [Mobile access](/capability-guides/mobile-access/index) * [Seam Bridge](/capability-guides/seam-bridge) # Developing in a Sandbox Workspace Source: https://docs.seam.co/capability-guides/mobile-access/developing-in-a-sandbox-workspace Develop and test mobile key integrations without real hardware by using a Seam sandbox workspace and simulated phones for user identities. Seam's sandbox workspaces enable you to develop integrations without access to a real system. Use your sandbox workspace to test out issuing mobile keys and other related aspects of your integration. ## Creating a Simulated Phone for a User Identity When issuing mobile credentials, some systems require the user identity to have a provisioned phone. While you are developing and testing your integration, you can add a simulated phone in your sandbox workspace. Use the following flow to [add a simulated phone](/api/phones/simulate/create_sandbox_phone) for a user identity: **Command:** ```javascript JavaScript theme={null} // Step 1: Create the user identity. const userIdentity = await seam.userIdentities.create({ user_identity_key: 'jean_doe', full_name: 'Jean Doe', }) // Step 2: Create a simulated, sandbox phone. await seam.phones.simulate.createSandboxPhone({ user_identity_id: userIdentity.user_identity_id, }) ``` ```bash cURL theme={null} # Step 1: Create the user identity. user_identity=$(curl -X 'POST' \ 'https://connect.getseam.com/user_identities/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "user_identity_key": "jean_doe", "full_name": "Jean Doe" }') # Step 2: Create a simulated, sandbox phone. curl -X 'POST' \ 'https://connect.getseam.com/phones/simulate/create_sandbox_phone' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"user_identity_id\": \"$(jq -r '.user_identity.user_identity_id' <<< ${user_identity})\" }" ``` ```python Python theme={null} # Step 1: Create the user identity. user_identity = seam.user_identities.create( user_identity_key = "jean_doe", full_name = "Jean Doe" ) # Step 2: Create a simulated, sandbox phone. seam.phones.simulate.create_sandbox_phone( user_identity_id = user_identity.user_identity_id ) ``` ```ruby Ruby theme={null} # Step 1: Create the user identity. user_identity = seam.user_identities.create( user_identity_key: "jean_doe", full_name: "Jean Doe", ) # Step 2: Create a simulated, sandbox phone. seam.phones.simulate.create_sandbox_phone( user_identity_id: user_identity.user_identity_id, ) ``` ```php PHP theme={null} // Step 1: Create the user identity. $seam->user_identities->create( user_identity_key: "jean_doe", full_name: "Jean Doe" ); // Step 2: Create a simulated, sandbox phone. $seam->phones->simulate->create_sandbox_phone( user_identity_id: $user_identity->user_identity_id ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} { "user_identity_id": "22222222-2222-2222-2222-222222222222", "full_name": "Jean Doe", ... } { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... } ``` ```json cURL theme={null} { "user_identity": { "user_identity_id": "22222222-2222-2222-2222-222222222222", "full_name": "Jean Doe", ... }, "ok": true } { "phone": { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, "ok": true } ``` ```json Python theme={null} UserIdentity( user_identity_id='22222222-2222-2222-2222-222222222222', user_identity_key='jean_doe', full_name='Jean Doe', ... ) Phone( device_id='22222222-2222-2222-2222-444444444444', device_type='android_phone', created_at='2025-01-01T10:40:00+00:00', ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "user_identity_id": "22222222-2222-2222-2222-222222222222", "full_name": "Jean Doe", ... } { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... } ``` ```json C# theme={null} Coming soon! ``` # Mobile Access Source: https://docs.seam.co/capability-guides/mobile-access/index Use Seam to issue mobile credentials across a wide variety of access platforms. Seam SDK lets you unlock doors using BLE and NFC credentials across a wide
variety of access platforms ## Managing Mobile Credentials Mobile access is the use of a mobile device, such as a smartphone, tablet, or wearable, to gain access to secured doors, gates, services, and more. This functionality is incorporated in [access control systems](/low-level-apis/access-systems/index) (ACSs) of diverse types and levels of complexity. The Seam mobile access solution makes it easy to issue and retrieve mobile credentials across a wide variety of access control systems. This guide provides an overview of these basic operations and introduces the basic terminology related to mobile access. *** ## Applicable Lock and Access Platforms The Seam mobile access solution is primarily focused on electronic locks and access hardware that support Bluetooth® or near-field communication (NFC) wireless technology. These groups of devices include a vast array of modern electronic door locks, turnstiles, and gate systems. Before implementation, it is important to verify that the existing hardware can communicate with smartphones through one of these wireless technologies.\ If you aim to enable mobile access with Wi-Fi or Z-Wave locks, see [Smart Locks](/low-level-apis/smart-locks/index). This section describes API endpoints that you can use directly in your mobile application. *** ## Mobile Credential Process The following process describes how mobile credentials work: 1. **Installation of an app**\ First, users download a specialized app onto their smartphones. Your team can develop this app, or you can use the Seam Passport app. 2. **Credential assignment** Credentials are then issued to the user's app account. This process also links their specific account to their unique user profile in the access control system. 3. **Bluetooth or NFC technology** The smartphone communicates with the access control system using either Bluetooth or NFC. These technologies enable the phone to communicate with a reader installed at the access point. 4. **Authentication** When a user approaches an access point, such as a door or gate, they use the app to signal their intent to enter. The app communicates with the reader to authenticate the user's credentials. This signaling can occur by the user tapping a button in the app, by the user using a gesture, or even automatically when the phone comes into range, depending on the configuration of the system. 5. **Access granted or denied** The access control system verifies the credentials and either grants access (by unlocking the door or gate) or denies it. The system can also record the access event, noting the time and the identity of the user. *** ## Use Cases Use the Seam API and Mobile SDK for the following tasks: * **Issue and distribute mobile credentials across many platforms.** The Seam API is compatible with many access control systems. The Mobile SDK also supports multiple mobile technologies, like Bluetooth low energy (BLE), NFC, and Apple Wallet. * **Automatically provision new phones and issue credentials.**\ When a user signs into their account on a new phone, Seam automatically provisions the device and issues the necessary credentials. It also ensures that the mobile credentials are synced to the access control system. # Issuing Mobile Credentials from an Access Control System Source: https://docs.seam.co/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system Learn how to create mobile credentials across a user's multiple phones. ## Overview A credential manager, such as HID Origo Mobile Identities, is a cloud-based service responsible for issuing [mobile credentials](/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system) and keeping track of which mobile credentials have been issued to which phones. Enrolling the phone with the credential manager is a prerequisite for issuing mobile credentials. Seam performs this registration automatically and detects when new phones come online for a [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity). Typically, without Seam, you would have to wait for a phone to complete enrollment before you could start sending credentials. Seam, however, simplifies this process by enabling you to preconfigure the mobile credential details. As soon as a new phone is enrolled successfully, Seam automatically issues the designated mobile credential to it. Because a user might have multiple phones, when you create a mobile credential, you must use a [multi-phone sync credential](#what-are-multi-phone-sync-credentials) to guarantee that the user has access across all their phones. *** ## What Are Multi-Phone Sync Credentials? When issuing mobile credentials for a mobile app user, it is necessary to issue a multi-phone sync credential. As [Managing Phones for a User Identity](/capability-guides/mobile-access/managing-phones-for-a-user-identity) describes, a user identity (that is, a mobile app user) may possess multiple phones. To guarantee access across all of the phones for the user identity, the multi-phone sync credential manages the distribution of credentials to each phone linked to the user identity. The multi-phone sync credential also imports the credentials into the ACS and allocates them to the corresponding ACS user. The multi-phone sync credential creates one credential per phone for the user identity. *** ## Issuing Multi-Phone Sync Credentials To issue mobile credentials, you must configure a multi-phone sync credential. This type of credential automatically replicates itself when the app user logs in on a new phone. To configure a multi-phone sync credential, include the ID of the ACS user, set `is_multi_phone_sync_credential` to `true`, and include the card details that should be shared across these credentials. Seam configures the card details that you include in the request across all the credentials that it creates for each phone. Include only common card details, such as the [facility code](https://www.idwholesaler.com/learning-center/26-bit-proximity-card/), and omit any unique card details, such as the card number. For more information about specific card properties, see the user guide for the access control system or credential manager. The code samples in this section contain manufacturer-specific metadata that may vary by ACS. For details, see the [system integration guide](/device-and-system-integration-guides#access-control-systems) for your ACS. **Command:** ```javascript JavaScript theme={null} await seam.acs.credentials.create({ is_multi_phone_sync_credential: true, acs_user_id: "33333333-3333-3333-3333-333333333333", access_method: "mobile_key", credential_manager_acs_system_id: "88888888-8888-8888-8888-888888888888", // ACS manufacturer-specific properties visionline_metadata: { "cardFormat": "rfid48", "label": "%ROOMNUM% - %SITENAME%", "override": true }, ... }); ``` ```bash cURL theme={null} # Note the manufacturer-specific visionline_metadata in this request. curl -X 'POST' \ 'https://connect.getseam.com/acs/credentials/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "is_multi_phone_sync_credential": true, "acs_user_id": "33333333-3333-3333-3333-333333333333", "access_method": "mobile_key", "credential_manager_acs_system_id": "88888888-8888-8888-8888-888888888888", "visionline_metadata": { "cardFormat": "rfid48", "label": "%ROOMNUM% - %SITENAME%", "override": true }, ... }' ``` ```python Python theme={null} seam.acs.credentials.create( is_multi_phone_sync_credential=True, acs_user_id="33333333-3333-3333-3333-333333333333", access_method="mobile_key", credential_manager_acs_system_id="88888888-8888-8888-8888-888888888888", # ACS manufacturer-specific properties visionline_metadata={ "cardFormat": "rfid48", "label": "%ROOMNUM% - %SITENAME%", "override": True }, ... ) ``` ```ruby Ruby theme={null} seam.acs.credentials.create( is_multi_phone_sync_credential: true, acs_user_id: "33333333-3333-3333-3333-333333333333", access_method: "mobile_key", credential_manager_acs_system_id: "88888888-8888-8888-8888-888888888888", # ACS manufacturer-specific properties visionline_metadata: { "cardFormat" => "rfid48", "label" => "%ROOMNUM% - %SITENAME%", "override" => true }, ... ) ``` ```php PHP theme={null} $seam->acs->credentials->create( is_multi_phone_sync_credential: true, acs_user_id: "33333333-3333-3333-3333-333333333333", access_method: "mobile_key", credential_manager_acs_system_id: "88888888-8888-8888-8888-888888888888", // ACS manufacturer-specific properties visionline_metadata => [ "cardFormat" => "rfid48", "label" => "%ROOMNUM% - %SITENAME%", "override" => true ], ... ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} { acs_credential_id: '99999999-9999-9999-9999-999999999999', acs_user_id: '33333333-3333-3333-3333-333333333333', access_method: 'mobile_key', is_multi_phone_sync_credential: true, ... } ``` ```json cURL theme={null} { "acs_credential": { "acs_credential_id": "99999999-9999-9999-9999-999999999999", "acs_user_id": "33333333-3333-3333-3333-333333333333", "access_method": "mobile_key", "is_multi_phone_sync_credential": true, ... }, "ok": true } ``` ```json Python theme={null} AcsCredential( acs_credential_id='99999999-9999-9999-9999-999999999999', acs_user_id='33333333-3333-3333-3333-333333333333', access_method='mobile_key', is_multi_phone_sync_credential=True, ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "acs_credential_id": "99999999-9999-9999-9999-999999999999", "acs_user_id": "33333333-3333-3333-3333-333333333333", "access_method": "mobile_key", "is_multi_phone_sync_credential": true, ... } ``` ```json C# theme={null} Coming soon! ``` # Managing Mobile App User Accounts with User Identities Source: https://docs.seam.co/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities Learn how to use Seam user identities to manage mobile app user accounts. ## What is a User Identity? Seam user identities are a feature for tracking and managing user accounts in your application. This feature assigns unique identifiers to each of your users, enabling you to issue and manage their [mobile credentials](/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system) and access permissions. Each user identity is mapped to a user account in your app. Each user identity is mapped to a user account in your app. ### User Identities Can Be Connected to Users in Multiple Access Control Systems User identities can be linked to one [ACS user](/low-level-apis/access-systems/user-management) in each access control system. Any mobile credentials issued to these ACS users are consolidated under the user identity. Consequently, a user's mobile app account has access to these credentials through the user identity. A user identity can be connected to an ACS user in each ACS. *** ## Create a User Identity and Associate it with an ACS User ### 1. Create a User Identity To [create a user identity](/api/user_identities/create), you can specify any of the following characteristics: * Unique user identity key (`user_identity_key`) * Unique email address (`email_address`) * Unique phone number (`phone_number`) * Full name (`full_name`) Note that if you specify one or more of the `user_identity_key`, `email_address`, or `phone_number`, each of these values must be unique within your [workspace](/core-concepts/workspaces/index). **Command:** ```javascript JavaScript theme={null} await seam.userIdentities.create({ user_identity_key: 'jean_doe', email_address: 'jean@example.com', phone_number: '+15555550110', full_name: 'Jean Doe', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/user_identities/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "user_identity_key": "jean_doe", "email_address": "jean@example.com", "phone_number": "+15555550110", "full_name": "Jean Doe" }' ``` ```python Python theme={null} seam.user_identities.create( user_identity_key = "jean_doe", email_address = "jean@example.com", phone_number = "+15555550110", full_name = "Jean Doe" ) ``` ```ruby Ruby theme={null} seam.user_identities.create( user_identity_key: "jean_doe", email_address: "jean@example.com", phone_number: "+15555550110", full_name: "Jean Doe", ) ``` ```php PHP theme={null} $seam->user_identities->create( user_identity_key: "jean_doe", email_address: "jean@example.com", phone_number: "+15555550110", full_name: "Jean Doe" ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} { "user_identity_id": "22222222-2222-2222-2222-222222222222", "user_identity_key": "jean_doe", "email_address": "jean@example.com", "phone_number": "+15555550110", "display_name": "Jean Doe", "full_name": "Jean Doe", ... } ``` ```json cURL theme={null} { "user_identity": { "user_identity_id": "22222222-2222-2222-2222-222222222222", "user_identity_key": "jean_doe", "email_address": "jean@example.com", "phone_number": "+15555550110", "display_name": "Jean Doe", "full_name": "Jean Doe", ... }, "ok": true } ``` ```json Python theme={null} UserIdentity( user_identity_id='22222222-2222-2222-2222-222222222222', user_identity_key='jean_doe', email_address='jean@example.com', phone_number='+15555550110', display_name='Jean Doe', full_name='Jean Doe', ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "user_identity_id": "22222222-2222-2222-2222-222222222222", "user_identity_key": "jean_doe", "email_address": "jean@example.com", "phone_number": "+15555550110", "display_name": "Jean Doe", "full_name": "Jean Doe", ... } ``` ```json C# theme={null} Coming soon! ``` ### 2. Assign an ACS User to the User Identity To [link an ACS user with a user identity](/api/user_identities/add_acs_user), provide the ID of the user identity and the ID of the ACS user. **Command:** ```javascript JavaScript theme={null} const userIdentity = await seam.userIdentities.get({ email_address: 'jean@example.com', }) const acsUser = await seam.acs.users.get({ email_address: 'jean@example.com', }) await seam.userIdentities.addAcsUser({ user_identity_id: userIdentity.user_identity_id, acs_user_id: acsUser.acs_user_id, }) ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/user_identities/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"email_address\": \"jane@example.com\" }") # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/acs/users/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"email_address\": \"jane@example.com\" }") curl -X 'POST' \ 'https://connect.getseam.com/user_identities/add_acs_user' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${API_KEY}' \ -H 'Content-Type: application/json' \ -d "{ \"user_identity_id\": \"$(jq -r '.user_identity.user_identity_id' <<< ${user_identity})\", \"acs_user_id\": \"$(jq -r '.acs_user.acs_user_id' <<< ${acs_user})\", }" ``` ```python Python theme={null} user_identity = seam.user_identities.get( email_address = "jean@example.com" ) acs_user = seam.acs.users.get( email_address = "jean@example.com" ) seam.user_identities.add_acs_user( user_identity_id = user_identity.user_identity_id, acs_user_id = acs_user.acs_user_id ) ``` ```ruby Ruby theme={null} user_identity = seam.user_identities.get( email_address: "jane@example.com" ) acs_user = seam.acs.users.get( email_address: "jane@example.com" ) seam.user_identities.add_acs_user( user_identity_id: user_identity.user_identity_id, acs_user_id: acs_user.acs_user_id, ) ``` ```php PHP theme={null} $user_identity = $seam->user_identities->get( email_address: "jean@example.com", ); $acs_user = $seam->acs->users->get( email_address: "jean@example.com", ); $seam->user_identities->add_acs_user( user_identity_id: $user_identity->user_identity_id, acs_user_id: $acs_user->acs_user_id ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} // void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} null ``` ```json C# theme={null} Coming soon! ``` *** ## Removing a User Identity When you [delete a user identity](/api/user_identities/delete), Seam automatically cleans up all other associated resources. **Command:** ```javascript JavaScript theme={null} await seam.userIdentities.delete({ user_identity_id: '22222222-2222-2222-2222-222222222222', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/user_identities/delete' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "user_identity_id": "22222222-2222-2222-2222-222222222222" }' ``` ```python Python theme={null} seam.user_identities.delete( user_identity_id = "22222222-2222-2222-2222-222222222222" ) ``` ```ruby Ruby theme={null} seam.user_identities.delete( user_identity_id: "22222222-2222-2222-2222-222222222222" ) ``` ```php PHP theme={null} $seam->user_identities->delete( user_identity_id: "22222222-2222-2222-2222-222222222222" ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} // void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} null ``` ```json C# theme={null} Coming soon! ``` # Managing Phones for a User Identity Source: https://docs.seam.co/capability-guides/mobile-access/managing-phones-for-a-user-identity Learn how to manage the phones associated with a user identity. An app user may have several phones. When they sign into their account on your mobile application, it is important that additional phones also provide access. Seam facilitates this access by registering each phone within the [user identity](/capability-guides/mobile-access/managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) and synchronizing [mobile credentials](/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system) across these phones. Further, Seam provides a feature to deactivate a phone if an app user loses it. *** ## App User New Phone Process When an app user signs in to a new phone, Seam can automatically set up the new phone, generate matching credentials, and issue these credentials. To facilitate this capability, you must [issue a multi-phone sync credential](/capability-guides/mobile-access/issuing-mobile-credentials-from-an-access-control-system) when creating a mobile credential. When a user sign in to a new phone, Seam also issues matching credentials to the new phone. *** ## App User Lost Phone Process If an app user loses their phone or wants to deactivate it, you can deactivate the phone. Seam then automatically invalidates the stored credentials on their deactivated phone. When a phone is revoked, Seam revokes all the credentials issued to this phone. To [deactivate](/api/phones/deactivate) a phone, provide the ID of the phone. When a phone is deactivated, Seam also revokes all the credentials issued to the deactivated phone. Seam also removes the associated ACS credentials from the ACS. **Command:** ```javascript JavaScript theme={null} await seam.phones.deactivate({ device_id: lostPhoneId, }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/phones/deactivate' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"${lost_phone_id}\" }" ``` ```python Python theme={null} seam.phones.deactivate( device_id = lost_phone_id ) ``` ```ruby Ruby theme={null} seam.phones.deactivate( device_id: lost_phone_id ) ``` ```php PHP theme={null} $seam->phones->deactivate( device_id: $lost_phone_id, ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} // void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} null ``` ```json C# theme={null} Coming soon! ``` *** ## Retrieving Phones for a User Identity To retrieve the list of phones that the mobile app user has used to sign in to their account, use the [List Phones](/api/phones/list) endpoint and include the ID of the user identity. **Command:** ```javascript JavaScript theme={null} await seam.phones.list({ owner_user_identity_id: user_identity.id, }) ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/phones/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"owner_user_identity_id\": \"${user_identity_id}\" }" ``` ```python Python theme={null} seam.phones.list( owner_user_identity_id = user_identity.id ) ``` ```ruby Ruby theme={null} seam.phones.list( owner_user_identity_id: user_identity.id, ) ``` ```php PHP theme={null} $seam->phones->list( owner_user_identity_id: $user_identity->id ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} [ { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, { "device_id": "22222222-2222-2222-2222-555555555555", "device_type": "ios_phone", "created_at": "2025-01-02T10:40:00+00:00", ... }, ... ] ``` ```json cURL theme={null} { "phones": [ { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, { "device_id": "22222222-2222-2222-2222-555555555555", "device_type": "ios_phone", "created_at": "2025-01-02T10:40:00+00:00", ... }, ... ], "ok": true } ``` ```json Python theme={null} [ Phone( device_id='22222222-2222-2222-2222-444444444444', device_type='android_phone', created_at='2025-01-01T10:40:00+00:00', ... ) Phone( device_id='22222222-2222-2222-2222-555555555555', device_type='ios_phone', created_at='2025-01-02T10:40:00+00:00', ... ) ... ] ``` ```json Ruby theme={null} [ , , ... ] ``` ```json PHP theme={null} [ { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, { "device_id": "22222222-2222-2222-2222-555555555555", "device_type": "ios_phone", "created_at": "2025-01-02T10:40:00+00:00", ... }, ... ] ``` ```json C# theme={null} Coming soon! ``` *** ## Retrieving a Phone by ID To retrieve a phone by its ID, use the [Get Phone](/api/phones/get) endpoint and include the `device_id` of the phone. **Command:** ```javascript JavaScript theme={null} await seam.phones.list({ owner_user_identity_id: user_identity.id, }) ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/phones/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "22222222-2222-2222-2222-444444444444" }' ``` ```python Python theme={null} seam.phones.get( device_id = "22222222-2222-2222-2222-444444444444" ) ``` ```ruby Ruby theme={null} seam.phones.list( owner_user_identity_id: user_identity.id, ) ``` ```php PHP theme={null} $seam->phones->list( owner_user_identity_id: $user_identity->id ); ``` ```csharp C# theme={null} Coming soon! ``` **Output:** ```json JavaScript theme={null} [ { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, { "device_id": "22222222-2222-2222-2222-555555555555", "device_type": "ios_phone", "created_at": "2025-01-02T10:40:00+00:00", ... }, ... ] ``` ```json cURL theme={null} { "phone": { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, "ok": true } ``` ```json Python theme={null} Phone( device_id='22222222-2222-2222-2222-444444444444', device_type='android_phone', created_at='2025-01-01T10:40:00+00:00', ... ) ``` ```json Ruby theme={null} [ , , ... ] ``` ```json PHP theme={null} [ { "device_id": "22222222-2222-2222-2222-444444444444", "device_type": "android_phone", "created_at": "2025-01-01T10:40:00+00:00", ... }, { "device_id": "22222222-2222-2222-2222-555555555555", "device_type": "ios_phone", "created_at": "2025-01-02T10:40:00+00:00", ... }, ... ] ``` ```json C# theme={null} Coming soon! ``` # Prepare your Workspace Source: https://docs.seam.co/capability-guides/mobile-access/mobile-access-setup Learn how to set up the prerequisite components for the Seam mobile access solution. To use the [Seam mobile access](./) solution, you must first set up the following components: * **An access control system that is compatible with your chosen mobile access solution**\ Obtain the account login information for your access control system (ACS). See the [brand-specific ACS guide](/device-and-system-integration-guides#access-control-systems) for instructions on where to find this information. In addition, verify that your ACS is compatible with the mobile technology that you intend to implement, such as Apple Wallet. It may be necessary to upgrade your system to support these technologies. Further, you may need to register for developer access with the ACS that you have chosen to use. * **A credential manager account that is appropriate for the installed access hardware**\ Depending on the make and model of your lock or access hardware, you may need to set up a credential manager account for issuing mobile credentials for your brand of lock. The credential manager is responsible for issuing mobile credentials and keeping track of which mobile credentials have been issued to which mobile devices. Often, the mobile credentials that the credential manager generates need to be imported into the access control system, before they can be used to grant access. * **Access hardware that is configured with the appropriate settings**\ Certain makes and models of lock hardware may require you to configure specific encryption keys on the access hardware to enable mobile access. See the appropriate [device guides](/device-and-system-integration-guides#smart-locks) for detailed instructions related to these requirements. *** ## Set up Your Workspace To set up your Seam workspace to use the Seam mobile access solution: 1. **Connect your ACS account to Seam using a** [**Connect Webview**](/core-concepts/connect-webviews/index) This step requires the account information for your ACS account. For more information, see the [guide](/device-and-system-integration-guides#access-control-systems) for your specific ACS brand. 2. **Connect your credential manager account to Seam using a Connect Webview**\ This step requires the account information for your credential manager account. For more information, see the corresponding [guide](/device-and-system-integration-guides#access-control-systems) for your credential manager type. 3. **Configure any workspace settings required**\ Some integrations require certain workspace-wide settings to be configured. For more information, see the [guide](/device-and-system-integration-guides#access-control-systems) for your specific ACS brand. # Handling System Permissions Source: https://docs.seam.co/capability-guides/mobile-access/mobile-device-sdks/handling-system-permissions Detect and resolve missing system permissions like Bluetooth and connectivity in your mobile app by handling the Seam SDK's credential errors. The mobile SDK surfaces missing or required system permissions (Bluetooth, internet connectivity, and so on) as `CredentialError.userInteractionRequired(action)` entries in each credential’s `errors` array. After activation, observe these errors and handle the specified actions. Errors update automatically as requirements change. *** ## Platform Setup Requirements First, configure the required platform capabilities. 1. **Suppress Apple Wallet while unlocking with BLE**\ To prevent the Apple Wallet dialog from appearing when your app uses BLE to unlock a door, do the following: * Add the `requestAutomaticPassPresentationSuppression()` call to your app.\ This method suppresses Apple Wallet while your mobile app is in the foreground and ensures a smoother `unlockWithTap` experience. * Request the `com.apple.developer.passkit.pass-presentation-suppression` entitlement from Apple. Apple Wallet suppression and Bluetooth scanning only apply while the app is in the foreground. Ensure unlock operations are initiated while the app is active. 2. **Enable Bluetooth capability** Add the required Bluetooth key to your app’s entitlements file: ```xml theme={null} com.apple.security.device.bluetooth ``` 1. **Request Bluetooth permissions** Define and call a helper function in your app to request the necessary Bluetooth permissions at runtime. 2. **For Android 12 (API 31) and newer:** ``` Manifest.permission.BLUETOOTH_SCAN Manifest.permission.BLUETOOTH_CONNECT Manifest.permission.BLUETOOTH_ADVERTISE ``` 3. **For Android 11 (API 30) and older:** ``` Manifest.permission.BLUETOOTH Manifest.permission.BLUETOOTH_ADMIN Manifest.permission.ACCESS_COARSE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION ``` See [Android request permissions](https://developer.android.com/training/permissions/requesting) for more details. ## Monitoring Permission Errors Use Combine to watch the published credentials array and handle permission-related errors: ```swift theme={null} import SeamSDK import Combine func startMonitoringPermissionErrors() { permissionCancellable = Seam.shared.$credentials .map { credentials in credentials.flatMap { credential in credential.errors.compactMap { error in guard case .userInteractionRequired(let action) = error else { return nil } return action } } } .receive(on: RunLoop.main) .sink { actions in actions.forEach { handlePermissionAction($0) } } } ``` The mobile SDK automatically clears resolved permission errors once the required permission is granted, reflecting the updated credential state. ```kotlin theme={null} coroutineScope.launch { SeamSDK.getInstance().credentials.collect { credentialsList -> val errors = credentialsList.flatMap { it.errors } errors.forEach { error -> when (error) { is SeamCredentialError.UserInteractionRequired -> { handleUserInteractionRequired(error.interaction) } else -> { /* handle other errors */ } } } } fun handleUserInteractionRequired(interaction: SeamRequiredUserInteraction) { when (interaction) { is SeamRequiredUserInteraction.GrantPermissions -> { /* handle permissions error */ // interaction.permissions contains the list of required permissions } else -> { /* handle other errors */ } } } } ``` The mobile SDK automatically clears resolved permission errors once the required permission is granted, reflecting the updated credential state. ## Handling Permission Actions Implement your handler for each action: ```kotlin Android Kotlin theme={null} fun handleUserInteractionRequired(interaction: SeamRequiredUserInteraction) { when (interaction) { is SeamRequiredUserInteraction.CompleteOtpAuthorization -> { /* handle OTP authorization */ } is SeamRequiredUserInteraction.EnableBluetooth -> { /* handle Bluetooth error */ } is SeamRequiredUserInteraction.EnableInternet -> { /* handle Internet connection error*/ } is SeamRequiredUserInteraction.GrantPermissions -> { /* handle permissions error*/ } } } ``` ```swift iOS Swift theme={null} func handlePermissionAction(_ action: CredentialUserAction) { switch action { case .enableInternet: // Prompt the user to enable network connectivity. case .enableBluetooth: // Prompt the user to turn on Bluetooth. case .grantBluetoothPermission: // Prompt the user to grant Bluetooth permission in Settings. } } ``` *** ## See also For a complete SwiftUI-based implementation of credential error handling for iOS, see `SeamUnlockCardView` in the SeamComponents library, which demonstrates observing credential errors and updating the UI accordingly. # Integrating into Your Mobile Application Source: https://docs.seam.co/capability-guides/mobile-access/mobile-device-sdks/index The Seam mobile SDKs help you to create native applications for Apple (iOS) and Android devices and platforms. ## Overview We have designed the Seam mobile SDKs to provide the flexibility to support a range of workflows. This example describes a mobile key workflow, in which the smart door lock scans for and unlocks in the presence of a nearby mobile device acting as a passive key. Note that the mobile device in this example uses Bluetooth Low Energy (BLE) technology. 1. Once the mobile app is downloaded, it requests Bluetooth permissions from the user. 2. The user presses the **Unlock** button, prompting the phone to search for nearby locks. 3. When the user holds their phone close to the lock, a Bluetooth connection is established, and the phone transmits a key to the lock. 4. The lock verifies the mobile key, confirms that the key can access this lock, and sends a success response back to the app. 5. The lock successfully unlocks! Example of Unlock sequence in a Mobile App # Initializing the Seam Mobile SDK Source: https://docs.seam.co/capability-guides/mobile-access/mobile-device-sdks/initializing-the-seam-mobile-sdk Install and initialize the Seam Mobile SDK in your Android or iOS app, configure Gradle for Seam GitHub Packages, and start issuing mobile keys. ## 1. Install the Seam SDK The Seam SDK is [available for download on request](mailto:support@seam.co) and is fully documented. See the Seam [Android](/mobile-sdks/android/index) and [iOS](/mobile-sdks/ios/reference/seam) SDK reference documentation. You must also use the Seam API to perform server-side actions. Consequently, [install a Seam server-side SDK](/api/installation) in the language of your choice if you have not done so already. #### Configure Gradle to use Seam GitHub Packages This project retrieves the Seam Mobile SDK artifacts from GitHub Packages. To build successfully, you need valid credentials and must configure Gradle to fetch dependencies from Seam’s private package repository. **Using Kotlin Script (settings.gradle.kts):** ```kotlin theme={null} // getPropertyOrNull is a helper function defined in settings.gradle.kts // to safely read properties from local.properties fun getPropertyOrNull(propertyName: String): String? { val propertiesFile = file("local.properties") if (!propertiesFile.exists()) return null val properties = Properties() properties.load(propertiesFile.inputStream()) return properties.getProperty(propertyName, null) } // settings.gradle.kts repositories { // ... other repositories maven { name = "GitHubPackages" url = uri("https://maven.pkg.github.com/seampkg/seam-mobile-sdk") credentials { username = getPropertyOrNull("seamUsername") password = getPropertyOrNull("seamPat") } } } ``` **Using Groovy (settings.gradle):** ```groovy theme={null} // getPropertyOrNull is a helper function defined in settings.gradle // to safely read properties from local.properties String getPropertyOrNull(String propertyName) { def propertiesFile = file("local.properties") if (!propertiesFile.exists()) return null def properties = new Properties() properties.load(propertiesFile.inputStream()) return properties.getProperty(propertyName, null) } // settings.gradle repositories { // ... other repositories maven { name = "GitHubPackages" url = uri("https://maven.pkg.github.com/seampkg/seam-mobile-sdk") credentials { username = getPropertyOrNull("githubUsername") password = getPropertyOrNull("githubPat") } } } ``` *** #### Add your GitHub credentials Gradle requires two credentials to download the Seam SDK packages from GitHub:
Credential Description Where to get it
githubUsername Your GitHub username. Use the same username you use to log in to GitHub.
githubPat Personal Access Token (PAT) with the read:packages scope Follow the steps below to generate it.
**To retrieve your credentials** 1. Ask Seam to add your GitHub account as a collaborator to the private repository:\ [https://github.com/seampkg/seam-mobile-sdk](https://github.com/seampkg/seam-mobile-sdk) 2. Once you’ve been added, go to your GitHub account: **Settings** → **Developer settings** → **Personal access tokens** → **Tokens (classic)** 3. Select **Generate new token (classic)** and choose: * Expiration: as needed (e.g., 90 days or “No expiration” if permitted) * Scopes: check only `read:packages` 4. Copy the generated token. This is your `githubPat` value. Once you have both values, create a `local.properties` file in your project root: ```properties theme={null} # local.properties (DO NOT COMMIT THIS FILE) githubUsername=YOUR_GITHUB_USERNAME githubPat=YOUR_GITHUB_CLASSIC_PAT ``` Important: `local.properties` is listed in `.gitignore` by default. Never commit this file to version control. PATs are private credentials--treat them like passwords. If your token expires or you lose access, generate a new one from your GitHub settings. *** #### Add Seam SDK dependencies Include the required Seam SDK components in your `app/build.gradle.kts`. The `seam-phone-sdk-android-core` module provides the core functionality and must be included for all other components to work. Each additional dependency enables support for a specific lock or credential integration. For example, to use **Salto Space**, add the `seam-phone-sdk-android-saltospace` module. You can include as many integration modules as your app requires. **Kotlin script (build.gradle.kts):** ```kotlin theme={null} val seamVersion = "3.1.6" // Or the desired version dependencies { // ... other dependencies implementation("co.seam:seam-phone-sdk-android-core:$seamVersion") implementation("co.seam:seam-phone-sdk-android-saltoks:$seamVersion") implementation("co.seam:seam-phone-sdk-android-saltospace:$seamVersion") implementation("co.seam:seam-phone-sdk-android-latch:$seamVersion") implementation("co.seam:seam-phone-sdk-android-assaabloy:$seamVersion") implementation("co.seam:seam-phone-sdk-android-legic:$seamVersion") // ... } ``` **Groovy script (build.gradle):** ```groovy theme={null} // app/build.gradle.kts def seamVersion = "3.1.6" // Or the desired version dependencies { // ... other dependencies implementation "co.seam:seam-phone-sdk-android-core:$seamVersion" implementation "co.seam:seam-phone-sdk-android-saltoks:$seamVersion" implementation "co.seam:seam-phone-sdk-android-saltospace:$seamVersion" implementation "co.seam:seam-phone-sdk-android-latch:$seamVersion" implementation "co.seam:seam-phone-sdk-android-assaabloy:$seamVersion" implementation "co.seam:seam-phone-sdk-android-legic:$seamVersion" // ... } ```
You can install SeamSDK via CocoaPods or Swift Package Manager (SPM).\ SeamSDK supports per-lock-provider integration granularity. Include only the modules you need to keep your app footprint minimal. **CocoaPods:** ```ruby theme={null} use_frameworks! platform :ios, '15.0' target 'YourApp' do # Local pod install with file path to SeamSdk.podspec pod 'SeamSDK', :path => 'PATH_TO_SEAM_SDK/SeamSDK.podspec' # Optional subspecs for specific providers: pod 'SeamSDK/SeamDormakabaIntegration', :path => 'PATH_TO_SEAM_SDK/SeamSDK.podspec' pod 'SeamSDK/SeamLatchIntegration', :path => 'PATH_TO_SEAM_SDK/SeamSDK.podspec' end ``` **Swift Package Manager:** ```swift theme={null} dependencies: [ .package(path: "PATH_TO_SEAM_SDK/SeamSDK") ], targets: [ .target( name: "YourApp", dependencies: ["SeamSDK", "SeamSaltoIntegration"] ) ] ```
*** ## 2. Implement any Manufacturer- and Mobile OS-Specific Requirements Note the following manufacturer- and OS-specific requirements: ### Manufacturer-Specific Requirements See the [device or system integration guide](/device-and-system-integration-guides#access-control-systems) for the access control system or device for which you are planning to develop. Further, you may need to register for developer access with the ACS that you have chosen to use. *** ### iOS Requirement While not required, you can optionally request the `com.apple.developer.passkit.pass-presentation-suppression` entitlement from the Apple Developer portal. This entitlement prevents Apple Wallet from appearing when scanning for Bluetooth low energy (BLE) or similar locks, improving the unlock experience. *** ## 3. Configure a User Identity for your App User and Generate a Client Session Token A [user identity](../managing-mobile-app-user-accounts-with-user-identities) enables the application to request a user's mobile access permissions and use the app to unlock doors. First, use the Seam API or Seam Console to create a [user identity](../managing-mobile-app-user-accounts-with-user-identities#what-is-a-user-identity) that will correspond to the App User Account using your internal user ID or other identifying information. Then, using the user identity, create a [client session](/core-concepts/authentication/client-session-tokens/index) and capture the resulting [client session token](/core-concepts/authentication/client-session-tokens/index). This token will be used to authenticate the user on your application. ```javascript JavaScript theme={null} // Create the user identity. const userIdentity = await seam.userIdentities.create({ email_address: 'jane@example.com', }) // Create the client session. const clientSession = await seam.clientSessions.create({ user_identity_ids: [userIdentity.user_identity_id], }) // Use this token to launch your mobile controller. const token = clientSession.token ``` ```bash cURL theme={null} # Create the user identity. user_identity=$(curl -X 'POST' \ 'https://connect.getseam.com/user_identities/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "email_address": "jane@example.com" }') # Get the user identity ID. user_identity_id=$(echo $user_identity | jq -r '.user_identity.user_identity_id') # Create the client session. client_session=$(curl -X 'POST' \ 'https://connect.getseam.com/client_sessions/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"user_identity_ids\": [\"$user_identity_id\"] }") # Get the resulting client session token and # use this token to launch your mobile controller. token=$(echo $client_session | jq -r '.client_session.token') ``` ```python Python theme={null} # Create the user identity. user_identity = seam.user_identities.create( email_address="jane@example.com" ) # Create the client session. client_session = seam.client_sessions.create( user_identity_ids=[user_identity.user_identity_id] ) # Use this token to launch your mobile controller. token = client_session.token ``` ```ruby Ruby theme={null} # Create the user identity. user_identity = client.user_identities.create( email_address: "jane@example.com" ) # Create the client session. client_session = client.client_sessions.create( user_identity_ids: [user_identity.user_identity_id] ) # Use this token to launch your mobile controller. token = client_session.token ``` ```php PHP theme={null} // Create the user identity. $user_identity = $seam->user_identities->create( email_address: "jane@example.com" ); // Create the client session. $client_session = $seam->client_sessions->create( user_identity_ids: [$user_identity->user_identity_id] ); // Use this token to launch your mobile controller. $token = $client_session->token; ``` *** ## 4. Initialize the Mobile SDK with the Client Session Token Use the client session token that you generated earlier to bootstrap the Seam SDK on the device. Under the hood, this action sets up credential synchronization and starts a background sync loop to keep permissions up to date. ### Initialization and Error Handling Perform initialization and activation within your app’s asynchronous context (for example, Swift’s `Task` or Kotlin coroutines) so that you can handle errors. The initialization call may fail due to configuration issues (such as an invalid token), and the activation call may fail due to network or runtime errors. Catch these errors and present a user-friendly message or fallback UI as appropriate. ```swift iOS Swift theme={null} import SeamSDK // Initialize the Mobile SDK with the client session token (CST). Task { do { // Bootstrap the SDK with the CST from your login flow. try Seam.initialize(clientSessionToken: token) // Start credential sync and background polling. try await Seam.shared.activate() print("Seam SDK is now active.") } catch let error as SeamError { // Handle SDK-specific initialization errors (invalid token, etc). showAlert(title: "Initialization Failed", message: error.localizedDescription) } } ``` ```kotlin Android Kotlin theme={null} try { SeamSDK.initialize(context, "seam_cst_...") SeamSDK.getInstance().activate() } catch (seamError: SeamError) { when (seamError) { is SeamError.AlreadyInitialized -> { // handle error when SDK is already initialized } is SeamError.DeactivationInProgress -> { // handle error when app is being deactivated } is SeamError.InternetConnectionRequired -> { // handle error when internet connection is required } is SeamError.InvalidClientSessionToken -> { // handle error when client session token is invalid } else -> { // handle other errors } } } ``` ### Credential Errors Any errors that occur between activation and deactivation surface on individual credential objects through their `errors` property. You can observe the `credentials` list to detect and handle these issues in real time. **Observe credential errors** ```swift theme={null} import SeamSDK import Combine private var credentialErrorsCancellable: AnyCancellable? func startMonitoringCredentialErrors() { credentialErrorsCancellable = Seam.shared.$credentials .sink { credentials in for credential in credentials where !credential.errors.isEmpty { print("Errors for \(credential.displayName):", credential.errors) } } } ``` **Credential error types** * `awaitingLocalCredential`: Waiting for a local credential to become available. * `expired`: The credential has expired and is no longer valid. * `userInteractionRequired(action)`: User interaction is required to resolve the issue; inspect action for details. * `unsupportedDevice`: The current device is not supported. * `contactSeamSupport`: Configuration error requiring developer attention. * `unknown`: An unclassified or unexpected credential error occurred. **userInteractionRequired actions** * `completeOtpAuthorization(otpUrl:)`: The user must complete OTP authorization via the provided URL. * `enableInternet`: The user must enable internet connectivity. * `enableBluetooth`: The user must enable Bluetooth on the device. * `grantBluetoothPermission`: The user must grant Bluetooth permission to the app. * `appRestartRequired`: The user must restart the app to resolve the issue. **Observe credential errors** ```kotlin theme={null} // One of the attributes of the credential is a list of errors of type `SeamCredentialError` coroutineScope.launch { SeamSDK.getInstance().credentials.collect { credentialsList -> val errors = credentialsList.flatMap { it.errors } errors.forEach { error -> when (error) { is SeamCredentialError.Expired -> { /* handle credential expiration error */} is SeamCredentialError.Loading -> { /* handle not loaded yet */ } is SeamCredentialError.Unknown -> { /* handle unknown error */} is SeamCredentialError.UserInteractionRequired -> { handleUserInteractionRequired(error.interaction) } } } } } fun handleUserInteractionRequired(interaction: SeamRequiredUserInteraction) { when (interaction) { is SeamRequiredUserInteraction.CompleteOtpAuthorization -> { /* handle OTP authorization */ } is SeamRequiredUserInteraction.EnableBluetooth -> { /* handle Bluetooth error */ } is SeamRequiredUserInteraction.EnableInternet -> { /* handle Internet connection error*/ } is SeamRequiredUserInteraction.GrantPermissions -> { /* handle permissions error*/ } } } ``` **Credential error types** * `Loading`: The system is waiting for a local credential to become available. * `Expired`: The credential has expired and is no longer valid. * `UserInteractionRequired(val interaction: SeamRequiredUserInteraction)`: User interaction is required to resolve the issue; check interaction for specifics. * `Unknown`: An unclassified or unexpected credential error occurred. **userInteractionRequired actions** * `CompleteOtpAuthorization(val otpUrl: String)`: The user must complete OTP authorization via the provided URL. * `EnableInternet`: The user must enable internet connectivity. * `EnableBluetooth`: The user must enable Bluetooth on the device. * `GrantPermissions(val permissions: List)`: The user must grant the required permissions. * `AppRestartRequired`: The user must restart the app to resolve the issue. # Using Unlock With Tap Source: https://docs.seam.co/capability-guides/mobile-access/mobile-device-sdks/using-unlock-with-tap This feature enables your app to perform unlock operations using mobile credentials. Unlocking with SeamSDK uses proximity to communicate credentials to door readers. When a user initiates an unlock, the SDK performs scanning, error handling, and unlock events using `Seam.shared.unlock(using:)`. Using this process involves the following steps: 1. Retrieve available mobile credentials. 2. Monitor for permission or credential errors. Unhandled errors are thrown as `credentialErrors([SeamCredentialError])`. 3. Perform the unlock operation. 4. Handle unlock status events. 5. Cancel the unlock operation if needed. *** ## 1. Retrieve Mobile Credentials Access the current credentials through the published `credentials` array on `Seam.shared`: ```swift iOS Swift theme={null} import SeamSDK import Combine // Access credentials let credentials = Seam.shared.credentials // Observe updates with Combine let credentialsSubscription = Seam.shared.$credentials .sink { creds in // Update UI with new credentials array. } ``` ```kotlin Android Kotlin theme={null} import co.seam.core.api.SeamCredential import co.seam.core.api.SeamSDK // Collect credentials SeamSDK.getInstance().credentials.collect { credentials -> // Update UI with new credentials array. } ``` ## 2. Monitor Credential Errors Permission or setup issues appear in each credential’s `errors` property. Observe like this: ```swift iOS Swift theme={null} import SeamSDK import Combine let errorSubscription = Seam.shared.$credentials .flatMap { creds in creds.publisher } .map { $0.errors } .sink { errors in // Handle errors, for example, `.userInteractionRequired`, `.expired`, etc. } ``` ```kotlin Android Kotlin theme={null} import co.seam.core.api.SeamCredential import co.seam.core.api.SeamSDK import co.seam.core.sdkerrors.SeamCredentialError import co.seam.core.sdkerrors.SeamError import co.seam.core.sdkerrors.SeamRequiredUserInteraction SeamSDK.getInstance().credentials.collect { credentialsList -> val errors = credentialsList.flatMap { it.errors } errors.forEach { error -> when (error) { is SeamCredentialError.Expired -> { /* handle credential expiration error */} is SeamCredentialError.Loading -> { /* handle not loaded yet */ } is SeamCredentialError.Unknown -> { /* handle unknown error */} is SeamCredentialError.UserInteractionRequired -> { handleUserInteractionRequired(error.interaction) } } } } fun handleUserInteractionRequired(interaction: SeamRequiredUserInteraction) { when (interaction) { is SeamRequiredUserInteraction.CompleteOtpAuthorization -> { /* handle OTP authorization */ } is SeamRequiredUserInteraction.EnableBluetooth -> { /* handle Bluetooth error */ } is SeamRequiredUserInteraction.EnableInternet -> { /* handle Internet connection error*/ } is SeamRequiredUserInteraction.GrantPermissions -> { /* handle permissions error*/ } } } ``` > **Note:** The `.errors` array on credentials represents per-credential issues, though some issues may be repeated across several credentials (for example, bluetooth requirements). SDK- or credential-level errors (such as invalid token or expired credential) are thrown directly by methods like `unlock(using:)` because `SeamError` or `SeamCredentialError` and must be handled through `do/catch`. ## 3. Perform Unlock Operation The call to `Seam.shared.unlock(using:)` may throw: * `SeamError`: For SDK-level issues (for example, invalid token, uninitialized SDK). * `SeamCredentialError`: For credential-specific issues (for example, expired credential, device not eligible). Ensure that you wrap the call in `do/catch` blocks to handle these errors. Use Async/Await or Combine to initiate an unlock with a selected credential: ```swift iOS Swift theme={null} import SeamSDK import Combine let credentialId = credentials.first!.id // Async/Await example Task { do { for try await event in try Seam.shared.unlock(using: credentialId).values { switch event { case .grantedAccess: // The lock granted access. Show a success indicator. default: print("Unlock event: \(event)") // Access wasn't granted. Inform the user and offer retry. } } } catch { // Handle unlock error, for example, invalid credential or SDK error print("Unlock error: \(error)") } } // Combine example do { let unlockPublisher = try Seam.shared.unlock(using: credentialId) let unlockSubscription = unlockPublisher.sink( receiveCompletion: { _ in // Unlock completed. }, receiveValue: { event in switch event { case .grantedAccess: // The lock granted access—show a success indicator. default: // Access wasn't granted, inform the user and offer retry. print("Unlock event: \(event)") } } ) // Retain `unlockSubscription`; discarding it will cancel the unlock attempt. } catch { // Handle unlock initialization error. print("Unlock error: \(error)") } ``` ```kotlin Android Kotlin theme={null} import co.seam.core.api.SeamCredential import co.seam.core.api.SeamSDK import co.seam.core.events.SeamUnlockEvent import co.seam.core.sdkerrors.SeamCredentialError import co.seam.core.sdkerrors.SeamError import co.seam.core.sdkerrors.SeamRequiredUserInteraction val seamSDK = SeamSDK.getInstance() // Perform unlock try { val credentialId = credential.id // Timeout is optional seamSDK.unlock( credentialId = credentialId, timeout = 30.seconds ) } catch (seamError: SeamError) { when (seamError) { is SeamError.ActivationRequired -> { // handle error when SDK is not activated } is SeamError.CredentialErrors -> { val credentialErrors = seamError.errors handleCredentialErrors(credentialErrors) // handle error when there are credential errors } is SeamError.InitializationRequired -> { // handle error when SDK is not initialized } is SeamError.IntegrationNotFound -> { // handle error when integration is not found, Such as Assa Abloy, Latch and Salto } is SeamError.InternetConnectionRequired -> { // handle error when internet connection is required } is SeamError.InvalidClientSessionToken -> { // handle error when client session token is invalid } else -> { // handle other errors } } } // Handle credential errors on unlock fun handleCredentialErrors(credentialErrors: List) { credentialErrors.forEach { credentialError -> when (credentialError) { is SeamCredentialError.Invalid -> { // handle error when credential is invalid } is SeamCredentialError.Expired -> { // handle error when credential is expired } is SeamCredentialError.Loading -> { // handle error when credential is not loaded yet } is SeamCredentialError.UserInteractionRequired -> { // handle user interaction required credential error } is SeamCredentialError.Unknown -> { // handle unknown credential error } } } } ``` *** ## 4. Handle Unlock Events Handle each `SeamUnlockEvent` to update your UI and logic. Available events: * **launched**\ Unlock operation has started. * **grantedAccess**\ Access was granted by the lock. * **timedOut**\ Unlock operation timed out without success. * **connectionFailed(debugDescription:)**\ Unlock operation failed to connect; `debugDescription` may contain additional details. Async/Await example: ```swift theme={null} Task { do { for try await event in Seam.shared.unlock(using: credentialID) { switch event { case .launched: // Show scanning indicator. case .grantedAccess: // Show access granted. case .timedOut: // Show timeout and offer retry. case .connectionFailed(let debugDescription): // Show error with debugDescription. } } } catch { // Handle thrown errors. } } ``` Combine example: ```swift theme={null} do { let unlockPublisher = try Seam.shared.unlock(using: credentialID) let unlockSubscription = unlockPublisher .receive(on: RunLoop.main) .sink( receiveCompletion: { _ in // unlock completed. }, receiveValue: { event in switch event { case .launched: // Show scanning indicator. case .grantedAccess: // Show success indicator. case .timedOut: // Operation timed out—offer retry. case .connectionFailed(let debugDescription): // Show debugDescription details. } } ) // Retain `unlockSubscription` as a property and cancel when appropriate (for example, in deinit or viewWillDisappear). } catch { // Handle unlock initialization error. print("Unlock initialization error: \(error)") } ``` ```kotlin theme={null} // Start collecting unlock events before unlock coroutineScope.launch { seamSDK.unlockStatus.collect { event -> when (event) { is SeamUnlockEvent.ScanningStarted -> { /* handle scanning started */} is SeamUnlockEvent.Connecting -> { /* handle connecting */} is SeamUnlockEvent.AccessGranted -> { /* handle access granted */} is SeamUnlockEvent.Timeout -> { /* handle timeout */} is SeamUnlockEvent.ReaderError -> { /* handle reader error */} else -> { /* handle other events */} } } } ``` ## 5. Cancel the Unlock Operation Stop scanning by canceling your active task or subscription. ```swift iOS Swift theme={null} // For Combine unlockSubscription.cancel() // For Async/Await, cancel the Task as needed. ``` ```kotlin Android Kotlin theme={null} val seamSDK = SeamSDK.getInstance() // The unlock function returns a Job val job = seamSDK.unlock( credentialId = credentialId, timeout = 30.seconds ) // Canceling the job stops the unlock process job.cancel() ``` # Configuring Noise Threshold Settings Source: https://docs.seam.co/capability-guides/noise-sensors/configure-noise-threshold-settings Learn how to configure noise thresholds for noise sensors. Seam enables you to configure the [noise thresholds](#set-up-noise-thresholds) of your noise sensor, as well as to receive events when a disturbance is detected. This guide walks you through how to configure noise thresholds with the Seam API. ## Set Up Noise Thresholds First, create a threshold using the [Create a Noise Threshold](/api/noise_sensors/noise_thresholds/create) endpoint. For example: **Request:** ```javascript JavaScript theme={null} const deviceId = '98dc7c66-045d-49cb-a62b-4bb431b0a9fa' const noiseThresholdAttempt = await seam.noiseThresholds.create({ device_id: deviceId, starts_daily_at: '20:00:00[America/Los_Angeles]', ends_daily_at: '06:00:00[America/Los_Angeles]', noise_threshold_decibels: 70, }) console.log(noiseThresholdAttempt) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/noise_sensors/noise_thresholds/create' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "device_id": "98dc7c66-045d-49cb-a62b-4bb431b0a9fa", "starts_daily_at": "20:00:00[America/Los_Angeles]", "ends_daily_at": "06:00:00[America/Los_Angeles]", "noise_threshold_decibels": 70 }' ``` ```python Python theme={null} device_id = "98dc7c66-045d-49cb-a62b-4bb431b0a9fa" noise_threshold = seam.noise_sensors.noise_thresholds.create( device_id = device_id, starts_daily_at = "20:00:00[America/Los_Angeles]", ends_daily_at = "06:00:00[America/Los_Angeles]", noise_threshold_decibels = 70 ) pprint(noise_threshold) ``` ```csharp C# theme={null} var deviceId = "98dc7c66-045d-49cb-a62b-4bb431b0a9fa"; var noiseThresholdAttempt = seam.NoiseThresholdsNoiseSensors.Create( deviceId: deviceId, startsDailyAt: "20:00:00[America/Los_Angeles]", endsDailyAt: "06:00:00[America/Los_Angeles]", noiseThresholdDecibels: 70 ); Type t = noiseThresholdAttempt.GetType(); PropertyInfo[] props = t.GetProperties(); foreach (var prop in props) { Console.WriteLine(prop.Name + ": " + prop.GetValue(noiseThresholdAttempt)); } ``` **Response:** ```json JavaScript theme={null} { "action_attempt": { "status": "pending", "action_type": "CREATE_NOISE_THRESHOLD", "action_attempt_id": "5e24ef90-8043-44d8-89f9-9f7ae60ec390", "result": null, "error": null }, "ok": true } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "CREATE_NOISE_THRESHOLD", "action_attempt_id": "64130fb6-94ed-4268-a7e5-ccba4165fab8", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} NoiseThreshold(noise_threshold_id='1b64e4b6-4d5d-4416-acca-dc3b1cbc00cd', device_id='98dc7c66-045d-49cb-a62b-4bb431b0a9fa', name='builtin_quiet_hours', noise_threshold_decibels=70, starts_daily_at='20:00:00[America/Los_Angeles]', ends_daily_at='06:00:00[America/Los_Angeles]', noise_threshold_nrs=None) ``` ```json C# theme={null} Status: pending ActionType: CREATE_NOISE_THRESHOLD ActionAttemptId: eb611597-64d2-4b1a-995b-fb00361922c6 Result: Error: ``` This threshold creates a noise threshold of 70 decibels from 20:00-06:00 PST called `builtin_quiet_hours`. Once you have created a threshold, connect it to a webhook to log events. ### Best Practices * For Minut devices, you can configure two thresholds—one for quiet hours and one for the rest of the day. * For NoiseAware devices, you can configure as many thresholds as you want, provided that they do not overlap during daytime hours. ## Set Up Webhooks You can set up webhooks in the [Seam Console](https://console.seam.co). 1. In the left-hand navigation pane of Seam Console, click **Webhooks**. 2. On the **Webhooks** page, click **+ Add Webhook**. On the Webhooks page in the Seam Console, click + Add Webhook. 3. In the **Create Webhook** dialog: 1. Type your URL. 2. Select the event types for which you want to receive events. 3. Click **Create**. The Seam Console displays the URL and secret for the newly-created webhook. To test your webhook, click **Test your webhook**. ## Monitor Events Once you have configured your thresholds and webhooks, you can monitor events with the Seam API. The following sample shows how events look: ```json theme={null} { "created_at": "2023-01-09T18:54:32.737Z", "device_id": "c1296d07-3e96-4ee9-8219-3cd33a09aa37", "event_id": "c1296d07-3e96-4ee9-8219-3cd33a09aa37", "event_type": "noise_sensors.noise_threshold_triggered", "minut_metadata": {}, "noise_level_decibels": 50, "noise_level_nrs": 40, "noise_threshold_id": "c1296d07-3e96-4ee9-8219-3cd33a09aa37", "noise_threshold_name": "builtin_first_disturbance", "noiseaware_metadata": {} } ``` For a detailed reference of event parameters, see [Events](/api/noise_sensors/noise_thresholds/events). # Noise Sensors Source: https://docs.seam.co/capability-guides/noise-sensors/index Learn about managing noise sensors that detect noise levels that exceed configured thresholds in specific areas. ## What Is a Noise Sensor? Noise sensors are devices that measure that sound level in a given area. You can use noise sensors to monitor noise levels remotely and receive notifications when the noise volume is too loud. The Seam API enables you to configure the noise thresholds of a noise sensor and receive events when a disturbance is detected. ## What Is a Threshold? Thresholds represent the limits of noise tolerated at a property, which can be customized for each hour of the day. Each device has its own default thresholds, but you can use the API to modify them. ## Use Cases * You can configure noise threshold default settings for a customer's portfolio or on a property-by-property basis. When a new noise sensor is added, you can use the Seam API to configure its noise thresholds automatically according to these defaults. * You can react to noise disturbances by sending notifications to your users when a `noise_sensor.noise_threshold_triggered` event occurs. * Seam provides prebuilt UI components for displaying information for a noise sensor. You can show the noise level, ways to configure noise thresholds, and the activity log of any noise events. ## **Best Practices** While you can theoretically set noise thresholds to any decibel value, we have found that setting them within the following specific ranges lead to fewer false positives: | Property Type | Decibels | | ------------- | -------- | | Apartment | 50-70 | | House | 70-90 | | Estate | 80-100 | ## **Next Steps** See the following topics: * [Configuring Noise Threshold Settings](/capability-guides/noise-sensors/configure-noise-threshold-settings) * [Noise Sensors API Reference](/api/noise_sensors/object) # Reservation Automations Source: https://docs.seam.co/capability-guides/reservation-automations Learn how to automate access and climate around reservations. Reservation Automations sync reservation and guest data with your access and climate systems. Instead of building custom workflows for check-in, mid-stay changes, and checkout, you send reservation data to Seam and device settings update automatically. Built for short-term bookings—whether hotel stays, gym classes, coworking rooms, or event rentals—Reservation Automations ensure access and climate settings apply only during the reserved time. *** ### How it works Reservation Automations follow the lifecycle of a reservation: 1. You create spaces and assign devices using [`/spaces/create`](/api/spaces/create). 2. You send reservation and guest data with `push_data`. 3. Seam applies the right access and climate settings at the right times. 4. Webhooks notify you when settings are issued, updated, or revoked. 5. If a reservation is canceled, you call `delete_data` to roll back device settings. *** ### Before you begin Set up these resources in your Seam workspace: * [Customer](/capability-guides/customer-portals/index) – identify who the automation belongs to with a `customer_key`. * [Spaces](../core-concepts/mapping-your-resources-to-seam-resources) – represent the real-world units your customer manages (i.e. *Room 101* in a hotel, *Studio 3* in a gym). Each space must be created via [`/spaces/create`](/api/spaces/create) with a `space_key` and assigned devices or entrances **before** you call `push_data`. Reservations reference these spaces by `space_key`. * Devices or entrances – connect locks, thermostats, or ACS entrances to each space (e.g., assign the lock in Room 101 to the *Room 101* space). Use `device_ids` for smart locks and thermostats, or `acs_entrance_ids` for access control system entrances. * Unique user identity emails – each `user_identity` you push must have a unique `email_address`. If an email already exists from a previous call, the reservation is silently skipped. Although `push_data` accepts a `spaces` array, it only creates a lightweight resource reference — it does **not** assign devices or entrances to the space. If you skip [`/spaces/create`](/api/spaces/create), the space will have no devices and automations will have nothing to configure. The call still returns `ok: true`, making this a silent failure. Always create spaces with device or entrance assignments first using `/spaces/create`. You can also let customers configure their own accounts, spaces, and devices with [Customer Portals](/capability-guides/customer-portals/index). *** ### 1. Create spaces with devices Before pushing reservation data, create a space for each bookable unit using the [`/spaces/create`](/api/spaces/create) endpoint. Each space must have a `space_key` (your identifier) and at least one assigned device or entrance. ```bash theme={null} curl -X POST \ https://connect.getseam.com/spaces/create \ -H "Authorization: Bearer $SEAM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Room 101", "space_key": "unit-101-key", "device_ids": ["YOUR_LOCK_DEVICE_ID"] }' ``` Use `device_ids` for smart locks and thermostats, or `acs_entrance_ids` for access control system entrances. You can include both if the space has multiple access points. The `space_key` is what you reference in `push_data` reservations. Without it, `push_data` cannot match reservations to the space. *** ### 2. Customize automation settings After enabling automations, you can configure how access credentials are issued for each reservation. These settings are available in **Console** > **Developer** > **Automations** under the access automation section. **Access methods** Choose which credential types to issue when a reservation is created. You must enable at least one. | Method | Description | | ---------------- | --------------------------------------------- | | **PIN code** | A numeric code the guest enters on a keypad. | | **Plastic card** | A physical card encoded for the lock. | | **Mobile key** | A digital key delivered to the guest's phone. | **Access method creation strategy** Controls how many access methods are created per device when multiple types are enabled: | Strategy | Behavior | | ----------------------------- | ------------------------------------------------------- | | **First available** (default) | Creates only the first supported method on each device. | | **First two available** | Creates up to two supported methods on each device. | | **All available** | Creates every supported method on each device. | **Card count** The number of plastic cards to create per reservation. Only applies when the plastic card access method is enabled. **Instant key max use count** The maximum number of times a mobile key can be used. Only applies when the mobile key access method is enabled. **Use guest phone last 4 digits as code** When enabled, Seam will attempt to use the last 4 digits of the guest's phone number as the PIN code instead of generating a random one. The phone number is looked up from the user identity data you provide via `push_data`. PIN code priority: 1. An explicit `preferred_code` on the reservation always takes precedence. 2. If no `preferred_code` is set and this option is enabled, Seam uses the last 4 digits of the guest's phone number. 3. If the phone number is unavailable or has fewer than 4 digits, Seam falls back to an auto-generated code. The derived code is a best-effort preference, not a guarantee. If the code conflicts with a device's PIN constraints (for example, the code is already in use on that lock) Seam assigns an auto-generated code for that device and adds a relevant warning to the access grant. **Allow shared email and phone across guests** When enabled, multiple guests can share the same email address or phone number. This is useful when the same person has multiple reservations or holds different roles. ### 3. Push reservation data Use the `push_data` endpoint to send customer, user, and reservation data to Seam. Automations use this information to configure devices at the right times. A **reservation** represents a time-bound assignment of a user to a space. This can be a hotel stay, a gym day pass, or a coworking member's conference room booking. Each reservation must include a unique `reservation_key`, which can be your system's identifier for that record. Seam uses this key to know whether it should create a new reservation, update an existing one, or remove it later with `delete_data`. ```bash theme={null} curl -X POST \ https://connect.getseam.com/customers/push_data \ -H "Authorization: Bearer $SEAM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "customer_key": "sample_customer_key", "user_identities": [ { "user_identity_key": "user_789", "name": "John Doe", "email_address": "john@example.com" } ], "reservations": [ { "reservation_key": "res_456", "user_identity_key": "user_789", "starts_at": "2025-08-12T19:47:27.490Z", "ends_at": "2025-08-14T19:47:27.490Z", "space_keys": ["unit-101-key"] } ] }' ``` * Call `push_data` with a new `reservation_key` to create a reservation. * Call it again with the same `reservation_key` to update times or other details—Seam automatically reconfigures the device settings. The `push_data` [API reference](/api/customers/push_data) also documents `access_grants` and `bookings` as alternative top-level keys. This guide uses `reservations`, which is the recommended key for short-term booking workflows. If you use `access_grants` instead, use `access_grant_keys` (not `reservation_keys`) when calling [`delete_data`](/api/customers/delete_data). *** ### 4. Use webhooks to listen for updates Configure webhooks in **Console** > **Developer** > **Webhooks** to get notified when automations apply or revoke settings. **Key events:** * `access_method.issued` – access created * `access_method.reissued` – access updated * `access_method.deleted` – access removed Webhook payloads include the keys that triggered the event, letting you sync state with your application. *** ### 5. Delete data The `delete_data` endpoint is optional but important. Use it when access or device settings should no longer apply—such as when: * A hotel reservation is canceled * A conference room reservation ends early * A gym class is dropped * An event reservation is called off Calling `delete_data` removes the underlying reservation records, which tells automations to immediately roll back any device settings tied to them. This could mean revoking access, resetting thermostats, or clearing other applied states. Without cleanup, those settings may stay active longer than intended. ```bash theme={null} curl -X POST \ https://connect.getseam.com/customers/delete_data \ -H "Authorization: Bearer $SEAM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reservation_keys": ["res_456"], "user_identity_keys": ["user_789"] }' ``` * Pass a `reservation_key` to cancel a specific reservation and remove its device settings. * Pass a `user_identity_key` to remove all device settings tied to a specific person. * Pass a `customer_key` to offboard an entire customer and clear all their spaces, users, and settings. *** ### Troubleshooting #### I called `push_data` and got `ok: true` but no access code was created `push_data` returns a success response even when automations cannot act on the data. Check these common causes: | Symptom | Cause | Fix | | ---------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | No access code created | Space does not exist or is missing a `space_key` | Create the space via [`/spaces/create`](/api/spaces/create) with a `space_key` and `device_ids` or `acs_entrance_ids` before calling `push_data` | | No access code created | No devices or entrances assigned to the space | Add `device_ids` or `acs_entrance_ids` when creating the space, or update the space to include them | | Reservation silently skipped | Duplicate `email_address` on a `user_identity` | Each user identity must have a unique email. Check **Console** → **Automation Runs** for `user_identity_email_or_phone_conflict` errors | | Automation did not run | Automations not enabled | Go to **Console** → **Developer** → **Automations** and verify automations are enabled for your workspace | Check **Console** → **Automation Runs** for detailed error information. Errors like `user_identity_email_or_phone_conflict` are only visible there — they do not appear in the `push_data` response. *** # Seam Bridge Source: https://docs.seam.co/capability-guides/seam-bridge Use Seam Bridge to connect on-premises access systems to Seam. ## Overview Seam Bridge is a lightweight app that brings your on-premises access system online—without exposing any ports to the public internet. Install it on a computer in the same local network as your access system. Seam Bridge creates a secure tunnel between your on-premises system and Seam Cloud, handling all the encryption and authentication for you. With Seam Bridge, you get the reliability of a local system, plus the flexibility of the cloud. It is important to understand the difference between Seam Bridge and smart lock Wi-Fi bridges. Seam Bridge is specifically designed to connect on-premises access systems to the Seam platform. On the other hand, Smart lock Wi-Fi bridges enable remote management of smart lock devices that do not have integrated Wi-Fi connectivity. That is, a smart lock Wi-Fi bridge uses a short-range communication protocol, such as Bluetooth, to connect one or more locks to the internet through a property's local Wi-Fi network. *** ## Getting Started Download the Seam Bridge application onto an on-premises computer. Then, pair Seam Bridge with your Seam [workspace](/core-concepts/workspaces/index) and connect the on-premises access system to Seam. You install and pair Seam Bridge while you are connecting your on-premises access system to Seam. That is, the [Connect Webview](/core-concepts/connect-webviews/index) that you use to connect your on-premises access system to Seam walks you through the process of downloading and pairing Seam Bridge. For detailed information, see the setup instructions within the [system integration guide](/device-and-system-integration-guides#access-control-systems) for your on-premises access system. *** ## **Download Seam Bridge** In a web browser, go to [the Seam Bridge repo](https://www.seam.co/seam-bridge/releases/latest) and download the latest version of the Seam Bridge application for the appropriate operating system. Download the Seam Bridge application for your operating system. *** ## System Setup Guides Please refer to these guides to set up the Seam Bridge application. *** ## Troubleshooting Seam Bridge If issues affect the connections between Seam Bridge, your on-premises access system, and the Seam platform, the Seam Bridge app displays status, error, and other information to help you understand and troubleshoot these issues. The **Connected Systems** area displays the status of each connection. A green checkmark indicates a healthy connection. The Seam Bridge app also displays communication errors at the top of the window. Seam Bridge displays information about the connections to on-premises
access systems. *** ## Next Steps Go to the setup instructions within the [system integration guide](/device-and-system-integration-guides#access-control-systems) for your on-premises access system. These instructions describe how to pair Seam Bridge with your workspace and then connect your on-premises access system to Seam through Seam Bridge. # Seam Bridge Setup for Linux Source: https://docs.seam.co/capability-guides/seam-bridge/seam-bridge-setup-for-linux Step-by-step instructions for installing, launching, and configuring Seam Bridge on Linux. ## System Requirements ### Supported distributions Ubuntu, Debian, Fedora, Arch, OpenSUSE, and most Linux desktops that include WebKitGTK. ### Runtime dependencies WebKitGTK 3 or 4 1. Check if installed: ```bash theme={null} ldd ./seambridge | grep webkit ``` 2. If not installed, the user must install (depending on distro): * **Ubuntu/Debian** ```bash theme={null} sudo apt install libwebkit2gtk-4.0-37 ``` * **Fedora** ```bash theme={null} sudo dnf install webkit2gtk3 ``` * **Arch** ```bash theme={null} sudo pacman -S webkit2gtk ``` ### Minimum hardware * 1 GB RAM * \~150 MB disk space * x64 architecture * LAN Network access *** ## Run Seam Bridge ### Launch the app and allow required permissions 1. Open the downloaded Seam Bridge file. 2. If it does not open, you may need to mark it as executable. ```bash theme={null} chmod +x ./seambridge ``` 3. Launch the app: ``` ./seambridge ``` 4. If the app does not start due to permissions, you may need to allow it through your system’s security settings: * Some Linux distributions block files downloaded from the internet. * If this happens, remove the quarantine attribute (if present): ```bash theme={null} xattr -d com.apple.quarantine ./seambridge ``` *(On most Linux systems this won’t appear, but it’s safe to run.)* 5. If your Linux system prompts you to allow the app to access the network, approve the request so Seam Bridge can connect to your on-premises system. 6. Seam Bridge will launch. *** ### Complete Seam Bridge setup 1. Accept the **Terms of Service.** 2. Enter a name for the site that you are connecting using Seam Bridge—for example, `My Site`—and then click **Start pairing**. 3. Seam Bridge displays a **Pairing code.** Use this code when connecting Seam Bridge to your workspace. Return to this window whenever a new pairing code is requested. *** ### Set up Seam Bridge to reboot on restart Use `systemd` to keep an app running on Linux. It supervises the process, restarts it on crash, and handles boot startup. #### Create a systemd service file 1. Open Terminal. 2. Create the service file:\\ ```bash theme={null} sudo nano /etc/systemd/system/SeamBridge.service ``` 3. Add this template: ``` [Unit] Description=Seam Bridge - Keep Running After=network.target [Service] ExecStart=/usr/local/bin/SeamBridge.exe Restart=always RestartSec=3 WorkingDirectory=/usr/local/bin User=ubuntu Environment=NODE_ENV=production [Install] WantedBy=multi-user.target ``` 4. Replace paths and `User` as needed. #### Enable and start the service 1. Within Terminal, run the following commands: ``` sudo systemctl daemon-reload sudo systemctl enable SeamBridge.service sudo systemctl start SeamBridge.service ``` #### Verify status 1. Run the following command in Terminal to confirm that the service is running: ``` systemctl status SeamBridge.service ``` You should see the service running and supervised. #### Test auto-restart 1. Kill the process manually with `pkill SeamBridge`. 2. `systemd` should restart it immediately. # Seam Bridge Setup for macOS Source: https://docs.seam.co/capability-guides/seam-bridge/seam-bridge-setup-for-macos Step-by-step instructions for installing, launching, and configuring Seam Bridge on macOS. ### System Requirements * **Supported versions:** * macOS 10.13 High Sierra or later * Intel and Apple Silicon supported * **Minimum hardware** * 1 GB RAM * \~200–300 MB disk space depending on bundle size * **Network:** LAN connection required *** ## Run Seam Bridge ### Unzip and launch the app 1. Double click on the zipped file to unzip the file. 2. Try opening the SeamBridge.app by double-clicking it. 3. macOS will show a *“Seam Bridge" Not Opened* dialog.\\ 4. Select **Done** to close the dialog. ### Approve the app in System Settings 1. Open **System Settings**. 2. Go to **Privacy & Security**. 3. Scroll to the bottom of the page. 4. Look for a message that says: * *“Seam Bridge was blocked to protect your Mac.”* 5. Select **Open Anyway**. 6. Select **Open Anyway** in the popup.
*** ### Complete Seam Bridge setup 1. Accept the **Terms of Service.** 2. Enter a name for the site that you are connecting using Seam Bridge—for example, `My Site`—and then click **Start pairing**. 3. Seam Bridge displays a **Pairing code.** Use this code when connecting Seam Bridge to your workspace. Return to this window whenever a new pairing code is requested. *** ### Set up Seam Bridge to reboot on restarts Use `launchd` to keep the Seam Bridge running on macOS. A LaunchAgent restarts the app if it crashes and starts it whenever the user logs in. #### Create and Launch the LaunchAgent file 1. Open **Terminal**. 2. Create a plist file in your user `LaunchAgents` directory: ```bash theme={null} mkdir -p ~/Library/LaunchAgents nano ~/Library/LaunchAgents/com.seambridge.keepalive.plist ``` 3. Paste this template: ```xml theme={null} Label com.myapp.keepalive ProgramArguments /path/to/app/SeamBridge.app/Contents/MacOS/SeamBridge KeepAlive RunAtLoad ``` 4. Replace `/path/to/app` with the actual path to your binary/script. Keep the `/Contents/MacOS/SeamBridge` path at the end. 5. To save your changes in Nano: * `Ctrl X` to Exit. * `Y` to save changes. * Confirm the file name and click **Enter**. 6. Within terminal, paste the following command to launch the launch agent: ```bash theme={null} launchctl load ~/Library/LaunchAgents/com.seambridge.keepalive.plist ``` #### Test the setup 1. Kill the app manually. 2. `launchd` should restart it automatically. 3. Restart your Mac and confirm the app launches on login. #### Prevent sleep from killing your app 1. Go to **System Settings** → **Battery**. 2. Set **Turn display off** as desired but disable **sleep while plugged in**. *** # Seam Bridge Setup for Windows Source: https://docs.seam.co/capability-guides/seam-bridge/seam-bridge-setup-for-windows Step-by-step instructions for installing, launching, and configuring Seam Bridge on Windows. ### System Requirements * **Supported versions:** * Windows 10/11 AMD64/ARM64 * **Minimum hardware:** * 1 GB RAM * \~150 MB disk space * x64 architecture * **Network:** LAN connection required *** ## Run Seam Bridge ### Launch the app and allow required permissions 1. Open the downloaded executable file. 2. If you are using a Windows computer running Microsoft Defender, you may need to allow Windows to run the Seam Bridge app. 1. In the **Windows protected your PC** dialog, click **More info**. 2. Click **Run anyway**. 3. If you are using a Windows computer, you may need to allow public networks to access the Seam Bridge app. 1. In the **Do you want to allow public and private networks to access this app?** dialog, click **Show more**. 2. Make sure that the **Public networks** and **Private networks** checkboxes are selected. 3. Click **Allow**. 4. The Seam Bridge app will launch. *** ### Complete Seam Bridge setup 1. Accept the **Terms of Service.** 2. Enter a name for the site that you are connecting using Seam Bridge—for example, `My Site`—and then click **Start pairing**. Seam Bridge Welcome screen 3. Seam Bridge displays a **Pairing code.** Use this code when connecting Seam Bridge to your workspace. Return to this window whenever a new pairing code is requested. Seam Bridge pairing code screen *** ### Set up Seam Bridge to Reboot on Restart Use Task Scheduler to auto-start your app and restart it if it fails. #### **Open Task Scheduler** 1. Press **Win** key and type **Task Scheduler**. 2. Open **Task Scheduler**. #### **Create a new task** 1. In the right-hand **Actions** pane, select **Create Task…** (not *Create Basic Task*). Task Scheduler - Create Task option 2. In the **General** tab: * Name: e.g. `Seam Bridge - Keep Running`. * (Recommended) Check **Run when user is logged on.** * (If needed) Check **Run with highest privileges**. * Pick the right OS under **Configure for** (e.g. Windows 10/11). Task Properties - General tab 3. **Set up trigger to launch at start up** * Go to the **Triggers** tab and click **New….** * Set **Begin the task** to **At startup**. * Make sure **Enabled** is checked, then click **OK**. Task Properties - Triggers tab, At startup trigger 4. **Add another trigger to relaunch Seam Bridge if it closes** 1. In the **Triggers** tab, select **New…** 2. Set **Begin the task** to **On a schedule** 3. Under **Settings**, select: * Daily * Recur every: 1 day 4. Under **Advanced settings**, enable: * **Repeat task every:** 5 minutes * **For a duration of:** 1 day * Ensure **Enabled** is checked 5. Select **OK** to save the trigger. Task Properties - Triggers tab, scheduled trigger 5. **Configure launching the Seam Bridge app** * Go to the **Actions** tab and click **New….** * Set **Action** to **Start a program**. * In **Program/script**, select your app's .exe or script: * Example: `C:\Users\user\Downloads\SeamBridge.exe` * Click **OK**. Task Properties - Actions tab 6. **Configure settings for relaunching** 1. Go to the **Settings** tab. 2. Enable: * **Allow task to be run on demand**. * **If the task fails, restart every:** `1 minute`, for a duration of: `Indefinitely` or a reasonable number of attempts (> 100). 3. Uncheck **Stop the task if it runs longer than:**. 4. Check **If the running task does not end when requested, force it to stop**. Task Properties - Settings tab 7. **Prevent power settings from stopping the task** * Go to the **Conditions** tab. * If this is a plugged-in machine (kiosk/server style): * Uncheck **Start the task only if the computer is on AC power**. * Uncheck **Stop if the computer switches to battery power**. Task Properties - Conditions tab #### **Save and test** 1. Click **OK** to save the task. 2. If prompted, enter the user's password so Windows can run it in the background. 3. In Task Scheduler, right-click your new task and select **Run**. 4. Confirm the app starts as expected. 5. Restart the computer and verify the app launches automatically. *** # Setting the Current HVAC and Fan Mode Settings Source: https://docs.seam.co/capability-guides/thermostats/configure-current-climate-settings Learn how to configure the current climate settings on a thermostat. You can use the following Seam API "imperative" endpoints to set the current HVAC and fan mode settings for a connected thermostat, individually: * [`/thermostats/heat`](/api/thermostats/heat) * [`/thermostats/cool`](/api/thermostats/cool) * [`/thermostats/heat_cool`](/api/thermostats/heat_cool) * [`/thermostats/off`](/api/thermostats/off) * [`/thermostats/set_fan_mode`](/api/thermostats/set_fan_mode) You can also use the [`/thermostats/set_hvac_mode`](/api/thermostats/set_hvac_mode) endpoint to set a thermostat to the desired HVAC mode, including `heat`, `cool`, `heat_cool`, `eco` (for Google Nest), or `off`, depending on the capabilities of the device. For `heat`, `cool`, and `heat_cool`, also specify the desired heating and cooling set points, as appropriate. Note that it's important to check the capabilities of a thermostat before attempting to use an imperative endpoint. For example, if a thermostat is attached to an HVAC system that does not have cooling capabilities, you cannot use `/thermostats/cool` or `/thermostats/heat_cool`. To check the capabilities of a thermostat, retrieve the thermostat and confirm the [relevant capability flags](#before-you-begin-confirm-capabilities). These imperative operations return an [action attempt](../../core-concepts/action-attempts) that enables you to track the progress of the action. Poll this action attempt, until the action completes. Further, Seam emits a [`thermostat.temperature_reached_set_point` event](/api/thermostats/events#thermostat-temperature_reached_set_point) when the thermostat reports a temperature within 1° Celsius of the heating or cooling temperature that you requested. *** ## HVAC Settings When you use an imperative endpoint to set the HVAC settings for a thermostat, you specify the [HVAC mode](../../capability-guides/thermostats/understanding-thermostat-concepts/hvac-mode) and the desired [set points](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points) in Fahrenheit or Celsius. To set the HVAC mode and set points, issue a thermostat [`heat`](#set-a-thermostat-to-heat-mode), [`cool`](#set-a-thermostat-to-cool-mode), [`heat_cool`](#set-a-thermostat-to-heat-cool-mode), `eco` (for Google Nest), or [`off`](#turn-off-heating-and-cooling) request and include the desired set points in the body of the request. *** ## Fan Mode Settings Seam supports the following fan mode settings:
Fan mode Description
on The fan runs all the time, regardless of whether the HVAC system is cooling or heating.
auto The fan runs whenever the HVAC system is cooling or heating but does not run at other times.
circulate The fan runs for a specific number of minutes each hour, regardless of whether the HVAC system is cooling or heating. To find out whether a thermostat supports this setting, view its device.properties.available\_fan\_mode\_settings property.
*** ## Process Overview To configure and then verify a climate setting on a thermostat, perform the following steps: 1. Confirm the capabilities of the thermostat. See [Before You Begin: Confirm Capabilities](#before-you-begin-confirm-capabilities). 2. Execute the imperative climate setting request.\ See the following instructions: * [Set a Thermostat to Heat Mode](#set-a-thermostat-to-heat-mode) * [Set a Thermostat to Cool Mode](#set-a-thermostat-to-cool-mode) * [Set a Thermostat to Heat-Cool Mode](#set-a-thermostat-to-heat-cool-mode) * [Turn off Heating and Cooling](#turn-off-heating-and-cooling) * [Set the Fan Mode Setting](#set-the-fan-mode-setting) 3. Poll the action attempt.\ See [Poll the Action Attempt](#poll-the-action-attempt). 4. If desired, configure a webhook to watch for a `thermostat.temperature_reached_set_point` event that indicates that the thermostat has reported a temperature within 1° Celsius of the heating or cooling [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points) that you requested.\ See [Webhooks](../../developer-tools/webhooks). *** ## Before You Begin: Confirm Capabilities Before you attempt to set the HVAC or fan mode settings for a thermostat, be sure to confirm that your device has the capability to perform these operations. You can inspect the capabilities of a device by checking the following [capability flags](../../capability-guides/device-and-system-capabilities#capability-flags) for the device: * `device.can_hvac_heat` * `device.can_hvac_cool` * `device.can_hvac_heat_cool` * `device.can_turn_off_hvac` Use the [`/devices/get`](/api/devices/get) endpoint for a specific device to return these capability flags. Then, use an `if` statement or similar check to confirm that the relevant flag is both present and `true` before attempting to perform the imperative thermostat action. If the relevant capability flag is `false` or not present, you can view the [properties](/api/devices/object) of the device, [errors or warnings](/api/devices/errors) for the device, and [events](/api/devices/events) related to the device to learn more about the cause of these issues. For example, you could examine `device.properties.online`. In addition, you could look for a `device.disconnected` event. **Request:** ```javascript JavaScript theme={null} await seam.devices.get({ device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', }) ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }' ``` ```python Python theme={null} seam.devices.get( device_id = "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ) ``` ```ruby Ruby theme={null} # Coming soon! ``` ```php PHP theme={null} $seam->devices->get( device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', can_hvac_heat: true, // You can use seam.thermostats.heat() on this device. can_hvac_cool: true, // You can use seam.thermostats.cool() on this device. can_hvac_heat_cool: true, // You can use seam.thermostats.heatCool() on this device. can_turn_off_hvac: true, // You can use seam.thermostats.off() on this device. ... } ``` ```json cURL theme={null} { "device": { "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61", "can_hvac_heat": true, // You can use /thermostats/heat on this device. "can_hvac_cool": true, // You can use /thermostats/cool on this device. "can_hvac_heat_cool": true, // You can use /thermostats/heat_cool on this device. "can_turn_off_hvac": true, // You can use /thermostats/off on this device. ... }, "ok": true } ``` ```json Python theme={null} Device( device_id='a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', can_hvac_heat=True, // You can use seam.thermostats.heat() on this device. can_hvac_cool=True, // You can use seam.thermostats.cool() on this device. can_hvac_heat_cool=True, // You can use seam.thermostats.heat_cool() on this device. can_turn_off_hvac=True, // You can use seam.thermostats.off() on this device. ... ) ``` ```json Ruby theme={null} # Coming soon! ``` ```json PHP theme={null} { "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61", "can_hvac_heat": true, // You can use $seam->thermostats->heat() on this device. "can_hvac_cool": true, // You can use $seam->thermostats->cool() on this device. "can_hvac_heat_cool": true, // You can use $seam->thermostats->heat_cool() on this device. "can_turn_off_hvac": true, // You can use $seam->thermostats->off() on this device. ... } ``` ```json C# theme={null} // Coming soon! ``` *** ## Set a Thermostat to Heat Mode You can [set a thermostat to heat mode](/api/thermostats/heat) or use the [`/thermostats/set_hvac_mode`](/api/thermostats/set_hvac_mode) endpoint, and specify a desired heating [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points) temperature. By establishing the set point, the thermostat activates the associated heating system to maintain the specified temperature. Issue the thermostat `heat` request, providing the `device_id` of the thermostat and the `heating_set_point_celsius` or `heating_set_point_fahrenheit`. **Request:** ```javascript JavaScript theme={null} // Get the thermostat. const thermostat = await seam.devices.get({ device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', }) // Confirm that the thermostat supports heat mode. if (thermostat.can_hvac_heat) { // Perform the heat request. await seam.thermostats.heat({ device_id: thermostat.device_id, heating_set_point_celsius: 20, }) } ``` ```bash cURL theme={null} # Get the thermostat. thermostat=$( # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }') # Confirm that the thermostat supports heat mode. if $(jq -r '.device.can_hvac_heat' <<< ${thermostat}); then \ # Perform the heat request. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/heat' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"heating_set_point_celsius\": 20 }"; fi ``` ```python Python theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id = "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ) # Confirm that the thermostat supports heat mode. if thermostat.can_hvac_heat: # Perform the heat request. seam.thermostats.heat( device_id = thermostat.device_id, heating_set_point_celsius = 20 ) ``` ```ruby Ruby theme={null} // Get the thermostat. thermostat = seam.devices.get({ device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }); # Confirm that the thermostat supports heat mode. if (thermostat.can_hvac_heat) # Perform the heat request. seam.thermostats.heat( device_id: thermostat.device_id, heating_set_point_celsius: 20 ) end ``` ```php PHP theme={null} // Get the thermostat. $thermostat = $seam->devices->get( device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ); // Confirm that the thermostat supports heat mode. if ($thermostat->can_hvac_heat) { // Perform the heat request. $seam->thermostats->heat( device_id: $thermostat->device_id, heating_set_point_celsius: 20 ); } ``` ```java C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "97125745-15d9-4970-b5be-c34ec3ce1c81", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "SET_HVAC_MODE", "action_attempt_id": "97125745-15d9-4970-b5be-c34ec3ce1c81", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='97125745-15d9-4970-b5be-c34ec3ce1c81', action_type='SET_HVAC_MODE', status='success', result={}, error=None ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "97125745-15d9-4970-b5be-c34ec3ce1c81", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` *** ## Set a Thermostat to Cool Mode You can [set a thermostat to cool mode](/api/thermostats/cool) or use the [`/thermostats/set_hvac_mode`](/api/thermostats/set_hvac_mode) endpoint, and specify a desired cooling [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points) temperature. By establishing the set point, the thermostat activates the associated cooling system to maintain the specified temperature. Issue the thermostat `cool` request, providing the `device_id` of the thermostat and the `cooling_set_point_celsius` or `cooling_set_point_fahrenheit`. **Request:** ```javascript JavaScript theme={null} // Get the thermostat. const thermostat = await seam.devices.get({ device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', }) // Confirm that the thermostat supports cool mode. if (thermostat.can_hvac_cool) { // Perform the cool request. await seam.thermostats.cool({ device_id: thermostat.device_id, cooling_set_point_celsius: 25, }) } ``` ```bash cURL theme={null} # Get the thermostat. thermostat=$( # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }') # Confirm that the thermostat supports cool mode. if $(jq -r '.device.can_hvac_cool' <<< ${thermostat}); then \ # Perform the cool request. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/cool' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"cooling_set_point_celsius\": 25 }"; fi ``` ```python Python theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id = "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ) # Confirm that the thermostat supports cool mode. if thermostat.can_hvac_cool: # Perform the cool request. seam.thermostats.cool( device_id = thermostat.device_id, cooling_set_point_celsius = 25 ) ``` ```ruby Ruby theme={null} // Get the thermostat. thermostat = seam.devices.get({ device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }); # Confirm that the thermostat supports cool mode. if (thermostat.can_hvac_cool) # Perform the cool request. seam.thermostats.cool( device_id: thermostat.device_id, cooling_set_point_celsius: 25 ) end ``` ```php PHP theme={null} // Get the thermostat. $thermostat = $seam->devices->get( device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ); // Confirm that the thermostat supports cool mode. if ($thermostat->can_hvac_cool) { // Perform the cool request. $seam->thermostats->cool( device_id: $thermostat->device_id, cooling_set_point_celsius: 25 ); } ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "87478724-0e30-4fed-9f2a-456971b7b04f", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "SET_HVAC_MODE", "action_attempt_id": "87478724-0e30-4fed-9f2a-456971b7b04f", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='87478724-0e30-4fed-9f2a-456971b7b04f', action_type='SET_HVAC_MODE', status='success', result={}, error=None ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "87478724-0e30-4fed-9f2a-456971b7b04f", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` *** ## Set a Thermostat to Heat-Cool Mode You can [set a thermostat to heat-cool (also known as "auto") mode](/api/thermostats/heat_cool) or use the [`/thermostats/set_hvac_mode`](/api/thermostats/set_hvac_mode) endpoint, and specify desired [set point](../../capability-guides/thermostats/understanding-thermostat-concepts/set-points) temperatures for both heating and cooling. By establishing the set points, the thermostat activates the associated heating and cooling systems as needed to maintain the specified temperature range. Issue the thermostat `heat_cool` request, providing the `device_id` of the thermostat and the following set points: * `heating_set_point_celsius` or `heating_set_point_fahrenheit` * `cooling_set_point_celsius` or `cooling_set_point_fahrenheit` **Request:** ```javascript JavaScript theme={null} // Get the thermostat. const thermostat = await seam.devices.get({ device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', }) // Confirm that the thermostat supports heat-cool mode. if (thermostat.can_hvac_heat_cool) { // Perform the heatCool request. await seam.thermostats.heatCool({ device_id: thermostat.device_id, heating_set_point_celsius: 20, cooling_set_point_celsius: 25, }) } ``` ```bash cURL theme={null} # Get the thermostat. thermostat=$( # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }') # Confirm that the thermostat supports heat-cool mode. if $(jq -r '.device.can_hvac_heat_cool' <<< ${thermostat}); then \ # Perform the heat_cool request. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/heat_cool' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"heating_set_point_celsius\": 20, \"cooling_set_point_celsius\": 25 }"; fi ``` ```python Python theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id = "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ) # Confirm that the thermostat supports heat-cool mode. if thermostat.can_hvac_heat_cool: # Perform the heat_cool request. seam.thermostats.heat_cool( device_id = thermostat.device_id, heating_set_point_celsius = 20, cooling_set_point_celsius = 25 ) ``` ```ruby Ruby theme={null} // Get the thermostat. thermostat = seam.devices.get({ device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }); # Confirm that the thermostat supports heat-cool mode. if (thermostat.can_hvac_heat_cool) # Perform the heat_cool request. seam.thermostats.heat_cool( device_id: thermostat.device_id, heating_set_point_celsius: 20, cooling_set_point_celsius: 25 ) end ``` ```php PHP theme={null} // Get the thermostat. $thermostat = $seam->devices->get( device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ); // Confirm that the thermostat supports heat-cool mode. if ($thermostat->can_hvac_heat_cool) { // Perform the heat_cool request. $seam->thermostats->heat_cool( device_id: $thermostat->device_id, heating_set_point_celsius: 20, cooling_set_point_celsius: 25 ); } ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "8050ec59-7f29-4d0d-9842-dedaf304740d", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "SET_HVAC_MODE", "action_attempt_id": "8050ec59-7f29-4d0d-9842-dedaf304740d", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='8050ec59-7f29-4d0d-9842-dedaf304740d', action_type='SET_HVAC_MODE', status='success', result={}, error=None ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "8050ec59-7f29-4d0d-9842-dedaf304740d", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` *** ## Turn off Heating and Cooling You can [set a thermostat to "off" mode](/api/thermostats/off) or use the [`/thermostats/set_hvac_mode`](/api/thermostats/set_hvac_mode) endpoint, which deactivates the associated heating and cooling systems. In this state, the thermostat does not regulate indoor temperatures. Issue the thermostat `off` request, providing the `device_id` of the thermostat. **Request:** ```javascript JavaScript theme={null} // Get the thermostat. const thermostat = await seam.devices.get({ device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', }) // Confirm that the thermostat supports off mode. if (thermostat.can_turn_off_hvac) { // Perform the off request. await seam.thermostats.off({ device_id: thermostat.device_id, }) } ``` ```bash cURL theme={null} # Get the thermostat. thermostat=$( # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }') # Confirm that the thermostat supports off mode. if $(jq -r '.device.can_turn_off_hvac' <<< ${thermostat}); then \ # Perform the off request. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/off' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\" }"; fi ``` ```python Python theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id = "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ) # Confirm that the thermostat supports off mode. if thermostat.can_turn_off_hvac: # Perform the off request. seam.thermostats.off( device_id = thermostat.device_id ) ``` ```ruby Ruby theme={null} // Get the thermostat. thermostat = seam.devices.get({ device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" }); # Confirm that the thermostat supports off mode. if (thermostat.can_turn_off_hvac) # Perform the off request. seam.thermostats.off( device_id: thermostat.device_id ) end ``` ```php PHP theme={null} // Get the thermostat. $thermostat = $seam->devices->get( device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ); // Confirm that the thermostat supports off mode. if ($thermostat->can_turn_off_hvac) { // Perform the off request. $seam->thermostats->off( device_id: $thermostat->device_id ); } ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "ef94c8b2-3ff0-4e56-a97e-033ca07ba0fd", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "SET_HVAC_MODE", "action_attempt_id": "ef94c8b2-3ff0-4e56-a97e-033ca07ba0fd", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='ef94c8b2-3ff0-4e56-a97e-033ca07ba0fd', action_type='SET_HVAC_MODE', status='success', result={}, error=None ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "ef94c8b2-3ff0-4e56-a97e-033ca07ba0fd", "action_type": "SET_HVAC_MODE", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` *** ## Set the Fan Mode Setting You can [configure the fan mode setting for a thermostat](/api/thermostats/set_fan_mode). For details about the supported fan modes, see [Fan Mode Settings](#fan-mode-settings). Set the fan mode setting by providing the `device_id` of the thermostat and specifying the desired `fan_mode_setting`. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.setFanMode({ device_id: 'a4b775e3-feb2-4c6b-8e78-a73ec2d70b61', fan_mode_setting: 'auto', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/set_fan_mode' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "device_id": "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61", "fan_mode_setting": "auto" }' ``` ```python Python theme={null} seam.thermostats.set_fan_mode( device_id = "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61", fan_mode_setting = "auto" ) ``` ```ruby Ruby theme={null} # Coming soon! ``` ```php PHP theme={null} $seam->thermostats->set_fan_mode( device_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61", fan_mode_setting: "auto" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396", "action_type": "SET_FAN_MODE", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "SET_FAN_MODE", "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='9c9b584b-c645-4ce0-a9c2-79b6f1db2396', action_type='SET_FAN_MODE', status='success', result={}, error=None ) ``` ```json Ruby theme={null} # Coming soon! ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396", "action_type": "SET_FAN_MODE", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` *** ## Poll the Action Attempt The imperative HVAC or fan mode setting request returns an [action attempt](../../core-concepts/action-attempts). Use the `action_attempt_id` from this response to poll the associated action attempt using the [`/action_attempts/get`](/api/action_attempts/get) request. When the setting modification completes successfully, the `status` of the action attempt changes to `success`. **Request:** ```javascript JavaScript theme={null} await seam.actionAttempts.get( action_attempt_id: "9c9b584b-c645-4ce0-a9c2-79b6f1db2396" ); ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/action_attempts/get' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${SEAM_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396" }' ``` ```python Python theme={null} seam.action_attempts.get( action_attempt_id = "9c9b584b-c645-4ce0-a9c2-79b6f1db2396" ) ``` ```ruby Ruby theme={null} # Coming soon! ``` ```php PHP theme={null} $seam->action_attempts->get( action_attempt_id: "a4b775e3-feb2-4c6b-8e78-a73ec2d70b61" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396", "action_type": "SET_FAN_MODE", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "success", "action_type": "SET_FAN_MODE", "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='9c9b584b-c645-4ce0-a9c2-79b6f1db2396', action_type='SET_FAN_MODE', status='success', result={}, error=None ) ``` ```json Ruby theme={null} # Coming soon! ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "9c9b584b-c645-4ce0-a9c2-79b6f1db2396", "action_type": "SET_FAN_MODE", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` # Activating a Climate Preset Source: https://docs.seam.co/capability-guides/thermostats/creating-and-managing-climate-presets/activating-a-climate-preset Learn how to activate a preconfigured climate preset immediately. In addition to [scheduling](../creating-and-managing-thermostat-schedules) climate presets for a thermostat, you can activate a configured climate preset immediately. When you activate a climate preset, it overrides any scheduled climate preset that is already active on the thermostat. Activating a climate preset returns an [action attempt](../../../core-concepts/action-attempts) that enables you to track the progress of the action. Poll this action attempt, until the action completes. Further, Seam emits a [`thermostat.temperature_reached_set_point` event](/api/thermostats/events#thermostat-temperature_reached_set_point) when the thermostat reports a temperature within 1° Celsius of the heating or cooling [set point](../understanding-thermostat-concepts/set-points) specified in the climate preset that you've activated. You can configure a [webhook](../../../developer-tools/webhooks) to watch for this event. *** ## Activate a Climate Preset To activate a climate preset, issue a [`/thermostats/activate_climate_preset`](/api/thermostats/activate_climate_preset) request and specify the `climate_preset_key` of the desired climate preset. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.activateClimatePreset({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/activate_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied" }' ``` ```python Python theme={null} seam.thermostats.activate_climate_preset( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key = "occupied" ) ``` ```ruby Ruby theme={null} # Coming soon! ``` ```php PHP theme={null} $seam->thermostats->activate_climate_preset( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key: "occupied" ); ``` ```java C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20", "action_type": "ACTIVATE_CLIMATE_PRESET", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "ACTIVATE_CLIMATE_PRESET", "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='05de2295-d1dc-4748-aae3-9931658bde20', action_type='ACTIVATE_CLIMATE_PRESET', error={}, result={}, status='success' ) ``` ```json Ruby theme={null} # Coming soon! ``` ```json PHP theme={null} { "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20", "action_type": "ACTIVATE_CLIMATE_PRESET", "error": null, "result": {}, "status": "success" } ``` ```json C# theme={null} // Coming soon! ``` *** ## Poll the Action Attempt Activating a climate preset returns an [action attempt](../../../core-concepts/action-attempts). Use the `action_attempt_id` from this response to poll the associated action attempt using the [`/action_attempts/get`](/api/action_attempts/get) request. When the activation completes successfully, the `status` of the action attempt changes to `success`. **Request:** ```javascript JavaScript theme={null} await seam.actionAttempts.get( action_attempt_id: "05de2295-d1dc-4748-aae3-9931658bde20" ); ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/action_attempts/get' \ -H 'accept: application/json' \ -H 'Authorization: Bearer ${SEAM_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20" }' ``` ```python Python theme={null} seam.action_attempts.get( action_attempt_id = "05de2295-d1dc-4748-aae3-9931658bde20" ) ``` ```ruby Ruby theme={null} # Coming soon! ``` ```php PHP theme={null} $seam->action_attempts->get( action_attempt_id: "05de2295-d1dc-4748-aae3-9931658bde20" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20", "action_type": "ACTIVATE_CLIMATE_PRESET", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "success", "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20", "action_type": "ACTIVATE_CLIMATE_PRESET", "result": {}, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='05de2295-d1dc-4748-aae3-9931658bde20', action_type='ACTIVATE_CLIMATE_PRESET', error={}, result={}, status='success' ) ``` ```json Ruby theme={null} # Coming soon! ``` ```json PHP theme={null} { "action_attempt_id": "05de2295-d1dc-4748-aae3-9931658bde20", "action_type": "ACTIVATE_CLIMATE_PRESET", "error": null, "result": {}, "status": "success" } ``` ```json C# theme={null} // Coming soon! ``` # Creating and Managing Climate Presets Source: https://docs.seam.co/capability-guides/thermostats/creating-and-managing-climate-presets/index Learn how to create, list, update, and delete climate presets for thermostats. You create a set of climate presets for each thermostat, customized for your—and your users'—needs. Each climate preset is a predefined configuration for a thermostat that specifies settings, such as HVAC mode, fan mode, and temperature set points. These presets make it quick and efficient for users to apply consistent climate settings tailored to different scenarios, enhancing both comfort and energy efficiency. Once you create climate presets, you can [activate them](/api/thermostats/activate_climate_preset), add them to thermostat [schedules](../creating-and-managing-thermostat-schedules) and [programs](../creating-and-managing-thermostat-programs), and set them as the [fallback climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset). *** ## Climate Preset Properties Each climate preset can contain the following properties, depending on the [capabilities](/capability-guides/thermostats/index#thermostat-capabilities) of the thermostat:
Property Description
climate\_preset\_key (Required) Key to identify the climate preset.
name (Optional) User-friendly name to identify the climate preset.
fan\_mode\_setting Desired fan mode setting, such as on, auto, or circulate.
hvac\_mode\_setting Desired HVAC mode setting, such as heat, cool, heat\_cool, or off.
cooling\_set\_point\_celsius Temperature to which the thermostat should cool (in °C). See also Set Points .
cooling\_set\_point\_fahrenheit Temperature to which the thermostat should cool (in °F).
heating\_set\_point\_celsius Temperature to which the thermostat should heat (in °C).
heating\_set\_point\_fahrenheit Temperature to which the thermostat should heat (in °F).
manual\_override\_allowed (Optional) Indicates whether a person at the thermostat or using the API can change the thermostat's settings.

Deprecated. Use thermostat\_schedule.is\_override\_allowed instead.
can\_edit Indicates whether the climate preset can be edited. There are some cases in which Seam syncs in climate presets (from the device) that cannot be modified.
can\_delete Indicates whether the climate preset can be deleted. There are some cases in which Seam syncs in climate presets (from the device) that cannot be deleted.
*** ## Create a Climate Preset To create a climate preset, issue a [`/thermostats/create_climate_preset`](/api/thermostats/create_climate_preset) request, providing the `device_id` of the desired thermostat. Also, include the desired settings for the climate preset and, optionally, a name. The following example creates two climate presets with the keys `occupied` and `unoccupied`: **Request:** ```javascript JavaScript theme={null} // Get the thermostat. const thermostat = await seam.devices.get({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', }) // Confirm that the thermostat supports heat_cool mode // so that the climate presets can use this mode. if (thermostat.can_hvac_heat_cool) { // Create the climate presets. await seam.thermostats.createClimatePreset({ device_id: thermostat.device_id, climate_preset_key: 'occupied', name: 'Occupied', fan_mode_setting: 'auto', hvac_mode_setting: 'heat_cool', cooling_set_point_celsius: 25, heating_set_point_celsius: 20, }) await seam.thermostats.createClimatePreset({ device_id: thermostat.device_id, climate_preset_key: 'unoccupied', name: 'Unoccupied', fan_mode_setting: 'auto', hvac_mode_setting: 'heat_cool', cooling_set_point_celsius: 30, heating_set_point_celsius: 15, }) } ``` ```bash cURL theme={null} # Get the thermostat. thermostat=$( # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5" }') # Confirm that the thermostat supports heat_cool mode # so that the climate presets can use this mode. if $(jq -r '.device.can_hvac_heat_cool' <<< ${thermostat}); then \ # Create the climate presets. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/create_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"climate_preset_key\": \"occupied\", \"name\": \"Occupied\", \"fan_mode_setting\": \"auto\", \"hvac_mode_setting\": \"heat_cool\", \"cooling_set_point_celsius\": 25, \"heating_set_point_celsius\": 20 }"; curl -X 'POST' \ 'https://connect.getseam.com/thermostats/create_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"climate_preset_key\": \"unoccupied\", \"name\": \"Unoccupied\", \"fan_mode_setting\": \"auto\", \"hvac_mode_setting\": \"heat_cool\", \"cooling_set_point_celsius\": 30, \"heating_set_point_celsius\": 15 }"; fi ``` ```python Python theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5" ) # Confirm that the thermostat supports heat_cool mode # so that the climate presets can use this mode. if thermostat.can_hvac_heat_cool: # Create the climate presets. seam.thermostats.create_climate_preset( device_id = thermostat.device_id, climate_preset_key = "occupied", name = "Occupied", fan_mode_setting = "auto", hvac_mode_setting = "heat_cool", cooling_set_point_celsius = 25, heating_set_point_celsius = 20 ) seam.thermostats.create_climate_preset( device_id: thermostat.device_id, climate_preset_key = "unoccupied", name = "Unoccupied", fan_mode_setting = "auto", hvac_mode_setting = "heat_cool", cooling_set_point_celsius = 30, heating_set_point_celsius = 15 ) ``` ```ruby Ruby theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ) # Confirm that the thermostat supports heat_cool mode # so that the climate presets can use this mode. if (thermostat.can_hvac_heat_cool) # Create the climate presets. seam.thermostats.create_climate_preset( device_id: thermostat.device_id, climate_preset_key: "occupied", name: "Occupied", fan_mode_setting: "auto", hvac_mode_setting: "heat_cool", cooling_set_point_celsius: 25, heating_set_point_celsius: 20 ) seam.thermostats.create_climate_preset( device_id: thermostat.device_id, climate_preset_key: "unoccupied", name: "Unoccupied", fan_mode_setting: "auto", hvac_mode_setting: "heat_cool", cooling_set_point_celsius: 30, heating_set_point_celsius: 15 ) end ``` ```php PHP theme={null} // Get the thermostat. $thermostat = $seam->devices->get( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ); // Confirm that the thermostat supports heat_cool mode // so that the climate presets can use this mode. if ($thermostat->can_hvac_heat_cool) { // Create the climate presets. $seam->thermostats->create_climate_preset( device_id: $thermostat->device_id, climate_preset_key: "occupied", name: "Occupied", fan_mode_setting: "auto", hvac_mode_setting: "heat_cool", cooling_set_point_celsius: 25, heating_set_point_celsius: 20 ); $seam->thermostats->create_climate_preset( device_id: $thermostat->device_id, climate_preset_key: "unoccupied", name: "Unoccupied", fan_mode_setting: "auto", hvac_mode_setting: "heat_cool", cooling_set_point_celsius: 30, heating_set_point_celsius: 15 ); } ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` *** ## List All Climate Presets for a Thermostat To list climate presets for a thermostat, issue a [`/devices/get`](/api/devices/get) request, providing the `device_id` of the desired thermostat. Then, inspect the `available_climate_presets` property. **Request:** ```javascript JavaScript theme={null} await seam.devices.get({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', }) ``` ```bash cURL theme={null} # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5" }' ``` ```python Python theme={null} seam.devices.get( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5" ) ``` ```ruby Ruby theme={null} seam.devices.get( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ) ``` ```php PHP theme={null} $seam->devices->get( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', properties: { available_climate_presets: [ { climate_preset_key: 'occupied', name: 'Occupied', display_name: 'Occupied', fan_mode_setting: 'auto', hvac_mode_setting: 'heat_cool', cooling_set_point_celsius: 25, heating_set_point_celsius: 20, cooling_set_point_fahrenheit: 77, heating_set_point_fahrenheit: 68, ... }, { climate_preset_key: 'unoccupied', name: 'Unoccupied', display_name: 'Unoccupied', fan_mode_setting: 'auto', hvac_mode_setting: 'heat_cool', cooling_set_point_celsius: 30, heating_set_point_celsius: 15, cooling_set_point_fahrenheit: 86, heating_set_point_fahrenheit: 59, ... } ], ... }, ... } ``` ```json cURL theme={null} { "device": { "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "properties": { "available_climate_presets": [ { "climate_preset_key": "occupied", "name": "Occupied", "display_name": "Occupied", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "cooling_set_point_celsius": 25, "heating_set_point_celsius": 20, "cooling_set_point_fahrenheit": 77, "heating_set_point_fahrenheit": 68, ... }, { "climate_preset_key": "unoccupied", "name": "Unoccupied", "display_name": "Unoccupied", "fan_mode_setting": "auto", "hvac_mode_setting": "heat_cool", "cooling_set_point_celsius": 30, "heating_set_point_celsius": 15, "cooling_set_point_fahrenheit": 86, "heating_set_point_fahrenheit": 59, ... } ], ... }, ... }, "ok": true } ``` ```json Python theme={null} Device( device_id='2d488679-6f07-4810-aed2-e726872c1dd5', properties={ 'available_climate_presets': [ { 'climate_preset_key': 'occupied', 'cooling_set_point_celsius': 25, 'cooling_set_point_fahrenheit': 77, 'display_name': 'Occupied', 'fan_mode_setting': 'auto', 'heating_set_point_celsius': 20, 'heating_set_point_fahrenheit': 68, 'hvac_mode_setting': 'heat_cool', 'name': 'Occupied', ... }, { 'climate_preset_key': 'unoccupied', 'cooling_set_point_celsius': 30, 'cooling_set_point_fahrenheit': 86, 'display_name': 'Unoccupied', 'fan_mode_setting': 'auto', 'heating_set_point_celsius': 15, 'heating_set_point_fahrenheit': 59, 'hvac_mode_setting': 'heat_cool', 'name': 'Unoccupied', ... } ], ... }, ... ) ``` ```json Ruby theme={null} [ { "climate_preset_key"=>"occupied", "name"=>"Occupied", "display_name"=>"Occupied", "fan_mode_setting"=>"auto", "hvac_mode_setting"=>"heat_cool", "cooling_set_point_celsius"=>25, "heating_set_point_celsius"=>20, "cooling_set_point_fahrenheit"=>77, "heating_set_point_fahrenheit"=>68, ... }, { "climate_preset_key"=>"unoccupied", "name"=>"Unoccupied", "display_name"=>"Unoccupied", "fan_mode_setting"=>"auto", "hvac_mode_setting"=>"heat_cool", "manual_override_allowed"=>true, "cooling_set_point_celsius"=>30, "heating_set_point_celsius"=>15, "cooling_set_point_fahrenheit"=>86, "heating_set_point_fahrenheit"=>59, ... } ] ... } ... > ``` ```json PHP theme={null} { "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "properties": { "available_climate_presets": [ { "climate_preset_key": "occupied", "cooling_set_point_celsius": 25, "cooling_set_point_fahrenheit": 77, "display_name": "Occupied", "fan_mode_setting": "auto", "heating_set_point_celsius": 20, "heating_set_point_fahrenheit": 68, "hvac_mode_setting": "heat_cool", "name": "Occupied", ... }, { "climate_preset_key": "unoccupied", "cooling_set_point_celsius": 30, "cooling_set_point_fahrenheit": 86, "display_name": "Unoccupied", "fan_mode_setting": "auto", "heating_set_point_celsius": 15, "heating_set_point_fahrenheit": 59, "hvac_mode_setting": "heat_cool", "name": "Unoccupied", ... } ], ... }, ... } ``` ```json C# theme={null} // Coming soon! ``` *** ## Update a Climate Preset To update a climate preset, issue a [`/thermostats/update_climate_preset`](/api/thermostats/update_climate_preset) request, providing the `device_id` of the thermostat and the `climate_preset_key` of the desired climate preset. Also, include the desired updated settings for the climate preset. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.updateClimatePreset({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', cooling_set_point_celsius: 24, }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/update_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "cooling_set_point_celsius": 24 }' ``` ```python Python theme={null} seam.thermostats.update_climate_preset( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key = "occupied", cooling_set_point_celsius = 24 ) ``` ```ruby Ruby theme={null} seam.thermostats.update_climate_preset( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key: "occupied", cooling_set_point_celsius: 24 ) ``` ```php PHP theme={null} $seam->thermostats->update_climate_preset( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key: "occupied", cooling_set_point_celsius: 24 ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` *** ## Delete a Climate Preset To delete a climate preset, issue a [`/thermostats/delete_climate_preset`](/api/thermostats/delete_climate_preset) request, providing the `device_id` of the thermostat and the `climate_preset_key` of the desired climate preset. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.deleteClimatePreset({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/delete_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied" }' ``` ```python Python theme={null} seam.thermostats.delete_climate_preset( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key = "occupied" ) ``` ```ruby Ruby theme={null} seam.thermostats.delete_climate_preset( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key: "occupied" ) ``` ```php PHP theme={null} $seam->thermostats->delete_climate_preset( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key: "occupied" ); ``` ```java C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` # Setting the Fallback Climate Preset Source: https://docs.seam.co/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset Learn how to set a configured climate preset as the "fallback" preset for a thermostat. Once you have created climate presets for a thermostat, you can set one of them as the "fallback" preset. Seam applies this fallback preset whenever no other climate preset is active. It works with the Seam API's [scheduling mechanism](../creating-and-managing-thermostat-schedules). The fallback climate preset is only applied once, after a thermostat schedule ends. If settings are changed while the fallback climate preset is active, the thermostat will override the fallback preset with the new settings. For example, you could set a fallback "eco" climate preset for the thermostat in your short-term rental property. Then, you could schedule—in advance—a "comfort" climate preset to correspond to each upcoming guest's stay. Whenever your property is unoccupied—that is, whenever there is no scheduled climate preset—Seam activates the fallback "eco" climate preset. To set the fallback climate preset for a device, issue a [`/thermostats/set_fallback_climate_preset`](/api/thermostats/set_fallback_climate_preset) request and specify the `climate_preset_key` of the desired climate preset. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.setFallbackClimatePreset({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'eco', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/set_fallback_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "eco" }' ``` ```python Python theme={null} seam.thermostats.set_fallback_climate_preset( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key = "eco" ) ``` ```ruby Ruby theme={null} # Coming soon! ``` ```php PHP theme={null} $seam->thermostats->set_fallback_climate_preset( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", climate_preset_key: "eco" ); ``` ```java C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} # Coming soon! ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` # Creating and Managing Thermostat Programs Source: https://docs.seam.co/capability-guides/thermostats/creating-and-managing-thermostat-programs Learn how to create and manage daily and weekly programs for thermostats. You can create thermostat weekly programs in a unified manner across the variety of thermostats that Seam supports. This standard feature of smart thermostats enables you to define full-week programs that are made up of reusable daily programs. Each daily program consists of a set of thermostat daily program periods, that is, time blocks with associated [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets/index). To set a thermostat weekly program: 1. [Create the climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets/index#create-a-climate-preset) that you want to use in your weekly program. 2. [Create the daily programs](#create-a-daily-program) that you want to use in your weekly program. In each daily program, define a set of time periods. For each of these time periods, specify the starting time for the period and the key that identifies the climate preset that you want to activate at the starting time. 3. [Update the weekly program](#update-the-weekly-program) on the thermostat. To define the weekly program, specify the configured daily program that you want to apply to each day of the week. You can update daily programs, and you can update the weekly program again as desired. You can also delete any daily programs that are not being used in a weekly program. *** ## Daily Program Period Properties Each daily program period contains the following properties: | Property | Description | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `starts_at_time` | Time at which the thermostat daily program period starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. | | `climate_preset_key` | Key of the climate preset to activate at the `starts_at_time`. | *** ## Daily Program Properties Each daily program contains the following properties: | Property | Description | | ----------------------------- | -------------------------------------------------------------------------------- | | `thermostat_daily_program_id` | ID of the thermostat daily program. | | `device_id` | ID of the thermostat device on which the thermostat daily program is configured. | | `name` | User-friendly name to identify the thermostat daily program. | | `periods` | Array of thermostat daily program periods. | | `created_at` | Date and time at which the thermostat daily program was created. | *** ## Weekly Program Properties Each weekly program contains the following properties: | Property | Description | | ---------------------- | ---------------------------------------------------------------------- | | `device_id` | ID of the thermostat device on which the weekly program is configured. | | `monday_program_id` | ID of the thermostat daily program to run on Mondays. | | `tuesday_program_id` | ID of the thermostat daily program to run on Tuesdays. | | `wednesday_program_id` | ID of the thermostat daily program to run on Wednesdays. | | `thursday_program_id` | ID of the thermostat daily program to run on Thursdays. | | `friday_program_id` | ID of the thermostat daily program to run on Fridays. | | `saturday_program_id` | ID of the thermostat daily program to run on Saturdays. | | `sunday_program_id` | ID of the thermostat daily program to run on Sundays. | | `created_at` | Date and time at which the thermostat weekly program was created. | *** ## Create a Daily Program To define a daily program, use `/thermostats/daily_programs/create`, specifying the thermostat that you want to program, a name for the daily program, and the desired set of daily program periods. The following example creates a weekday daily program with four period, each of which is linked to a configured climate preset: **Request:** ```javascript JavaScript theme={null} await seam.thermostats.dailyPrograms.create({ device_id: '11111111-1111-1111-2222-444444444444', name: 'Weekday Program', periods: [ { starts_at_time: '07:00:00', climate_preset_key: 'Home' }, { starts_at_time: '09:00:00', climate_preset_key: 'Away' }, { starts_at_time: '16:00:00', climate_preset_key: 'Home' }, { starts_at_time: '22:30:00', climate_preset_key: 'Sleep' }, ], }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/daily_programs/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "11111111-1111-1111-2222-444444444444", "name": "Weekday Program", "periods": [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Away" }, { "starts_at_time": "16:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] }' ``` ```python Python theme={null} seam.thermostats.daily_programs.create( device_id = "11111111-1111-1111-2222-444444444444", name = "Weekday Program", periods = [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Away" }, { "starts_at_time": "16:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] ) ``` ```ruby Ruby theme={null} seam.thermostats.daily_programs.create( device_id: "11111111-1111-1111-2222-444444444444", name: "Weekday Program", periods: [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Away" }, { "starts_at_time": "16:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] ) ``` ```php PHP theme={null} $seam->thermostats->daily_programs->create( device_id: "11111111-1111-1111-2222-444444444444", name: "Weekday Program", periods: [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Away" }, { "starts_at_time": "16:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { thermostat_daily_program_id: '99999999-1111-1111-1111-111111111111', device_id: '11111111-1111-1111-2222-444444444444', name: 'Weekday Program', periods: [ {'starts_at_time': '07:00:00', 'climate_preset_key': 'Home'}, {'starts_at_time': '09:00:00', 'climate_preset_key': 'Away'}, {'starts_at_time': '16:00:00', 'climate_preset_key': 'Home'}, {'starts_at_time': '22:30:00', 'climate_preset_key': 'Sleep'} ], ... } ``` ```json cURL theme={null} { "thermostat_daily_program": { "thermostat_daily_program_id": "99999999-1111-1111-1111-111111111111", "device_id": "11111111-1111-1111-2222-444444444444", "name": "Weekday Program", "periods": [ {"starts_at_time": "07:00:00", "climate_preset_key": "Home"}, {"starts_at_time": "09:00:00", "climate_preset_key": "Away"}, {"starts_at_time": "16:00:00", "climate_preset_key": "Home"}, {"starts_at_time": "22:30:00", "climate_preset_key": "Sleep"} ], ... }, "ok": true } ``` ```json Python theme={null} ThermostatDailyProgram( thermostat_daily_program_id='99999999-1111-1111-1111-111111111111', device_id='11111111-1111-1111-2222-444444444444', name="Weekday Program", periods=[ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Away" }, { "starts_at_time": "16:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ], ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "thermostat_daily_program_id": "99999999-1111-1111-1111-111111111111", "device_id": "11111111-1111-1111-2222-444444444444", "name": "Weekday Program", "periods": [ {"starts_at_time": "07:00:00", "climate_preset_key": "Home"}, {"starts_at_time": "09:00:00", "climate_preset_key": "Away"}, {"starts_at_time": "16:00:00", "climate_preset_key": "Home"}, {"starts_at_time": "22:30:00", "climate_preset_key": "Sleep"} ], ... } ``` ```json C# theme={null} // Coming soon! ``` *** ## Update a Daily Program To update a daily program, use `/thermostats/daily_programs/update`, specifying the ID of the daily program that you want to change. You can edit the name for the daily program and the desired replacement set of daily program periods. To delete a daily program period, simply omit it when specifying the complete set of replacement program periods for the daily program. Updating a daily program returns an [action attempt](../../core-concepts/action-attempts) so that you can track the status of pushing this program change to the thermostat. The following example changes the climate preset for the second period and the starting time of the third period: **Request:** ```javascript JavaScript theme={null} await seam.thermostats.dailyPrograms.update({ thermostat_daily_program_id: '99999999-1111-1111-1111-111111111111', name: 'Weekday Program', periods: [ { starts_at_time: '07:00:00', climate_preset_key: 'Home' }, { starts_at_time: '09:00:00', climate_preset_key: 'Eco' }, { starts_at_time: '18:00:00', climate_preset_key: 'Home' }, { starts_at_time: '22:30:00', climate_preset_key: 'Sleep' }, ], }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/daily_programs/update' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "thermostat_daily_program_id": "99999999-1111-1111-1111-111111111111", "name": "Weekday Program", "periods": [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Eco" }, { "starts_at_time": "18:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] }' ``` ```python Python theme={null} seam.thermostats.daily_programs.update( thermostat_daily_program_id = "99999999-1111-1111-1111-111111111111", name = "Weekday Program", periods = [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Eco" }, { "starts_at_time": "18:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] ) ``` ```ruby Ruby theme={null} seam.thermostats.daily_programs.update( thermostat_daily_program_id: "99999999-1111-1111-1111-111111111111", name: "Weekday Program", periods: [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Eco" }, { "starts_at_time": "18:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] ) ``` ```php PHP theme={null} $seam->thermostats->daily_programs->update( thermostat_daily_program_id: "99999999-1111-1111-1111-111111111111", name: "Weekday Program", periods: [ { "starts_at_time": "07:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "09:00:00", "climate_preset_key": "Eco" }, { "starts_at_time": "18:00:00", "climate_preset_key": "Home" }, { "starts_at_time": "22:30:00", "climate_preset_key": "Sleep" } ] ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "11111111-2222-3333-4444-555555555555", "action_type": "PUSH_THERMOSTAT_PROGRAMS", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "PUSH_THERMOSTAT_PROGRAMS", "action_attempt_id": "11111111-2222-3333-4444-555555555555", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='11111111-2222-3333-4444-555555555555', action_type='PUSH_THERMOSTAT_PROGRAMS', status='success', result={}, error=None ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "11111111-2222-3333-4444-555555555555", "action_type": "PUSH_THERMOSTAT_PROGRAMS", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` *** ## Delete a Daily Program To delete a daily program, use `/thermostats/daily_programs/delete`, specifying the ID of the daily program that you want to delete. You cannot delete a daily program that's currently assigned to a weekly program. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.dailyPrograms.delete({ thermostat_daily_program_id: '99999999-1111-1111-1111-111111111111', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/daily_programs/delete' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "thermostat_daily_program_id": "99999999-1111-1111-1111-111111111111" }' ``` ```python Python theme={null} seam.thermostats.daily_programs.delete( thermostat_daily_program_id = "99999999-1111-1111-1111-111111111111" ) ``` ```ruby Ruby theme={null} seam.thermostats.daily_programs.delete( thermostat_daily_program_id: "99999999-1111-1111-1111-111111111111" ) ``` ```php PHP theme={null} $seam->thermostats->daily_programs->delete( thermostat_daily_program_id: "99999999-1111-1111-1111-111111111111" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` *** ## Update the Weekly Program You set or update the weekly program using `/thermostats/update_weekly_program`. In this command, specify the ID of the thermostat for which you want to set or update the weekly program, as well as the ID of the configured daily program that you want to use for each day of the week. You can use a different daily program for each day of the week, or you can assign the same daily program to multiple days. If you do not want to specify a program for a day, set the corresponding program ID parameter to null. To replace a weekly program, use `/thermostats/update_weekly_program`, specifying the desired replacement daily program IDs. The new weekly program overwrites any previous weekly program. To clear all daily programs from the weekly program, set all daily program ID parameters to null. Updating the weekly program returns an [action attempt](../../core-concepts/action-attempts) so that you can track the status of pushing this program change to the thermostat. The following example assigns the same weekday program to each weekday and the same weekend program to each weekend day: **Request:** ```javascript JavaScript theme={null} await seam.thermostats.updateWeeklyProgram({ device_id: '11111111-1111-1111-2222-444444444444', monday_program_id: '99999999-1111-1111-1111-111111111111', tuesday_program_id: '99999999-1111-1111-1111-111111111111', wednesday_program_id: '99999999-1111-1111-1111-111111111111', thursday_program_id: '99999999-1111-1111-1111-111111111111', friday_program_id: '99999999-1111-1111-1111-111111111111', saturday_program_id: '99999999-1111-1111-1111-222222222222', sunday_program_id: '99999999-1111-1111-1111-222222222222', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/update_weekly_program' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "11111111-1111-1111-2222-444444444444", "monday_program_id": "99999999-1111-1111-1111-111111111111", "tuesday_program_id": "99999999-1111-1111-1111-111111111111", "wednesday_program_id": "99999999-1111-1111-1111-111111111111", "thursday_program_id": "99999999-1111-1111-1111-111111111111", "friday_program_id": "99999999-1111-1111-1111-111111111111", "saturday_program_id": "99999999-1111-1111-1111-222222222222", "sunday_program_id": "99999999-1111-1111-1111-222222222222" }' ``` ```python Python theme={null} seam.thermostats.update_weekly_program( device_id = "11111111-1111-1111-2222-444444444444", monday_program_id = "99999999-1111-1111-1111-111111111111", tuesday_program_id = "99999999-1111-1111-1111-111111111111", wednesday_program_id = "99999999-1111-1111-1111-111111111111", thursday_program_id = "99999999-1111-1111-1111-111111111111", friday_program_id = "99999999-1111-1111-1111-111111111111", saturday_program_id = "99999999-1111-1111-1111-222222222222", sunday_program_id = "99999999-1111-1111-1111-222222222222" ) ``` ```ruby Ruby theme={null} seam.thermostats.update_weekly_program( device_id: "11111111-1111-1111-2222-444444444444", monday_program_id: "99999999-1111-1111-1111-111111111111", tuesday_program_id: "99999999-1111-1111-1111-111111111111", wednesday_program_id: "99999999-1111-1111-1111-111111111111", thursday_program_id: "99999999-1111-1111-1111-111111111111", friday_program_id: "99999999-1111-1111-1111-111111111111", saturday_program_id: "99999999-1111-1111-1111-222222222222", sunday_program_id: "99999999-1111-1111-1111-222222222222" ) ``` ```php PHP theme={null} $seam->thermostats->update_weekly_program( device_id: "11111111-1111-1111-2222-444444444444", monday_program_id: "99999999-1111-1111-1111-111111111111", tuesday_program_id: "99999999-1111-1111-1111-111111111111", wednesday_program_id: "99999999-1111-1111-1111-111111111111", thursday_program_id: "99999999-1111-1111-1111-111111111111", friday_program_id: "99999999-1111-1111-1111-111111111111", saturday_program_id: "99999999-1111-1111-1111-222222222222", sunday_program_id: "99999999-1111-1111-1111-222222222222" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { "status": "success", "action_attempt_id": "11111111-2222-3333-4444-666666666666", "action_type": "PUSH_THERMOSTAT_PROGRAMS", "result": {}, "error": null } ``` ```json cURL theme={null} { "action_attempt": { "status": "pending", "action_type": "PUSH_THERMOSTAT_PROGRAMS", "action_attempt_id": "11111111-2222-3333-4444-666666666666", "result": null, "error": null }, "ok": true } ``` ```json Python theme={null} ActionAttempt( action_attempt_id='11111111-2222-3333-4444-666666666666', action_type='PUSH_THERMOSTAT_PROGRAMS', status='success', result={}, error=None ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "status": "success", "action_attempt_id": "11111111-2222-3333-4444-666666666666", "action_type": "PUSH_THERMOSTAT_PROGRAMS", "result": {}, "error": null } ``` ```json C# theme={null} // Coming soon! ``` # Creating and Managing Thermostat Schedules Source: https://docs.seam.co/capability-guides/thermostats/creating-and-managing-thermostat-schedules Learn how to create, list, get, update, and delete thermostat schedules for thermostats. Once you have created a set of [climate presets](/capability-guides/thermostats/creating-and-managing-climate-presets/index) for a thermostat, you can define schedules using the [`/thermostats/schedules/create`](/api/thermostats/schedules/create) endpoint. The Seam API's scheduling mechanism is flexible and intelligent. It can prioritize and handle multiple scheduled climate presets. For example, you could [set a fallback](/capability-guides/thermostats/creating-and-managing-climate-presets/setting-the-fallback-climate-preset) energy-saving climate preset for whenever a short-term rental property is unoccupied. Then, you could schedule—in advance—a "comfort" climate preset to correspond to each upcoming guest's stay. *** ## Thermostat Schedule Properties Each thermostat schedule can contain the following properties:
Property Description
name (Optional) User-friendly name to identify the thermostat schedule.
climate\_preset\_key (Required) Key of the climate preset to use for the thermostat schedule.
is\_override\_allowed (Optional) Indicates whether a person at the thermostat or using the API can change (that is, override) the thermostat's settings from an active scheduled climate preset.
max\_override\_period\_minutes Number of minutes for which a person at the thermostat or using the API can change (that is, override) the thermostat's settings after the activation of the scheduled climate preset.
Note: If you set this value to null, there is no enforced maximum override period. That is, the override applies until another climate preset becomes active.
Default: null
See also Specifying Manual Override Permissions .
starts\_at (Required) Date and time at which the thermostat schedule starts, in ISO 8601 format.
ends\_at (Required) Date and time at which the thermostat schedule ends, in ISO 8601 format.
*** ## Setting the Schedule In the Seam API, use the `starts_at` and `ends_at` parameters to define the time period during which to apply an existing climate preset. For example, a short-term rental host could set `starts_at` to the beginning of a guest reservation or perhaps even slightly before the reservation starts so that the property reaches a comfortable temperature in time for guest arrival. The host could set `ends_at` to coincide with the end of the reservation. `starts_at` is required and must be unique within all the schedules for the thermostat. However, if you want to schedule a climate preset that starts immediately, set `start_at` to a time in the past. Alternately, you can [activate a climate preset](/capability-guides/thermostats/creating-and-managing-climate-presets/activating-a-climate-preset) immediately. After a scheduled climate preset starts, Seam emits a [`thermostat.temperature_reached_set_point` event](/api/thermostats/events#thermostat-temperature_reached_set_point) when the thermostat reports a temperature within 1° Celsius of the heating or cooling set point specified in this climate preset. You can configure a webhook to watch for this event. *** ## Specifying Manual Override Permissions When creating a schedule for a thermostat, you can specify `is_override_allowed` and `max_override_period_minutes`. The `is_override_allowed` parameter indicates whether a person at the thermostat or using the Seam API can change the thermostat's settings for the active duration of the thermostat schedule. Setting `max_override_period_minutes` defines the length of the allowed override period. If an override period is allowed, at the end of this period, Seam sets the thermostat back to the climate preset defined by the thermostat schedule. The override period starts again each time a person makes a change at the thermostat or using the API. Through these override period settings, the Seam API provides you with the flexibility to customize the thermostat behavior to suit your needs. For example, a multifamily property manager may want to give complete control of the thermostat to a unit's residents as soon as they move into the unit. However, a short-term rental host may want to enforce stricter rules to ensure that their guests are using the associated HVAC system in a reasonable manner. To allow complete control at the thermostat, set `is_override_allowed` to `true` and `max_override_period_minutes` to `null`. To disable manual overrides entirely, set `is_override_allowed` to `false`. *** ## Create a Thermostat Schedule To create a thermostat schedule, issue a [`/thermostats/schedules/create`](/api/thermostats/schedules/create) request, providing the `device_id` of the desired thermostat, as well as the `climate_preset_key`, and the `starts_at` and `ends_at` timestamps. You can also specify a `name` for the thermostat schedule and the desired `is_override_allowed` and `max_override_period_minutes` values. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.schedules.create({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', name: "Jim's stay", climate_preset_key: 'occupied', starts_at: '2024-11-01T15:00:00Z', ends_at: '2024-11-05T12:00:00Z', is_override_allowed: true, max_override_period_minutes: 90, }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "name": "Jim'\''s stay", "climate_preset_key": "occupied", "starts_at": "2024-11-01T15:00:00Z", "ends_at": "2024-11-05T12:00:00Z", "is_override_allowed": true, "max_override_period_minutes": 90 }' ``` ```python Python theme={null} seam.thermostats.schedules.create( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5", name = "Jim's stay", climate_preset_key = "occupied", starts_at = "2024-11-01T15:00:00Z", ends_at = "2024-11-05T12:00:00Z", is_override_allowed = True, max_override_period_minutes = 90 ) ``` ```ruby Ruby theme={null} seam.thermostats.schedules.create({ device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", name: "Jim's stay", climate_preset_key: "occupied", starts_at: "2024-11-01T15:00:00Z", ends_at: "2024-11-05T12:00:00Z", is_override_allowed: true, max_override_period_minutes: 90 ) ``` ```php PHP theme={null} $seam->thermostats->schedules->create( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5", name: "Jim's stay", climate_preset_key: "occupied", starts_at: "2024-11-01T15:00:00Z", ends_at: "2024-11-05T12:00:00Z", is_override_allowed: true, max_override_period_minutes: 90 ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { thermostat_schedule_id: '4a5bd61f-b402-41a5-9757-d92ba1e20708', name: "Jim's stay", device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', starts_at: '2024-11-01T15:00:00.000Z', ends_at: '2024-11-05T12:00:00.000Z', is_override_allowed: true, max_override_period_minutes: 90, ... } ``` ```json cURL theme={null} { "thermostat_schedule": { "thermostat_schedule_id": "56d29fcf-0674-4db5-8e03-b2370a77460a", "name": "Jim's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-01T15:00:00.000Z", "ends_at": "2024-11-05T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... }, "ok": true } ``` ```json Python theme={null} ThermostatSchedule( thermostat_schedule_id='56d29fcf-0674-4db5-8e03-b2370a77460a', name="Jim's stay", device_id='2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key='occupied', starts_at='2024-11-01T15:00:00.000Z', ends_at='2024-11-05T12:00:00.000Z', is_override_allowed=True, max_override_period_minutes=90, ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "thermostat_schedule_id": "a05960b9-d787-4621-a7b0-ab76a566e5e8", "name": "Jim's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-01T15:00:00.000Z", "ends_at": "2024-11-05T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... } ``` ```json C# theme={null} // Coming soon! ``` *** ## Schedule Multiple Climate Presets Suppose a short-term rental host wants to set a fallback "unoccupied" climate preset that takes effect immediately, as well as scheduling an "occupied" climate preset for two periods that correspond to guest reservations. Seam handles a fallback climate preset, along with multiple thermostat
schedules. The following example shows how to set up these schedules: **Request:** ```javascript JavaScript theme={null} // Get the thermostat. const thermostat = await seam.devices.get({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', }) // Set the fallback climate preset. await seam.thermostats.setFallbackClimatePreset({ device_id: thermostat.device_id, climate_preset_key: 'unoccupied', }) // Create the thermostat schedule for the first reservation. await seam.thermostats.schedules.create({ device_id: thermostat.device_id, name: "Joe's stay", climate_preset_key: 'occupied', starts_at: '2024-11-10T15:00:00Z', ends_at: '2024-11-15T12:00:00Z', is_override_allowed: true, max_override_period_minutes: 90, }) // Create the thermostat schedule for the second reservation. await seam.thermostats.schedules.create({ device_id: thermostat.device_id, name: "Jane's stay", climate_preset_key: 'occupied', starts_at: '2024-11-16T15:00:00Z', ends_at: '2024-11-18T12:00:00Z', is_override_allowed: true, max_override_period_minutes: 90, }) ``` ```bash cURL theme={null} # Get the thermostat. thermostat=$( # Use GET or POST. curl -X 'GET' \ 'https://connect.getseam.com/devices/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5" }') # Set the fallback climate preset. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/set_fallback_climate_preset' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"climate_preset_key\": \"unoccupied\" }" # Create the thermostat schedule for the first reservation. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"name\": \"Joe's stay\", \"climate_preset_key\": \"occupied\", \"starts_at\": \"2024-11-10T15:00:00Z\", \"ends_at\": \"2024-11-15T12:00:00Z\", \"is_override_allowed\": true, \"max_override_period_minutes\": 90 }" # Create the thermostat schedule for the second reservation. curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/create' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d "{ \"device_id\": \"$(jq -r '.device.device_id' <<< ${thermostat})\", \"name\": \"Jane's stay\", \"climate_preset_key\": \"occupied\", \"starts_at\": \"2024-11-16T15:00:00Z\", \"ends_at\": \"2024-11-18T12:00:00Z\", \"is_override_allowed\": true, \"max_override_period_minutes\": 90 }" ``` ```python Python theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5" ) # Set the fallback climate preset. seam.thermostats.set_fallback_climate_preset( device_id = thermostat.device_id, climate_preset_key = "unoccupied" ) # Create the thermostat schedule for the first reservation. seam.thermostats.schedules.create( device_id = thermostat.device_id, name = "Joe's stay", climate_preset_key = "occupied", starts_at = "2024-11-10T15:00:00Z", ends_at = "2024-11-15T12:00:00Z", is_override_allowed = True, max_override_period_minutes = 90 ) # Create the thermostat schedule for the second reservation. seam.thermostats.schedules.create( device_id = thermostat.device_id, name = "Jane's stay", climate_preset_key = "occupied", starts_at = "2024-11-16T15:00:00Z", ends_at = "2024-11-18T12:00:00Z", is_override_allowed = True, max_override_period_minutes = 90 ) ``` ```ruby Ruby theme={null} # Get the thermostat. thermostat = seam.devices.get( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ) # Set the fallback climate preset. seam.thermostats.set_fallback_climate_preset( device_id: thermostat.device_id, climate_preset_key: "unoccupied" ) # Create the thermostat schedule for the first reservation. seam.thermostats.schedules.create( device_id: thermostat.device_id, name: "Joe's stay", climate_preset_key: "occupied", starts_at: "2024-11-10T15:00:00Z", ends_at: "2024-11-15T12:00:00Z", is_override_allowed: true, max_override_period_minutes: 90 ) # Create the thermostat schedule for the second reservation. seam.thermostats.schedules.create( device_id: thermostat.device_id, name: "Jane's stay", climate_preset_key: "occupied", starts_at: "2024-11-16T15:00:00Z", ends_at: "2024-11-18T12:00:00Z", is_override_allowed: true, max_override_period_minutes: 90 ) ``` ```php PHP theme={null} // Get the thermostat. $thermostat = $seam->devices->get( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ); // Set the fallback climate preset. $seam->thermostats->set_fallback_climate_preset( device_id: $thermostat->device_id, climate_preset_key: "unoccupied" ); // Create the thermostat schedule for the first reservation. $seam->thermostats->schedules->create( device_id: $thermostat->device_id, name: "Joe's stay", climate_preset_key: "occupied", starts_at: "2024-11-10T15:00:00Z", ends_at: "2024-11-15T12:00:00Z", is_override_allowed: true, max_override_period_minutes: 90 ); // Create the thermostat schedule for the second reservation. $seam->thermostats->schedules->create( device_id: $thermostat->device_id, name: "Jane's stay", climate_preset_key: "occupied", starts_at: "2024-11-16T15:00:00Z", ends_at: "2024-11-18T12:00:00Z", is_override_allowed: true, max_override_period_minutes: 90 ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { thermostat_schedule_id: '4082a585-cf6e-4f6c-889d-d208fde226d0', name: "Joe's stay", device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', starts_at: '2024-11-10T15:00:00.000Z', ends_at: '2024-11-15T12:00:00.000Z', is_override_allowed: true, max_override_period_minutes: 90, ... } { thermostat_schedule_id: '9d2b1c55-68cc-4c86-8478-dea3249e26b7', name: "Jane's stay", device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', starts_at: '2024-11-16T15:00:00.000Z', ends_at: '2024-11-18T12:00:00.000Z', is_override_allowed: true, max_override_period_minutes: 90, ... } ``` ```json cURL theme={null} { "thermostat_schedule":{ "thermostat_schedule_id":"a46b96bf-7b4c-408d-b7c6-74ff7c747ff1", "name":"Joe's stay", "device_id":"2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key":"occupied", "starts_at":"2024-11-10T15:00:00.000Z", "ends_at":"2024-11-15T12:00:00.000Z", "is_override_allowed":true, "max_override_period_minutes":90, ... }, "ok":true } { "thermostat_schedule":{ "thermostat_schedule_id":"5acded62-dc35-4d37-b94c-35bc68352ea5", "name":"Jane's stay", "device_id":"2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key":"occupied", "starts_at":"2024-11-16T15:00:00.000Z", "ends_at":"2024-11-18T12:00:00.000Z", "is_override_allowed":true, "max_override_period_minutes":90, ... }, "ok":true } ``` ```json Python theme={null} ThermostatSchedule( thermostat_schedule_id='c02a3cc5-87f2-409d-b21d-164f2c94d37c' name="Joe's stay", device_id='2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key='occupied', starts_at='2024-11-10T15:00:00.000Z', ends_at='2024-11-15T12:00:00.000Z', is_override_allowed=True, max_override_period_minutes=90, ... ) ThermostatSchedule( thermostat_schedule_id='ed14ed8d-c012-4d89-af96-053e0c16197d', name="Jane's stay", device_id='2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key='occupied', starts_at='2024-11-16T15:00:00.000Z', ends_at='2024-11-18T12:00:00.000Z', is_override_allowed=True, max_override_period_minutes=90, ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "thermostat_schedule_id": "89d3507e-60e3-4101-bd1b-ba066ec30ad4", "name": "Joe's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-10T15:00:00.000Z", "ends_at": "2024-11-15T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... } { "thermostat_schedule_id": "665553d1-94f9-4e92-9739-06ac6362c959", "name": "Jane's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-16T15:00:00.000Z", "ends_at": "2024-11-18T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... } ``` ```json C# theme={null} // Coming soon! ``` *** ## List All Thermostat Schedules for a Thermostat To retrieve all thermostat schedules for a thermostat, issue a [`/thermostats/schedules/list`](/api/thermostats/schedules/list) request, specifying the `device_id` of the desired thermostat. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.schedules.list({ device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/list' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5" }' ``` ```python Python theme={null} seam.thermostats.schedules.list( device_id = "2d488679-6f07-4810-aed2-e726872c1dd5" ) ``` ```ruby Ruby theme={null} seam.thermostats.schedules.list( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ) ``` ```php PHP theme={null} $seam->thermostats->schedules->list( device_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} [ { thermostat_schedule_id: '89d3507e-60e3-4101-bd1b-ba066ec30ad4', name: "Joe's stay", device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', starts_at: '2024-11-10T15:00:00.000Z', ends_at: '2024-11-15T12:00:00.000Z', is_override_allowed: true, max_override_period_minutes: 90, ... }, { thermostat_schedule_id: '665553d1-94f9-4e92-9739-06ac6362c959', name: "Jane's stay", device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', starts_at: '2024-11-16T15:00:00.000Z', ends_at: '2024-11-18T12:00:00.000Z', is_override_allowed: true, max_override_period_minutes: 90, ... } ] ``` ```json cURL theme={null} { "thermostat_schedules": [ { "thermostat_schedule_id":"89d3507e-60e3-4101-bd1b-ba066ec30ad4", "name":"Joe's stay", "device_id":"2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key":"occupied", "starts_at":"2024-11-10T15:00:00.000Z", "ends_at":"2024-11-15T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes":90, ... }, { "thermostat_schedule_id":"665553d1-94f9-4e92-9739-06ac6362c959", "name":"Jane's stay", "device_id":"2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key":"occupied", "starts_at":"2024-11-16T15:00:00.000Z", "ends_at":"2024-11-18T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes":90, ... } ], "ok":true } ``` ```json Python theme={null} [ ThermostatSchedule( thermostat_schedule_id='89d3507e-60e3-4101-bd1b-ba066ec30ad4', name="Joe's stay", device_id='2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key='occupied', starts_at='2024-11-10T15:00:00.000Z', ends_at='2024-11-15T12:00:00.000Z', is_override_allowed=True, max_override_period_minutes=90, ... ), ThermostatSchedule( thermostat_schedule_id='665553d1-94f9-4e92-9739-06ac6362c959', name="Jane's stay", device_id='2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key='occupied', starts_at='2024-11-16T15:00:00.000Z', ends_at='2024-11-18T12:00:00.000Z', is_override_allowed=True, max_override_period_minutes=90, ... ) ] ``` ```json Ruby theme={null} [ , ] ``` ```json PHP theme={null} [ { "thermostat_schedule_id": "89d3507e-60e3-4101-bd1b-ba066ec30ad4", "name": "Joe's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-10T15:00:00.000Z", "ends_at": "2024-11-15T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... }, { "thermostat_schedule_id": "665553d1-94f9-4e92-9739-06ac6362c959", "name": "Jane's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-16T15:00:00.000Z", "ends_at": "2024-11-18T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... } ] ``` ```json C# theme={null} // Coming soon! ``` *** ## Get an Individual Thermostat Schedule To get a specific thermostat schedule, issue a [`/thermostats/schedules/get`](/api/thermostats/schedules/get) request, including the `thermostat_schedule_id` of the desired thermostat schedule. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.schedules.get({ thermostat_schedule_id: '89d3507e-60e3-4101-bd1b-ba066ec30ad4', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/get' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "thermostat_schedule_id": "89d3507e-60e3-4101-bd1b-ba066ec30ad4" }' ``` ```python Python theme={null} seam.thermostats.schedules.get( thermostat_schedule_id = "89d3507e-60e3-4101-bd1b-ba066ec30ad4" ) ``` ```ruby Ruby theme={null} seam.thermostats.schedules.get( thermostat_schedule_id: "89d3507e-60e3-4101-bd1b-ba066ec30ad4" ) ``` ```php PHP theme={null} $seam->thermostats->schedules->get( thermostat_schedule_id: "89d3507e-60e3-4101-bd1b-ba066ec30ad4" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} { thermostat_schedule_id: '89d3507e-60e3-4101-bd1b-ba066ec30ad4', name: "Joe's stay", device_id: '2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key: 'occupied', starts_at: '2024-11-10T15:00:00.000Z', ends_at: '2024-11-15T12:00:00.000Z', is_override_allowed: true, max_override_period_minutes: 90, ... } ``` ```json cURL theme={null} { "thermostat_schedule": { "thermostat_schedule_id":"89d3507e-60e3-4101-bd1b-ba066ec30ad4", "name":"Joe's stay", "device_id":"2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key":"occupied", "starts_at":"2024-11-10T15:00:00.000Z", "ends_at":"2024-11-15T12:00:00.000Z", "is_override_allowed":true, "max_override_period_minutes":90, ... }, "ok":true } ``` ```json Python theme={null} ThermostatSchedule( thermostat_schedule_id='89d3507e-60e3-4101-bd1b-ba066ec30ad4', name="Joe's stay", device_id='2d488679-6f07-4810-aed2-e726872c1dd5', climate_preset_key='occupied', starts_at='2024-11-10T15:00:00.000Z', ends_at='2024-11-15T12:00:00.000Z', is_override_allowed=True, max_override_period_minutes=90, ... ) ``` ```json Ruby theme={null} ``` ```json PHP theme={null} { "thermostat_schedule_id": "89d3507e-60e3-4101-bd1b-ba066ec30ad4", "name": "Joe's stay", "device_id": "2d488679-6f07-4810-aed2-e726872c1dd5", "climate_preset_key": "occupied", "starts_at": "2024-11-10T15:00:00.000Z", "ends_at": "2024-11-15T12:00:00.000Z", "is_override_allowed": true, "max_override_period_minutes": 90, ... } ``` ```json C# theme={null} // Coming soon! ``` *** ## Update a Thermostat Schedule To update a thermostat schedule, issue a [`/thermostats/schedules/update`](/api/thermostats/schedules/update) request, providing the `thermostat_schedule_id` of the desired thermostat schedule and the desired updated settings. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.schedules.update({ thermostat_schedule_id: '89d3507e-60e3-4101-bd1b-ba066ec30ad4', ends_at: '2024-11-15T15:00:00Z', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/update' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "thermostat_schedule_id": "89d3507e-60e3-4101-bd1b-ba066ec30ad4", "ends_at": "2024-11-15T15:00:00Z" }' ``` ```python Python theme={null} seam.thermostats.schedules.update( thermostat_schedule_id = "89d3507e-60e3-4101-bd1b-ba066ec30ad4", ends_at = "2024-11-15T15:00:00Z" ) ``` ```ruby Ruby theme={null} seam.thermostats.schedules.update( thermostat_schedule_id: "89d3507e-60e3-4101-bd1b-ba066ec30ad4", ends_at: "2024-11-15T15:00:00Z" ) ``` ```php PHP theme={null} $seam->thermostats->schedules->update( thermostat_schedule_id: "89d3507e-60e3-4101-bd1b-ba066ec30ad4", ends_at: "2024-11-15T15:00:00Z" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` *** ## Delete a Thermostat Schedule To delete a thermostat schedule, issue a [`/thermostats/schedules/delete`](/api/thermostats/schedules/delete) request, providing the `thermostat_schedule_id` of the desired thermostat schedule. **Request:** ```javascript JavaScript theme={null} await seam.thermostats.schedules.delete({ thermostat_schedule_id: '2d488679-6f07-4810-aed2-e726872c1dd5', }) ``` ```bash cURL theme={null} curl -X 'POST' \ 'https://connect.getseam.com/thermostats/schedules/delete' \ -H 'accept: application/json' \ -H "Authorization: Bearer ${SEAM_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "thermostat_schedule_id": "2d488679-6f07-4810-aed2-e726872c1dd5" }' ``` ```python Python theme={null} seam.thermostats.schedules.delete( thermostat_schedule_id = "2d488679-6f07-4810-aed2-e726872c1dd5" ) ``` ```ruby Ruby theme={null} seam.thermostats.schedules.delete( thermostat_schedule_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ) ``` ```php PHP theme={null} $seam->thermostats->schedules->delete( thermostat_schedule_id: "2d488679-6f07-4810-aed2-e726872c1dd5" ); ``` ```csharp C# theme={null} // Coming soon! ``` **Response:** ```json JavaScript theme={null} void ``` ```json cURL theme={null} { "ok": true } ``` ```json Python theme={null} None ``` ```json Ruby theme={null} nil ``` ```json PHP theme={null} void ``` ```json C# theme={null} // Coming soon! ``` # Thermostats Source: https://docs.seam.co/capability-guides/thermostats/index Learn about managing smart thermostats that automatically adjust and program your users' heating and cooling systems for comfort and cost savings. The Seam API provides flexible and robust functionality that enables you to control your users' thermostats. The Seam API provides flexible and robust functionality that enables you to control your users' thermostats. In addition to monitoring a thermostat and making immediate changes to its climate settings, with the Seam API, you can create and schedule climate presets, and you can create daily and weekly thermostat programs. The Seam API's thermostat features enable you to satisfy a variety of scenarios, including the following and many more: * You can synchronize the thermostat automatically for occupancy. * You can enable comfortable temperature settings in advance of occupancy. Then, you can minimize costs and maximize efficiency by scheduling your property's thermostats to return to energy savings settings when the property is empty. * You can use an app to program different climates to apply throughout the day. You can also set your thermostat to an energy-saving vacation mode when you're away. * You can set unoccupied units' thermostats to energy saving settings and also schedule comfortable climates when units are occupied. Further, you can pass control of a unit's thermostats to the new residents. * You can configure Seam to help you monitor your thermostats proactively. In this way, reported temperatures outside acceptable thresholds automatically alert you to potential HVAC system issues.