Skip to content
API
On this pageBefore you start

Read a lock end to end

List locks, open one detail record, and read its live state.

This guide follows one lock through all three read-only operations. Use the same API key and base URL for every request.

Before you start

Ask an organization administrator for a key with both read scopes:

ScopeAllows
locks:readList locks and read lock details.
lock-state:readAsk the provider for a live locked or unlocked state.

Set the environment that issued the key. Use the production URL for a production key or the dev URL for a dev key.

sh
export MYREMOTELY_BASE_URL='https://app.myremotely.ai'
export MYREMOTELY_API_KEY='mr_lock_REPLACE_WITH_YOUR_KEY'

Do not send a dev key to production or a production key to dev.

1. List active locks

GET /v1/locks returns active locks owned by the key organization. limit is optional and must be an integer from 1 to 100. If the response has a non-null nextCursor, send that opaque value unchanged as cursor on the next list request.

sh
curl --fail-with-body \
  --header "x-api-key: $MYREMOTELY_API_KEY" \
  "$MYREMOTELY_BASE_URL/v1/locks?limit=20"

The response root contains:

FieldMeaning
dataActive locks in this page.
nextCursorCursor for the next page, or null on the last page.

Each item in data contains only these safe fields:

FieldMeaning
idPublic lock ID. Use it as lockId in the next two operations.
nameLock display name.
connectivityCached online, offline, or error status. It is not the live lock state.
batteryLevelBattery percentage from 0 to 100.
lastOnlineAtLast online time, or null when unknown.
unitIdsPublic IDs of units bound to the lock.
createdAtLock record creation time.
updatedAtLast lock record update time.

2. Read lock details

Take one id from the list response. GET /v1/locks/{lockId} returns the same safe lock data and expands unitIds into units with id and name.

sh
LOCK_ID='lock_demo_01'

curl --fail-with-body \
  --header "x-api-key: $MYREMOTELY_API_KEY" \
  "$MYREMOTELY_BASE_URL/v1/locks/$LOCK_ID"

The detail response contains id, name, connectivity, batteryLevel, lastOnlineAt, units, createdAt, and updatedAt. It does not contain provider IDs, passcodes, credentials, notes, or entry instructions.

3. Read live state

GET /v1/locks/{lockId}/state asks the provider for the current lock state. It does not use cached connectivity as the answer.

sh
curl --fail-with-body \
  --header "x-api-key: $MYREMOTELY_API_KEY" \
  "$MYREMOTELY_BASE_URL/v1/locks/$LOCK_ID/state"
FieldWhen presentMeaning
stateAlwayslocked, unlocked, or unknown.
reasonWhen state is unknownStable reason why no live state was available.
checkedAtAlwaysTime when MyRemotely checked the live state.

TypeScript example

This server-side example performs the same list → detail → live-state flow.

ts
const baseUrl = process.env.MYREMOTELY_BASE_URL
const apiKey = process.env.MYREMOTELY_API_KEY

if (!baseUrl || !apiKey) throw new Error('API base URL and key are required')

const headers = { 'x-api-key': apiKey }
const readJson = async (path: string) => {
  const response = await fetch(`${baseUrl}${path}`, { headers })
  if (!response.ok)
    throw new Error(`MyRemotely API returned ${response.status}`)
  return response.json()
}

const page = await readJson('/v1/locks?limit=20')
const lockId = page.data[0]?.id
if (!lockId) throw new Error('No active lock is available')

const encodedLockId = encodeURIComponent(lockId)
const detail = await readJson(`/v1/locks/${encodedLockId}`)
const liveState = await readJson(`/v1/locks/${encodedLockId}/state`)

Errors by operation

Every error uses RFC 9457 application/problem+json with a stable code and requestId.

OperationScopeOperation-specific errors
List lockslocks:read400 invalid_request for an invalid limit; 404 cursor_not_found for an invalid or cross-organization cursor.
Get a locklocks:read404 lock_not_found for a missing, retired, or cross-organization lock.
Get live statelock-state:read404 lock_not_found for a missing, retired, or cross-organization lock.

All three operations can also return 401 invalid_api_key, 403 missing_scope, 429 rate_limited, or 500 internal_error. For 429, wait for the number of seconds in Retry-After.

See the complete API reference and error handling guide.

Last updated Sep 16, 2026