NAV Navbar
shell ruby javascript

Seam Documentation Header

INTRODUCTION

Welcome to the Seam API! We built Seam to make building applications that interact with IoT devices as easy as possible. We spent years wrestling with many of these problems and wished that there could be a simple API that would abstract it all away.

The following guide is intended to walk you through the core ideas behind Seam, such as making authenticated API requests, sending device commands, and listening for events.

KEY TERMINOLOGY

Seam Architecture Overview

Above is an end to end overview diagram of the Seam architecture. On the far left is your Application. On the far right are the devices you wish to control. Let's define each term.

YOUR APP

This is You! You can send requests to the Seam REST API and receive responses from that API, as well as status updates from either Webhooks or Websockets.

SEAM API

This is the REST API that your application can query. This API is accessible from anywhere and takes simple commands and forwards them to the gateway via a secure tunnel.

SEAM GATEWAY

This is the hardware device that's provided by Seam. It resides on your local area network (LAN) and creates a link to the outside world (WAN) via a secure tunnel to the Seam API.

Its job is to take simple commands and translate them to lower-level mesh protocol commands that end devices can understand. This is because most IoT devices don't connect to standard wifi given they are battery-powered and wifi is power hungry.

END DEVICES

This is a generic term we'll be using and which refers to any connected device or sensor, such as door locks, lights, noise sensors thermostats...etc.

API REFERENCE

The SEAM API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Request/Response Format

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}/actions/${ACTION_NAME}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

url = "https://api.getseam.com/v1/devices/#{DEVICE_ID}/actions/#{ACTION_NAME}"

payload = {
}

RestClient.post(url, payload, headers: headers)

All request submitting parameters must set their Content-Type to application/json. Nonconforming requests will not be accepted.

You can set your request content-type by adding the Content-Type: application/json header to your Seam API request.

The default response format is JSON. Successful requests will return a 200 OK HTTP status.

Some general information about responses:

HTTPS/SSL

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail (see Authentication Section).

Errors

Seam uses conventional HTTP response codes to indicate the success or failure of an API request.

In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a resource is not authorized for writes, etc.). Codes in the 5xx range indicate an error with Seam's servers (these are rare).

Below are a few example of such errors:

Status Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Couldn't authenticate your request
403 Invalid scope -- User hasn’t authorized necessary scope
500 Internal Server Error -- Server error

AUTHENTICATION

To authorize a request, you can use this code:

# With curl, you can use -u followed by your API key. Adding `:` after the key will simply tell curl not to ask you for a password.
curl "https://api.getseam.com/v1/groups" \
  -u "${YOUR_API_KEY}:"
# In ruby, we first need to encode the key using Base64 before adding it to the request header
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = 'https://api.getseam.com/v1/groups'

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

[
    {
        "id": "512beb75-2538-47bf-b646-f39239d2e127",
        "name": "12119 robinridge ln"
    }
]

The Seam API uses API keys to authenticate requests. You can view and manage your API keys in the Seam Dashboard.

Seam Architecture Overview

Authentication to the API is performed via HTTP Basic Auth. Provide your API key as the basic auth username value. You do not need to provide a password.

If you do not include your key when making an API request, or use an incorrect or outdated key, Seam will return an error.

Keeping Your Key Safe

Your secret API key can be used to make any API call on behalf of your account, such as performing actions or retrieving data. Treat your secret API key as you would any other password.

Grant access only to those who need it. Ensure it is kept out of any version control system you may be using. Control access to your key using a password manager or secrets management service. We also plan to eventually introduce restricted API keys for granular permissions.

If you are running the shell examples in this documentation, you can simply export your API key in your current terminal session as such: export YOUR_API_KEY="<your actual API key>"

WORKSPACES

Seam defines your workspace as the top-level entity that encompasses all other resources below it, such as groups, gateways, and end devices.

A workspace has one owner (e.g. you) and one unique API key.

Enterprise Plan users can have multiple workspaces and multiple collaborators per workspace. No two workspaces may share the same API key, groups, gateways, or devices.

Workspace Group Gateway End Devices Architecture

LOCATIONS

Locations are how you organize your Gateways and Devices. It represents a geographical grouping of devices with one set Timezone.

Locations are useful for issuing the same command to a set of devices (e.g. alert me when X happens) as well as sectioning off access for Enterprise Plan users.

Location Timezone

When creating a new location, you must specify the timezone for the location. This will then set all displayed timestamps in your dashboard to the specified time zone. Internally, the Seam API uses UTC timestamps to store dates, and automatically converts them to your location's timezone preference.

Location Object

Parameter Type Description
id uuid The ID of the Location
name string The name of the Location

Getting All Your Locations

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/locations"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = 'https://api.getseam.com/v1/locations'

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

[
    {
        "id": "512beb75-2538-47bf-b646-f39239d2e127",
        "name": "12119 robinridge ln"
    },
    {
        "id": "d8df1c9b-57db-44ee-80b3-2df525181f7f",
        "name": "210 Church St"
    },
]

You can issue the following request to retrieve all the locations associated with your workspace.

HTTP Request

GET /v1/locations

GATEWAYS

Seam Gateways are the resource representing the hardware hub that's provided by Seam.

Installing Your Gateway

Gateway Installation Instructions

Installing your Gateway is easy:

  1. Plug in the power cord to provide the Gateway power.
  2. Connect the ethernet backhaul to your home router or internet access point.
  3. Wait approximately 2 minutes for the Gateway to boot.

At this point, the Gateway should be online and must now be paired to your account and attached to a location before you can start using it.

Pairing the Gateway with Your Account

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"registration_token": "calm-haiku-42", "name": "my first gateway"}' \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/register_gateway"
require 'rest-client'

token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

payload = {
    "registration_token": "calm-haiku-42",
    "name": "my first gateway"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/register_gateway"

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "486044af-5b15-436e-a356-d5f28c28f22a",
    "devices": [],
    "name": "my first gateway",
    "status": "online"
}

Workspace Location Gateway End Devices Architecture

Pair the Gateway with your account and let's attaching it to a location:

  1. Look for your gateway's registration code located on the actual device.
  2. Pick a location that you want to pair the Gateway.
  3. Issue the pairing request as seen in the example on the right. Make sure to give your Gateway a nice name :)
  4. If successful, the API will return your paired Gateway.

Pair Using the Seam Dashboard (UI)

Alternatively, you can also attach the gateway to a location in your workspace by using our dashboard.

  1. go to the Gateways on the left menu.
  2. Click on the "+ Add Gateway" Button.
  3. Enter the Gateways registration_token.
  4. Give your gateway a name and press "Pair Gateway".

Workspace Location Gateway End Devices Architecture

Gateway Object

Parameter Type Description
id uuid The ID of the Gateway
devices array The associated devices of the Gateway
name string The name of the Gateway
status string The connectivity status of the Gateway

Get All Gateways

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/gateways"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = 'https://api.getseam.com/v1/gateways'

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

[
    {
        "id": "486044af-5b15-436e-a356-d5f28c28f22a",
        "devices": [
           {
               "id": "70354027-dcfa-48aa-acb1-9b79fd56b485",
               "name": "Kwikset914 5c:a1:0",
               "manufacturer": "Kwikset",
               "model": "914"
           }
        ],
        "name": "650 Valencia",
        "status": "online"
    },
    {
        "id": "1996c71c-09e6-454a-9d0b-efc214231907",
        "devices": [],
        "name": "538 Folsom - Unit 20",
        "status": "offline"
    }
]

This endpoint retrieves all of your organization's Seam Gateways.

HTTP Request

GET /v1/gateways

Get a Specific Gateway Object

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/gateways/${GATEWAY_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/gateways/#{GATEWAY_ID}"

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

{
    "id": "486044af-5b15-436e-a356-d5f28c28f22a",
    "devices": [
       {
           "id": "70354027-dcfa-48aa-acb1-9b79fd56b485",
           "name": "Kwikset914 5c:a1:0",
           "manufacturer": "Kwikset",
           "model": "914"
       }
    ],
    "name": "650 Valencia",
    "status": "online"
}

This endpoint retrieves a specific gateway and its associated devices.

HTTP Request

GET /v1/gateways/<GATEWAY_ID>

URL Parameters

Parameter Description
GATEWAY_ID The ID of the gateway to retrieve

Update a Gateway Object

curl -X PUT \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"name": "<new_gateway_name>"}' \
  "https://api.getseam.com/v1/gateways/${GATEWAY_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
  "Content-Type": "application/json"
}


payload = {
  "name": "<new_gateway_name>"
}

url = "https://api.getseam.com/v1/gateways/#{GATEWAY_ID}"

RestClient.put(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "486044af-5b15-436e-a356-d5f28c28f22a",
    "devices": [
       {
           "id": "70354027-dcfa-48aa-acb1-9b79fd56b485",
           "name": "Kwikset914 5c:a1:0",
           "manufacturer": "Kwikset",
           "model": "914"
       }
    ],
    "name": "<new_gateway_name>",
    "status": "online"
}

This endpoint updates a specific gateway.

HTTP Request

PUT /v1/gateways/<GATEWAY_ID>

URL Parameters

Parameter Description
GATEWAY_ID The ID of the gateway to retrieve

Query Parameters

Parameter Type Description
name string the name for your gateway

DEVICES

End devices are any end device such as a sensor, a door locks, a light, a thermostats...etc. Most of these devices are battery-powered and therefore low-powered. As a result, they usually speak a mesh network protocol that Seam abstracts away for you through clean API endpoints.

Device Object

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "manufacturer": "Kwikset",
    "model": "914",
    "name": "Kwikset914 5c:a1:0",
    "actions": {
        "lock": {
            "title": "Lock",
            "description": "Locks the Door Lock",
            "inputs": null
        },
        "unlock": {
            "title": "Unlock",
            "description": "Unlocks the Door Lock",
            "inputs": null
        },
        "set_code": {
            "title": "Set Code",
            "description": "Set User Code for the Door Lock",
            "inputs": {
                "code": {
                    "title": "Code",
                    "description": "Pin Code, all numbers, can start
                        with 0, must be between 4 and 8 digits in
                        length",
                    "type": "string"
                },
                "slot_id": {
                    "title": "Slot ID",
                    "description": "2 through 11",
                    "type": "integer"
                }
            }
        },
        "clear_code": {
            "title": "Clear Code",
            "description": "Clear a User Code for the Door Lock",
            "inputs": {
                "slot_id": {
                    "title": "Slot ID",
                    "description": "2 through 11",
                    "type": "integer"
                }
            }
        }
    }
}
Parameter Type Description
id uuid The ID of the Device
manufacturer string The manufacturer of the Device
model string The model of the Device
name string The name of the Device
actions object The list of supported actions by this device

Get a Specific Device Object

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/devices/#{DEVICE_ID}"

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "manufacturer": "Kwikset",
    "model": "914",
    "name": "Kwikset914 5c:a1:0",
    "actions": {
        "lock": {
            "title": "Lock",
            "description": "Locks the Door Lock",
            "inputs": null
        },
        "unlock": {
            "title": "Unlock",
            "description": "Unlocks the Door Lock",
            "inputs": null
        },
        "set_code": {
            "title": "Set Code",
            "description": "Set User Code for the Door Lock",
            "inputs": {
                "code": {
                    "title": "Code",
                    "description": "Pin Code, all numbers, can start
                        with 0, must be between 4 and 8 digits in
                        length",
                    "type": "string"
                },
                "slot_id": {
                    "title": "Slot ID",
                    "description": "2 through 11",
                    "type": "integer"
                }
            }
        },
        "clear_code": {
            "title": "Clear Code",
            "description": "Clear a User Code for the Door Lock",
            "inputs": {
                "slot_id": {
                    "title": "Slot ID",
                    "description": "2 through 11",
                    "type": "integer"
                }
            }
        }
    }
}

This endpoint retrieves a specific device. Note that the listed device will also list its supported actions. Please refer to the Action Requests section to see how to make an action request to a device

HTTP Request

GET /v1/devices/<DEVICE_ID>

URL Parameters

Parameter Description
DEVICE_ID The ID of the device to retrieve

ACTION REQUESTS

Actions are how you interact with gateways and their end devices. Examples of interactions include locking a door, turning off a light, or asking the gateway to pair with new devices.

You can see the list of supported actions when you query a device. Keep in mind that gateway's also have their own actions, which we cover in the gateway actions section.

Action Requests are a special way of encapsulating a request for a device to perform an action and we discuss them in-depth in the Understanding Action Requests section.

Action Request Object

{
    "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
    "device_id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "data": {
        "set_code": {
            "code": "8888",
            "slot_id": 3
        }
    },
    "status": "pending",
    "created_at": "2020-02-10T01:33:19.955Z",
    "updated_at": "2020-02-10T01:33:19.955Z",
}
Parameter Type Description
id uuid The ID of the Action Request
device_id uuid The ID of the Device that received the Action Request
data object The key contains the action name, and the values contain the inputs issued for the action
status string The status of the Action Request
created_at datetime Datetime when the Action Request was created
updated_at datetime Datetime when the Action Request was last updated

Understanding Action Requests

Each time we issue an action request for a specific end device, the Seam API creates an ActionRequest object and returns its reference. It also forwards the action request to the specific device via the Seam Gateway.

The Action Request States

You will notice that the ActionRequest object has a status field which indicates the state of the action. This is because in the IoT world, everything is asynchronous, meaning that action requests can take on the order of seconds, minutes, or even days to complete.

There are currently 6 different valid statuses that are listed in the table below.

Status Description
pending The action request has been created but not yet received by the gateway
gateway_received The action request has been received by the gateway but has not yet started processing it. This could because the gateway is busy processing another non-asynchronous request or is currently updating.
gateway_failure The action request could not be sent to the gateway. Usually this is because the gateway is offline (network/power outage, updating...etc).
processing The gateway has begun processing of the action request.
completed The action request was successfully received and performed by the device
failed The action request was not successfully performed.

The Action Request Lifecycle

As seen in the table in the previous section and the diagram below, when an action request object is created, its initial status will be pending.

Action Request Lifecycle

Once the gateway has received the action request, it will update its status to gateway_received.

If the gateway fails to receive the action request, the Seam API will update the action request status to gateway_failure. Usually this is because the Gateway is offline or busy doing a software update.

When the gateway begins handling the action request, it will update its status to processing, and if the action request succeeds, it will further update it to completed. However, if the action request fails, then the gateway will update the status to failed.

Finally, when the command has been successfully completed by the end device, its status will update to completed.

Tracking the Progress of an Action Request

When you initiate an action, the API will create an action request object and return its reference. You can then receive updates on the status of the action by fetching the Action Request again or via a predefined HTTP Webhook (upcoming feature).

Get a Specific Action Request

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  "https://api.getseam.com/v1/action_requests/${ACTION_REQUEST_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

url = "https://api.getseam.com/v1/action_requests/#{ACTION_REQUEST_ID}"

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

{
    "id": "f328e715-d158-43cd-b98d-a594d3f0e210",
    "location_id": "fb4beead-029b-4a7b-a1d7-d2bfb77cce91",
    "entity_id": "f3f94eac-d5d4-43d3-ac65-2f6f80695cf8",
    "entity_type": "Gateway",
    "data": {
        "pair_devices": {
            "duration": 60
        }
    },
    "status": "completed",
    "created_at": "2020-06-23T06:47:53.206Z",
    "updated_at": "2020-06-23T06:47:53.238Z"
}

This endpoint retrieves a specific action request.

HTTP Request

GET /v1/action_requests/<ACTION_REQUEST_ID>

URL Parameters

Parameter Description
ACTION_REQUEST_ID The UUID of the action request to retrieve

GATEWAY ACTIONS

Gateway Actions represent the capabilities of a Gateway.

We discuss action requests in detail in the Understanding Action Requests section.

Pair New Device to Gateway

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"data": {"duration": 120}}' \
  "https://api.getseam.com/v1/gateways/${GATEWAY_ID}/actions/pair_devices"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

payload = {
  'data': {
    'duration': 120
  }
}

url = "https://api.getseam.com/v1/gateways/#{GATEWAY_ID}/actions/pair_devices"

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "f328e715-d158-43cd-b98d-a594d3f0e210",
    "location_id": "fb4beead-029b-4a7b-a1d7-d2bfb77cce91",
    "entity_id": "f3f94eac-d5d4-43d3-ac65-2f6f80695cf8",
    "entity_type": "Gateway",
    "data": {
        "pair_devices": {
            "duration": 60
        }
    },
    "status": "pending",
    "created_at": "2020-06-23T06:47:53.206Z",
    "updated_at": "2020-06-23T06:47:53.238Z"
}

To connect a device to a gateway, you need to put the gateway into pairing mode and manually add the end devices.

When the end devices join your Seam Gateway's network, the Gateway will automatically register them to the Seam API.

Once you issue the request, an action request will be created and sent to the gateway. You can use the action request id to track the progress of the pairing process.

HTTP Request

POST /v1/gateways/<GATEWAY_ID>/actions/pair_devices

URL Parameters

Parameter Description
GATEWAY_ID The ID of the gateway to make the request to

Query Parameters

Parameter Type Description
duration integer How long to keep the gateway into pairing mode

Remove a Device from the Gateway

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"data": {"duration": 120, "device_id": '"${DEVICE_ID}"'}}' \
  "https://api.getseam.com/v1/gateways/${GATEWAY_ID}/actions/unpair_devices"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

payload = {
  'data': {
    'duration': 120,
    'device_id': DEVICE_ID
  }
}

url = "https://api.getseam.com/v1/gateways/#{GATEWAY_ID}/actions/unpair_devices"

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "7a7362db-72cd-4538-8806-9913cf497763",
    "location_id": "fb4beead-029b-4a7b-a1d7-d2bfb77cce91",
    "entity_id": "f3f94eac-d5d4-43d3-ac65-2f6f80695cf8",
    "entity_type": "Gateway",
    "data": {
        "unpair_devices": {
            "duration": 60,
            "device_id": "772b5b3e-c6c8-4276-b8fc-6540c86d0d90"
        }
    },
    "status": "pending",
    "created_at": "2020-06-23T06:48:34.525Z",
    "updated_at": "2020-06-23T06:48:34.534Z"
}

To remove a device from a gateway, you need to put the gateway into unpairing mode and manually remove the end devices using the manufacturer's instructions.

When the end devices leaves your Seam Gateway's network, the Gateway will automatically remove them from the Seam API.

Once you issue the request, an action request will be created and sent to the gateway. You can use the action request id to track the progress of the unpairing process.

HTTP Request

POST /v1/gateways/<GATEWAY_ID>/actions/unpair_devices

URL Parameters

Parameter Description
GATEWAY_ID The ID of the gateway to make the request to

Query Parameters

Parameter Type Description
duration integer How long to keep the gateway into unpairing mode
device_id uuid The ID of the device you wish to remove

DEVICE ACTIONS

Actions represent the capabilities of a Device. Each type of device supports a unique list of actions. This Action Object defines the requisite inputs for requesting each action type.

Action Request Object

{
    "set_code": {
        "title": "Set Code",
        "description": "Set User Code for the Door Lock",
        "inputs": {
            "code": {
                "title": "Code",
                "description": "Pin Code, all numbers, can start
                    with 0, must be between 4 and 8 digits in
                    length",
                "type": "string"
            },
            "slot_id": {
                "title": "Slot ID",
                "description": "2 through 11",
                "type": "integer"
            }
        }
    }
}
Parameter Type Description
title string A title of the Action
description string A description of the Action
inputs object An input object with: a title for the input, a description of its validation parameters, and its primitive type (one of null, boolean, object, array, number, integer or string)

Issuing an Action Request to a Device

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}/actions/${ACTION_NAME}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

url = "https://api.getseam.com/v1/devices/#{DEVICE_ID}/actions/#{ACTION_NAME}"

payload = {
}

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
    "status": "pending",
    "device_id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "created_at": "2020-02-10T01:33:19.955Z",
    "updated_at": "2020-02-10T01:33:19.955Z",
    "data": {
        "lock": {}
    }
}

This endpoint requests an Action from a specific device. You will receive an Action Request object as a response. The Action Request can be used to track the progress of the request. Please read the Understanding Action Requests section for a more thorough explanation of the Action Request lifecycle.

HTTP Request

POST /v1/devices/<DEVICE_ID>/actions/<ACTION_NAME>

URL Parameters

Parameter Description
DEVICE_ID The ID of the device to retrieve
ACTION_NAME The Name of the Action requested

Query Parameters

Please refer to the Inputs field in the Device Actions list to see the requirements of each input

EVENTS

Each and every time an action takes place on one of your device or gateway, a device event gets created. For example, an individual manually unlocking a door would generate an event.

You can find out more about how to receive event notifications in the Webhooks section.

Event Object

{
    "type": "device_event",
    "details": {
        "method": "pin_code"
    },
    "device_id": "c28590b4-4556-44cc-8694-31489aa27ebb",
    "event_name": "door unlocked",
    "date_created": "2020-06-11T21:08:36.000Z"
}
Parameter Type Description
type string the type of event
device_id uuid the ID of the device for which the event occurred
event_name string the name of the event that occurred
details object contains additional information about the event, such as the method that triggered the event
date_created timestamp indicates when the event took place

WEBHOOKS

Seam allows you to configure webhook endpoints to receive notification when certain events occur (see events section).

Setting Up Webhooks

Workspace Group Gateway End Devices Architecture You can add a webhook endpoint by going to the Webhook menu on your dashboard. Seam supports Basic HTTP Auth for webhook and will include credentials in every webhook requests if you provide them.

Testing a Webhook Endpoint

Not available. See one of the runtime language examples.
# Using Sinatra
require 'sinatra'

use Rack::Auth::Basic, "Protected Area" do |username, password|
  username == 'username' && password == 'a_strong_password'
end

post '/webhooks' do
  payload = request.body.read
  print("Received Seam webhook: payload=#{payload}")

  status 200
end
/* Using Express */
const app = require('express')();
const basicAuth = require('express-basic-auth')

app.use(basicAuth({
    users: { 'username': 'a_strong_password' }
}))

// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');

app.post('/webhooks', bodyParser.json(), (request, response) => {

    console.log(`Incoming webhook request:`);
    console.log(request.body);
    return response.json({received: true});
});

app.listen(4242, () => console.log('Running on port 4242'));

The above command will receive incoming request with JSON structured like this:

{
    "type": "device_event",
    "details": {
        "method": "pin_code"
    },
    "device_id": "c28590b4-4556-44cc-8694-31489aa27ebb",
    "event_name": "door unlocked",
    "date_created": "2020-06-11T21:08:36.000Z"
}

This endpoint on your server receives webhooks from the Seam API. Make sure to return a 200 status, otherwise the Seam API will retry the webhook after some initial back-off.

Verifying Webhook Signatures (Coming Soon)

#Seam-Signature Verification:
timestamp=1588998550
v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
endpoint_secret = 'whsec_...'
body='{"event":"door","type":"door_event"}'

signed_payload="${timestamp}.${body}"

echo -n $signed_payload | openssl dgst -sha256 -hmac $endpoint_secret -binary | base64
require 'openssl'
require "base64"

#Seam-Signature Verification:
timestamp=1588998550
v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
endpoint_secret = 'whsec_...'
body='{"event":"door","type":"door_event"}'

signed_payload="#{timestamp}.#{body}"

hash  = OpenSSL::HMAC.digest('sha256', endpoint_secret, signed_payload)
puts Base64.encode64(hash)

The Seam-Signature header included in each signed webhook requests contains a timestamp and one signatures. The timestamp is prefixed by t=, and each signature is prefixed by the API version (v1=).

Seam generates signatures using a hash-based message authentication code (HMAC) with SHA-256.

Step 1: Extract the timestamp and signatures from the header

Split the header, using the , character as the separator, to get a list of the timestamp and signature elements. Then split each element, using the = character as the separator, to get a prefix and value pair.

As mentioned above, the value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature. You can discard everything else, if any.

Step 2: Prepare the signed_payload string

The signed_payload string is created by concatenating:

Step 3: Get your endpoint signing secret

Before you can generate the signature, you need to obtain your endpoint's signing secret. To do so, go to the Webhook section in the dashboard and copy the value there.

Step 4: Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use your endpoint’s signing secret as the key, and use the signed_payload string as the message.s

Step 5: Compare the signatures

Compare the signature (or signatures) in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.

To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.

Preventing Replay Attacks

A replay attack is when an attacker intercepts a valid payload and its signature, then re-transmits them.

To mitigate such attacks, Seam includes a timestamp in the Seam-Signature header.Because this timestamp is part of the signed payload, it is also verified by the signature, so an attacker cannot just change the timestamp without invalidating the signature.

If the signature is valid but the timestamp is too old, you can simply reject the payload. In general, we'd recommend a tolerance of 5 minutes between the timestamp signature and the current time. Use Network Time Protocol (NTP) to ensure that your server’s clock is accurate and synchronizes with the time on Seam’s servers.

DOOR LOCKS

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "manufacturer": "Kwikset",
    "name": "Kwikset914 5c:a1:0",
    "actions": {
        "lock": {
            "title": "Lock",
            "description": "Locks the Door Lock",
            "inputs": null
        },
        "unlock": {
            "title": "Unlock",
            "description": "Unlocks the Door Lock",
            "inputs": null
        },
        "set_code": {
            "title": "Set Code",
            "description": "Set User Code for the Door Lock",
            "inputs": {
                "code": {
                    "title": "Code",
                    "description": "Pin Code, all numbers, can start
                        with 0, must be between 4 and 8 digits in
                        length",
                    "type": "string"
                },
                "slot_id": {
                    "title": "Slot ID",
                    "description": "2 through 11",
                    "type": "integer"
                }
            }
        },
        "clear_code": {
            "title": "Clear Code",
            "description": "Clear a User Code for the Door Lock",
            "inputs": {
                "slot_id": {
                    "title": "Slot ID",
                    "description": "2 through 11",
                    "type": "integer"
                }
            }
        }
    }
}

Door locks are currently the only device type supported by the Seam API.

At the moment, the API supports 4 basic commands:

As you can see on the right side, a door lock device object will indicate its supported commands given a manufacturer/model type.

Lock a Door

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}/actions/lock"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

url = "https://api.getseam.com/v1/devices/#{DEVICE_ID}/actions/lock"

RestClient.post(url, {}, headers: headers)

The above command returns JSON structured like this:

{
    "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
    "status": "pending",
    "device_id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "created_at": "2020-02-10T01:33:19.955Z",
    "updated_at": "2020-02-10T01:33:19.955Z",
    "data": {
        "lock": {}
    }
}

This endpoint issues a "lock" action to a door lock.

HTTP Request

POST /v1/devices/<DEVICE_ID>/actions/lock

URL Parameters

Parameter Description
DEVICE_ID The ID of the device you're commanding

Unlock a Door

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}/actions/unlock"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

url = 'https://api.getseam.com/v1/devices/#{DEVICE_ID}/actions/unlock'

RestClient.post(url, {}, headers: headers)

The above command returns JSON structured like this:

{
    "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
    "status": "pending",
    "device_id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "created_at": "2020-02-10T01:33:19.955Z",
    "updated_at": "2020-02-10T01:33:19.955Z",
    "data": {
        "unlock": {}
    }
}

This endpoint issues a "unlock" action to a door lock.

HTTP Request

POST /v1/devices/<DEVICE_ID>/actions/unlock

URL Parameters

Parameter Description
DEVICE_ID The ID of the device you're commanding

Set a Pin Code

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"data": {"code": "8888", "slot_id": 8}}' \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}/actions/set_code"
require 'rest-client'

token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

payload = {
  'data': {
    'code': '8888',
    'slot_id': 8
  }
}

url = 'https://api.getseam.com/v1/devices/#{DEVICE_ID}/actions/set_code'

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
    "status": "pending",
    "device_id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "created_at": "2020-02-10T01:33:19.955Z",
    "updated_at": "2020-02-10T01:33:19.955Z",
    "data": {
        "set_code": {
            "code": "8888",
            "slot_id": 8
        }
    }
}

This endpoint issues a "set_code" action to a door lock.

The Seam API allows you to set a different code for up to 10 different users. To do set the a code for a specific user, set the slot_id parameter to a value between 1 to 10. If you do not provide this value, the slot_id will default to 1.

HTTP Request

POST /v1/devices/<DEVICE_ID>/actions/set_code

URL Parameters

Parameter Description
DEVICE_ID The ID of the device you're commanding

Query Parameters

Parameter Type Description
code String Code to be programmed
slot_id integer ID of the Code slot to be programmed in

Clear a Pin Code

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"data": {"slot_id": 8}}' \
  "https://api.getseam.com/v1/devices/${DEVICE_ID}/actions/clear_code"
require 'rest-client'

token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}",
  "Content-Type": "application/json"
}

payload = {
  data: {
    slot_id: 8
  }
}

url = 'https://api.getseam.com/v1/devices/#{DEVICE_ID}/actions/clear_code'

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
    "status": "pending",
    "device_id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "created_at": "2020-02-10T01:33:19.955Z",
    "updated_at": "2020-02-10T01:33:19.955Z",
    "data": {
        "clear_code": {
            "slot_id": 8
        }
    }
}

This endpoint issues a "clear_code" action to a door lock.

HTTP Request

POST /v1/devices/<DEVICE_ID>/actions/clear_code

URL Parameters

Parameter Description
DEVICE_ID The ID of the device you're commanding

Query Parameters

Parameter Type Description
slot_id integer ID of Code slot to be programmed in

DOOR LOCK EVENTS

An unlock event that indicate a user manually entered a pin code to open the door:

{
    "type": "device_event",
    "details": {
        "method": "pin_code"
    },
    "device_id": "c28590b4-4556-44cc-8694-31489aa27ebb",
    "event_name": "door unlocked",
    "date_created": "2020-06-11T21:08:36.000Z"
}

An lock event that indicate a user manually locked the door:

{
    "type": "device_event",
    "details": {
        "method": "manual"
    },
    "device_id": "c28590b4-4556-44cc-8694-31489aa27ebb",
    "event_name": "door locked",
    "date_created": "2020-06-11T21:12:20.000Z"
}

Door locks generate events of type device_events each time they are locked and unlocked. Depending on the door lock manufacturer and model, certain locks provide more granular information such as the method by which the door was locked or unlocked, which access code was used...etc.

As the level of event information granularity varies on a door-lock model basis, please check with us first if you have a specific use case in mind and we can help recommend the right device model.

Event Name Description
door unlocked Triggered whenever the doorlock is unlocked
door locked Triggered whenever the doorlock is switched to a locked state

ACCESS CODES

This is a higher level application for programming door codes on top of Door Locks API.

By creating an Access Code object, you are programming a code on a given set of Devices. Seam enables you to program a scheduled access code or an ongoing access code.

The API allows you to retrieve information about access codes (either individually or as a list), create, update and cancel access codes.

Access Code Object

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Customer-generated Label",
    "start_date": "2020-01-01T12:12:12",
    "end_date": "2020-01-05T12:12:12",
    "code": "1234",
    "devices": [
        {
            "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
            "name": "Room 203 Lock"
        }
    ]
}
Parameter Type Description
id uuid The ID of the Device
label string Customer generated Label
start_date string Start Time for Access Code. See discussion of date formats below.
end_date string End Time for Access Code. See discussion of date formats below.
timezone string The access code timezone (ex: America/New_York). See discussion of date formats below.
code string Key code for Access Code
devices Device[] Devices programmed with this Access Code

Create an Access Code

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"label": "Booking 123", "start_date": "2020-01-01T12:12:12", "end_date": "2020-01-05T12:12:12" }' \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes"

RestClient.post(url, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Booking 123",
    "start_date": "2020-01-01T12:12:12",
    "end_date": "2020-01-05T12:12:12",
    "code": "1234",
    "devices": []
}

This endpoint retrieves a specific access code. The list of devices are encoded with this access code.

HTTP Request

POST /v1/locations/<LOCATION_ID>/access_codes

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to retrieve

Query Parameters

Parameter Type Description Required
label String Name of Access Code True
code String Code to be programmed False
start_date string Local datetime string False
end_date string Local datetime string False

Date Format

We support separated Datetime and Timezone components.

With separated date time/timezone components, a local access can be created by omitting the timezone. If the timezone is specified, the access start and end times will be adjusted to the location of the door lock. For example, an access code that ends at 00:00 in America/Vancouver will end at 03:00 in America/New_York. A local access code that ends at 00:00 will end at midnight in both timezones.

Omitting date/time data will result in an ongoing access. Omitting timezone data will result in a local access.

Getting All Your Access Codes at a Location

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes"

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

[
    {
        "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
        "label": "Booking 1234",
        "start_date": "2020-01-01T12:12:12",
        "end_date": "2020-01-05T12:12:12",
        "code": "1234",
        "devices": [
            {
                "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
                "name": "Room 203 Lock"
            }
        ]
    },
    {
        "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
        "label": "Booking 4567",
        "start_date": "2020-01-01T12:12:12",
        "end_date": "2020-01-05T12:12:12",
        "code": "9595",
        "devices": [
            {
                "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
                "name": "Main Entrance"
            },
            {
                "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
                "name": "Room 204 Lock"
            }
        ]
    },
]

You can issue the following request to retrieve all the access codes programmed at a location.

HTTP Request

GET /v1/locations/<LOCATION_ID>/access_codes

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access codes to retrieve

Get an Access Code

curl -X GET \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes/${ACCESS_CODE_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes/#{ACCESS_CODE_ID}"

RestClient.get(url, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Customer-generated Label",
    "start_date": "2020-01-01T12:12:12",
    "end_date": "2020-01-05T12:12:12",
    "code": "1234",
    "devices": [
        {
            "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
            "name": "Room 203 Lock"
        }
    ]
}

This endpoint retrieves a specific access code. The list of devices are encoded with this access code.

HTTP Request

GET /v1/locations/<LOCATION_ID>/access_codes/<ACCESS_CODE_ID>

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to retrieve
ACCESS_GROUP_ID The ID of the access code to retrieve

Update an Access Code

curl -X PUT \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"label": "Booking 123", "start_date": "2020-01-01T12:12:12", "end_date": "2020-01-05T12:12:12" }' \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes/${ACCESS_CODE_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

payload = {
    label: "Booking 123",
    start_date: "2020-01-02T12:12:12",
    end_date: "2020-01-03T12:12:12"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes/#{ACCESS_CODE_ID}"

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Booking 123",
    "start_date": "2020-01-02T12:12:12",
    "end_date": "2020-01-03T12:12:12",
    "code": "1234",
    "devices": []
}

This endpoint updates a specific access code

HTTP Request

DELETE /v1/locations/<LOCATION_ID>/access_codes/<ACCESS_CODE_ID>

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to modify
ACCESS_CODE_ID The ID of the access code to modify

Query Parameters

Parameter Type Description Required
label String Name of Access Code False
code String Code to be programmed False
start_date string Local datetime string False
end_date string Local datetime string False

Delete an Access Code

curl -X DELETE \
  -u "${YOUR_API_KEY}:" \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes/${ACCESS_CODE_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes/#{ACCESS_CODE_ID}"

RestClient.post(url, headers: headers)

The above command returns JSON structured like this:

{
    "success": true
}

This endpoint deletes a specific access code

HTTP Request

DELETE /v1/locations/<LOCATION_ID>/access_codes/<ACCESS_CODE_ID>

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to delete
ACCESS_CODE_ID The ID of the access code to delete

Add a Device to an Access Code

curl -X POST \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"device_id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48" }' \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes/${ACCESS_CODE}/devices"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

payload = {
  "device_id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes/#{ACCESS_CODE_ID}/devices"

RestClient.post(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Booking 123",
    "start_date": "2020-01-01T12:12:12",
    "end_date": "2020-01-05T12:12:12",
    "code": "1234",
    "devices": [
        {
            "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
            "name": "Room 205 Lock"
        }
    ]
}

This endpoint adds a device to an access code.

HTTP Request

POST /v1/locations/<LOCATION_ID>/access_codes/<ACCESS_CODE_ID>/devices

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to modify
ACCESS_CODE_ID The ID of the access code to modify

Query Parameters

Parameter Type Description Required
device_id UUID ID of Device to add True

Delete a Device from an Access Code

curl -X DELETE \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"device_id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48" }' \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes/${ACCESS_CODE}/devices/${DEVICE_ID}"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes/#{ACCESS_CODE_ID}/devices/#{DEVICE_ID}"

RestClient.post(url, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Booking 123",
    "start_date": "2020-01-01T12:12:12",
    "end_date": "2020-01-05T12:12:12",
    "code": "1234",
    "devices": []
}

This endpoint adds a device to an access code.

HTTP Request

POST /v1/locations/<LOCATION_ID>/access_codes/<ACCESS_CODE_ID>/devices/<DEVICE_ID>

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to modify
ACCESS_CODE_ID The ID of the access code to modify
DEVICE_ID The ID of the device to remove

Add/Remove Devices to/from an Access Code

curl -X PATCH \
  -u "${YOUR_API_KEY}:" \
  -H "Content-Type: application/json" \
  -d '{"add_ids": ["cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48"], "remove_ids": ["cb41f7cf-b49d-4e8b-856c-5e12d1b8ca3] }' \
  "https://api.getseam.com/v1/locations/${LOCATION_ID}/access_codes/${ACCESS_CODE}/devices"
require 'base64'
require 'rest-client'


token = Base64.strict_encode64("#{YOUR_API_KEY}:")
headers = {
  "Authorization": "Basic #{token}"
}

payload = {
  "add_ids": ["cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48"],
  "remove_ids": ["cb41f7cf-b49d-4e8b-856c-5e12d1b8ca3"]
}

url = "https://api.getseam.com/v1/locations/#{LOCATION_ID}/access_codes/#{ACCESS_CODE_ID}/devices"

RestClient.patch(url, payload, headers: headers)

The above command returns JSON structured like this:

{
    "id": "9980a513-7a7b-434c-801f-27008fd0fcda",
    "label": "Booking 123",
    "start_date": "2020-01-01T12:12:12",
    "end_date": "2020-01-05T12:12:12",
    "code": "1234",
    "devices": [
        {
            "id": "cb41f7cf-b49d-4e8b-856c-5e12d1b8ca48",
            "name": "Room 205 Lock"
        }
    ]
}

This endpoint adds or removes devices to an access code.

HTTP Request

PATCH /v1/locations/<LOCATION_ID>/access_codes/<ACCESS_CODE_ID>/devices

URL Parameters

Parameter Description
LOCATION_ID The ID of the location of the access code to modify
ACCESS_CODE_ID The ID of the access code to modify

Query Parameters

Parameter Type Description Required
add_ids Array List of Device IDs to be added False
remove_ids Array List of Device IDs to be removed False

API COMPATIBILITY

The Seam API is versioned via a prefix in the URL. Currently, we only support v1 of the API via https://api.getseam.com/v1/.

Within an API version, we strive to only make backwards-compatible changes to the API.

This means that a client that integrates with v1 of our REST API will continue to work when querying v1 in the future.

SUPPORT

Please send API support request to [email protected] We generally respond to support requests and bug reports within a few hours. Our company also provides Slack shared channels where your team can directly interact with our engineers.




last revision: June 24th, 2020