Events Stay organized with collections Save and categorize content based on your preferences.
AI-generated Key Takeaways
The SDM API uses Google Cloud Pub/Sub to deliver asynchronous events, allowing you to stay updated on device and structure changes.
To receive events, enable the feature for your project, create a Pub/Sub subscription, and initiate events with a
devices.listAPI call.Resource and relation events provide detailed information about device and structure updates, including user IDs and relational changes.
Utilize event threads and updateable notifications to efficiently manage and minimize notification frequency for related events.
Service accounts with the Pub/Sub Subscriber role are recommended for subscription management and API access using OAuth 2.0.
Events are asynchronous and managed by Google Cloud Pub/Sub, in a single topic per Project. Events provide updates for all devices and structures and receipt of events is assured as long as the access token is not revoked by the user and the event messages have not expired.
Note: If yourDevice Access integration relies on Pub/Sub events and rarely makes API calls,the user's authorization will be revoked if the refresh token expires.For continued access, you must use the refresh token to refresh the access token within 6months. For further help with authorization, seeRefresh token expiration.Enable events
Events are an optional feature of the SDM API. SeeEnable events to learn how to enable them for your Project.
Google Cloud Pub/Sub
See theGoogle Cloud Pub/Sub documentation to learn more about how Pub/Sub works. In particular:
- Learn the basics of Pub/Sub with theirHow-to guides.
- Understand howAuthentication works.
- Choose a providedClient Library or write your own and use theREST/HTTP or gRPC API surfaces.
Event subscription
Prior to January 2025, if events were enabled for your Project, you would have been provided a topic specific to that Project ID, in the form of:
projects/gcp-project-name/subscriptions/topic-id
To receive events, create apull orpush subscription to that topic, depending on your use case. Multiple subscriptions to the SDM topic are supported. SeeManaging subscriptions for more information.
Publishing messages to an SDM topic is not supported. Usetraits to get the current state of resources or to send commands.Initiate events
To initiate events for the first time once the Pub/Sub subscription has been created, make adevices.list API call as a one-time trigger. Events for all structures and devices will publish after this call.
For an example, see theAuthorize page in the Quick Start Guide.
Event order
Pub/Sub does not guarantee ordered delivery of events, and the receipt order of events may not correspond to the order in which the events actually occurred. Use thetimestamp field to aid in reconciliation of event order. Events may also arrive individually or combined into a single event message.
For more information, seeOrdering messages.
User IDs
If your implementation is based around users (rather than structure or device), use theuserID field from the event payload to correlate resources and events. This field is an obfuscated ID representing a specific user.
TheuserID is also available in the HTTP response header of each API call.
Relation events
Relation events represent a relational update for a resource. For example, when a device is added to a structure, or when a device is deleted from a structure.
There are three types of relation events:
- CREATED
- DELETED
- UPDATED
The payload for a relation event is as follows:
Payload
{ "eventId" : "4faf077b-1776-4a1f-91e4-a2cecb85e0a8", "timestamp" : "2019-01-01T00:00:01Z", "relationUpdate" : { "type" : "CREATED", "subject" : "enterprises/project-id/structures/structure-id", "object" : "enterprises/project-id/devices/device-id" }, "userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi"}In a relation event, theobject is the resource that triggered the event and thesubject is the resource that theobject now has a relation with. In the example above, a user has granted access to this specific device to a developer, and the user's authorized device is now related to their authorized structure, which triggers the event.
Asubject can only be a room or a structure. If a developer does not have permission to view the user's structure, thesubject is always empty.
Fields
| Field | Description | Data Type |
|---|---|---|
eventId | The unique identifier for the event. | stringExample: "8a892447-09cf-4043-b085-32f666b64e71" |
timestamp | The time when the event occurred. | stringExample: "2019-01-01T00:00:01Z" |
relationUpdate | An object that details information about the relation update. | object |
userId | A unique, obfuscated identifier that represents the user. | stringExample: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
SeeEvents for more information on the different types of events and how they work.
Examples
Event payloads differ for each type of relation event:
CREATED
Structure created
"relationUpdate" : { "type" : "CREATED", "subject" : "", "object" : "enterprises/project-id/structures/structure-id"}Device created
"relationUpdate" : { "type" : "CREATED", "subject" : "enterprises/project-id/structures/structure-id", "object" : "enterprises/project-id/devices/device-id"}Device created
"relationUpdate" : { "type" : "CREATED", "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id", "object" : "enterprises/project-id/devices/device-id"}UPDATED
Device moved
"relationUpdate" : { "type" : "UPDATED", "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id", "object" : "enterprises/project-id/devices/device-id"}DELETED
Structure deleted
"relationUpdate" : { "type" : "DELETED", "subject" : "", "object" : "enterprises/project-id/structures/structure-id"}Device deleted
"relationUpdate" : { "type" : "DELETED", "subject" : "enterprises/project-id/structures/structure-id", "object" : "enterprises/project-id/devices/device-id"}Device deleted
"relationUpdate" : { "type" : "DELETED", "subject" : "enterprises/project-id/structures/structure-id/rooms/room-id", "object" : "enterprises/project-id/devices/device-id"}Relation events are not sent when:
- A room is deleted
Resource events
A resource event represents an update specific to a resource. It can be in response to a change in the value of a trait field, such as changing the mode of a thermostat. It can also represent a device action that doesn't change a trait field such as pressing a device button.
Any trait field change generates a resource event, unless otherwise noted in the trait reference documentation.An event generated in response to a change in the value of trait field contains atraits object, similar to a device GET call:
Payload
{ "eventId" : "fd6d9afc-0468-470a-a284-5f6cffc7f409", "timestamp" : "2019-01-01T00:00:01Z", "resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "traits" : { "sdm.devices.traits.ThermostatMode" : { "mode" : "COOL" } } }, "userId": "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi", "resourceGroup" : [ "enterprises/project-id/devices/device-id" ]}Use theindividual trait documentation to understand the payload format for any trait field change resource event.
An event generated in response to a device action that doesn't change a trait field also has a payload with aresourceUpdate object, but with anevents object instead of atraits object:
Payload
{ "eventId" : "a0c93a23-aa21-465f-a38d-5c9dc04dddc1",
"timestamp" : "2019-01-01T00:00:01Z",
"resourceUpdate" : { "name" : "enterprises/project-id/devices/device-id", "events" : { "sdm.devices.events.CameraMotion.Motion" : { "eventSessionId" : "CjY5Y3VKaTZwR3o4Y19YbTVfMF...", "eventId" : "1eG5lFEUSfvsFWzACapDHjqA5F...", } } } "userId" : "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi",
"eventThreadId" : "d67cd3f7-86a7-425e-8bb3-462f92ec9f59",
"eventThreadState" : "STARTED",
"resourceGroup" : [ "enterprises/project-id/devices/device-id" ]}These types of resource events are defined in specific traits. For example, the Motion event is defined in theCameraMotion trait. See each trait's documentation to understand the payload format for these types of resource events.
Fields
| Field | Description | Data Type |
|---|---|---|
eventId | The unique identifier for the event. | stringExample: "a0c93a23-aa21-465f-a38d-5c9dc04dddc1" |
timestamp | The time when the event occurred. | stringExample: "2019-01-01T00:00:01Z" |
resourceUpdate | An object that details information about the resource update. | object |
userId | A unique, obfuscated identifier that represents the user. | stringExample: "AVPHwEuBfnPOnTqzVFT4IONX2Qqhu9EJ4ubO-bNnQ-yi" |
eventThreadId | The unique identifier for the event thread. | stringExample: "d67cd3f7-86a7-425e-8bb3-462f92ec9f59" |
eventThreadState | The state of the event thread. | stringValues: "STARTED", "UPDATED", "ENDED" |
resourceGroup | An object that indicates resources that might have similar updates to this event. The resource of the event itself (from theresourceUpdate object) will always be present in this object. | object |
SeeEvents for more information on the different types of events and how they work.
Updateable notifications
Notifications based on resource events can be implemented in an app, such as forAndroid or iOS. To reduce the number of notifications sent, a feature calledupdateable notifications may be implemented, where existing notificationsare updated with new information based on subsequent events in the same eventthread.Select events feature support for updateable notifications and are tagged asUpdateable eventThreadId in their payloads. Use thisfield to link individual events together for the purpose of updating an existingnotification that has been surfaced for a user.
An event thread is not the same as an event session. Theevent threadidentifies an updated status for a previous event in the same thread. Theevent session identifies separate events that relate to each other, andthere can be multiple event threads for a given event session.
For notification purposes, different types of events are grouped into differentthreads.
This thread grouping and timing logic is handled by Google and is subject tochange at any time. A developer should update notifications based on theevent threads and sessions provided by the SDM API.
Thread state
Events that support updateable notifications also have aneventThreadStatefield that indicates the state of the event thread at that point in time. Thisfield has the following values:
- STARTED — The first event in an event thread.
- UPDATED — An event in an ongoing event thread. There can be zero or more events with this state in a single thread.
- ENDED — The last event in an event thread, which may be a duplicate of the last UPDATED event, depending on the thread type.
This field can be used to track the progress of an event thread and when it hasended.
Event filtering
In some cases, events detected by a device may be filtered out from publishingto an SDM Pub/Sub topic. This behavioris calledevent filtering. The purpose of event filtering is to avoidpublishing too many similar event messages in a short amount of time.
For example, a message may get published to an SDM topicfor an initial Motion event. Othermessages for Motion after that will befiltered out from publishing until a set period of time passes. Once that periodof time passes, an event message for that event type may be published again.
In the Google Home App (GHA), events that werefiltered will still show in the user's event history. However, suchevents don't generate an app notification (even if that notification type isenabled).
Each type of event has its own event filtering logic, which is defined byGoogle and subject to change at any time. This event filtering logic isindependent of the event thread and session logic.
Service accounts
Service accounts are recommended for managing SDM APIsubscriptions and event messages. A service account is used by an application orvirtual machine, not a person, and has its own unique account key.
Service account authorization for the Pub/Sub API usesTwo-legged OAuth (2LO).
In the 2LO authorization flow:
- The developer requests an access token using a service key.
- The developer uses the access token with calls to the API.
To learn more about Google 2LO and how to get set up, seeUsing OAuth 2.0 for Server to ServerApplications.
Authorization
The service account should be authorized for use with thePub/Sub API:
- Enable the Cloud Pub/SubAPIin Google Cloud.
- Create a service account and service account key as described inCreating a service account.We recommend giving it only thePub/Sub Subscriber role. Make sure todownload the service account key to the machine that will be using thePub/Sub API.
- Provide your authentication credentials (service account key) to yourapplication code by following the instructions at the page in the previousstep, or get an access token manually using
oauth2l, if youwant to quickly test API access. - Use service account credentials or the access token with thePub/Sub
project.subscriptionsAPIto pull and acknowledge messages.
oauth2l
Googleoauth2l is a command line tool for OAuth written in Go. Install it forMac or Linux using Go.
- If you do not have Go on your system,download and install it first.
- Once Go is installed, install
oauth2land add its location to yourPATHenvironment variable:go install github.com/google/oauth2l@latestexport PATH=$PATH:~/go/bin - Use
oauth2lto get an access token for the API, using the appropriateOAuth scope(s): For example, if your service key is located atoauth2l fetch --credentialspath-to-service-key.json --scope https://www.googleapis.com/auth/pubsubhttps://www.googleapis.com/auth/cloud-platform~/myServiceKey-eb0a5f900ee3.json:oauth2l fetch --credentials ~/myServiceKey-eb0a5f900ee3.json --scope https://www.googleapis.com/auth/pubsubhttps://www.googleapis.com/auth/cloud-platformya29.c.Elo4BmHXK5...
See theoauth2l README for more usageinformation.
Google API Client Libraries
There are several client libraries available for Google APIs that utilize OAuth2.0. SeeGoogle API Client Libraries for more information on thelanguage of your choice.
When using these libraries with the Pub/Sub API, use thefollowing scope string(s):
https://www.googleapis.com/auth/pubsubhttps://www.googleapis.com/auth/cloud-platform
Errors
The following error code(s) may be returned in relation to this guide:
| Error Message | RPC | Troubleshooting |
|---|---|---|
| Camera image is no longer available for download. | DEADLINE_EXCEEDED | Event images expire 30 seconds after the event is published. Make sure to download the image prior to expiration. |
| Event id does not belong to the camera. | FAILED_PRECONDITION | Use the correcteventID returned by the camera event. |
See theAPI Error Code Reference for the full list of API error codes.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-07-25 UTC.
