openapi: 3.0.3 info: title: Schlage Home API version: '2.0' description: | Schlage Home API V2 - REST + webhook API for the Schlage Home residential smart-lock platform (Schlage Encode, Encode Plus, Encode Lever). Designed for business and commercial integrations (partner apps, smart-home automation platforms) that scale across residential deployments. Uses OAuth 2.0 Authorization Code flow against account.schlage.com. Device management commands are asynchronous (202 ACCEPTED), with downstream device state surfaced via webhook events. Generated from public documentation at https://developer.allegion.com/en/products/schlage-home (Getting Started, Schlage Home API V2, Best Practices, Access Codes, Release Notes, Blog). Path naming and shapes are inferred where docs describe semantics but do not publish a verbatim endpoint catalogue. contact: name: Allegion Developer Support url: https://developersupport.allegion.com/hc/en-us termsOfService: https://developer.allegion.com/en/index.html license: name: Allegion Developer Terms url: https://developer.allegion.com/en/index.html servers: - url: https://api.allegion.com/schlage-home description: Production - url: https://api.allegion.com/schlage-home/v2 description: Production (v2 path prefix) tags: - name: Devices description: Manage and read Schlage Home WiFi-enabled smart locks - name: Access Codes description: Create, schedule, update, and delete numeric access codes per device - name: Commands description: Track the asynchronous status of lock / unlock and configuration commands - name: Webhook Subscriptions description: Subscribe partner endpoints to device, command, access code, and account events security: - OAuth2: [] paths: /devices: get: tags: [Devices] summary: List Devices description: Returns the WiFi-enabled Schlage Home devices the authenticated user account has authorized for this integration. operationId: listDevices responses: '200': description: Devices returned content: application/json: schema: type: object properties: devices: type: array items: $ref: '#/components/schemas/Device' '401': { $ref: '#/components/responses/Unauthorized' } '429': { $ref: '#/components/responses/RateLimited' } /devices/{deviceId}: get: tags: [Devices] summary: Get Device description: Returns a single device including lock state, battery level, WiFi signal strength, firmware, and connectivity state. operationId: getDevice parameters: - $ref: '#/components/parameters/DeviceId' responses: '200': description: Device returned content: application/json: schema: $ref: '#/components/schemas/Device' '401': { $ref: '#/components/responses/Unauthorized' } '404': { $ref: '#/components/responses/NotFound' } put: tags: [Devices] summary: Update Device description: Update device configuration (name, default lock timer, vacation mode). Returns 202 ACCEPTED and emits a command that completes asynchronously. operationId: updateDevice parameters: - $ref: '#/components/parameters/DeviceId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DeviceUpdate' responses: '202': { $ref: '#/components/responses/CommandAccepted' } '401': { $ref: '#/components/responses/Unauthorized' } '404': { $ref: '#/components/responses/NotFound' } /devices/{deviceId}/lock: post: tags: [Devices] summary: Lock Device description: Issue an asynchronous lock command. Returns 202 ACCEPTED with a command id; final state surfaces via webhook. operationId: lockDevice parameters: - $ref: '#/components/parameters/DeviceId' responses: '202': { $ref: '#/components/responses/CommandAccepted' } /devices/{deviceId}/unlock: post: tags: [Devices] summary: Unlock Device description: Issue an asynchronous unlock command. Returns 202 ACCEPTED with a command id; final state surfaces via webhook. operationId: unlockDevice parameters: - $ref: '#/components/parameters/DeviceId' responses: '202': { $ref: '#/components/responses/CommandAccepted' } /devices/{deviceId}/access-codes: get: tags: [Access Codes] summary: List Access Codes description: List access codes currently stored on the device. operationId: listAccessCodes parameters: - $ref: '#/components/parameters/DeviceId' responses: '200': description: Access codes returned content: application/json: schema: type: object properties: accessCodes: type: array items: $ref: '#/components/schemas/AccessCode' post: tags: [Access Codes] summary: Create Access Code description: Create a numeric access code on the device with an Always, Temporary, or Recurring schedule. Returns 202 ACCEPTED. operationId: createAccessCode parameters: - $ref: '#/components/parameters/DeviceId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AccessCodeCreate' responses: '202': { $ref: '#/components/responses/CommandAccepted' } /devices/{deviceId}/access-codes/{accessCodeId}: get: tags: [Access Codes] summary: Get Access Code operationId: getAccessCode parameters: - $ref: '#/components/parameters/DeviceId' - $ref: '#/components/parameters/AccessCodeId' responses: '200': description: Access code returned content: application/json: schema: $ref: '#/components/schemas/AccessCode' put: tags: [Access Codes] summary: Update Access Code description: Update an access code name or schedule. The numeric code itself is not changed by name updates. operationId: updateAccessCode parameters: - $ref: '#/components/parameters/DeviceId' - $ref: '#/components/parameters/AccessCodeId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AccessCodeUpdate' responses: '202': { $ref: '#/components/responses/CommandAccepted' } delete: tags: [Access Codes] summary: Delete Access Code operationId: deleteAccessCode parameters: - $ref: '#/components/parameters/DeviceId' - $ref: '#/components/parameters/AccessCodeId' responses: '202': { $ref: '#/components/responses/CommandAccepted' } /devices/{deviceId}/commands/{commandId}: get: tags: [Commands] summary: Get Command Status description: Retrieve the current status of a previously issued device command. Error messages are populated on failure. operationId: getCommand parameters: - $ref: '#/components/parameters/DeviceId' - in: path name: commandId required: true schema: { type: string } responses: '200': description: Command status returned content: application/json: schema: $ref: '#/components/schemas/Command' /webhooks/subscriptions: get: tags: [Webhook Subscriptions] summary: List Webhook Subscriptions operationId: listWebhookSubscriptions responses: '200': description: Subscriptions returned content: application/json: schema: type: object properties: subscriptions: type: array items: $ref: '#/components/schemas/WebhookSubscription' post: tags: [Webhook Subscriptions] summary: Create Webhook Subscription description: | Register an HTTPS callback URL for one or more event types. On subscription creation an OPTIONS validation request is sent to the URL and must receive a 2xx response within 30 seconds or the subscription is not created. operationId: createWebhookSubscription requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookSubscriptionCreate' responses: '201': description: Subscription created content: application/json: schema: $ref: '#/components/schemas/WebhookSubscription' '400': { $ref: '#/components/responses/BadRequest' } /webhooks/subscriptions/{subscriptionId}: get: tags: [Webhook Subscriptions] summary: Get Webhook Subscription operationId: getWebhookSubscription parameters: - in: path name: subscriptionId required: true schema: { type: string } responses: '200': description: Subscription returned content: application/json: schema: $ref: '#/components/schemas/WebhookSubscription' delete: tags: [Webhook Subscriptions] summary: Delete Webhook Subscription operationId: deleteWebhookSubscription parameters: - in: path name: subscriptionId required: true schema: { type: string } responses: '204': description: Subscription deleted components: securitySchemes: OAuth2: type: oauth2 flows: authorizationCode: authorizationUrl: https://account.schlage.com/OAuth2/authorize tokenUrl: https://account.schlage.com/OAuth2/token scopes: devices.read: Read device state, battery, connectivity, and firmware devices.write: Issue lock, unlock, and configuration commands access_codes.read: Read access codes stored on devices access_codes.write: Create, update, and delete access codes webhooks.manage: Create, list, and delete webhook subscriptions parameters: DeviceId: in: path name: deviceId required: true schema: { type: string } description: Unique identifier for a Schlage Home device. AccessCodeId: in: path name: accessCodeId required: true schema: { type: string } description: Unique identifier for an access code on a specific device. responses: Unauthorized: description: Access token missing, expired, or insufficient scope. content: application/json: schema: { $ref: '#/components/schemas/Error' } NotFound: description: Resource not found. content: application/json: schema: { $ref: '#/components/schemas/Error' } BadRequest: description: Request validation failed. content: application/json: schema: { $ref: '#/components/schemas/Error' } RateLimited: description: Rate limit exceeded. content: application/json: schema: { $ref: '#/components/schemas/Error' } CommandAccepted: description: | Asynchronous command accepted. The response includes a commandId that can be polled at GET /devices/{deviceId}/commands/{commandId} or watched for via the corresponding command-status webhook event. content: application/json: schema: { $ref: '#/components/schemas/Command' } schemas: Device: type: object properties: deviceId: { type: string } name: { type: string } model: type: string enum: [BE489WB, BE499WB, FE789WB] description: Schlage Encode Deadbolt, Encode Plus, or Encode Lever firmwareVersion: { type: string } batteryLevel: type: integer minimum: 0 maximum: 100 wifiSignalStrength: type: integer description: WiFi RSSI in dBm (added March 6, 2025). connectivityState: type: string enum: [Online, Offline] lockState: type: string enum: [Locked, Unlocked, Unknown] timeZone: { type: string } DeviceUpdate: type: object properties: name: { type: string } autoLockDelaySeconds: { type: integer } vacationMode: { type: boolean } AccessCode: type: object properties: accessCodeId: { type: string } name: type: string minLength: 1 maxLength: 12 pattern: '^[a-zA-Z0-9]+$' description: 1-12 character alpha-numeric label. Updating the name does not change the numeric code. code: type: string description: Numeric access code (length is per-device, changed by deleting all codes). schedule: $ref: '#/components/schemas/Schedule' accessorType: type: string description: Accessor classification (Owner, Guest, etc.). New accessor types added March 25, 2025. AccessCodeCreate: allOf: - $ref: '#/components/schemas/AccessCode' required: [name, code] AccessCodeUpdate: type: object properties: name: { type: string, maxLength: 12 } schedule: { $ref: '#/components/schemas/Schedule' } Schedule: oneOf: - $ref: '#/components/schemas/AlwaysSchedule' - $ref: '#/components/schemas/TemporarySchedule' - $ref: '#/components/schemas/RecurringSchedule' discriminator: propertyName: type mapping: Always: '#/components/schemas/AlwaysSchedule' Temporary: '#/components/schemas/TemporarySchedule' Recurring: '#/components/schemas/RecurringSchedule' AlwaysSchedule: type: object properties: type: { type: string, enum: [Always] } TemporarySchedule: type: object properties: type: { type: string, enum: [Temporary] } startDateTime: type: string format: date-time description: Includes DST offset since April 14, 2026. endDateTime: type: string format: date-time description: Includes DST offset since April 14, 2026. RecurringSchedule: type: object properties: type: { type: string, enum: [Recurring] } daysOfWeek: type: array items: type: string enum: [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday] startTime: { type: string, example: '08:00' } endTime: { type: string, example: '17:00' } Command: type: object properties: commandId: { type: string } deviceId: { type: string } type: type: string enum: [Lock, Unlock, UpdateDevice, CreateAccessCode, UpdateAccessCode, DeleteAccessCode] status: type: string enum: [Pending, InProgress, Completed, Failed] errorMessage: type: string description: Populated when status is Failed (improved March 6, 2025). createdAt: { type: string, format: date-time } completedAt: { type: string, format: date-time } WebhookSubscription: type: object properties: subscriptionId: { type: string } url: type: string format: uri description: HTTPS-only callback URL. eventTypes: type: array items: type: string enum: - DeviceLockStateChanged - DeviceConnectivityStateChanged - DeviceBatteryLevelChanged - DeviceKeypadLockedOut - DeviceAlarmTriggered - AccessCodeCreated - AccessCodeUpdated - AccessCodeDeleted - AccessCodeUsed - InvalidAccessCodeAttempted - AccessCodeSynchronized - CommandStatusUpdated - UserSignedOut - IntegrationManagementUpdated signingPublicKey: type: string description: Public key used to verify webhook signatures. createdAt: { type: string, format: date-time } WebhookSubscriptionCreate: type: object required: [url, eventTypes] properties: url: { type: string, format: uri } eventTypes: type: array items: { type: string } Error: type: object properties: code: { type: string } message: { type: string } details: { type: string }