Java SDK EventBridge subscription filter for conversation.end by queue not working

I can’t seem to figure out why my Spring Boot service is still receiving conversation.end events for queues I explicitly excluded in the EventBridge filter policy.

I am using the Genesys Cloud Java SDK to manage EventBridge subscriptions. According to the documentation for EventBridgeApi, the putEventBridgeSubscription method accepts a PutEventBridgeSubscriptionRequest which includes a filter object. The docs state: “The filter property allows you to specify criteria for the events that are sent to the subscription.” I have constructed a JSON filter that should theoretically restrict events to only those originating from a specific queue ID, yet my consumer logs show events from unrelated queues flooding in.

Here is the relevant snippet from my configuration service:

PutEventBridgeSubscriptionRequest request = new PutEventBridgeSubscriptionRequest();
request.setSubscriptionName("QueueSpecificEndEvents");
request.setDestination(new EventBridgeDestination().region("us-east-1").arn("arn:aws:sqs:us-east-1:123456789012:my-queue"));

// Attempting to filter by event type and queue ID
Map<String, Object> filterCriteria = new HashMap<>();
filterCriteria.put("type", Collections.singletonList("conversation.end"));
filterCriteria.put("queue_id", Collections.singletonList("e1234567-89ab-cdef-0123-456789abcdef"));

request.setFilter(new EventBridgeFilter().filter(filterCriteria));

eventBridgeApi.putEventBridgeSubscription(request);

When I inspect the EventBridge console in AWS, the filter policy shows up correctly. However, the conversation.end event payload contains a routing object with queue details, but the top-level event structure seems to vary. I suspect I am filtering on the wrong path or the SDK is not serializing the nested filter correctly. The docs are vague on whether queue_id is a valid top-level filter key or if I need to use a path like routing.queue.id. I am getting 201 Created when updating the subscription, so the API accepts it, but the filtering logic clearly fails in practice. Is there a specific schema version or attribute path I must use for queue-based filtering in the Java SDK?

Make sure you are not relying solely on the high-level Java SDK builder methods for EventBridge filters, as they often omit the specific attribute path syntax required for deep object filtering in the underlying JSON payload. The conversation.end event structure in Genesys Cloud nests queue information within the routing object, and the EventBridge filter policy requires exact path matching using dot notation. If you are constructing the PutEventBridgeSubscriptionRequest via the SDK’s fluent interface, verify that the filter object is correctly serializing the or or and logic with the precise attribute paths.

Here is the correct JSON structure for the filter policy that excludes specific queues. You can bypass the SDK builder and send this directly via the REST API to ensure the syntax is exactly as expected by the EventBridge service.

{
 "filter": {
 "or": [
 {
 "attributePath": "routing.queueId",
 "operator": "notEqual",
 "value": "your-excluded-queue-id-1"
 },
 {
 "attributePath": "routing.queueId",
 "operator": "notEqual",
 "value": "your-excluded-queue-id-2"
 }
 ]
 }
}

In your Java code, if you must use the SDK, ensure you are setting the filter property on the PutEventBridgeSubscription object with a Map or a custom object that serializes to this exact structure. The SDK’s default serialization might flatten the structure incorrectly if you use the generic filter setter without explicitly defining the or array structure. Test the subscription with a simple curl command first to validate the filter logic before integrating it back into your Spring Boot service. This approach isolates the SDK serialization issue from the EventBridge configuration logic.

The documentation actually says EventBridge filters operate on the raw JSON payload structure, not SDK abstractions. You must explicitly target the nested routing.queueId field in your filter policy. Here is the correct JSON structure for the filter object:

{
 "condition": "EQUALS",
 "value": "your-queue-id",
 "path": "$.routing.queueId"
}