> ## Documentation Index
> Fetch the complete documentation index at: https://docs.seam.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Locking and Unlocking Smart Locks

> Learn how to lock and unlock a smart lock, and confirm the action's success.

## Overview

Seam enables you to lock or unlock your door lock remotely. This guide walks you through how to perform these actions using the Seam API.

When you send a command to a smart lock, it might take a while for Seam to confirm the action's success. To handle this, Seam provides [an "action attempt" object](../../core-concepts/action-attempts), which indicates whether the action was successful.

To ensure that the action has been successfully executed, we advise checking the status of the action attempt object by polling the ["Get Action Attempt" request](/api/action_attempts/get). Once Seam has successfully confirmed the action, the action attempt's `status` will indicate `success`.

Some providers and device models cannot confirm whether the physical lock or unlock happened in a reasonable time or at all. In those cases, a successful action attempt can still include `action_attempt.result.was_confirmed_by_device = false`.

***

## Before You Begin: Confirm Capabilities

Before you attempt to lock or unlock a device, be sure to confirm that your device has the capability to perform these operations. You can inspect the capabilities of a device by checking the following [capability flags](../../capability-guides/device-and-system-capabilities#capability-flags) for the device:

* `device.can_remotely_lock`
* `device.can_remotely_unlock`

Use [Get Device](/api/devices/get) for a specific device to return these capability flags. Then, use an `if` statement or similar check to confirm that the relevant flag is both present and `true` before attempting to lock or unlock the device.

If either of these capability flags is `false` or not present, you can view the [properties](/api/devices/object) of the device, [errors or warnings](/api/devices/errors) for the device, and [events](/api/devices/events) related to the device to learn more about the cause of these issues. For example, you could examine `device.properties.online`. In addition, you could look for a `device.disconnected` event.

**Request:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  await seam.devices.get('11111111-1111-1111-1111-444444444444')
  ```

  ```bash cURL theme={null}
  # Use GET or POST.
  curl -X 'GET' \
    'https://connect.getseam.com/devices/get' \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${SEAM_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
    "device_id": "11111111-1111-1111-1111-444444444444"
  }'
  ```

  ```python Python theme={null}
  seam.devices.get(device_id="11111111-1111-1111-1111-444444444444")
  ```

  ```ruby Ruby theme={null}
  client.devices.get(device_id: "11111111-1111-1111-1111-444444444444")
  ```

  ```php PHP theme={null}
  $seam->devices->get("11111111-1111-1111-1111-444444444444");
  ```

  ```csharp C# theme={null}
  seam.Devices.Get(deviceId: "11111111-1111-1111-1111-444444444444");
  ```
</CodeGroup>

**Response:**

<CodeGroup>
  ```json JavaScript theme={null}
  {
    device_id: '11111111-1111-1111-1111-444444444444',
    can_remotely_lock: true,   // You can use seam.locks.lockDoor() on this device.
    can_remotely_unlock: true, // You can use seam.locks.unlockDoor() on this device.
    ...
  }
  ```

  ```json cURL theme={null}
  {
    "device": {
      "device_id": "11111111-1111-1111-1111-444444444444",
      "can_remotely_lock": true,   // You can use /locks/lock_door on this device.
      "can_remotely_unlock": true, // You can use /locks/unlock_door on this device.
      ...
    },
    "ok": true
  }
  ```

  ```json Python theme={null}
  Device(
    device_id='11111111-1111-1111-1111-444444444444',
    can_remotely_lock=True,   // You can use seam.locks.lock_door() on this device.
    can_remotely_unlock=True, // You can use seam.locks.unlock_door() on this device.
    ...
  )
  ```

  ```json Ruby theme={null}
  <
    Seam::Device:0x00438
      device_id="11111111-1111-1111-1111-444444444444"
      can_remotely_lock=true   // You can use client.locks.lock_door() on this device.
      can_remotely_unlock=true // You can use client.locks.unlock_door() on this device.
      ...
  >
  ```

  ```json PHP theme={null}
  {
    "device_id": "11111111-1111-1111-1111-444444444444",
    "can_remotely_lock": true,   // You can use $seam->locks->lock_door() on this device.
    "can_remotely_unlock": true, // You can use $seam->locks->unlock_door() on this device.
    ...
  }
  ```

  ```json C# theme={null}
  {
    "device_id": "11111111-1111-1111-1111-444444444444",
    "can_remotely_lock": true,   // You can use seam.Locks.LockDoor() on this device.
    "can_remotely_unlock": true, // You can use seam.Locks.UnlockDoor() on this device.
    ...
  }
  ```
</CodeGroup>

***

## Locking a Door

You can lock a door using the [`lock_door`](/api/locks/lock_door) endpoint. To confirm the success of the action, see [Verifying the success of a lock or unlock action](#verifying-the-success-of-a-lock-or-unlock-action).

**Request:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Get the device.
  const device = await seam.devices.get({
    device_id: '11111111-1111-1111-1111-444444444444',
  })

  // Confirm that the device can remotely lock.
  if (device.can_remotely_lock) {
    // Perform the lock operation.
    await seam.locks.lockDoor({
      device_id: device.device_id,
    })
  }
  ```

  ```bash cURL theme={null}
  # Get the device.
  device=$(
    # Use GET or POST.
    curl -X 'GET' \
      'https://connect.getseam.com/devices/get' \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${SEAM_API_KEY}" \
      -H 'Content-Type: application/json' \
      -d '{
        "device_id": "11111111-1111-1111-1111-444444444444"
    }')

  # Confirm that the device can remotely lock.
  if  $(jq -r '.device.can_remotely_lock' <<< ${device}); then \
    # Perform the lock operation.
    curl -X 'POST' \
      'https://connect.getseam.com/locks/lock_door' \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${SEAM_API_KEY}" \
      -H 'Content-Type: application/json' \
      -d "{
        \"device_id\": \"$(jq -r '.device.device_id' <<< ${device})\"
    }";
  fi
  ```

  ```python Python theme={null}
  # Get the device.
  device = seam.devices.get(
    device_id="11111111-1111-1111-1111-444444444444"
  )

  # Confirm that the device can remotely lock.
  if device.can_remotely_lock:
    # Perform the lock operation.
    seam.locks.lock_door(device_id=device.device_id)
  ```

  ```ruby Ruby theme={null}
  # Get the device.
  device = client.devices.get(device_id: "11111111-1111-1111-1111-444444444444")

  # Confirm that the device can remotely lock.
  if (device.can_remotely_lock)
    # Perform the lock operation.
    client.locks.lock_door(device_id: device.device_id)
  end
  ```

  ```php PHP theme={null}
  // Get the device.
  $device = $seam->devices->get(device_id: "11111111-1111-1111-1111-444444444444");

  // Confirm that the device can remotely lock.
  if ($device->can_remotely_lock) {
    // Perform the lock operation.
    $seam->locks->lock_door(device_id: $device->device_id);
  }
  ```

  ```csharp C# theme={null}
  // Get the device.
  Device device = seam.Devices.Get(deviceId: "11111111-1111-1111-1111-444444444444");

  // Confirm that the device can remotely lock.
  if (device.CanRemotelyLock == true) {
    // Perform the lock operation.
    seam.Locks.LockDoor(deviceId: device.DeviceId);
  }
  ```
</CodeGroup>

**Response:**

<CodeGroup>
  ```json JavaScript theme={null}
  {
    "actionAttempt": {
      "status": "success",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "action_type": "LOCK_DOOR",
      "result": {},
      "error": null
    }
  }
  ```

  ```json cURL theme={null}
  {
    "action_attempt": {
      "status": "pending",
      "action_type": "LOCK_DOOR",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "result": null,
      "error": null
    },
    "ok": true
  }
  ```

  ```json Python theme={null}
  ActionAttempt(status='pending',
                action_type='LOCK_DOOR',
                action_attempt_id='11111111-2222-3333-4444-555555555555',
                result=None,
                error={})
  ```

  ```json Ruby theme={null}
  <Seam::ActionAttempt:0x00438
    status="pending"
    action_type="LOCK_DOOR"
    action_attempt_id="11111111-2222-3333-4444-555555555555"
    result=nil>
  ```

  ```json PHP theme={null}
  {
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "action_type": "LOCK_DOOR",
    "error": null,
    "result": {},
    "status": "success"
  }
  ```

  ```json C# theme={null}
  {
    "status": "pending",
    "action_type": "LOCK_DOOR",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555"
  }
  ```
</CodeGroup>

***

## Unlocking a Door

You can unlock a door using the [unlock\_door](/api/locks/unlock_door) endpoint. To confirm the success of the action, see [Verifying the success of a lock or unlock action](#verifying-the-success-of-a-lock-or-unlock-action).

**Request:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Get the device.
  const device = await seam.devices.get({
    device_id: '11111111-1111-1111-1111-444444444444',
  })

  // Confirm that the device can remotely unlock.
  if (device.can_remotely_unlock) {
    // Perform the unlock operation.
    await seam.locks.unlockDoor({
      device_id: device.device_id,
    })
  }
  ```

  ```bash cURL theme={null}
  # Get the device.
  device=$(
    # Use GET or POST.
    curl -X 'GET' \
      'https://connect.getseam.com/devices/get' \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${SEAM_API_KEY}" \
      -H 'Content-Type: application/json' \
      -d '{
        "device_id": "11111111-1111-1111-1111-444444444444"
    }')

  # Confirm that the device can remotely unlock.
  if  $(jq -r '.device.can_remotely_unlock' <<< ${device}); then \
    # Perform the unlock operation.
    curl -X 'POST' \
      'https://connect.getseam.com/locks/unlock_door' \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${SEAM_API_KEY}" \
      -H 'Content-Type: application/json' \
      -d "{
        \"device_id\": \"$(jq -r '.device.device_id' <<< ${device})\"
    }";
  fi
  ```

  ```python Python theme={null}
  # Get the device.
  device = seam.devices.get(
    device_id="11111111-1111-1111-1111-444444444444"
  )

  # Confirm that the device can remotely unlock.
  if device.can_remotely_unlock:
    # Perform the unlock operation.
    seam.locks.unlock_door(device_id=device.device_id)
  ```

  ```ruby Ruby theme={null}
  # Get the device.
  device = client.devices.get(device_id: "11111111-1111-1111-1111-444444444444")

  # Confirm that the device can remotely unlock.
  if (device.can_remotely_unlock)
    # Perform the unlock operation.
    client.locks.unlock_door(device_id: device.device_id)
  end
  ```

  ```php PHP theme={null}
  // Get the device.
  $device = $seam->devices->get(device_id: "11111111-1111-1111-1111-444444444444");

  // Confirm that the device can remotely unlock.
  if ($device->can_remotely_unlock) {
    // Perform the unlock operation.
    $seam->locks->unlock_door(device_id: $device->device_id);
  }
  ```

  ```csharp C# theme={null}
  // Get the device.
  Device device = seam.Devices.Get(deviceId: "11111111-1111-1111-1111-444444444444");

  // Confirm that the device can remotely unlock.
  if (device.CanRemotelyUnlock == true) {
    // Perform the unlock operation.
    seam.Locks.UnlockDoor(deviceId: device.DeviceId);
  }
  ```
</CodeGroup>

**Response:**

<CodeGroup>
  ```json JavaScript theme={null}
  {
    "actionAttempt": {
      "status": "success",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "action_type": "UNLOCK_DOOR",
      "result": {
        "was_confirmed_by_device": false
      },
      "error": null
    }
  }
  ```

  ```json cURL theme={null}
  {
    "action_attempt": {
      "status": "pending",
      "action_type": "UNLOCK_DOOR",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "result": null,
      "error": null
    },
    "ok": true
  }
  ```

  ```json Python theme={null}
  ActionAttempt(status='pending',
                action_type='UNLOCK_DOOR',
                action_attempt_id='11111111-2222-3333-4444-555555555555',
                result=None,
                error={})
  ```

  ```json Ruby theme={null}
  <Seam::ActionAttempt:0x00438
    status="pending"
    action_type="UNLOCK_DOOR"
    action_attempt_id="11111111-2222-3333-4444-555555555555"
    result=nil>
  ```

  ```json PHP theme={null}
  {
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "action_type": "UNLOCK_DOOR",
    "error": null,
    "result": {
      "was_confirmed_by_device": false
    },
    "status": "success"
  }
  ```

  ```json C# theme={null}
  {
    "status": "pending",
    "action_type": "UNLOCK_DOOR",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555"
  }
  ```
</CodeGroup>

***

## Verifying the Success of a Lock or Unlock Action

### 1. Execute a Lock request (or other action)

When initiating a lock or unlock action, the Seam API returns an action attempt, which monitors the success or failure of the action.

**Request:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  await seam.locks.lockDoor({
    device_id: '11111111-1111-1111-1111-444444444444',
  })
  ```

  ```bash cURL theme={null}
  curl -X 'POST' \
    'https://connect.getseam.com/locks/lock_door' \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${SEAM_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
      "device_id": "11111111-1111-1111-1111-444444444444"
  }'
  ```

  ```python Python theme={null}
  seam.locks.lock_door(device_id="11111111-1111-1111-1111-444444444444")
  ```

  ```ruby Ruby theme={null}
  client.locks.lock_door(device_id: "11111111-1111-1111-1111-444444444444")
  ```

  ```php PHP theme={null}
  $seam->locks->lock_door(device_id: "11111111-1111-1111-1111-444444444444");
  ```

  ```csharp C# theme={null}
  seam.Locks.LockDoor(deviceId: "11111111-1111-1111-1111-444444444444");
  ```
</CodeGroup>

**Response:**

<CodeGroup>
  ```json JavaScript theme={null}
  {
    "actionAttempt": {
      "status": "success",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "action_type": "LOCK_DOOR",
      "result": {},
      "error": null
    }
  }
  ```

  ```json cURL theme={null}
  {
    "action_attempt": {
      "status": "pending",
      "action_type": "LOCK_DOOR",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "result": null,
      "error": null
    },
    "ok": true
  }
  ```

  ```json Python theme={null}
  ActionAttempt(status='pending',
                action_type='LOCK_DOOR',
                action_attempt_id='11111111-2222-3333-4444-555555555555',
                result=None,
                error={})
  ```

  ```json Ruby theme={null}
  <Seam::ActionAttempt:0x00438
    status="pending"
    action_type="LOCK_DOOR"
    action_attempt_id="11111111-2222-3333-4444-555555555555"
    result=nil>
  ```

  ```json PHP theme={null}
  {
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "action_type": "LOCK_DOOR",
    "error": null,
    "result": {},
    "status": "success"
  }
  ```

  ```json C# theme={null}
  {
    "status": "pending",
    "action_type": "LOCK_DOOR",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555"
  }
  ```
</CodeGroup>

### 2. Poll the Action Attempt to Verify the Success of the Action

Use the `action_attempt_id` from the prior response to make a [Get Action Attempt request](/api/action_attempts/get). When the action attempt's `status` changes to `success`, it indicates the action has been successful.

<Info>
  Some providers and device models do not confirm whether a lock or unlock
  completed on the physical device. In those cases, the action attempt can still
  succeed while `action_attempt.result.was_confirmed_by_device` is `false`. Use
  this property to set the right expectation in your UI, especially for unlock
  flows.
</Info>

**Request:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  await seam.actionAttempts.get({
    action_attempt_id: '11111111-2222-3333-4444-555555555555',
  })
  ```

  ```bash cURL theme={null}
  # Use GET or POST.
  curl -X 'GET' \
    'https://connect.getseam.com/action_attempts/get' \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${SEAM_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
    "action_attempt_id": "11111111-2222-3333-4444-555555555555"
  }'
  ```

  ```python Python theme={null}
  seam.action_attempts.get(action_attempt_id="11111111-2222-3333-4444-555555555555")
  ```

  ```ruby Ruby theme={null}
  client.action_attempts.get(action_attempt_id: "11111111-2222-3333-4444-555555555555")
  ```

  ```php PHP theme={null}
  $seam->action_attempts->get(action_attempt_id: "11111111-2222-3333-4444-555555555555");
  ```

  ```csharp C# theme={null}
  seam.ActionAttempts.Get("11111111-2222-3333-4444-555555555555");
  ```
</CodeGroup>

**Response:**

<CodeGroup>
  ```json JavaScript theme={null}
  {
    "status": "success",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "action_type": "LOCK_DOOR",
    "result": {
      "was_confirmed_by_device": true
    },
    "error": null
  }
  ```

  ```json cURL theme={null}
  {
    "action_attempt": {
      "status": "success",
      "action_attempt_id": "11111111-2222-3333-4444-555555555555",
      "action_type": "LOCK_DOOR",
      "result": {
        "was_confirmed_by_device": true
      },
      "error": null
    },
    "ok": true
  }
  ```

  ```json Python theme={null}
  ActionAttempt(action_attempt_id='11111111-2222-3333-4444-555555555555',
                action_type='LOCK_DOOR',
                status='success',
                result={'was_confirmed_by_device': True},
                error=None)
  ```

  ```json Ruby theme={null}
  <Seam::ActionAttempt:0x00438
    status="success"
    action_attempt_id="11111111-2222-3333-4444-555555555555"
    action_type="LOCK_DOOR"
    result={"was_confirmed_by_device"=>true}>
  ```

  ```json PHP theme={null}
  {
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "action_type": "LOCK_DOOR",
    "error": null,
    "result": {
      "was_confirmed_by_device": true
    },
    "status": "success"
  }
  ```

  ```json C# theme={null}
  {
    "status": "success",
    "action_type": "LOCK_DOOR",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555",
    "result": {
      "was_confirmed_by_device": true
    },
    "error": null
  }
  ```
</CodeGroup>

***

## Checking the Locked Status of a Lock

To retrieve the locked status of a specific door lock, use the [Get Device](/api/devices/get) endpoint by providing the `device_id` of the desired lock. This operation returns detailed information, including the current locked status. Note that if the lock is offline, Seam does not return the `device.locked` property.

**Request:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  await seam.devices.get('11111111-1111-1111-1111-444444444444')
  ```

  ```bash cURL theme={null}
  # Use GET or POST.
  curl -X 'GET' \
    'https://connect.getseam.com/devices/get' \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${SEAM_API_KEY}" \
    -H 'Content-Type: application/json' \
    -d '{
    "device_id": "11111111-1111-1111-1111-444444444444"
  }'
  ```

  ```python Python theme={null}
  seam.devices.get(device_id="11111111-1111-1111-1111-444444444444")
  ```

  ```ruby Ruby theme={null}
  client.devices.get(device_id: "11111111-1111-1111-1111-444444444444")
  ```

  ```php PHP theme={null}
  $seam->devices->get("11111111-1111-1111-1111-444444444444");
  ```

  ```csharp C# theme={null}
  seam.Devices.Get("11111111-1111-1111-1111-444444444444");
  ```
</CodeGroup>

**Response:**

<CodeGroup>
  ```json JavaScript theme={null}
  {
    device_id: '11111111-1111-1111-1111-444444444444',
    properties: {
      locked: true,
      ...
    },
    ...
  }
  ```

  ```json cURL theme={null}
  {
    "lock": {
      "device_id": "11111111-1111-1111-1111-444444444444",
      "properties": {
        "locked": true,
        ...
      },
      ...
    },
    "ok": true
  }
  ```

  ```json Python theme={null}
  Device(
    device_id='11111111-1111-1111-1111-444444444444',
    properties={
      'locked': True,
      ...
    },
    ...
  )
  ```

  ```json Ruby theme={null}
  <Seam::Device:0x00438
    device_id="11111111-1111-1111-1111-444444444444"
    properties={
      "locked"=>true,
      ...
    }
    ...
  >
  ```

  ```json PHP theme={null}
  {
    "device_id": "11111111-1111-1111-1111-444444444444",
    "properties": {
      "locked": true,
      ...
    },
    ...
  }
  ```

  ```json C# theme={null}
  {
    "device_id": "11111111-1111-1111-1111-444444444444",
    "properties": {
      "locked": true,
      ...
    },
    ...
  }
  ```
</CodeGroup>

***

## Lock and Unlock Events

Whenever a lock is locked or unlocked, Seam emits a `lock.locked` or `lock.unlocked` event. You can retrieve these events by making a [List Events request](/api/events/list) or receive them in real time by setting up a webhook. For more information on how to set up webhooks, see the [Webhooks guide](../../developer-tools/webhooks). For the complete list of properties on each event, see the [Lock Events reference](/api/locks/events).

A `lock.unlocked` event looks like the following:

```json theme={null}
{
  "event_id": "22222222-3333-4444-5555-666666666666",
  "event_type": "lock.unlocked",
  "device_id": "11111111-1111-1111-1111-444444444444",
  "method": "keycode",
  "access_code_id": "99999999-9999-9999-9999-999999999999",
  "access_code_is_managed": true,
  "occurred_at": "2025-01-01T00:00:00.000Z",
  "created_at": "2025-01-01T00:00:00.000Z",
  "workspace_id": "00000000-0000-0000-0000-000000000000"
}
```

### Determining How a Lock Was Operated

Use the `method` property to determine how the lock was locked or unlocked. Both `lock.locked` and `lock.unlocked` events include this property.

| `method`    | Meaning                                                                                               | Related properties                                    |
| ----------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `keycode`   | An access code was entered on the keypad.                                                             | `access_code_id`, `access_code_is_managed`            |
| `manual`    | A direct physical action at the lock, such as turning the thumbturn or pressing a button.             | —                                                     |
| `remote`    | A remote action initiated from an app, over Bluetooth, or through the Seam API.                       | `action_attempt_id`, `is_via_bluetooth`, `is_via_nfc` |
| `automatic` | Triggered automatically, without user interaction—for example, by an auto-relock timer or a schedule. | —                                                     |
| `unknown`   | Seam could not determine the method from the provider's event.                                        | —                                                     |

For `remote` events, the following properties tell you which remote channel was used:

* **`action_attempt_id`**: Present only when the action was initiated through Seam, using a `LOCK_DOOR` or `UNLOCK_DOOR` [action attempt](../../core-concepts/action-attempts). Use it to tie the event back to the specific API call your application made. When this property is absent, the remote action originated outside of Seam—for example, from the provider's own mobile app.
* **`is_via_bluetooth`**: `true` when the action was performed over Bluetooth by a remote client, such as the provider's [mobile app](/low-level-apis/smart-locks/access-codes/accommodating-manufacturer-mobile-apps), rather than through Seam or a physical interaction.
* **`is_via_nfc`**: `true` when the action was performed by tapping an NFC credential, such as an Apple Home Key or an NFC key fob, at the lock.

### Identifying the Access Code Used

When `method` is `keycode`, the event identifies the [access code](/low-level-apis/smart-locks/access-codes) that was used:

* **`access_code_id`**: ID of the access code that was entered.
* **`access_code_is_managed`**: `true` if the code is managed by Seam—that is, one that you created through the Seam API—or `false` if it is an unmanaged code that was programmed directly on the device. This property is present only when `access_code_id` is set.

### Common Scenarios

The following examples show the properties that distinguish common ways a lock is operated. Each event also includes the standard `event_id`, `device_id`, `occurred_at`, and other envelope properties, omitted here for brevity.

<CodeGroup>
  ```json A guest enters a Seam-managed code theme={null}
  {
    "event_type": "lock.unlocked",
    "method": "keycode",
    "access_code_id": "99999999-9999-9999-9999-999999999999",
    "access_code_is_managed": true
  }
  ```

  ```json Your app unlocks via the Seam API theme={null}
  {
    "event_type": "lock.unlocked",
    "method": "remote",
    "action_attempt_id": "11111111-2222-3333-4444-555555555555"
  }
  ```

  ```json A resident unlocks with the provider's app over Bluetooth theme={null}
  {
    "event_type": "lock.unlocked",
    "method": "remote",
    "is_via_bluetooth": true
  }
  ```

  ```json Someone taps an Apple Home Key theme={null}
  {
    "event_type": "lock.unlocked",
    "method": "remote",
    "is_via_nfc": true
  }
  ```

  ```json The door auto-relocks on a timer theme={null}
  {
    "event_type": "lock.locked",
    "method": "automatic"
  }
  ```
</CodeGroup>
