A resposta de @Tom J Nowell é imediata. Encontrei outra alternativa (usando funções diferentes) explicada aqui, mas gosto mais desta.
No meu caso, tenho uma matriz de $ posts com todas as postagens que desejo inserir e uma $ media separada (as mesmas chaves $ nid que $ posts) com a mídia. Meu código é a mesma solução que a de Tom, mas refatorada para usar uma função anônima:
foreach( $posts as $nid=>$post )
$posts[$nid]['ID'] = wp_insert_post( $post );
foreach( $posts as $nid=>$post )
foreach( $media[$nid] as $m=>$mitem ) {
if( 0 == $m ) add_action( 'add_attachment',
function( $att_id ) use ($posts, $nid, $mitem) {
update_post_meta($posts[$nid]['ID'], '_thumbnail_id', $att_id);
$posts[$nid]['media_urls'][] = $mitem['url'];
}
);
media_sideload_image($mitem['url'], $post['ID']);
remove_all_actions( 'add_attachment' );
}
No meu caso, suponho que o primeiro item em cada $ media [$ nid] seja a imagem em destaque de sua postagem.
O WordPress definitivamente mudará media_sideload_image () para retornar o $ id. De fato, a função tem em mãos, veja a fonte aqui . Na verdade, há um ticket para isso e eles ainda têm patches para aplicar isso ao seu núcleo nesse meio tempo, se você quiser.