From a3e7be5720899a65ec3eb30bc91f3813774eceea Mon Sep 17 00:00:00 2001 From: Evan Sosenko Date: Wed, 26 Aug 2026 16:16:29 -0700 Subject: [PATCH 1/2] chore: update blueprint and types --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index d58494d..513bbca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,10 +6,10 @@ "": { "name": "@seamapi/ruby", "devDependencies": { - "@seamapi/blueprint": "^1.8.0", + "@seamapi/blueprint": "^1.9.1", "@seamapi/fake-seam-connect": "2.0.5", "@seamapi/smith": "^1.1.0", - "@seamapi/types": "1.1037.0", + "@seamapi/types": "1.1047.0", "change-case": "^5.4.4", "markdown-toc": "^1.2.0", "prettier": "^3.2.5" @@ -788,9 +788,9 @@ "license": "MIT" }, "node_modules/@seamapi/blueprint": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@seamapi/blueprint/-/blueprint-1.8.0.tgz", - "integrity": "sha512-NUghBmYaKreBeBxwPIB2O9hjIFZtEjVj73tAsuKdJR8t4BxlKK1I0XDQXxo3ZsH2QezNlbdo9/0MoX/33VXuhQ==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@seamapi/blueprint/-/blueprint-1.9.1.tgz", + "integrity": "sha512-A9H3dZE9f+ZEEnOAlMl5jSlL5F/RIKkjOF8NDFbnuahAiu/trDz/RzHOGhbQd6sd0RErIyx3eG1p4HCOJDKDCA==", "dev": true, "license": "MIT", "dependencies": { @@ -854,9 +854,9 @@ } }, "node_modules/@seamapi/types": { - "version": "1.1037.0", - "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.1037.0.tgz", - "integrity": "sha512-3HbkUbACvkQsybIOdmDslMHRXPePrPgZ6WwX6pXO8MyO8o3hMsxy5qTr+HJZbG6tTSqMHQ8HP1uVLZIk+WrN5A==", + "version": "1.1047.0", + "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.1047.0.tgz", + "integrity": "sha512-S3A3FcQ4fWJ1IsxVjHaE14k7WlQt0iKJsb3oPF/YVUZHJAmHnFg6riAF6LghlMig7prLf6C2uxaTDairw5dCJQ==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index a99bbc0..b084288 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,10 @@ }, "packageManager": "npm@11.19.0", "devDependencies": { - "@seamapi/blueprint": "^1.8.0", + "@seamapi/blueprint": "^1.9.1", "@seamapi/fake-seam-connect": "2.0.5", "@seamapi/smith": "^1.1.0", - "@seamapi/types": "1.1037.0", + "@seamapi/types": "1.1047.0", "change-case": "^5.4.4", "markdown-toc": "^1.2.0", "prettier": "^3.2.5" From 3210a3ca7ddc4585eb64db0f20853be8f0073d74 Mon Sep 17 00:00:00 2001 From: Seam Bot Date: Wed, 26 Aug 2026 23:17:48 +0000 Subject: [PATCH 2/2] ci: Generate code --- lib/seam/resources/access_grant.rb | 2 +- lib/seam/resources/event.rb | 15 ++++++++------- lib/seam/routes/access_codes.rb | 2 +- lib/seam/routes/access_grants.rb | 8 ++++---- lib/seam/routes/access_methods.rb | 8 ++++---- lib/seam/routes/acs_encoders_simulate.rb | 12 ++++++------ lib/seam/routes/customers.rb | 6 +++--- lib/seam/routes/noise_sensors_noise_thresholds.rb | 2 +- lib/seam/routes/user_identities.rb | 8 ++++---- lib/seam/routes/workspaces.rb | 2 +- 10 files changed, 33 insertions(+), 32 deletions(-) diff --git a/lib/seam/resources/access_grant.rb b/lib/seam/resources/access_grant.rb index b0684bd..d5e4400 100644 --- a/lib/seam/resources/access_grant.rb +++ b/lib/seam/resources/access_grant.rb @@ -320,7 +320,7 @@ class DeviceTimeConstraintsViolated < Warnings # Display name of the Access Grant. # @return [String] attr_accessor :display_name - # Human-readable sentence answering whether the user can currently get in, for example `Awaiting encoding` on an access method or `Upcoming` here. For display only. The wording is not stable and is not an enumeration — it may change at any time, so never compare against or branch on it. To make decisions, read `starts_at`, `ends_at`, `errors`, and the access methods' own fields. + # Human-readable sentence answering whether the user can currently get in, for example `Active`, `Awaiting issuance`, or `Upcoming`. For display only. The wording is not stable and is not an enumeration — it may change at any time, so never compare against or branch on it. To make decisions, read `starts_at`, `ends_at`, `errors`, and the access methods' own fields. # @return [String] attr_accessor :display_status # Instant Key URL. Only returned if the Access Grant has a single mobile_key access_method. diff --git a/lib/seam/resources/event.rb b/lib/seam/resources/event.rb index 4383ae8..534e73c 100644 --- a/lib/seam/resources/event.rb +++ b/lib/seam/resources/event.rb @@ -3481,15 +3481,13 @@ class DeviceTampered < SeamEvent # A device battery level dropped below the low threshold. class DeviceLowBattery < SeamEvent - # Number in the range 0 to 1.0 indicating the amount of battery in the affected device, as reported by the device. + # Number in the range 0 to 1.0 indicating the battery level of the affected device's paired accessory keypad, when the device has one and its level is known. + # @return [Float, nil] + attr_accessor :accessory_keypad_battery_level + # Number in the range 0 to 1.0 indicating the level of the battery whose drop triggered this event. # @return [Float] + # @deprecated Use device_battery_level and accessory_keypad_battery_level, which distinguish the device's own battery from a paired accessory keypad's battery. attr_accessor :battery_level - # Battery that dropped below the low threshold. `lock`: the lock's own battery. `accessory_keypad`: a paired accessory keypad's battery. Omitted for events emitted before this field existed, which always refer to the lock's own battery. - # @return [String, nil] - # Known values: - # - `lock` - # - `accessory_keypad` - attr_accessor :battery_source # Custom metadata of the connected account, present when connected_account_id is provided. # @return [Hash{String => String, Boolean}, nil] attr_accessor :connected_account_custom_metadata @@ -3499,6 +3497,9 @@ class DeviceLowBattery < SeamEvent # The customer key associated with the device, if any. # @return [String, nil] attr_accessor :customer_key + # Number in the range 0 to 1.0 indicating the affected device's own battery level, when known. + # @return [Float, nil] + attr_accessor :device_battery_level # Custom metadata of the device, present when device_id is provided. # @return [Hash{String => String, Boolean}, nil] attr_accessor :device_custom_metadata diff --git a/lib/seam/routes/access_codes.rb b/lib/seam/routes/access_codes.rb index 97ff56a..5370cd9 100644 --- a/lib/seam/routes/access_codes.rb +++ b/lib/seam/routes/access_codes.rb @@ -196,7 +196,7 @@ def report_device_constraints(device_id:, max_code_length: nil, min_code_length: # @param type [String, nil] Type to which you want to convert the access code. To convert a time-bound access code to an ongoing access code, set `type` to `ongoing`. See also [Changing a time-bound access code to permanent access](https://docs.seam.co/low-level-apis/smart-locks/access-codes/modifying-access-codes#special-case-2-changing-a-time-bound-access-code-to-permanent-access). # @return [nil] OK def update(access_code_id:, allow_external_modification: nil, attempt_for_offline_device: nil, code: nil, device_id: nil, ends_at: nil, is_external_modification_allowed: nil, is_managed: nil, name: nil, starts_at: nil, type: nil) - @client.put("/access_codes/update", {access_code_id: access_code_id, allow_external_modification: allow_external_modification, attempt_for_offline_device: attempt_for_offline_device, code: code, device_id: device_id, ends_at: ends_at, is_external_modification_allowed: is_external_modification_allowed, is_managed: is_managed, name: name, starts_at: starts_at, type: type}.compact) + @client.patch("/access_codes/update", {access_code_id: access_code_id, allow_external_modification: allow_external_modification, attempt_for_offline_device: attempt_for_offline_device, code: code, device_id: device_id, ends_at: ends_at, is_external_modification_allowed: is_external_modification_allowed, is_managed: is_managed, name: name, starts_at: starts_at, type: type}.compact) nil end diff --git a/lib/seam/routes/access_grants.rb b/lib/seam/routes/access_grants.rb index 193ba42..8c0a96d 100644 --- a/lib/seam/routes/access_grants.rb +++ b/lib/seam/routes/access_grants.rb @@ -14,8 +14,6 @@ def unmanaged # Creates a new [Access Grant](https://docs.seam.co/use-cases/granting-access/access-grants). 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. # @param requested_access_methods [Array] - # @param user_identity_id [String, nil] ID of user identity for whom access is being granted. - # @param user_identity [Hash, nil] When used, creates a new user identity with the given details, and grants them access. # @param access_grant_key [String, nil] Unique key for the access grant within the workspace. # @param acs_entrance_ids [Array, nil] Set of IDs of the [entrances](https://docs.seam.co/api/acs/systems/list) to which access is being granted. # @param customization_profile_id [String, nil] ID of the customization profile to apply to the Access Grant and its access methods. @@ -30,9 +28,11 @@ def unmanaged # @param space_ids [Array, nil] Set of IDs of existing spaces to which access is being granted. # @param space_keys [Array, nil] Set of keys of existing spaces to which access is being granted. # @param starts_at [String, nil] Date and time at which the validity of the new grant starts, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. + # @param user_identity [Hash, nil] When used, creates a new user identity with the given details, and grants them access. + # @param user_identity_id [String, nil] ID of user identity for whom access is being granted. # @return [Seam::Resources::AccessGrant] OK - def create(requested_access_methods:, user_identity_id: nil, user_identity: nil, access_grant_key: nil, acs_entrance_ids: nil, customization_profile_id: nil, device_ids: nil, ends_at: nil, location: nil, location_ids: nil, name: nil, reservation_key: nil, space_ids: nil, space_keys: nil, starts_at: nil) - res = @client.post("/access_grants/create", {requested_access_methods: requested_access_methods, user_identity_id: user_identity_id, user_identity: user_identity, access_grant_key: access_grant_key, acs_entrance_ids: acs_entrance_ids, customization_profile_id: customization_profile_id, device_ids: device_ids, ends_at: ends_at, location: location, location_ids: location_ids, name: name, reservation_key: reservation_key, space_ids: space_ids, space_keys: space_keys, starts_at: starts_at}.compact) + def create(requested_access_methods:, access_grant_key: nil, acs_entrance_ids: nil, customization_profile_id: nil, device_ids: nil, ends_at: nil, location: nil, location_ids: nil, name: nil, reservation_key: nil, space_ids: nil, space_keys: nil, starts_at: nil, user_identity: nil, user_identity_id: nil) + res = @client.post("/access_grants/create", {requested_access_methods: requested_access_methods, access_grant_key: access_grant_key, acs_entrance_ids: acs_entrance_ids, customization_profile_id: customization_profile_id, device_ids: device_ids, ends_at: ends_at, location: location, location_ids: location_ids, name: name, reservation_key: reservation_key, space_ids: space_ids, space_keys: space_keys, starts_at: starts_at, user_identity: user_identity, user_identity_id: user_identity_id}.compact) Seam::Resources::AccessGrant.load_from_response(res.body["access_grant"]) end diff --git a/lib/seam/routes/access_methods.rb b/lib/seam/routes/access_methods.rb index 26cc27e..7da35f3 100644 --- a/lib/seam/routes/access_methods.rb +++ b/lib/seam/routes/access_methods.rb @@ -27,16 +27,16 @@ def assign_card(access_method_id:, card_number:, wait_for_action_attempt: nil) end # Deletes an access method. - # @param access_method_id [String, nil] ID of access method to delete. # @param access_grant_id [String, nil] ID of access grant whose access methods should be deleted. + # @param access_method_id [String, nil] ID of access method to delete. # @param reservation_key [String, nil] Reservation key of the access grant whose access methods should be deleted. # @return [nil] OK - def delete(access_method_id: nil, access_grant_id: nil, reservation_key: nil) - if access_method_id.nil? && access_grant_id.nil? && reservation_key.nil? + def delete(access_grant_id: nil, access_method_id: nil, reservation_key: nil) + if access_grant_id.nil? && access_method_id.nil? && reservation_key.nil? raise TypeError, "At least one parameter is required for /access_methods/delete" end - @client.delete("/access_methods/delete", {access_method_id: access_method_id, access_grant_id: access_grant_id, reservation_key: reservation_key}.compact) + @client.delete("/access_methods/delete", {access_grant_id: access_grant_id, access_method_id: access_method_id, reservation_key: reservation_key}.compact) nil end diff --git a/lib/seam/routes/acs_encoders_simulate.rb b/lib/seam/routes/acs_encoders_simulate.rb index 5fed42e..c6661d7 100644 --- a/lib/seam/routes/acs_encoders_simulate.rb +++ b/lib/seam/routes/acs_encoders_simulate.rb @@ -10,11 +10,11 @@ def initialize(client:, defaults:) # Simulates that the next attempt to encode a [credential](https://docs.seam.co/low-level-apis/access-systems/managing-credentials) using the specified [encoder](https://docs.seam.co/low-level-apis/access-systems/working-with-card-encoders-and-scanners) will fail. You can only perform this action within a [sandbox workspace](https://docs.seam.co/core-concepts/workspaces#sandbox-workspaces). # @param acs_encoder_id [String] ID of the `acs_encoder` that will be used in the next request to encode the `acs_credential`. - # @param error_code [String, nil] Code of the error to simulate. # @param acs_credential_id [String, nil] ID of the `acs_credential` that will fail to be encoded onto a card in the next request. + # @param error_code [String, nil] Code of the error to simulate. # @return [nil] OK - def next_credential_encode_will_fail(acs_encoder_id:, error_code: nil, acs_credential_id: nil) - @client.post("/acs/encoders/simulate/next_credential_encode_will_fail", {acs_encoder_id: acs_encoder_id, error_code: error_code, acs_credential_id: acs_credential_id}.compact) + def next_credential_encode_will_fail(acs_encoder_id:, acs_credential_id: nil, error_code: nil) + @client.post("/acs/encoders/simulate/next_credential_encode_will_fail", {acs_encoder_id: acs_encoder_id, acs_credential_id: acs_credential_id, error_code: error_code}.compact) nil end @@ -31,11 +31,11 @@ def next_credential_encode_will_succeed(acs_encoder_id:, scenario: nil) # Simulates that the next attempt to scan a [credential](https://docs.seam.co/low-level-apis/access-systems/managing-credentials) using the specified [encoder](https://docs.seam.co/low-level-apis/access-systems/working-with-card-encoders-and-scanners) will fail. You can only perform this action within a [sandbox workspace](https://docs.seam.co/core-concepts/workspaces#sandbox-workspaces). # @param acs_encoder_id [String] ID of the `acs_encoder` that will fail to scan the `acs_credential` in the next request. - # @param error_code [String, nil] # @param acs_credential_id_on_seam [String, nil] + # @param error_code [String, nil] # @return [nil] OK - def next_credential_scan_will_fail(acs_encoder_id:, error_code: nil, acs_credential_id_on_seam: nil) - @client.post("/acs/encoders/simulate/next_credential_scan_will_fail", {acs_encoder_id: acs_encoder_id, error_code: error_code, acs_credential_id_on_seam: acs_credential_id_on_seam}.compact) + def next_credential_scan_will_fail(acs_encoder_id:, acs_credential_id_on_seam: nil, error_code: nil) + @client.post("/acs/encoders/simulate/next_credential_scan_will_fail", {acs_encoder_id: acs_encoder_id, acs_credential_id_on_seam: acs_credential_id_on_seam, error_code: error_code}.compact) nil end diff --git a/lib/seam/routes/customers.rb b/lib/seam/routes/customers.rb index 32c2e1a..0a37cec 100644 --- a/lib/seam/routes/customers.rb +++ b/lib/seam/routes/customers.rb @@ -9,6 +9,7 @@ def initialize(client:, defaults:) end # Creates a new customer portal magic link with configurable features. + # @param customer_data [Hash, nil] # @param customer_resources_filters [Array, nil] Filter configuration for resources based on their custom_metadata. Each filter specifies a field, operation, and value to match against resource custom_metadata. # @param customization_profile_id [String, nil] The ID of the customization profile to use for the portal. # @param deep_link [Hash, nil] Deep link target resource for initial redirect. When set, the portal will navigate directly to the specified resource. @@ -19,10 +20,9 @@ def initialize(client:, defaults:) # @param locale [String, nil] The locale to use for the portal. # @param navigation_mode [String, nil] Navigation mode for the portal. 'restricted' tells frontend to hide navigation UI, typically used for embedded deep links. # @param read_only [Boolean, nil] Whether the portal is read-only. When true, the customer can browse the portal but cannot perform any mutating action; write requests made with the portal's client session are rejected. - # @param customer_data [Hash, nil] # @return [Seam::Resources::CustomerPortal] OK - def create_portal(customer_resources_filters: nil, customization_profile_id: nil, deep_link: nil, exclude_locale_picker: nil, features: nil, is_embedded: nil, landing_page: nil, locale: nil, navigation_mode: nil, read_only: nil, customer_data: nil) - res = @client.post("/customers/create_portal", {customer_resources_filters: customer_resources_filters, customization_profile_id: customization_profile_id, deep_link: deep_link, exclude_locale_picker: exclude_locale_picker, features: features, is_embedded: is_embedded, landing_page: landing_page, locale: locale, navigation_mode: navigation_mode, read_only: read_only, customer_data: customer_data}.compact) + def create_portal(customer_data: nil, customer_resources_filters: nil, customization_profile_id: nil, deep_link: nil, exclude_locale_picker: nil, features: nil, is_embedded: nil, landing_page: nil, locale: nil, navigation_mode: nil, read_only: nil) + res = @client.post("/customers/create_portal", {customer_data: customer_data, customer_resources_filters: customer_resources_filters, customization_profile_id: customization_profile_id, deep_link: deep_link, exclude_locale_picker: exclude_locale_picker, features: features, is_embedded: is_embedded, landing_page: landing_page, locale: locale, navigation_mode: navigation_mode, read_only: read_only}.compact) Seam::Resources::CustomerPortal.load_from_response(res.body["customer_portal"]) end diff --git a/lib/seam/routes/noise_sensors_noise_thresholds.rb b/lib/seam/routes/noise_sensors_noise_thresholds.rb index b74ce5c..702f222 100644 --- a/lib/seam/routes/noise_sensors_noise_thresholds.rb +++ b/lib/seam/routes/noise_sensors_noise_thresholds.rb @@ -60,7 +60,7 @@ def list(device_id:) # @param starts_daily_at [String, nil] Time at which the noise threshold should become active daily. # @return [nil] OK def update(device_id:, noise_threshold_id:, ends_daily_at: nil, name: nil, noise_threshold_decibels: nil, noise_threshold_nrs: nil, starts_daily_at: nil) - @client.put("/noise_sensors/noise_thresholds/update", {device_id: device_id, noise_threshold_id: noise_threshold_id, ends_daily_at: ends_daily_at, name: name, noise_threshold_decibels: noise_threshold_decibels, noise_threshold_nrs: noise_threshold_nrs, starts_daily_at: starts_daily_at}.compact) + @client.patch("/noise_sensors/noise_thresholds/update", {device_id: device_id, noise_threshold_id: noise_threshold_id, ends_daily_at: ends_daily_at, name: name, noise_threshold_decibels: noise_threshold_decibels, noise_threshold_nrs: noise_threshold_nrs, starts_daily_at: starts_daily_at}.compact) nil end diff --git a/lib/seam/routes/user_identities.rb b/lib/seam/routes/user_identities.rb index 218aa0b..8fff70c 100644 --- a/lib/seam/routes/user_identities.rb +++ b/lib/seam/routes/user_identities.rb @@ -142,16 +142,16 @@ def list_acs_users(user_identity_id:) # # Identify the user identities either by ID or by key, but not both in the same request. Repeating a merge that has already been applied makes no further changes. # @param merged_user_identity_ids [Array, nil] IDs of the user identities to merge into the primary user identity. These user identities are deleted. - # @param user_identity_id [String, nil] ID of the primary user identity to keep. # @param merged_user_identity_keys [Array, nil] Keys of the user identities to merge into the primary user identity. These user identities are deleted. + # @param user_identity_id [String, nil] ID of the primary user identity to keep. # @param user_identity_key [String, nil] Key of the primary user identity to keep. # @return [nil] OK - def merge(merged_user_identity_ids: nil, user_identity_id: nil, merged_user_identity_keys: nil, user_identity_key: nil) - if merged_user_identity_ids.nil? && user_identity_id.nil? && merged_user_identity_keys.nil? && user_identity_key.nil? + def merge(merged_user_identity_ids: nil, merged_user_identity_keys: nil, user_identity_id: nil, user_identity_key: nil) + if merged_user_identity_ids.nil? && merged_user_identity_keys.nil? && user_identity_id.nil? && user_identity_key.nil? raise TypeError, "At least one parameter is required for /user_identities/merge" end - @client.post("/user_identities/merge", {merged_user_identity_ids: merged_user_identity_ids, user_identity_id: user_identity_id, merged_user_identity_keys: merged_user_identity_keys, user_identity_key: user_identity_key}.compact) + @client.post("/user_identities/merge", {merged_user_identity_ids: merged_user_identity_ids, merged_user_identity_keys: merged_user_identity_keys, user_identity_id: user_identity_id, user_identity_key: user_identity_key}.compact) nil end diff --git a/lib/seam/routes/workspaces.rb b/lib/seam/routes/workspaces.rb index b099d03..12c5f20 100644 --- a/lib/seam/routes/workspaces.rb +++ b/lib/seam/routes/workspaces.rb @@ -17,7 +17,7 @@ def initialize(client:, defaults:) # @param connect_partner_name [String, Seam::Null, nil] Connect partner name for the new workspace. # @param connect_webview_customization [Hash, nil] [Connect Webview](https://docs.seam.co/core-concepts/connect-webviews) customizations for the new workspace. See also [Customize the Look and Feel of Your Connect Webviews](https://docs.seam.co/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-look-and-feel-of-your-connect-webviews). # @param is_sandbox [Boolean, nil] Indicates whether the new workspace is a [sandbox workspace](https://docs.seam.co/core-concepts/workspaces#sandbox-workspaces). - # @param organization_id [String, nil] ID of the organization to associate with the new workspace. + # @param organization_id [String, nil] ID of the organization to associate with the new workspace. If omitted, the new workspace is associated with the organization that you administer, if you administer exactly one. # @param webview_logo_shape [String, nil] # @deprecated webview_logo_shape: Use `connect_webview_customization.webview_logo_shape` instead. # @param webview_primary_button_color [String, nil]