---
schema_version: "1"
id: 4e0c2364d469ed5226e0b3c6934ad3ceb8a2f5c93b076c2f28b9fa1456e677c5
title: Custom Events
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/cc/264-0-0/b2c_event_custom.md
canonical_url: https://help.salesforce.com/s/articleView?id=cc.b2c_event_custom.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 604fe26f70c46e559a17c5e42974f36ad60c6671e1eb5697a4c804259e63baff
description: Declare your own B2C Commerce event types in a cartridge and send them from script. Custom events appear in Business Manager with platform events, and you route them to the same connectors.
products:
  - Commerce
  - B2C Commerce
release: "264"
---
# Custom Events

Declare your own B2C Commerce event types in a cartridge and send them from script. Custom events appear in Business Manager with platform events, and you route them to the same connectors.

**Available in:** B2C Commerce release 26.10 and later.

Use a custom event when a platform event doesn't cover the moment you need to notify an external system. You declare the event name in the cartridge, send a message from a controller, job, or hook, and route it in Business Manager the same way you route a platform event.

## Declare an event

Add an `events` array to the cartridge `package.json`, next to the hooks entry. Business Manager lists the union of every event declared on the active cartridge path. A third-party cartridge can declare and send an event without a separate setup step. Deploy the cartridge to add an event. Remove the entry and redeploy to delete it.

```json

{
  "hooks": "./hooks.json",
  "events": ["com.mycustomer.checkout.abandoned", "com.mycustomer.order.confirmed"]
}
```

Each custom event can be routed for one site or for the organization. The prefixes `demandware.`, `dw.`, and `sf.` are reserved for platform events. You can't declare those prefixes in a cartridge, and you can't send them with `EventManager`. Use a reverse-domain name, such as `com.mycustomer.checkout.abandoned`. The platform doesn't enforce that pattern. If two cartridges declare the same name, the webhook receiver can't tell which cartridge sent the event unless the payload says so.

## Send an event

Send custom events with `dw.event.EventManager`. Both methods queue the event and return without waiting for the webhook. If no route is configured, `sendEvent` does nothing and doesn't throw an error.

- `sendEvent(String eventName, String message)` queues the event immediately, including when the surrounding transaction later rolls back. Use it for notifications that should still go out if the operation fails.
- `sendEventOnCommit(String eventName, String message)` queues the event when the current transaction commits. If the transaction rolls back, the event is discarded. Calling it outside a transaction throws an error. Use it when the event depends on data that was just saved, such as an order confirmation.

The message is an opaque string. Send JSON. The platform doesn't parse or validate the body. The maximum size is 128 KB. A larger payload throws an error before the event is queued. Sending an event name that isn't declared in any loaded `package.json` also throws an error.

Custom events use the same HTTP headers as platform events. See [Common HTTP Headers for B2C Commerce Events](https://help.salesforce.com/s/articleView?id=cc.b2c_event_common_headers.htm&release=264.0.0&type=5 "Every B2C Commerce event includes the same set of standard x-sf-cc-* headers, so your connector can identify and correlate events consistently regardless of the event type."). `x-sf-cc-event-id` is the event name you declared.

## Site context and routing

The event keeps the site context that exists when you send it.

- Controllers, hooks, and site job steps include the site ID. Both a site route and an organization route can match.
- Organization job steps omit the site ID. Only an organization route matches.

`sendEvent` doesn't require a site context. After you deploy the cartridge, the event appears in Business Manager with the platform events. Choose an existing connector for it the same way you enable a platform event.

If you remove an event from `package.json` and a connector is still mapped to that name, Business Manager keeps the route and shows a warning. The route isn't deleted, so you can point it at a replacement event.

## Delivery and limits

Custom event delivery is asynchronous and best-effort. B2C Commerce retries a failed webhook up to five times. If the event is rejected before it's queued, it isn't stored for replay. Platform events don't count toward custom-event limits.

Salesforce limits how many custom events an instance can send per minute and how many a single storefront request can send. If a request exceeds a limit, or if the internal queue is full, `sendEvent` throws an error and the event isn't queued.

| Condition | Result |
| --- | --- |
| Event isn't declared in any `package.json` | Throws an error |
| Event is declared on another site's cartridge path, not the current site | The event is accepted |
| Payload is larger than 128 KB | Throws an error |
| `sendEventOnCommit` is called outside a transaction | Throws an error |
| Event is declared, but no route is configured | No event is sent, and no error is thrown |
| Queue is full, or a rate limit is exceeded | Throws an error |
| Webhook delivery fails | B2C Commerce retries up to five times and logs the failure |