Here is example apex code of creating a simple stream subscribing to two entities (an account and opportunity).
Since ConnectApi (aka Chatter in Apex) always runs as the context user then this stream belongs to the currently running user and they will see it when they navigate to Chatter tab in the UI (screen shot below).
ConnectApi.StreamSubscriptionInput sub1 = new ConnectApi.StreamSubscriptionInput();
sub1.entityId = '001B000000RBig8IAD'; // account, Burlington Textiles Corp of America
ConnectApi.StreamSubscriptionInput sub2 = new ConnectApi.StreamSubscriptionInput();
sub2.entityId = '006B0000003PAKiIAO'; // opportunity, Burlington Textiles Weaving Plant Generator
List<ConnectApi.StreamSubscriptionInput> subscriptions = new List<ConnectApi.StreamSubscriptionInput>();
subscriptions.add( sub1 );
subscriptions.add( sub2 );
ConnectApi.ChatterStreamInput streamInput = new ConnectApi.ChatterStreamInput();
streamInput.name = 'My Stream';
streamInput.description = 'Created via Apex';
streamInput.subscriptionsToAdd = subscriptions;
//streamInput.subscriptionsToRemove = someOtherSubscriptions;
ConnectApi.ChatterStream stream = ConnectApi.ChatterFeeds.createStream( Network.getNetworkId(), streamInput );
System.debug( stream );
System.debug( stream.id );
System.debug( stream.name );
System.debug( stream.description );
System.debug( 'Subscriptions:' );
for ( ConnectApi.FeedEnabledEntity entity : stream.subscriptions ) {
System.debug( entity.id ); // record id (e.g. 001xxx)
System.debug( entity.name ); // record name (e.g. Acme)
System.debug( entity.type ); // sobject name (e.g. Account)
}
Here is the created Chatter Stream:
You can continue to edit it from the UI: