Differences Between Change Events Received with Streaming API vs. Pub/Sub API

The format of change events received with Streaming API differs from change events received with Pub/Sub API. Streaming API delivers the entire event message in JSON format while Pub/Sub API delivers the event payload in the Apache Avro binary format.

If you're writing an app for publishing and subscribing to platform events and change data capture events, we recommend you use Pub/Sub API instead of Streaming API. Pub/Sub API is a newer API. Based on gRPC API and HTTP/2, Pub/Sub API efficiently publishes and delivers binary event messages.

Important

Event Message Content Streaming API Pub/Sub API
Event message format The entire event message is in JSON format. The event payload is in the Apache Avro binary format.

The client can retrieve the schema, replay ID, and payload from the received event separately and decode the payload to obtain the ChangeEventHeader and record fields. For more information, see Event Data Serialization with Apache Avro in the Pub/Sub API documentation.

Record fields Null fields and unchanged fields are excluded from the event message. All the record fields, including the unchanged fields. Unchanged fields are null even if they have a value in the Salesforce record. Unpopulated fields are also null.
ChangeEventHeader fields All the fields in ChangeEventHeader Fields except for changedFields and nulledFields. In addition to the fields that are sent in Streaming API, Pub/Sub API includes these fields:
  • changedFields
  • nulledFields

See ChangeEventHeader Fields in the Change Data Capture Developer Guide.

Also, nulledFields, diffFields, and changedFields require further processing. For more information, see Event Deserialization Considerations in the Pub/Sub API documentation.

Date field format Date fields contain the date in UTC format. Date fields are in Epoch time. They can be converted to another date format for readability.

Change Event Example in Streaming API (CometD)

This event message is sent for a new account in a CometD client.

1{
2  "schema": "V2MGwDA2aIP0yQS98S2L6Q",
3  "payload": {
4    "LastModifiedDate": "2024-04-09T20:26:27.000Z",
5    "Description": "Sample account record.",
6    "CleanStatus": "Pending",
7    "OwnerId": "0055f000005mc66AAA",
8    "CreatedById": "0055f000005mc66AAA",
9    "ChangeEventHeader": {
10      "commitNumber": 1082990428293,
11      "commitUser": "0055f000005mc66AAA",
12      "sequenceNumber": 1,
13      "entityName": "Account",
14      "changeType": "CREATE",
15      "changedFields": [],
16      "changeOrigin": "com/salesforce/api/soap/60.0;client=SfdcInternalAPI/",
17      "transactionKey": "0001ae4b-7024-a64a-87f0-f2c8cebdca76",
18      "commitTimestamp": 1712694387000,
19      "recordIds": [
20        "0015f00002J9YaUAAV"
21      ]
22    },
23    "CreatedDate": "2024-04-09T20:26:27.000Z",
24    "LastModifiedById": "0055f000005mc66AAA",
25    "Name": "Acme"
26  },
27  "event": {
28    "replayId": 37904280
29  }
30}

The order of the fields in the JSON event message received in a Streaming (CometD) isn’t guaranteed. The order is based on the underlying Apache Avro schema that change events are based on. When an event is expanded into JSON format, the order of the fields doesn’t always match the schema depending on the client used to receive the event.

Note

Change Event Example in Pub/Sub API

This event message is sent for a new account in a Pub/Sub API client.

1{
2  "ChangeEventHeader": {
3    "entityName": "Account",
4    "recordIds": [
5      "0015f00002J9YYEAA3"
6    ],
7    "changeType": "CREATE",
8    "changeOrigin": "com/salesforce/api/soap/60.0;client=SfdcInternalAPI/",
9    "transactionKey": "0001ade9-3f74-0b99-dbc4-42e73424b774",
10    "sequenceNumber": 1,
11    "commitTimestamp": 1712693965000,
12    "commitNumber": 1082985383811,
13    "commitUser": "0055f000005mc66AAA",
14    "nulledFields": [],
15    "diffFields": [],
16    "changedFields": []
17  },
18  "Name": "Acme",
19  "Type": null,
20  "ParentId": null,
21  "BillingAddress": null,
22  "ShippingAddress": null,
23  "Phone": null,
24  "Fax": null,
25  "AccountNumber": null,
26  "Website": null,
27  "Sic": null,
28  "Industry": null,
29  "AnnualRevenue": null,
30  "NumberOfEmployees": null,
31  "Ownership": null,
32  "TickerSymbol": null,
33  "Description": "Sample account record.",
34  "Rating": null,
35  "Site": null,
36  "OwnerId": "0055f000005mc66AAA",
37  "CreatedDate": 1712693965000,
38  "CreatedById": "0055f000005mc66AAA",
39  "LastModifiedDate": 1712693965000,
40  "LastModifiedById": "0055f000005mc66AAA",
41  "Jigsaw": null,
42  "JigsawCompanyId": null,
43  "CleanStatus": "Pending",
44  "AccountSource": null,
45  "DunsNumber": null,
46  "Tradestyle": null,
47  "NaicsCode": null,
48  "NaicsDesc": null,
49  "YearStarted": null,
50  "SicDesc": null,
51  "DandbCompanyId": null,
52  "OperatingHoursId": null,
53  "CustomerPriority__c": null,
54  "SLA__c": null,
55  "Active__c": null,
56  "NumberofLocations__c": null,
57  "UpsellOpportunity__c": null,
58  "SLASerialNumber__c": null,
59  "SLAExpirationDate__c": null
60}