diff --git a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-cloudevents.md b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-cloudevents.md
index 51d442f8a71..f7525632647 100644
--- a/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-cloudevents.md
+++ b/daprdocs/content/en/developing-applications/building-blocks/pubsub/pubsub-cloudevents.md
@@ -14,9 +14,15 @@ Dapr uses CloudEvents to provide additional context to the event payload, enabli
- Content-type for proper deserialization of event data
- Verification of sender application
-## CloudEvents example
+You can choose any of three methods for publish a CloudEvent via pub/sub:
-A publish operation to Dapr results in a cloud event envelope containing the following fields:
+1. Send a pub/sub event, which is then wrapped by Dapr in a CloudEvent envelope.
+1. Replace specific CloudEvents attributes provided by Dapr by overriding the standard CloudEvent properties.
+1. Write your own CloudEvent envelope as part of the pub/sub event.
+
+## Dapr-generated CloudEvents example
+
+Sending a publish operation to Dapr automatically wraps it in a CloudEvent envelope containing the following fields:
- `id`
- `source`
@@ -30,7 +36,9 @@ A publish operation to Dapr results in a cloud event envelope containing the fol
- `time`
- `datacontenttype` (optional)
-The following example demonstrates a cloud event generated by Dapr for a publish operation to the `orders` topic that includes a W3C `traceid` unique to the message, the `data` and the fields for the CloudEvent where the data content is serialized as JSON.
+The following example demonstrates a CloudEvent generated by Dapr for a publish operation to the `orders` topic that includes:
+- A W3C `traceid` unique to the message
+- The `data` and the fields for the CloudEvent where the data content is serialized as JSON
```json
{
@@ -55,20 +63,112 @@ As another example of a v1.0 CloudEvent, the following shows data as XML content
```json
{
- "specversion" : "1.0",
- "type" : "xml.message",
- "source" : "https://example.com/message",
- "subject" : "Test XML Message",
- "id" : "id-1234-5678-9101",
- "time" : "2020-09-23T06:23:21Z",
- "datacontenttype" : "text/xml",
- "data" : "User1user2hi"
+ "topic": "orders",
+ "pubsubname": "order_pub_sub",
+ "traceid": "00-113ad9c4e42b27583ae98ba698d54255-e3743e35ff56f219-01",
+ "tracestate": "",
+ "data" : "user2Order",
+ "id" : "id-1234-5678-9101",
+ "specversion" : "1.0",
+ "datacontenttype" : "text/xml",
+ "subject" : "Test XML Message",
+ "source" : "https://example.com/message",
+ "type" : "xml.message",
+ "time" : "2020-09-23T06:23:21Z"
+}
+```
+
+## Replace Dapr generated CloudEvents values
+
+Dapr automatically generates several CloudEvent properties. You can replace these generated CloudEvent properties by providing the following optional metadata key/value:
+
+- `cloudevent-id`: overrides `id`
+- `cloudevent-source`: overrides `source`
+- `cloudevent-type`: overrides `type`
+- `cloudevent-traceid`: overrides `traceid`
+- `cloudevent-tracestate`: overrides `tracestate`
+- `cloudevent-traceparent`: overrides `traceparent`
+
+The ability to replace CloudEvents properties using these metadata properties applies to all pub/sub components.
+
+### Example
+
+For example, to replace the `source` and `id` values from [the CloudEvent example above]({{< ref "#cloudevents-example" >}}) in code:
+
+{{< tabs "Python" ".NET" >}}
+
+{{% codetab %}}
+
+```python
+with DaprClient() as client:
+ order = {'orderId': i}
+ # Publish an event/message using Dapr PubSub
+ result = client.publish_event(
+ pubsub_name='order_pub_sub',
+ topic_name='orders',
+ publish_metadata={'cloudevent-id: 'd99b228f-6c73-4e78-8c4d-3f80a043d317', cloudevent-source: 'payment'}
+ )
+```
+
+{{% /codetab %}}
+
+
+{{% codetab %}}
+
+```csharp
+var order = new Order(i);
+using var client = new DaprClientBuilder().Build();
+
+// Override cloudevent metadata
+var metadata = new Dictionary() {
+ { "cloudevent.source", "payment" },
+ { "cloudevent.id", "d99b228f-6c73-4e78-8c4d-3f80a043d317" }
}
+
+// Publish an event/message using Dapr PubSub
+await client.PublishEventAsync("order_pub_sub", "orders", order, metadata);
+Console.WriteLine("Published data: " + order);
+
+await Task.Delay(TimeSpan.FromSeconds(1));
```
+{{% /codetab %}}
+
+{{< /tabs >}}
+
+
+The JSON payload then reflects the new `source` and `id` values:
+
+
+```json
+{
+ "topic": "orders",
+ "pubsubname": "order_pub_sub",
+ "traceid": "00-113ad9c4e42b27583ae98ba698d54255-e3743e35ff56f219-01",
+ "tracestate": "",
+ "data": {
+ "orderId": 1
+ },
+ "id": "d99b228f-6c73-4e78-8c4d-3f80a043d317",
+ "specversion": "1.0",
+ "datacontenttype": "application/json; charset=utf-8",
+ "source": "payment",
+ "type": "com.dapr.event.sent",
+ "time": "2020-09-23T06:23:21Z",
+ "traceparent": "00-113ad9c4e42b27583ae98ba698d54255-e3743e35ff56f219-01"
+}
+```
+
+{{% alert title="Important" color="warning" %}}
+While you can replace `traceid`/`traceparent` and `tracestate`, doing this may interfere with tracing events and report inconsistent results in tracing tools. It's recommended to use Open Telementry for distributed traces. [Learn more about distributed tracing.]({{< ref tracing-overview.md >}})
+
+{{% /alert %}}
+
+
## Publish your own CloudEvent
If you want to use your own CloudEvent, make sure to specify the [`datacontenttype`]({{< ref "pubsub-overview.md#setting-message-content-types" >}}) as `application/cloudevents+json`.
+
If the CloudEvent that was authored by the app does not contain the [minimum required fields](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#required-attributes) in the CloudEvent specification, the message is rejected. Dapr adds the following fields to the CloudEvent if they are missing:
- `time`