---
schema_version: "1"
id: 8f9a66e9b542f8c3f53305f5865563e02e553b35a96c3dcfe71ba2226c48d62e
title: Subscribe to Changes with Streaming API
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/platform/264-0-0/external_object_change_tracking_example_streaming_api.md
canonical_url: https://help.salesforce.com/s/articleView?id=platform.external_object_change_tracking_example_streaming_api.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: f9dd56acfe7a6ec3550560500d5ae5dbb53041e606ed5ce0e7d8ccc2371fcd78
description: When Codey Outfitters runs its Bayeux client, the client subscribes to Streaming API on the products publication channel.
products:
  - Salesforce Platform
  - Security
release: "264"
---
# Subscribe to Changes with Streaming API

When Codey Outfitters runs its Bayeux client, the client subscribes to Streaming API on the products publication channel.

Codey Outfitters uses a Visualforce page to show its customers updates to prices and inventory and new and discontinued outdoor gear. This sample source code for the Visualforce page is on [Github](https://github.com/forcedotcom/external-data-change-client), and you can modify it to work with your OData 4.0 producer.

The heart of the subscription mechanism is in the \_subscribeChannels method in src/js/channel/ServerConnection.js.

```javascript
cometd.subscribe(channelName, function(event) {
  if (event && event.data && event.data.payload && 
      event.data.payload.ChangeEventHeader) {
    var header = event.data.payload.ChangeEventHeader;
    var entityName = header.entityName;
    var recordId = header.recordIds[0];
    var timestamp = header.commitTimestamp;
    var changeType = header.changeType;
        
    switch (changeType) {
      case "UPDATE":
        // Update logic ...
        break;
     case "CREATE":
        // Create logic
        break;
     case "DELETE":
        // Delete logic
        break;
    }
  }
}
```

The channelName for Codey Outfitters’ products is /data/Products\_\_ChangeEvent. Each change event notification that’s published on the channel is in the Bayeux format and represents an updated record in the product inventory. The data.payload contains the change event data and includes a header that describes the nature of the change event. This sample event notification describes a change to a Codey Outfitters product record.

```
{ 
  schema=”lswW55LyUCYeU7raSrmZ5A”,
  payload={
    ChangeEventHeader={
      commitUser=”005xx000001SvAn”, 
      sequenceNumber=15,
      entityName=”Products__x”,
      changeType=”UPDATE”, 
      changeOrigin=”Products?$deltaToken=3779”, 
      transactionKey=”f158f145-a...”, 
      commitTimestamp=1507759119826, 
      recordIds=[“x03xx0000000008”]
    },
    Name__c=”Camping Stove”,
    ExternalId=7801,
    UnitPrice__c=10.0,
    Stock__c=1500.0,
    OrderLimit__c=12.0,
    ProductId__c=7801.0
  },
  event={replayId=15}
}
```

Each change event notification has this structure.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
      <colgroup>
        <col style="width:50%">
        <col style="width:50%">
      </colgroup>
      <thead class="slds-text-title_caps ">
        <tr class="">
          <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d92402e57">Field</th>
          <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d92402e60">Description</th>
        </tr>
      </thead>
      <tbody>
        <tr class="">
          <td data-label="Field" class="slds-cell-wrap" style="vertical-align:top;" headers="d92402e57 ">schema</td>

          <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d92402e60 ">Versioned schema reference that defines the change event.</td>

        </tr>
        <tr class="">
          <td data-label="Field" class="slds-cell-wrap" style="vertical-align:top;" headers="d92402e57 ">payload</td>

          <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d92402e60 ">
            <p>Details about the change event.</p>
            <ul>
              <li>ChangeEventHeader—Describes the nature of the data change
                event.</li>
              <li>Record fields and values—The OData producer can also
                include fields that have no changed values. To see the current
                values, query the external object using the record ID in the
                change event header.</li>
            </ul>
          </td>

        </tr>
        <tr class="">
          <td data-label="Field" class="slds-cell-wrap" style="vertical-align:top;" headers="d92402e57 ">event</td>

          <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d92402e60 ">The replay ID that refers to the position of the event notification
            in the event stream on a channel.</td>

        </tr>
      </tbody>
    </table>

Each change event header contains these fields.

 
| Field | Description |
| --- | --- |
| commitUser | User who publishes the event. |
| sequenceNumber | Change event sequence number. Each change occurs in the order in which it’s received. |
| entityName | API name of the external object. |
| changeType | Specifies whether a record was updated, created, or deleted. |
| changeOrigin | Delta link that’s used to request the change. The OData producer calculates the delta token while executing the previous change request. |
| transactionKey | Unique identifier for the transaction. |
| commitTimestamp | Specifies when the change event notification is published in milliseconds since January 1, 1970. |
| recordIds | Salesforce ID of the external object record that’s updated, created, or deleted. To see the current values of the record’s fields, query the external object using this record ID. |
| nulledFields | List of fields set to null. |