wp_insert_attachment( string|array $args, string|false $file = false, int $parent_post_id, bool $wp_error = false, bool $fire_after_hooks = true ): int|WP_Error

Inserts an attachment.


If you set the ‘ID’ in the $args parameter, it will mean that you are updating and attempt to update the attachment. You can also set the attachment name or title by setting the key ‘post_name’ or ‘post_title’.

You can set the dates for the attachment manually by setting the ‘post_date’ and ‘post_date_gmt’ keys’ values.

By default, the comments will use the default settings for whether the comments are allowed. You can close them manually or keep them open by setting the value for the ‘comment_status’ key.

See also


Arguments for inserting an attachment.


Parent post ID or 0 for no parent. Default 0.
Whether to return a WP_Error on failure.


Whether to fire the after insert hooks.



int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.


function wp_insert_attachment( $args, $file = false, $parent_post_id = 0, $wp_error = false, $fire_after_hooks = true ) {
	$defaults = array(
		'file'        => $file,
		'post_parent' => 0,

	$data = wp_parse_args( $args, $defaults );

	if ( ! empty( $parent_post_id ) ) {
		$data['post_parent'] = $parent_post_id;

	$data['post_type'] = 'attachment';

	return wp_insert_post( $data, $wp_error, $fire_after_hooks );


5.6.0Added the $fire_after_hooks parameter.
4.7.0Added the $wp_error parameter to allow a WP_Error to be returned on failure.

User Contributed Notes

  1. Skip to note 7 content

    Inserts an attachment to a parent with a post ID of 37:

    // $filename should be the path to a file in the upload directory.
    $filename = '/path/to/uploads/2013/03/filename.jpg';
    // The ID of the post this attachment is for.
    $parent_post_id = 37;
    // Check the type of file. We'll use this as the 'post_mime_type'.
    $filetype = wp_check_filetype( basename( $filename ), null );
    // Get the path to the upload directory.
    $wp_upload_dir = wp_upload_dir();
    // Prepare an array of post data for the attachment.
    $attachment = array(
    	'guid'           => $wp_upload_dir['url'] . '/' . basename( $filename ), 
    	'post_mime_type' => $filetype['type'],
    	'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
    	'post_content'   => '',
    	'post_status'    => 'inherit'
    // Insert the attachment.
    $attach_id = wp_insert_attachment( $attachment, $filename, $parent_post_id );
    // Make sure that this file is included, as wp_generate_attachment_metadata() depends on it.
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    // Generate the metadata for the attachment, and update the database record.
    $attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
    wp_update_attachment_metadata( $attach_id, $attach_data );
    set_post_thumbnail( $parent_post_id, $attach_id );
  2. Skip to note 8 content

    If you are trying to make a media attachment, caption and description are ‘post_excerpt’ and ‘post_content’, respectively. Example:

    			'guid' => $upload['url'],
    			'post_title' => sanitize_text_field( $title ),
    			'post_excerpt' => sanitize_text_field( $caption ),
    			'post_content' => sanitize_text_field( $description ),
    			'post_mime_type' => $response_headers['content-type'],

You must log in before being able to contribute a note or feedback.