Remote Operate#
Use the remote operate endpoint to lock, unlock, or get the status of a lock.
Here is a quick example using cURL.
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/status
Note
When you call this endpoint, the API sends a command to the lock through the bridge. So the bridge must be plugged in and connected to WiFi.
Available Actions#
These are the actions you can perform with the remote operate endpoint.
| Action | Description |
|---|---|
| lock | Lock the lock. |
| unlock | Unock the lock. |
| status | Get the status of the lock. |
| rebootLock | Reboot the lock. |
Synchronous vs Asynchronous#
You may call the remote operate endpoint in either asynchronous or synchronous mode. To do so, set the type query parameter to either async or sync. If you do not include a type query parameter then the API will default to sync.
- synchronous - The API will wait for the lock to finish the remote operation before it returns the results in the response body.
- asynchronous - The API will not wait for the lock. It immediately returns a 202 and an empty response body. To get the results of the remote operation you must use a webhook.
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/status?type=sync
Automatic Retries#
By default, the API will try three times to complete your remote lock operation. Each time it tries, it will wait up to 30 seconds for a response. That could mean waiting 90 seconds only to find out that your request failed! This is true for both synchronous and asynchronous requests.
If you would like to limit the number of tries made by the API, you can pass the optional query parameter retryLimit.
- You can set it to 1, 2, or 3.
- If you set it below 1, it will be set to 1.
- If you try above 3, it will be set to 3.
- If you do not include a
retryLimitparameter, the API will default to 3.
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/status?retryLimit=2
Webhooks#
The API can send a one-time webhook with the results of a remote operation. To do so, call the remote operate endpoint and include a webhook parameter in the request body.
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
--data '{ "webhook": "https://hook.example.com/unique-id" }' \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/status
Setting a one-time webhook is optional.
You can set a one-time webhook in both synchronous and asynchronous mode. So there are four ways to get the result of a remote operation.
| type | with webhook | no webhook |
|---|---|---|
| sync | result in response body and webhook | result in response body |
| async | result in webhook | no result. not advised. |
Furthermore, you can also have a persistent webhook on the lock -- setting a one-time webhook does not affect an existing persistent webhook. That means for a synchronous call you can get the final status three different ways:
- the return value from a remote operate call with
type=sync, - a one-time webhook, and
- a persistent webhook.
Secure Mode#
As an extra security step, you can use the secure mode version of the remote operate endpoint. It is designed to guard against replay attacks.
- Call the
GET /locks/:lockIDendpoint and save theremoteOperateSecretfield. - Call the
PUT /remoteoperate/:lockID/:command- Include the
Accept-Versionheader and set its value to2.0.0. - Include the
ivparameter in the request body. The initialization vector is a random hexadecimal string that is 32 characters long. - Include the
tokenparameter in the request body. The token is the current epoch timestamp in milliseconds, encrypted using the lock'sremoteOperateSecretfield, theiv, and the aes-256-cbc algorithm. Tokens are valid for 5 minutes.
- Include the
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
-H "Accept-Version: 2.0.0" \
--data '{ "iv": "9b89adce5e3fcee7a585624a0c948d68", "token": "f1cb5bb034ad823019d7bc337b05a745" }' \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/status
More Examples#
Status#
Use status when you want to get the current state of the lock.
Path#
remoteoperate/:lockID/status
Request#
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/status
Response#
For information about individual response fields, see the API reference.
{
"status": "kAugLockState_Unlocked",
"info": {
"action": "status",
"startTime": "2021-07-07T19:06:36.393Z",
"context": {
"transactionID": "yNdUeQ_2Y",
"startDate": "2021-07-07T19:06:36.392Z",
"retryCount": 1
},
"lockType": "lock_version_5",
"serialNumber": "L5W0000001",
"rssi": -1,
"wlanRSSI": -48,
"wlanSNR": -1,
"duration": 9212,
"lockID": "000LOCK0ID00000",
"bridgeID": "123456789012345678901234",
"serial": "L5W0000001"
},
"doorState": "kAugDoorState_Closed",
"retryCount": 1,
"totalTime": 9221,
"resultsFromOperationCache": false
}
Lock#
Use lock when you want to lock the lock.
Path#
remoteoperate/:lockID/lock
Request#
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/lock
Response#
{
"status": "kAugLockState_Locked",
"info": {
"action": "lock",
"startTime": "2021-07-07T19:06:36.393Z",
"context": {
"transactionID": "yNdUeQ_2Y",
"startDate": "2021-07-07T19:06:36.392Z",
"retryCount": 1
},
"lockType": "lock_version_5",
"serialNumber": "L5W0000001",
"rssi": -1,
"wlanRSSI": -48,
"wlanSNR": -1,
"duration": 9212,
"lockID": "000LOCK0ID00000",
"bridgeID": "123456789012345678901234",
"serial": "L5W0000001"
},
"doorState": "kAugDoorState_Closed",
"retryCount": 1,
"totalTime": 9221,
"resultsFromOperationCache": false
}
Unlock#
Use unlock when you want to unlock the lock.
Path#
remoteoperate/:lockID/unlock
Request#
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/unlock
Response Success#
{
"status": "kAugLockState_Unlocked",
"info": {
"action": "unlock",
"startTime": "2021-07-07T19:17:48.325Z",
"context": {
"transactionID": "kmRA9-fGj",
"startDate": "2021-07-07T19:17:48.323Z",
"retryCount": 1
},
"lockType": "lock_version_5",
"serialNumber": "L5W0000001",
"rssi": -1,
"wlanRSSI": -49,
"wlanSNR": -1,
"duration": 7429,
"lockID": "000LOCK0ID00000",
"bridgeID": "123456789012345678901234",
"lockStatusChanged": true,
"serial": "L5W0000001"
},
"doorState": "kAugDoorState_Closed",
"retryCount": 1,
"totalTime": 7440,
"resultsFromOperationCache": false
}
Response Failure#
{
"timeStamp": 1721845799947,
"status": "unknown",
"result": "failed",
"error": {
"jse_shortmsg": "",
"jse_info": {},
"message": "LockCommandTimeout",
"statusCode": 408,
"body": {
"code": 102,
"message": "LockCommandTimeout"
},
"restCode": 102,
"name": "ERRNO_LOCK_COMMAND_TIMEOUT",
"code": "Error"
},
"info": {
"lockID": "000LOCK0ID00000",
"action": "unlock"
}
}
Reboot Lock#
Use rebootLock when you want to reboot the lock.
Supported Locks
Only locks that use the Connected by August module support rebooting.
Path#
remoteoperate/:lockID/rebootLock
Request#
curl -X PUT \
-H "x-august-api-key: $APIKEY" \
-H "x-august-access-token: $AUGTOKEN" \
-H "Content-Type: application/json" \
https://api-production.august.com/remoteoperate/000LOCK0ID00000/rebootLock
Response#
{
"success": true,
"info": {
"serial": "C3WJA0008J"
},
"retryCount": 1,
"totalTime": 3437,
"resultsFromOperationCache": false
}
Remember to expect the unexpected!
That is, August may include new fields in the JSON object, or might add new values for existing fields at any time. You should ignore data you don't understand.