
-
Access Code Timeline in the Seam Console
- Today, we're excited to introduce the Access Code Timeline — a new side pane in the Seam Console that shows the full lifecycle of any access code at a glance. Open a device that supports access codes (
can_program_online_access_codesorcan_program_offline_access_codes), click any code, and a panel slides out with a chronological view of every programming event: creation, scheduled programming, set on the device, retries and delays, modifications, failures, deletion. -
Built for debugging
- Access code programming spans Seam, the manufacturer's backend API, and (often) the lock itself. When something goes sideways — a code didn't appear on the lock, a guest couldn't get in, a backup access code fired unexpectedly — the timeline answers what happened, when, and why without you having to stitch together logs, webhooks, and provider state.

-
Coming to more resources
- The timeline is the first piece of a broader pattern we're rolling out across the Seam Console — the same chronological detail pane will arrive for access grants, thermostat schedules, and other long-lived resources where lifecycle visibility matters.
- Have feedback, or other resources you'd like to see this pattern on? Email us at support@seam.co.
-
2026.05.04 Changelog
-
New
- API
- Spaces ↔ connected accounts: New endpoints
POST /spaces/add_connected_accountandPOST/DELETE /spaces/remove_connected_accountlet you scope a connected account to a specific space, and/connected_accounts/listaccepts aspace_idfilter. customer_dataon spaces: The Space resource now exposescustomer_datawithtime_zone,default_checkin_time, anddefault_checkout_time./spaces/createaccepts the field, and/spaces/updatepatches keys individually (passnullto clear).use_backup_access_code_poolon/access_codes/create_multiple: The bulk-create endpoint now honors the backup access code pool with the same constraints as/access_codes/create(time-bound only, supported providers only).requested_aton response errors: Error responses now include arequested_attimestamp, making it easier to correlate Seam errors with your logs and provider-side activity.- Inspect request error details: Every error response now includes a
request_error_id, and the corresponding error-detail page lives at a public URL (/public/request_error/<id>) so you can open it directly — and share it with Seam support — for richer context on a failed request. - Pagination on
/spaces/get_related: The endpoint now paginates results per resource type (capped at 50 per type), giving you cursor-based control over related-resource lookups and resolving query failures on workspaces with very large access-method counts.
- Spaces ↔ connected accounts: New endpoints
- Console
- Redesigned billing page and upgrade flow: The Console billing page has been redesigned, and the upgrade flow refreshed.
- Providers
- Dormakaba Ambiance mobile keys: Mobile key support is now wired up for Dormakaba Ambiance, including a new
can_issue_mobile_keys: truecapability flag and end-to-end issuance for mobile-key-only access grants. - Dormakaba Oracode — native time-bound codes: Oracode codes are now classified as native time-bound and program on creation. Codes scheduled up to a year in advance now report
creating(notdeferring_creation) and register with Dormakaba on the next sync, instead of waiting for a 1-hour pre-start window. - Brivo — PIN and mobile pass credentials: Credential discovery now includes PIN and mobile pass credentials in addition to cards. PINs map to
access_method: "code", mobile passes tocloud_key, and cards tocard. - Salto KS —
salto_ks_lock_access_code_support_removedwarning: When a Salto KS lock's device model changes from one that supports access codes to one that doesn't, the device now carries a clear warning with a link to the help-center article. The warning auto-clears if the lock model is restored.
- Dormakaba Ambiance mobile keys: Mobile key support is now wired up for Dormakaba Ambiance, including a new
- MCP
- DeviceDB now indexed in the public Seam MCP Docs Server: The hosted MCP at
mcp.seam.co/mcpnow indexes 400+ device models and full manufacturer / provider docs, plus per-device-type catalog chunks (sensors, smart locks, thermostats, etc.) — so questions like "which noise sensors does Seam support?" return the full inventory.
- DeviceDB now indexed in the public Seam MCP Docs Server: The hosted MCP at
-
Changed
- API
deletingpending mutation visible while a delete is in flight:/access_codes/deletenow writes adeletingentry topending_mutations_mapatomically withis_being_deleted = true, so/access_codes/getand the timeline reflect the in-flight delete until perm-delete completes.- Reason-aware error messages on access-code failures: When an access code fails because the device is offline, the connected account is disconnected, or the device has been removed, the
error_mapmessage onfailed_to_set_on_device/failed_to_remove_from_devicenow reflects the real cause instead of generic boilerplate. max_access_codes_reachedwarning fires from provider responses: Provider-reported "all PIN slots are full" errors now correctly raise themax_access_codes_reachedwarning on the device — previously the warning only fired from Seam's count-based pre-check.
- Providers
- Salto KS —
salto_ks_user_not_subscribedwarning surfaces on subscription-limit errors: When Salto returns the1101subscription-limit error, the affected access code now carriessalto_ks_user_not_subscribedinstead of being silently cleared. - ASSA ABLOY Visionline — provider error details preserved on card encoding 400s: The provider's
code,message, anddeveloperMessageare now surfaced in the credential'serror_mapinstead of being collapsed into a generic error.
- Salto KS —
-
Fixed
- API & access codes
- Pre-create updates clear pending mutations: Updating an access code before it's been programmed to the device now correctly clears
updating_code/updating_name/updating_time_frameonce the create succeeds. - Native time-bound codes outside the grace window report
deferring_creation: Far-future native time-bound codes (Schlage, Yale, August, Dormakaba) now reportdeferring_creationuntil inside the 72-hour grace window, instead of misleadingly reportingcreating.
- Pre-create updates clear pending mutations: Updating an access code before it's been programmed to the device now correctly clears
- Brivo
- Smarter disconnect handling: Brivo accounts no longer flip to
disconnectedon transient rate-limit responses, and theacs_system_disconnectedwarning clears once the account reconnects. Genuine refresh-token failures correctly disconnect the account and emitconnected_account.reauthorization_requestedso your app can prompt a reconnect. Note: we sent an advisory to all Brivo customers last week to reconnect their Brivo accounts so these changes take effect.
- Smarter disconnect handling: Brivo accounts no longer flip to
- Dormakaba Oracode
- Backup access code pool no longer accepted: Oracode PINs are derived algorithmically by the door firmware from the stay, so backup-pool semantics don't apply.
/access_codes/createwithuse_backup_access_code_pool: trueon Oracode now returns a 400, and/devices/getreportsproperties.supports_backup_access_code_pool: false.
- Backup access code pool no longer accepted: Oracode PINs are derived algorithmically by the door firmware from the stay, so backup-pool semantics don't apply.
- Salto
subscription_limit_almost_reachedwarning now clears correctly when the user count drops back below 80% utilization.- Self-heal access codes mid-create: Codes whose subscribe step failed after the user was created now self-heal on the next sync instead of staying stuck.
- Robust handling of access-group changes: ACS sync no longer crashes when an access group is deleted between the list and the read, and the access-group lifecycle is more resilient when the upstream API fails partially.
- Empty-sites accounts no longer hit Salto in a tight loop: Connected accounts where all sites have been removed no longer make repeating 401 calls to Salto.
- Schlage
- Recover already-created codes on duplicate-code errors: When Schlage reports
AccessCodeAlreadyInUse, Seam matches the existing code on the lock by PIN and binds the local row to it, eliminating a large class ofduplicate_code_on_deviceerrors. - Skip push when the device or account is disconnected: Push attempts now short-circuit on both device-level and account-level disconnection, so Seam stops calling Schlage with stale tokens for orphaned codes.
- Native time-bound codes respect IANA timezones: Timezone strings (
America/New_York, etc.) reported via/devices/report_provider_metadataare now resolved correctly, fixing native time-bound codes that were being shifted by the UTC offset on locks withlocation.timezoneset.
- Recover already-created codes on duplicate-code errors: When Schlage reports
- ASSA ABLOY Visionline
- Drop invalid joiner cards before encoding: Mobile-key requests now strip joiner cards Visionline can't accept (overridden, cancelled, discarded, expired, unknown) before sending — eliminating a class of stuck mobile keys with
illegal_card_in_joinerserrors. - Card and mobile key starts align for dual-access reservations: Dual-access reservations (card + mobile key) no longer fail when the front desk encodes the card after
starts_at; both credentials now align on a starts-no-earlier-than-now timestamp.
- Drop invalid joiner cards before encoding: Mobile-key requests now strip joiner cards Visionline can't accept (overridden, cancelled, discarded, expired, unknown) before sending — eliminating a class of stuck mobile keys with
- SmartThings
- No more false external-deletion on Schlage-via-SmartThings: Schlage locks behind SmartThings sometimes return an empty
lockCodesattribute right after asetCode/deleteCode. Seam no longer treats that signal as an external deletion.
- No more false external-deletion on Schlage-via-SmartThings: Schlage locks behind SmartThings sometimes return an empty
- August / Yale Home
- Webhooks with non-UUID
partnerUserIDignored: August webhooks carrying a non-UUIDpartnerUserIDno longer enter the matching flow. - PIN operations track end-to-end so webhooks resolve correctly: Pre-confirming deletes was masking real failures; deletes now wait for the actual
partnerUserID, and pin operations are tracked through their lifecycle so webhooks reliably resolve to the correct access code. - Managed access codes no longer adopt external partner PINs: A legacy August path could have a managed access code adopt an external partner's PIN, leaving the managed code stuck unset. Adoption is now blocked when the existing August user belongs to a different partner. Yale Home
/pinsdeletion is similarly gated on the partner-user link existing.
- Webhooks with non-UUID
- Nuki
- No disconnect on proactive token refresh failure: A failure during proactive token refresh no longer flips the account to
disconnected. - Device ownership preserved for shared Nuki Web locks: Devices shared via Nuki Web no longer get reassigned away from their owning account during sync.
- No disconnect on proactive token refresh failure: A failure during proactive token refresh no longer flips the account to
- Akiles
- No false low-battery events on mains-powered devices: AC-powered Akiles devices no longer emit false
device.low_batteryevents. Battery level is now only computed when the device is actually battery-powered.
- No false low-battery events on mains-powered devices: AC-powered Akiles devices no longer emit false
- Lockly
- Manual thumbturn lock/unlock events now surface: Manual thumbturn events were being dropped on negative-UTC devices and by case-sensitive event mapping. Both are fixed; manual thumbturn now reliably emits
lock.locked/lock.unlocked.
- Manual thumbturn lock/unlock events now surface: Manual thumbturn events were being dropped on negative-UTC devices and by case-sensitive event mapping. Both are fixed; manual thumbturn now reliably emits
- ControlByWeb
- No more online/offline flap from competing pollers: A second poller was overwriting the authoritative connection state, producing spurious
device.disconnected→device.connectedevent pairs every ~10 minutes. The device-level poll no longer writes online state.
- No more online/offline flap from competing pollers: A second poller was overwriting the authoritative connection state, producing spurious