Views - how to filter a result set based on a URL filter that affects an API call?
So, I am not 100% confident in this approach, but I got a working solution. The base table is Node, I have no join, this data is not stored locally and I use an API call to fetch the operating hours. So I looked at how the Global filter options worked and started from there with hook_views_data:

In mymodule.module:

/**
 * Implements hook_views_data().
 */
function harlib_restful_normalizer_views_data() {
  $data = [];
  $data['libcal']['table']['group'] = t('LibCal');
  $data['libcal']['table']['join'] = [
    '#global' =&gt; [],
  ];

  $data['libcal']['open_now'] = [
    'title' =&gt; t('Open Now'),
    'filter' =&gt; [
      'id' =&gt; 'open_now',
      'title' =&gt; t('Currently Open'),
      'help' =&gt; t('Filter results by "currently_open" value on results from LibCal Hours API.'),
    ],
  ];

  return $data;
}


In my custom OpenNow filter class:

namespace Drupal\harlib_restful_normalizer\Plugin\views\filter;

use Drupal\harlib_libcal_api\Client\HoursTodayClient;
use Drupal\views\Plugin\views\filter\BooleanOperator;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Filters nodes based on libcal currently open value.
 *
 * @ingroup views_filter_handlers
 *
 * @ViewsFilter("open_now")
 */
class OpenNow extends BooleanOperator {

  /**
   * @var \Drupal\harlib_libcal_api\Client\HoursTodayClient
   */
  protected $hoursClient;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, HoursTodayClient $client) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this-&gt;hoursClient = $client;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container-&gt;get('harlib_libcal_api.hours_today_client')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function query() {}

  /**
   * {@inheritdoc}
   */
  public function postExecute(&amp;$values) {
    if ($this-&gt;value) {
      foreach ($values as $key =&gt; $value) {
        $node = $value-&gt;_entity;
        $library_id = (int) $node-&gt;get('field_library_id')-&gt;value;

        if ($library_id === 0) {
          // No times associated with this library.
          unset($values[$key]);
          continue;
        }

        $hours = $this-&gt;hoursClient-&gt;request($library_id);

        if ($hours['currently_open'] == FALSE) {
          unset($values[$key]);
        }
      }

      $values = array_values($values);
    }

    parent::postExecute($values);
  }

}


If the filter is 'checked' or true, the postExecute method will loop the result set, check the hours returned and unset the result if the location is not currently open. I am not using pagination or anything, so, I did not test if it works in those conditions.

The better scenario is to filter the JSON list on the front end (since the data is already attached to the entity in the response), but I was asked to do it from the backend.