Guides/How to connect a smart lock to your app

How to connect a smart lock to your app

Seam connects smart locks from dozens of brands to your app through one API. Your user links their existing lock account in an embedded flow, and their locks show up as devices you can control, with no brand-specific integration work.
Quickstart

Connect a lock in 60 seconds

Connecting hardware is one call and one redirect. You never see the user's lock credentials, and you never write brand-specific login code.
1# 1. Create a Connect Webview. The response includes a url for your user.
2curl -X POST "https://connect.getseam.com/connect_webviews/create" \
3  -H "Authorization: Bearer $SEAM_API_KEY" \
4  -H "Content-Type: application/json" \
5  -d '{
6    "accepted_providers": ["schlage", "yale", "august", "smartthings"],
7    "custom_redirect_url": "https://example.com/locks/connected"
8  }'
9
10# 2. Open the url from the response in an iframe or a new window. Your user
11#    logs in to their lock account there; the credentials never reach you.
12
13# 3. After the redirect, confirm the connection succeeded.
14curl -X POST "https://connect.getseam.com/connect_webviews/get" \
15  -H "Authorization: Bearer $SEAM_API_KEY" \
16  -H "Content-Type: application/json" \
17  -d '{ "connect_webview_id": "c4c30885-ec87-4b31-8d7b-9bc0678fa028" }'
Fastest path

Build it with your AI agent

Install the Seam plugin and your coding agent picks up three integration skills: Reservation Automations, Access Grants and Access Codes. It then writes the calls the way we would. Paste the prompt below and let it build.
  • Reservation AutomationsPush reservations to Seam and let it manage codes across the booking lifecycle.
  • Access GrantsPer-entrance, per-credential access: PIN codes, mobile keys and Instant Keys.
  • Access CodesDirect, manual control of individual time-bound codes on a specific device.

1. Install the plugin

/plugin marketplace add seamapi/seam-plugin
/plugin install seam@seamapi

The Claude Code install also adds our documentation MCP server, so the agent can look up endpoints and device capabilities while it works. Cursor, Codex and other agents get the skills through npx skills add and can add the MCP server there separately.

2. Paste this prompt

Add smart lock connection to my app with Seam.

Build the flow in three parts:
1. A backend endpoint that calls /connect_webviews/create with accepted_providers for the brands we support and a custom_redirect_url back into our app, then returns the webview url to the client.
2. A frontend page that opens that url and, after the redirect, calls the backend to verify the webview with /connect_webviews/get: treat login_successful true as connected, anything else as a retry.
3. A sync step that lists the connected account's devices with /devices/list, stores device_id, display_name and the capability flags we care about, and re-runs when we get device lifecycle events.

Use a sandbox workspace and its virtual devices for the tests, keep the API key server-side only, and follow my existing routing and error-handling conventions.
Use cases

What you can build

  • Onboarding that survives brand variety

    Property managers show up with August in one building and Schlage in the next. One webview handles every brand's login, multifactor prompts and error states, so onboarding is the same flow no matter what is on the door.

  • A device list that stays current

    Once an account is connected, locks added to it later flow into Seam without another login. Your sync job lists devices and picks up the new hardware.

  • Capability-aware UI

    Every device carries capability flags, so your app can show a PIN pad only for locks that take codes and a remote unlock button only where it will work. No brand matrix to maintain by hand.

Walkthrough

How it works

  1. Install the SDK and export your API key

    Create a workspace in Seam Console, generate an API key under Developer > API Keys, and export it as SEAM_API_KEY. Start in a sandbox workspace: it comes with virtual locks, so you can run this whole flow before touching real hardware.

    1npm i seam
    2
    3# The SDK picks this up automatically.
    4export SEAM_API_KEY=seam_test_your_sandbox_api_key
  2. Create a Connect Webview

    One call from your backend. accepted_providers narrows the brand list to what your product supports; leaving it off shows every stable brand. The response carries a url for your user and a connect_webview_id you keep, because the id is how you find out what happened after they finish.

    1const connectWebview = await seam.connectWebviews.create({
    2  // Only the brands your product supports. Omit this to show all stable brands.
    3  accepted_providers: ["schlage", "yale", "august", "smartthings"],
    4  // Where the webview sends the user when they finish.
    5  custom_redirect_url: "https://example.com/locks/connected",
    6})
    7
    8// Store the id so you can verify the outcome after the redirect.
    9console.log(connectWebview.connect_webview_id)
    10console.log(connectWebview.url)
  3. Open the url and let your user log in

    Open the url in an iframe or a new window. Your user picks their brand and signs in with their own account. Seam runs the credential validation and any multifactor step, and sends them to your custom_redirect_url when the connection is made. Their password never passes through your servers, which keeps that login out of your security scope.

  4. Verify the connection and list the devices

    Fetch the webview by id. status authorized with login_successful true means the account is connected, and connected_account_id scopes a device list to exactly what this user linked. Read the capability flags off each device before you offer actions in your UI: a lock that cannot take codes should never show a PIN screen.

    1const finished = await seam.connectWebviews.get({
    2  connect_webview_id: storedConnectWebviewId,
    3})
    4
    5// "authorized" and login_successful arrive together when the user completes
    6// the flow. Anything else means they closed it or the login failed.
    7if (finished.status === "authorized" && finished.login_successful) {
    8  console.log(finished.connected_account_id)
    9}
  5. React to new hardware over time

    Accounts change after onboarding: locks get added, batteries die, someone renames the front door. Re-list devices on a schedule or subscribe to device lifecycle events with a webhook, and treat the device list as state you sync instead of a one-time import.

    1const devices = await seam.devices.list({
    2  connected_account_id: finished.connected_account_id,
    3})
    4
    5// Capability flags tell you what each lock can do before you offer it in
    6// your UI. true works today, false means blocked right now, absent means
    7// the model never does it.
    8for (const device of devices) {
    9  console.log(
    10    device.display_name,
    11    device.can_remotely_unlock,
    12    device.can_program_online_access_codes,
    13  )
    14}
FAQ

Frequently asked questions

Do my users need a Seam account?

No. They log in with their existing lock account, the one from the lock's own app. Seam sits between your app and the brand's cloud; your users never see Seam.

Which smart lock brands can my users connect?

Dozens, including August, Yale, Schlage, Kwikset, TTLock, Nuki, Tedee and igloohome, plus access control systems like Salto and Brivo. The supported devices page lists every model, and accepted_providers controls which ones your webview offers.

Should I open the webview in an iframe or a new window?

Both work across modern browsers. An iframe keeps the user in your flow and suits onboarding wizards; a new window is simpler when your app is mobile web. Either way, the custom_redirect_url brings the user back when they finish.

What happens when my user adds a lock to their account later?

New devices on a connected account flow into Seam without another webview. List devices again, or subscribe to device events, and the new lock is there with its capability flags set.

How do I test this without buying a lock?

Sandbox workspaces come with virtual devices for every major brand. The webview flow, the device list and the capability flags all behave like production, so you can build the whole feature before hardware arrives.

What do I store on my side?

The connect_webview_id while the flow is in progress, then the connected_account_id and the device_ids you care about. Keep the API key server-side; the webview url is the only thing the browser needs.

Pricing
Ready to Scale With You
Seam lets developers and businesses connect apps to real-world IoT devices. The free trial is built for small teams to build and test, while enterprise pricing scales with the biggest device fleets out there.
Best Enterprise Solution
Custom Subscription for Your Business
Access tailored solutions, paying a fixed monthly rate that scales as you grow.
Enhanced Security
Beta Features Access
Dedicated Support Channel
Volume Discounts
No Usage Limits
Trusted by Over 1,000 Companies
Start Now
Try It for Free
Start with a free trial and explore the full API and related features.
Have questions? Talk to our team.
Chat with us to learn how Seam can power your access automation.
—“Discovering Seam was one of these Aha moments in the business. I couldn’t believe what I was seeing. I mean, it was exactly what we were looking for: a simple API that we could integrate and have access to all these devices in a matter of seconds.
François Gouelo
CEO, Enso Connect
Company
How many devices you need to connect?
Name
Email
How did you find us?
Comment
We usually answer within 24 hours.
One API for All Devices
Global Infrastructure for Controlling the Physical World
Seam makes controlling IoT devices seamless and programmable. Our teams operate globally,
enabling businesses of all sizes.
Smart Locks
Access Systems
Knowledge
Lock Capabilities
Thermostats
Sensors
© 2026 Seam Labs, Inc.