Skip to main content
An Access Grant is a single API call that defines who gets access, where they can go, when access is valid, and how they get in. This guide walks through the full flow from creation to delivery.

Before You Begin

  • A Seam workspace with at least one connected device or access system. You can use a sandbox workspace with test devices.
  • An API key.
  • The Seam SDK installed in your language of choice (see Quick Start).

Step 1: Create the Access Grant

Call /access_grants/create with four things:
  1. Who — a user_identity_id for an existing user, or pass user_identity to create one inline
  2. Where — the resources to grant access to
  3. When — the access schedule (starts_at and ends_at)
  4. How — the access method modes to issue (e.g., code, mobile_key, card, cloud_key)

Choosing Resources

You specify where to grant access using one or more of these parameters:
ParameterBest forDescription
device_idsStandalone smart locksPass IDs of individual devices like August, Yale, or Schlage locks connected through a Connect Webview.
space_idsGrouped access pointsGrant access to all entrances and devices in one or more spaces. Useful when a guest needs access to a room door, lobby, and elevator in one call.
acs_entrance_idsAccess control system entrancesPass IDs of individual ACS entrances for fine-grained control.
You can combine these in a single Access Grant — for example, a standalone smart lock (device_ids) plus a set of ACS entrances (acs_entrance_ids).
If you’re using Dormakaba Ambiance, Dormakaba Community, Visionline, Salto Space, or Vostio, you’ll also need to pass a reservation_key to coordinate credential override sequencing. See Reservation Access Grants.
If you create multiple Access Grants for the same user_identity_id, Seam tries to reuse the same access methods across grants — for example, assigning the same PIN code so the user doesn’t have to learn a new one for each reservation.

Example

The example below creates an Access Grant for a single smart lock with a PIN code. To grant access to multiple doors at once, pass space_ids instead of device_ids. To target specific ACS entrances, use acs_entrance_ids. You can also request multiple modes in one call — for example, [{"mode": "code"}, {"mode": "mobile_key"}].
from seam import Seam

seam = Seam()

access_grant = seam.access_grants.create(
    user_identity={
        "full_name": "Jane Doe",
        "email_address": "jane@example.com",
    },
    device_ids=["6ba7b811-9dad-11d1-80b4-00c04fd430c8"],
    requested_access_methods=[{"mode": "code"}],
    starts_at="2025-07-13T15:00:00.000Z",
    ends_at="2025-07-16T11:00:00.000Z",
)
When you request mobile_key, Seam also generates an instant_key_url on the Access Grant — a shareable link that gives your user mobile access without downloading an app. See Using Instant Keys.

Requesting a Custom Access Code

By default, Seam generates a PIN code for each code access method. To request a specific code instead — for example, to reuse a code a guest already knows — include a code value alongside mode: "code" in requested_access_methods. The code must be 4–9 digits and contain only digits.
from seam import Seam

seam = Seam()

access_grant = seam.access_grants.create(
    user_identity={
        "full_name": "Jane Doe",
        "email_address": "jane@example.com",
    },
    device_ids=["6ba7b811-9dad-11d1-80b4-00c04fd430c8"],
    requested_access_methods=[{"mode": "code", "code": "1234"}],
    starts_at="2025-07-13T15:00:00.000Z",
    ends_at="2025-07-16T11:00:00.000Z",
)
A requested code is a preference, not a guarantee. Seam applies it when it can and falls back to a generated code when it can’t:
  • The code is already in use on a device: Seam assigns a different code for that device and records a warning on the Access Grant (warning_code: "requested_code_unavailable") that includes both the original and the replacement code.
  • The grant spans multiple Salto locks: Seam ignores the requested code and assigns a single shared generated code across those devices, because Salto can’t guarantee the same PIN on every device.
  • The provider has stricter code-length limits: Some devices accept a narrower range than 4–9 digits. If the requested code isn’t valid for a device, Seam assigns a compatible code for that device instead.
Always read the resulting code back from the access method (see Step 2: Deliver the Access Methods) rather than assuming the requested value was used, and check the grant’s warning_map for any requested_code_unavailable warnings. For more on delivering and updating codes, see Using PIN Codes and Managing Access Methods.

Step 2: Deliver the Access Methods

After creating the grant, list the access methods to see what was created and check their issuance status.
access_methods = seam.access_methods.list(
    access_grant_id=access_grant.access_grant_id
)

for method in access_methods:
    print(f"{method.mode}: is_issued={method.is_issued}")
Each access method has an is_issued flag. Once it’s true, the credential is active and ready to deliver. How you deliver depends on the mode:
ModeWhat to doGuide
codeRead the code property and share the PIN with your user.Using PIN Codes
mobile_keyInitialize the Seam mobile SDK with the client_session_token, or send the instant_key_url.Using Mobile Keys / Instant Keys
cardEncode a fresh card or assign an existing card. is_issued becomes true after encoding or assignment.Using Key Cards
cloud_keyCall access_methods.unlock_door from your web app to unlock on behalf of the user.Using Cloud Keys
In a sandbox workspace, automatically-issued access methods are ready almost instantly. On real devices, issuance can take a few moments.

Tracking Issuance with Events

Instead of polling is_issued, you can listen for webhook events:
EventMeaning
access_method.issuedThe access method is ready to deliver.
access_method.card_encoding_requiredA card needs to be encoded before it can be delivered.
access_method.card_assignment_requiredA card needs to be assigned to a physical card before it can be issued.