Under what circumstances is API joining available?
The API is largely metadata-driven, and whether an API field is joinable is usually determined by the data returned by that entity's getfields API action.  If you look in &lt;civiroot&gt;/templates/CRM/Admin/Page/APIExplorer.js at the renderJoinSelector() function you'll see the logic.

However, right at the top of that function there's a reference to the const NO_JOINS.  Right up at the top of that file, you'll see:

// The following apis do not use Api3SelectQuery so do not support advanced features like joins or OR
NO_JOINS = ['Contact', 'Contribution', 'Pledge', 'Participant'],


These sorts of quirky APIs are exactly the sort of thing that APIv4 is intended to eliminate.  It's no coincidence that the Participant entity is the first one slated to be released under APIv4.  It's quirky and it shouldn't be, but changing the behavior would break the API contract not to change on some extension author.