Вы можете попробовать это (я не проверял это, но это должно работать, я использую что-то подобное в моем плагине):
$image_path = 'path to your image';
$id = 'id of corresponding post';
$title = 'title of your image';
// Checking the filetype
$wp_filetype = wp_check_filetype(basename($image_path), null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => $title,
'post_content' => '',
'post_status' => 'inherit',
'post_parent' => $id
);
// inserting the attachment
$attach_id=wp_insert_attachment($attachment,$image_path);
require_once(ABSPATH . 'wp-admin/includes/image.php');
// Generating the metadate (and the thumbnails)
$attach_data=wp_generate_attachment_metadata($attach_id,$image_path );
// Setting it as thumbnail
update_post_meta( $id, '_thumbnail_id', $attach_id );