diff --git a/mintlify-codegen/errors.ts b/mintlify-codegen/errors.ts index 80d1271c9..c38d649dd 100644 --- a/mintlify-codegen/errors.ts +++ b/mintlify-codegen/errors.ts @@ -4,6 +4,7 @@ import { join } from 'node:path' import type { Blueprint, DiscriminatedListProperty } from '@seamapi/blueprint' +import type { PathMetadata } from './load-data.js' import { formatType, indent, sampleValue } from './property-fields.js' /** @@ -347,38 +348,35 @@ async function writeErrorPage( routes.push(routePath) } -// Some device sub-categories have their own docs route but no blueprint -// resource of their own — the Seam API models a lock, thermostat, or phone as a -// `device`. Their error/warning codes therefore live on the `device` resource -// under a variant group of the same key rather than on a resource of their own, -// so the per-resource loop never produces a page for them. This maps each such -// variant group to the route that should carry its dedicated page. -// -// The map is an explicit allowlist, not `'/' + groupKey`: groups like -// `access_codes`, `hardware`, and `provider_metadata` annotate the device page -// but have no standalone sub-category route. In particular /access_codes -// already documents the `access_code` resource's own, distinct errors — routing -// the device `access_codes` group there would clobber it. -const DEVICE_SUBCATEGORY_ERROR_ROUTES: Record = { - locks: '/locks', - phones: '/phones', - thermostats: '/thermostats', -} +// Route that surfaces the `phones` device variant group. A phone is documented +// as its own resource (`/phones`), but that resource has no error/warning codes +// of its own — the one phone code (`unknown_issue_with_phone`) lives on the +// `device` resource under the `phones` group. Unlike locks/thermostats it has no +// `include_groups` filter in paths.yaml, so it surfaces only that group's codes. +const PHONES_ROUTE_PATH = '/phones' /** - * Narrow a device `errors`/`warnings` property to a single variant group, - * flattening the kept variants to ungrouped (`variantGroupKey` cleared) so their - * codes render as top-level entries — a group heading would be redundant on a - * page already scoped to that sub-category. Returns undefined when the property - * is absent or the group has no variants, so the caller emits nothing. + * Filter a discriminated `errors`/`warnings` property to a subset of variant + * groups, flattening the kept variants into a single ungrouped, code-sorted + * list. Keeps the variants whose group is in `groups`, plus the universal + * (ungrouped) codes when `includeUngrouped` is set. This mirrors the GitBook API + * reference, which renders an `include_groups`-filtered view as one flat list + * rather than with per-group headings. Returns undefined when nothing matches, + * so the caller emits nothing. */ -function variantGroupProp( +function filterVariantGroups( prop: Property | undefined, - groupKey: string, + groups: readonly string[], + includeUngrouped: boolean, ): (Property & DiscriminatedListProperty) | undefined { if (!isDiscriminatedListProperty(prop)) return undefined + const keep = new Set(groups) const variants = prop.variants - .filter((v) => v.variantGroupKey === groupKey) + .filter((v) => + v.variantGroupKey == null + ? includeUngrouped + : keep.has(v.variantGroupKey), + ) .map((v) => ({ ...v, variantGroupKey: null })) if (variants.length === 0) return undefined return { ...prop, variants, variantGroups: [] } @@ -392,38 +390,64 @@ function variantGroupProp( export async function updateErrorPages( blueprint: Blueprint, docsDir: string, + pathMetadata: PathMetadata, ): Promise { const routes: string[] = [] for (const resource of blueprint.resources) { if (resource.isUndocumented) continue + // Honor an `include_groups` filter from paths.yaml (e.g. /access_codes lists + // only its `locks` and `access_codes` groups, dropping a stray `thermostats` + // code): keep the universal (ungrouped) codes plus the listed groups, + // flattened — matching the GitBook API reference. Resources without a filter + // keep every group and its subheading. + const include = pathMetadata[resource.routePath]?.include_groups + const pick = (name: string): Property | undefined => { + const prop = resource.properties.find((p) => p.name === name) + return include == null ? prop : filterVariantGroups(prop, include, true) + } await writeErrorPage( docsDir, resource.routePath, - resource.properties.find((p) => p.name === 'errors'), - resource.properties.find((p) => p.name === 'warnings'), + pick('errors'), + pick('warnings'), routes, ) } - // Pages for device sub-categories (locks, thermostats, …) that have their own - // docs route but no resource of their own: source each from the matching - // variant group on the device resource. + // Device sub-category pages. Locks and thermostats have their own docs route + // but no resource of their own (the Seam API models them as `device`s), so the + // per-resource loop never reaches them. Source their codes from the device + // resource, filtered the same way: + // - Routes that document `device` under an `include_groups` filter + // (thermostats, locks — see paths.yaml) show the universal device codes + // plus the listed groups. + // - Phones has no `include_groups` filter upstream and is a distinct concept + // from a lock/thermostat device, so it surfaces only its own group's code. const device = blueprint.resources.find((r) => r.resourceType === 'device') if (device != null) { const errorsProp = device.properties.find((p) => p.name === 'errors') const warningsProp = device.properties.find((p) => p.name === 'warnings') - for (const [groupKey, routePath] of Object.entries( - DEVICE_SUBCATEGORY_ERROR_ROUTES, - )) { + + for (const [routePath, meta] of Object.entries(pathMetadata)) { + if (!meta.resources?.includes('device')) continue + if (meta.include_groups == null) continue await writeErrorPage( docsDir, routePath, - variantGroupProp(errorsProp, groupKey), - variantGroupProp(warningsProp, groupKey), + filterVariantGroups(errorsProp, meta.include_groups, true), + filterVariantGroups(warningsProp, meta.include_groups, true), routes, ) } + + await writeErrorPage( + docsDir, + PHONES_ROUTE_PATH, + filterVariantGroups(errorsProp, ['phones'], false), + filterVariantGroups(warningsProp, ['phones'], false), + routes, + ) } return routes diff --git a/mintlify-codegen/generate.ts b/mintlify-codegen/generate.ts index 23901fbdf..7a323f7d5 100644 --- a/mintlify-codegen/generate.ts +++ b/mintlify-codegen/generate.ts @@ -97,7 +97,7 @@ await insertEventsPagesIntoNav(updatedEvents) // rewritten. Nav wiring runs after events so the sidebar reads // object -> events -> errors. console.log('Updating error and warning documentation...') -const updatedErrors = await updateErrorPages(blueprint, outputDir) +const updatedErrors = await updateErrorPages(blueprint, outputDir, pathMetadata) if (updatedErrors.length > 0) { console.log( ` Generated errors pages for ${updatedErrors.length} resources: ${updatedErrors.join(', ')}`, diff --git a/mintlify-codegen/load-data.ts b/mintlify-codegen/load-data.ts index 5fe2868e9..81ce504a1 100644 --- a/mintlify-codegen/load-data.ts +++ b/mintlify-codegen/load-data.ts @@ -16,6 +16,12 @@ interface PathMetadataEntry { description?: string overview?: string alpha?: string + // Resources this route documents (e.g. `device` for /thermostats and /locks, + // which have no resource of their own). + resources?: string[] + // Error/warning variant groups to surface on this route. When set, a filtered + // view shows the universal (ungrouped) codes plus only these groups. + include_groups?: string[] } export type PathMetadata = Record diff --git a/mintlify-docs/api/access_codes/errors.mdx b/mintlify-docs/api/access_codes/errors.mdx index 4b1505154..627d25ca9 100644 --- a/mintlify-docs/api/access_codes/errors.mdx +++ b/mintlify-docs/api/access_codes/errors.mdx @@ -84,6 +84,18 @@ Indicates that the account is disconnected. --- +### `august_lock_missing_bridge` + +Indicates that the lock is not connected to a bridge. + +--- + +### `august_lock_not_authorized` + +Indicates that the user is not authorized to use the August lock. + +--- + ### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](https://docs.seam.co/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](https://docs.seam.co/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system.errors.seam_bridge_disconnected). @@ -132,6 +144,12 @@ Duplicate access code detected on device. --- +### `empty_backup_access_code_pool` + +Indicates that the [backup access code pool](https://docs.seam.co/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. + +--- + ### `failed_to_remove_from_device` Failed to remove code from device. @@ -186,6 +204,12 @@ This access code was overridden on the device by a newer access code programmed --- +### `salto_ks_subscription_limit_exceeded` + +Indicates that the Salto site user limit has been reached. + +--- + ### `salto_ks_user_not_subscribed` Salto site user is not subscribed. @@ -204,42 +228,6 @@ Indicates that the lock is not paired with a gateway. --- -### Access Codes - -#### `empty_backup_access_code_pool` - -Indicates that the [backup access code pool](https://docs.seam.co/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. - ---- - -### Locks - -#### `august_lock_missing_bridge` - -Indicates that the lock is not connected to a bridge. - ---- - -#### `august_lock_not_authorized` - -Indicates that the user is not authorized to use the August lock. - ---- - -#### `salto_ks_subscription_limit_exceeded` - -Indicates that the Salto site user limit has been reached. - ---- - -### Thermostats - -#### `auxiliary_heat_running` - -Indicates that the auxiliary heat is running. - ---- - ## Warnings Each warning is an object with the following shape: diff --git a/mintlify-docs/api/access_codes/unmanaged/errors.mdx b/mintlify-docs/api/access_codes/unmanaged/errors.mdx index 1208914b2..10a29fe6f 100644 --- a/mintlify-docs/api/access_codes/unmanaged/errors.mdx +++ b/mintlify-docs/api/access_codes/unmanaged/errors.mdx @@ -84,6 +84,18 @@ Indicates that the account is disconnected. --- +### `august_lock_missing_bridge` + +Indicates that the lock is not connected to a bridge. + +--- + +### `august_lock_not_authorized` + +Indicates that the user is not authorized to use the August lock. + +--- + ### `bridge_disconnected` Indicates that the Seam API cannot communicate with [Seam Bridge](https://docs.seam.co/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](https://docs.seam.co/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system.errors.seam_bridge_disconnected). @@ -132,6 +144,12 @@ Duplicate access code detected on device. --- +### `empty_backup_access_code_pool` + +Indicates that the [backup access code pool](https://docs.seam.co/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. + +--- + ### `failed_to_remove_from_device` Failed to remove code from device. @@ -186,6 +204,12 @@ This access code was overridden on the device by a newer access code programmed --- +### `salto_ks_subscription_limit_exceeded` + +Indicates that the Salto site user limit has been reached. + +--- + ### `salto_ks_user_not_subscribed` Salto site user is not subscribed. @@ -204,42 +228,6 @@ Indicates that the lock is not paired with a gateway. --- -### Access Codes - -#### `empty_backup_access_code_pool` - -Indicates that the [backup access code pool](https://docs.seam.co/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. - ---- - -### Locks - -#### `august_lock_missing_bridge` - -Indicates that the lock is not connected to a bridge. - ---- - -#### `august_lock_not_authorized` - -Indicates that the user is not authorized to use the August lock. - ---- - -#### `salto_ks_subscription_limit_exceeded` - -Indicates that the Salto site user limit has been reached. - ---- - -### Thermostats - -#### `auxiliary_heat_running` - -Indicates that the auxiliary heat is running. - ---- - ## Warnings Each warning is an object with the following shape: diff --git a/mintlify-docs/api/locks/errors.mdx b/mintlify-docs/api/locks/errors.mdx index 3ab463a6f..428246fc6 100644 --- a/mintlify-docs/api/locks/errors.mdx +++ b/mintlify-docs/api/locks/errors.mdx @@ -9,8 +9,8 @@ Each error is an object with the following shape: ```json Example error { - "error_code": "salto_ks_subscription_limit_exceeded", - "message": "Indicates that the Salto site user limit has been reached.", + "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 @@ -33,6 +33,10 @@ Each error is an object with the following shape: Date and time at which Seam created the error. + + Indicates whether the error is related to [Seam Bridge](https://docs.seam.co/capability-guides/seam-bridge). + + Indicates that the error is a [connected account](https://docs.seam.co/api/connected_accounts/object) error. @@ -43,6 +47,12 @@ Each error is an object with the following shape: +### `account_disconnected` + +Indicates that the account is disconnected. + +--- + ### `august_lock_missing_bridge` Indicates that the lock is not connected to a bridge. @@ -55,20 +65,86 @@ Indicates that the user is not authorized to use the August lock. --- +### `bridge_disconnected` + +Indicates that the Seam API cannot communicate with [Seam Bridge](https://docs.seam.co/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](https://docs.seam.co/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system.errors.seam_bridge_disconnected). + +--- + +### `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. + +--- + +### `dormakaba_sites_disconnected` + +Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. + +--- + +### `empty_backup_access_code_pool` + +Indicates that the [backup access code pool](https://docs.seam.co/low-level-apis/smart-locks/access-codes/backup-access-codes) is empty. + +--- + +### `hub_disconnected` + +Indicates that the hub is disconnected. + +--- + +### `lockly_missing_wifi_bridge` + +Indicates that the Lockly lock is not connected to a Wi-Fi bridge. + +--- + +### `missing_device_credentials` + +Indicates that device credentials are missing. + +--- + ### `salto_ks_subscription_limit_exceeded` Indicates that the Salto site user limit has been reached. --- +### `subscription_required` + +Indicates that a subscription is required to connect. + +--- + +### `ttlock_lock_not_paired_to_gateway` + +Indicates that the lock is not paired with a gateway. + +--- + ## Warnings Each warning is an object with the following shape: ```json Example warning { - "warning_code": "ttlock_lock_gateway_unlocking_not_enabled", - "message": "Indicates that the Remote Unlock feature is not enabled in the settings.\"", + "warning_code": "partial_backup_access_code_pool", + "message": "Indicates that the backup access code is unhealthy.", "created_at": "2025-01-01T00:00:00.000Z" } ``` @@ -89,6 +165,14 @@ Each warning is an object with the following shape: 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. + + ### `accessory_keypad_setup_required` @@ -97,6 +181,18 @@ Indicates that the accessory keypad exists, but is not linked to the Igloohome B --- +### `device_communication_degraded` + +Indicates that the device appears to be unresponsive. + +--- + +### `device_has_flaky_connection` + +Indicates that the device has a flaky connection. + +--- + ### `hub_required_for_additional_capabilities` Indicates that a hub or relay must be connected to unlock additional capabilities such as remote unlock. @@ -115,20 +211,110 @@ 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. + +--- + +### `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. + +--- + ### `power_saving_mode` Indicates that the device is in power saving mode and may have limited functionality. --- +### `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 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. + +--- + +### `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 a scheduled maintenance window has been detected. + +--- + +### `third_party_integration_detected` + +Indicates that a third-party integration has been detected. + +--- + ### `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. --- + +### `wyze_device_missing_gateway` + +Indicates that the Wyze Lock is not connected to a gateway. + +--- diff --git a/mintlify-docs/api/thermostats/errors.mdx b/mintlify-docs/api/thermostats/errors.mdx index 6d6e9357f..4be1fce3c 100644 --- a/mintlify-docs/api/thermostats/errors.mdx +++ b/mintlify-docs/api/thermostats/errors.mdx @@ -9,9 +9,10 @@ Each error is an object with the following shape: ```json Example error { - "error_code": "auxiliary_heat_running", - "message": "Indicates that the auxiliary heat is running.", + "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 } ``` @@ -32,26 +33,100 @@ Each error is an object with the following shape: Date and time at which Seam created the error. + + Indicates whether the error is related to [Seam Bridge](https://docs.seam.co/capability-guides/seam-bridge). + + + + Indicates that the error is a [connected account](https://docs.seam.co/api/connected_accounts/object) error. + + - Indicates that the error is a device error. + Indicates that the error is not a device error. +### `account_disconnected` + +Indicates that the account is disconnected. + +--- + ### `auxiliary_heat_running` Indicates that the auxiliary heat is running. --- +### `bridge_disconnected` + +Indicates that the Seam API cannot communicate with [Seam Bridge](https://docs.seam.co/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](https://docs.seam.co/low-level-apis/access-systems/troubleshooting-your-access-control-system#acs_system.errors.seam_bridge_disconnected). + +--- + +### `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. + +--- + +### `dormakaba_sites_disconnected` + +Indicates that one or more dormakaba sites associated with the connected account could not be connected. Contact dormakaba support. + +--- + +### `hub_disconnected` + +Indicates that the hub is disconnected. + +--- + +### `lockly_missing_wifi_bridge` + +Indicates that the Lockly lock is not connected to a Wi-Fi bridge. + +--- + +### `missing_device_credentials` + +Indicates that device credentials are missing. + +--- + +### `subscription_required` + +Indicates that a subscription is required to connect. + +--- + +### `ttlock_lock_not_paired_to_gateway` + +Indicates that the lock is not paired with a gateway. + +--- + ## Warnings Each warning is an object with the following shape: ```json Example warning { - "warning_code": "temperature_threshold_exceeded", - "message": "Indicates that the temperature threshold has been exceeded.", + "warning_code": "wyze_device_missing_gateway", + "message": "Indicates that the Wyze Lock is not connected to a gateway.", "created_at": "2025-01-01T00:00:00.000Z" } ``` @@ -74,8 +149,68 @@ Each warning is an object with the following shape: +### `device_communication_degraded` + +Indicates that the device appears to be unresponsive. + +--- + +### `device_has_flaky_connection` + +Indicates that the device has a flaky connection. + +--- + +### `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. + +--- + +### `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 a scheduled maintenance window has been detected. + +--- + ### `temperature_threshold_exceeded` Indicates that the temperature threshold has been exceeded. --- + +### `third_party_integration_detected` + +Indicates that a third-party integration has been detected. + +--- + +### `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. + +--- + +### `wyze_device_missing_gateway` + +Indicates that the Wyze Lock is not connected to a gateway. + +---