How to add mobile keys to your app
Issue a mobile key in 60 seconds
1# A one-month membership starting now. In your app this comes from the plan.
2STARTS_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
3ENDS_AT=$(date -u -v+30d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '+30 days' +%Y-%m-%dT%H:%M:%SZ)
4
5# 1. Grant a mobile key on the entrances the member can use.
6curl -X POST "https://connect.getseam.com/access_grants/create" \
7 -H "Authorization: Bearer $SEAM_API_KEY" \
8 -H "Content-Type: application/json" \
9 -d '{
10 "user_identity": {
11 "full_name": "Jane Doe",
12 "email_address": "jane@example.com"
13 },
14 "acs_entrance_ids": ["f74e4879-5991-4e2f-a368-888983dcfbfc"],
15 "requested_access_methods": [{ "mode": "mobile_key" }],
16 "starts_at": "'"$STARTS_AT"'",
17 "ends_at": "'"$ENDS_AT"'"
18 }'
19
20# 2. Read the access method back. It carries what both delivery paths need:
21# the client session for your app's SDK, and an instant_key_url to text.
22curl -X POST "https://connect.getseam.com/access_methods/list" \
23 -H "Authorization: Bearer $SEAM_API_KEY" \
24 -H "Content-Type: application/json" \
25 -d '{ "access_grant_id": "ef83cca9-5fdf-4ac2-93f3-c21c5a8be54b" }'Build it with your AI agent
- 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@seamapiThe 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
Using the Seam Access Grants skill, add mobile key unlock to my app. In a sandbox workspace: create a user identity for a member, create an access grant on an entrance with requested_access_methods [{ mode: "mobile_key" }] for a one-month membership window, then list the access methods and show me the client_session_id and the instant_key_url. Then walk me through exchanging the client_session_id for a client session token for the mobile SDK, and explain which of the two artifacts I need for a native app versus a text message.What you can build
Tap-to-unlock in your own app
The Seam mobile SDK holds the credential and unlocks over Bluetooth, under your UI and your brand. Works with the phone offline, which is what stairwells, garages and basements demand.
Keys that arrive by text
Every mobile key carries an Instant Key URL: a browser-based key with no download and no account. Day passes, visitors and the guest who refuses to install anything are all covered.
Membership access that manages itself
The key lives on the grant's window, so a renewal extends it and a cancellation revokes it. Lost phone? Delete the grant and issue a new one; the door hardware never needs a visit.
How it works
Confirm the door can take a mobile key
Mobile keys run on the systems behind the doors: Salto, dormakaba, ASSA ABLOY and the other systems listed on the capability page. There is no device flag for mobile keys, so read the device's capabilities_supported array, or ask for the mode on the grant and handle what Seam reports back.
1const entrances = await seam.acs.entrances.list({ 2 acs_system_id: "c359cba2-8ef2-47fc-bee0-1c7c2a886339", 3}) 4 5// There is no device flag for mobile keys. Ask for the mode on the grant and 6// handle what Seam reports back, or read the device's capabilities_supported.Create an Access Grant with a mobile key
Name the person, the doors and the window, and ask for mode mobile_key. Seam provisions the credential on the underlying system, so the call is the same whether the doors are Salto entrances or a dormakaba building. Swap acs_entrance_ids for space_ids to cover a group of doors at once.
1const accessGrant = await seam.accessGrants.create({ 2 user_identity_id: member.seamUserIdentityId, 3 acs_entrance_ids: member.entranceIds, 4 requested_access_methods: [{ mode: "mobile_key" }], 5 starts_at: membership.startsAt, 6 ends_at: membership.endsAt, 7})Hand the key to your app
List the access methods to get the client_session_id, then look up that client session's token. The iOS entry point is initialize(clientSessionToken:), so the id on its own will not start a session. From there the SDK scans, connects and unlocks; your app supplies the button.
1const [mobileKey] = await seam.accessMethods.list({ 2 access_grant_id: accessGrant.access_grant_id, 3}) 4 5if (mobileKey?.is_issued) { 6 // Look up this client session's token. The mobile SDK takes the token, not 7 // the id: the iOS entry point is initialize(clientSessionToken:). 8 console.log(mobileKey.client_session_id) 9}Cover everyone else with the Instant Key
The same access method carries an instant_key_url. It opens in the browser and unlocks the same doors on the same schedule, so a visitor gets working access from one text message. Treat it like the credential it is: send it to the person it belongs to and nobody else.
1// The same access method carries a browser-based key. Text it to anyone 2// who will not install your app; no download, no account. 3if (mobileKey?.is_issued) { 4 await sendSms({ 5 to: member.phone, 6 body: `Tap to unlock: ${mobileKey.instant_key_url}`, 7 }) 8}
Frequently asked questions
Do my users need to install an app?
Not always. With your own app, the Seam mobile SDK holds the credential and unlocks over Bluetooth. Without one, text the instant_key_url that comes with every mobile key.
Does a mobile key work when the phone has no signal?
Yes, on systems that provision the credential to the phone. The key unlocks over Bluetooth with both the phone and the lock offline, which is why mobile keys suit stairwells and garages.
Which platforms does the mobile SDK support?
iOS and Android. Both take a client session token, hold the credentials, and expose the scan-and-unlock flow; your app owns everything the user sees.
How do I revoke a mobile key?
Delete the grant, or let it expire at ends_at. Seam removes the credential on the underlying system, so a lost phone is one API call instead of a locksmith.
Can one person have a mobile key and a PIN code?
Yes. Request both modes in one Access Grant, or add an access method to an existing grant later. They share the grant's schedule and doors, so a dead battery on the phone is not a lockout.
How is this different from each lock vendor's own mobile SDK?
Vendor SDKs are per brand: a different credential model, provisioning flow and revocation rule each time. Seam issues mobile keys through one Access Grants call and one mobile SDK across every system it supports.
Related
- Smart locks that support mobile keysEvery model and system that can hold a Bluetooth credential, with live status.
- Seam mobile SDKsInitializing the iOS and Android SDKs, client sessions, and the unlock flow.
- How to connect a smart lock to your appThe step before this one: getting your user's doors into Seam.
- How to generate temporary access codes programmaticallyThe PIN-code path, for doors with keypads and users without phones.