Seam is a simple API to connect and control almost any smartlocks. Seam already integrates popular smartlock brands such as August, Yale, Schlage, Igloo, and Kwikset, as well as lesser known ones like Nuki, Wyze, or TTLock.
The main benefit of Seam is that you can connect devices from these brands and control them with an easy to use API without having to worry about the underlying specific of each devices. Seam abstracts functions in capabilities such as access_codes or locks which you can use to integrate devices from multiple brands while expecting them to all behave more or less in the same way.
This guide is intended to show you how to connect and control smartlocks. To learn more about all devices supported by Seam such as thermostats and sensors, head over to our integration page.
Let's get started.
1 — Install Seam SDK
Seam provides client libraries for many languages, such as JavaScript, Python, Ruby, PHP, and others, as well as a Postman collection and OpenAPI spec.
This guide uses a Sandbox Workspace. Only virtual devices can be connected. If you need to connect a real device, use a non-sandbox workspace and API key.
2 — Link Your Smartlock Account with Seam
To control a smartlock via the Seam API, we need to first connect to your smartlock account and authorize your Seam workspace to control its device(s). To make this easy, Seam provides Connect Webviews authorization flows that walk you (or a device owner) through authorizing your workspace to control your device.
Request a Connect Webview
To start, we will create a Connect Webview and pass "stable" as the provider_category. This will ensure that only stable integrations are being presented.
from seam import Seamseam =Seam()webview = seam.connect_webviews.create(provider_category="stable")assert webview.login_successful isFalse# Send the webview URL to your userprint(webview.url)
import { Seam } from'seam'constseam=newSeam()constconnectWebview=awaitseam.connectWebviews.create({ provider_category:'stable',})console.log(connectWebview.login_successful) // false// Send the webview URL to your userconsole.log(connectWebview.url)
require"seam"seam =Seam.new(api_key: "MY_API_KEY")webview = seam.connect_webviews.create( provider_category: "stable")puts webview.login_successful # false# Send the webview URL to your userputs webview.url
Using a browser, navigate to the URL returned by the Connect Webview object. If you are in a sandbox workspace, you can select Yale as the provider and use the test login below to complete the process. If you have a non-sandbox workspace and a real device, simply use your account credentials.
Yale Test credentials:
email: jane@example.com
password: 1234
Confirm the Connect Webview was successful by querying its status:
After an account is linked with Seam, you can retrieve devices for this linked account. The Seam API exposes most of the device's properties such as battery level or door lock status.
useSeam\SeamClient;$seam =newSeamClient('YOUR_API_KEY');$some_lock = $seam->locks->list()[0];# unlock the door$seam->locks->unlock_door($lock->device_id);# lock the door$seam->locks->lock_door($lock->device_id);
5 — Setting Access Code
Many smartlocks have a built-in keypad or an external one that can be paired over bluetooth. This lets you program access codes that a user can then enter at a later time to unlock a door.
The Seam API makes it easy to program both ongoing codes and timebound codes on a smartlock. An ongoing code is a code that will be permanently programmed onto the device until you tell the Seam API you wish to remove it. A timebound code is, as the time implies, time bound by a set of ISO8601 timestamp that you provide the Seam API. You can find out more about access code in our core concept section on access codes.
# create an ongoing codeseam.access_codes.create( device=some_lock, code="123456", name="My Access Code")# create a timebound codeseam.access_codes.create( device=some_lock, code="888888", name="Scheduled Code", starts_at="2028-08-12T19:23:42+0000", ends_at="2028-08-13T19:23:42+0000")# you can use a device or a device_id as the "device" parameterseam.access_codes.list(device=some_lock)# [# AccessCode(# access_code_id='af5272b1-2a49-4eb5-9388-2447fc7b5bd1',# type='ongoing',# code='123459'# ),# AccessCode(# access_code_id='8c2db4da-b137-4c08-a2c3-d611e6ff91b3',# type='timebound',# code='888888',# starts_at='2028-08-12T19:24:00.000Z',# ends_at='2028-08-13T19:24:00.000Z',# )# ]
// create an ongoing codeawaitseam.accessCodes.create({ device_id:someLock.device_id, code:'123456', name:'My Access Code',})// create a timebound codeawaitseam.accessCodes.create({ device_id:someLock.device_id, code:'888888', name:'Scheduled Code', starts_at:'2028-11-12T19:23:42+0000', ends_at:'2028-11-13T19:23:42+0000',})// use a device_id as the "device_id" parameterawaitseam.accessCodes.list({ device_id:someLock.device_id,})/*[ { code: '1988', type: 'ongoing', status: 'setting', created_at: '2022-08-26T12:50:17.858Z', access_code_id: '26d6138c-6524-4f3c-ac96-43cc3bea0a8d' }, { type: 'timebound', code: '888888', starts_at: '2028-08-12T19:24:00.000Z', ends_at: '2028-08-13T19:24:00.000Z', access_code_id: '8c2db4da-b137-4c08-a2c3-d611e6ff91b3', }]*/
Now that you've completed this guide, you can try to build a real application to connect and control a device. Don't hesitate to reach out to our team if we can help with anything, or explore other aspects of Seam, here is a list of helpful resources: