How can I retrieve older versions of a custom entry type in bulk?
Okay, here's my stab at this. No doubt Brad will swagger in at some point, and declare that this can all be done with one line of trivial PHP.

Whatever, Brad. Moving on...

You can't use the ElementCriteriaModel to retrieve specific entry versions. This leaves you with two options:

Option 1: Use the Entry Revisions service

The EntryRevisionsService has a getVersionsByEntryId method, which does precisely what it says. If you're only dealing with a small number of Entries, this may suffice.

Option 2: Go old(ish) school

If the first option doesn't suit, you'll need to get your hands dirty querying the database, and populating EntryModel instances from the result.

Here's an example, to get you started:

$versionIds = [];

// Retrieve all the versions created before your "threshold" date.
$versions = craft()-&gt;db-&gt;createCommand()
    -&gt;select(['ev.entryId as entryId', 'ev.id as versionId'])
    -&gt;from('entryversions ev')
    -&gt;where('ev.dateCreated &lt; :date', [':date' =&gt; '2017-03-20'])
    -&gt;order('ev.dateCreated desc')
    -&gt;queryAll();

/**
 * Construct an associative array where the key is the entry ID,
 * and the value is the most recent entry version ID created _before_
 * your date threshold.
 */
foreach ($versions as $version) {
    if (!array_key_exists($version['entryId'], $versionIds)) {
        $versionIds[$version['entryId']] = $version['versionId'];
    }
}

/**
 * Finally, we can do something useful with our lives.
 * Retrieve the desired version of the entries.
 *
 * Note: you'll need to retrieve all of the required entry
 * columns, in order to populate your EntryModel. I've just
 * done a wildcard, you may wish to be more specific.
 */
$results = craft()-&gt;db-&gt;createCommand()
    -&gt;select('e.*, ev.*')
    -&gt;from('entries e')
    -&gt;join('entrytypes et', 'et.id = e.typeId')
    -&gt;join('entryversions ev', 'ev.entryId = e.id')
    -&gt;where('et.handle = :handle', [':handle' =&gt; 'entryTypeHandle'])
    -&gt;andWhere(['in', 'ev.id', array_values($versionIds)])
    -&gt;group('e.id')
    -&gt;order('ev.dateCreated desc')
    -&gt;queryAll();


Now that you've retrieved the results, you'll need to convert each row to an EntryModel. This could be fairly trivial, or a living hell, depending on whether your Entries contains Matrix fields, Relationships, and so forth.



Note: I don't think it's possible to do this in a single query, but your GROUP BY fu may be better than mine.