<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>wp-cli api integration Archives - WP-CLI Mastery</title>
	<atom:link href="https://wpclimastery.com/blog/tag/wp-cli-api-integration/feed/" rel="self" type="application/rss+xml" />
	<link>https://wpclimastery.com/blog/tag/wp-cli-api-integration/</link>
	<description>Automate WordPress Like a DevOps Pro.</description>
	<lastBuildDate>Mon, 24 Nov 2025 11:16:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wpclimastery.com/wp-content/uploads/2025/11/cropped-favicon-32x32.webp</url>
	<title>wp-cli api integration Archives - WP-CLI Mastery</title>
	<link>https://wpclimastery.com/blog/tag/wp-cli-api-integration/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Integrate Unsplash API with WordPress Using WP-CLI and Bash</title>
		<link>https://wpclimastery.com/blog/integrate-unsplash-api-with-wordpress-using-wp-cli-and-bash/</link>
		
		<dc:creator><![CDATA[Krasen]]></dc:creator>
		<pubDate>Sun, 30 Nov 2025 09:00:00 +0000</pubDate>
				<category><![CDATA[API Integration Tutorials]]></category>
		<category><![CDATA[featured image automation]]></category>
		<category><![CDATA[unsplash api wordpress]]></category>
		<category><![CDATA[unsplash wordpress automation]]></category>
		<category><![CDATA[wordpress media api]]></category>
		<category><![CDATA[wp-cli api integration]]></category>
		<guid isPermaLink="false">https://wpclimastery.com/?p=14</guid>

					<description><![CDATA[<p>Finding high-quality, royalty-free images for every blog post is time-consuming. Manually searching Unsplash, downloading images, uploading to WordPress, and adding attribution takes 5-10 minutes per post. For content-heavy sites publishing...</p>
<p>The post <a href="https://wpclimastery.com/blog/integrate-unsplash-api-with-wordpress-using-wp-cli-and-bash/">Integrate Unsplash API with WordPress Using WP-CLI and Bash</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Finding high-quality, royalty-free images for every blog post is time-consuming. Manually searching Unsplash, downloading images, uploading to WordPress, and adding attribution takes 5-10 minutes per post. For content-heavy sites publishing daily, that&#8217;s hours of wasted effort every week.</p>



<p>What if you could automatically fetch relevant images from Unsplash and set them as featured images—all from the command line?</p>



<p>In this tutorial, you&#8217;ll learn to integrate the Unsplash API with WordPress using WP-CLI and Bash. You&#8217;ll build a complete automation system that searches for images, downloads them, imports to WordPress media library, sets featured images, and handles proper attribution automatically.</p>



<p>This is a key component of the automated blog publishing pipeline you&#8217;ll build in WPCLI Mastery.</p>



<h3 class="wp-block-heading" id="why-automate-images-with-unsplash-why-unsplash">Why Automate Images with Unsplash?</h3>



<h4 class="wp-block-heading" id="the-manual-image-problem">The Manual Image Problem</h4>



<p><strong>Typical workflow:</strong></p>



<ol class="wp-block-list">
<li>Search Unsplash for relevant image (2 min)</li>



<li>Download image (30 sec)</li>



<li>Upload to WordPress (1 min)</li>



<li>Set as featured image (30 sec)</li>



<li>Add attribution in caption/alt text (1 min)</li>
</ol>



<p><strong>Total: ~5 minutes per post</strong></p>



<p>For 20 posts/month =&nbsp;<strong>100 minutes wasted</strong></p>



<h4 class="wp-block-heading" id="automated-solution">Automated Solution</h4>



<p>With WP-CLI + Unsplash API:</p>



<pre class="wp-block-code"><code><em># One command, 5 seconds</em>
wp unsplash set-featured 123 --query="technology"
</code></pre>



<p><strong>Result:</strong></p>



<ul class="wp-block-list">
<li>Image downloaded</li>



<li>Imported to media library</li>



<li>Set as featured image</li>



<li>Attribution added</li>



<li>Alt text optimized</li>
</ul>



<h4 class="wp-block-heading" id="unsplash-benefits">Unsplash Benefits</h4>



<p><strong>High Quality</strong>: Professional photography, all free&nbsp;<strong>Huge Library</strong>: Over 3 million images&nbsp;<strong>Legal Safety</strong>: Completely free for commercial use&nbsp;<strong>Developer-Friendly</strong>: Well-documented API&nbsp;<strong>SEO Value</strong>: Proper attribution builds credibility</p>



<p>According to&nbsp;<a href="https://unsplash.com/about">Unsplash</a>, images are downloaded&nbsp;<strong>over 10 billion times</strong>&nbsp;per year. It&#8217;s the go-to source for professional content creators.</p>



<h3 class="wp-block-heading" id="prerequisites-prerequisites">Prerequisites</h3>



<p>Before integrating Unsplash API, ensure you have:</p>



<h4 class="wp-block-heading" id="required-software">Required Software</h4>



<ul class="wp-block-list">
<li><strong>WP-CLI installed</strong>&nbsp;&#8211;&nbsp;<a href="#">Installation guide</a></li>



<li><strong>curl</strong>&nbsp;&#8211; For API requests</li>



<li><strong>jq</strong>&nbsp;&#8211; JSON parsing tool</li>



<li><strong>Bash</strong>&nbsp;&#8211; Shell scripting knowledge</li>
</ul>



<p>Install missing tools:</p>



<pre class="wp-block-code"><code><em># Ubuntu/Debian</em>
sudo apt-get install curl jq

<em># macOS</em>
brew install curl jq
</code></pre>



<h4 class="wp-block-heading" id="wordpress-requirements">WordPress Requirements</h4>



<ul class="wp-block-list">
<li>WordPress site with WP-CLI access</li>



<li>Write permissions for uploads directory</li>



<li>Basic understanding of&nbsp;<a href="https://wordpress.org/support/article/media-library-screen/">WordPress media library</a></li>
</ul>



<h4 class="wp-block-heading" id="bash-knowledge">Bash Knowledge</h4>



<p>Helpful background:</p>



<ul class="wp-block-list">
<li><a href="#">Bash functions for WordPress</a></li>



<li>API requests with curl</li>



<li>JSON parsing basics</li>
</ul>



<h3 class="wp-block-heading" id="getting-unsplash-api-access-api-access">Getting Unsplash API Access</h3>



<h4 class="wp-block-heading" id="step-1-create-unsplash-account">Step 1: Create Unsplash Account</h4>



<ol class="wp-block-list">
<li>Visit&nbsp;<a href="https://unsplash.com/">Unsplash.com</a></li>



<li>Sign up for free account</li>



<li>Verify your email</li>
</ol>



<h4 class="wp-block-heading" id="step-2-register-your-application">Step 2: Register Your Application</h4>



<ol class="wp-block-list">
<li>Go to&nbsp;<a href="https://unsplash.com/developers">Unsplash Developers</a></li>



<li>Click &#8220;Register as a Developer&#8221;</li>



<li>Accept the API terms</li>



<li>Click &#8220;New Application&#8221;</li>
</ol>



<h4 class="wp-block-heading" id="step-3-create-api-application">Step 3: Create API Application</h4>



<p>Fill in application details:</p>



<ul class="wp-block-list">
<li><strong>Application name</strong>: &#8220;WordPress Blog Automation&#8221;</li>



<li><strong>Description</strong>: &#8220;Automated featured image fetching for WordPress blog&#8221;</li>



<li><strong>Callback URLs</strong>: (not needed for this use case)</li>
</ul>



<p><strong>Important</strong>: Accept the&nbsp;<a href="https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines">API Guidelines</a></p>



<h4 class="wp-block-heading" id="step-4-get-api-keys">Step 4: Get API Keys</h4>



<p>After creating your app, you&#8217;ll receive:</p>



<ul class="wp-block-list">
<li><strong>Access Key</strong>: Public key for API requests (Demo: Limited to 50 requests/hour)</li>



<li><strong>Secret Key</strong>: Keep private (not needed for basic usage)</li>
</ul>



<p><strong>Demo vs Production:</strong></p>



<ul class="wp-block-list">
<li><strong>Demo</strong>: 50 requests/hour (good for testing)</li>



<li><strong>Production</strong>: 5,000 requests/hour (requires app approval by Unsplash)</li>
</ul>



<p>For most blogs, demo limits are sufficient. Production approval takes 1-2 business days.</p>



<h4 class="wp-block-heading" id="step-5-store-api-key-securely">Step 5: Store API Key Securely</h4>



<p><strong>Never hardcode API keys in scripts.</strong></p>



<p>Store in environment variable:</p>



<pre class="wp-block-code"><code><em># Add to ~/.bashrc or ~/.bash_profile</em>
export UNSPLASH_ACCESS_KEY="your_access_key_here"

<em># Reload</em>
source ~/.bashrc
</code></pre>



<p>Or use a config file:</p>



<pre class="wp-block-code"><code><em># Create config file</em>
nano ~/.unsplash-config

<em># Add key</em>
UNSPLASH_ACCESS_KEY=your_access_key_here

<em># Secure it</em>
chmod 600 ~/.unsplash-config
</code></pre>



<h3 class="wp-block-heading" id="understanding-unsplash-api-api-basics">Understanding Unsplash API</h3>



<h4 class="wp-block-heading" id="api-endpoints">API Endpoints</h4>



<p><strong>Search Photos:</strong></p>



<pre class="wp-block-code"><code>GET https://api.unsplash.com/search/photos
</code></pre>



<p><strong>Get Random Photo:</strong></p>



<pre class="wp-block-code"><code>GET https://api.unsplash.com/photos/random
</code></pre>



<p><strong>Get Specific Photo:</strong></p>



<pre class="wp-block-code"><code>GET https://api.unsplash.com/photos/{id}
</code></pre>



<h4 class="wp-block-heading" id="basic-api-request">Basic API Request</h4>



<pre class="wp-block-code"><code>curl -H "Authorization: Client-ID YOUR_ACCESS_KEY" \
	"https://api.unsplash.com/photos/random?query=nature"
</code></pre>



<h4 class="wp-block-heading" id="response-format">Response Format</h4>



<p>Unsplash returns JSON:</p>



<pre class="wp-block-code"><code>{
	"id": "abc123",
	"urls": {
		"raw": "https://images.unsplash.com/photo-...",
		"full": "https://images.unsplash.com/photo-...",
		"regular": "https://images.unsplash.com/photo-...",
		"small": "https://images.unsplash.com/photo-..."
	},
	"user": {
		"name": "John Doe",
		"username": "johndoe",
		"links": {
			"html": "https://unsplash.com/@johndoe"
		}
	},
	"description": "Beautiful sunset over mountains",
	"alt_description": "orange sunset"
}
</code></pre>



<p><strong>Key fields:</strong></p>



<ul class="wp-block-list">
<li><code>urls.regular</code>: Best for WordPress featured images (1080px wide)</li>



<li><code>user.name</code>: For attribution</li>



<li><code>user.links.html</code>: Link to photographer&#8217;s profile</li>



<li><code>alt_description</code>: Good for alt text</li>
</ul>



<p>Read full docs:&nbsp;<a href="https://unsplash.com/documentation">Unsplash API Documentation</a></p>



<h3 class="wp-block-heading" id="fetching-images-with-curl-fetching-images">Fetching Images with curl</h3>



<h4 class="wp-block-heading" id="search-for-images">Search for Images</h4>



<pre class="wp-block-code"><code>#!/bin/bash

UNSPLASH_KEY="your_access_key"
QUERY="technology"

<em># Search for images</em>
response=$(curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" \
	"https://api.unsplash.com/search/photos?query=${QUERY}&amp;per_page=1")

<em># Parse response with jq</em>
image_url=$(echo "$response" | jq -r '.results&#91;0].urls.regular')
photo_id=$(echo "$response" | jq -r '.results&#91;0].id')
photographer=$(echo "$response" | jq -r '.results&#91;0].user.name')
photographer_url=$(echo "$response" | jq -r '.results&#91;0].user.links.html')
alt_text=$(echo "$response" | jq -r '.results&#91;0].alt_description')

echo "Image URL: ${image_url}"
echo "Photographer: ${photographer}"
echo "Alt Text: ${alt_text}"
</code></pre>



<h4 class="wp-block-heading" id="get-random-image">Get Random Image</h4>



<pre class="wp-block-code"><code>get_random_image() {
		local query=$1
		local orientation=${2:-landscape}  <em># landscape, portrait, squarish</em>

		local response=$(curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" \
			"https://api.unsplash.com/photos/random?query=${query}&amp;orientation=${orientation}")

		echo "$response"
}

<em># Usage</em>
response=$(get_random_image "coding" "landscape")
image_url=$(echo "$response" | jq -r '.urls.regular')
</code></pre>



<h4 class="wp-block-heading" id="search-parameters">Search Parameters</h4>



<p>Common parameters:</p>



<pre class="wp-block-code"><code><em># Search with pagination</em>
?query=nature&amp;page=2&amp;per_page=10

<em># Filter by orientation</em>
?query=laptop&amp;orientation=landscape

<em># Filter by color</em>
?query=sunset&amp;color=orange

<em># Combine filters</em>
?query=workspace&amp;orientation=landscape&amp;color=black_and_white
</code></pre>



<p><strong>Orientation options:</strong></p>



<ul class="wp-block-list">
<li><code>landscape</code>&nbsp;&#8211; Horizontal (best for featured images)</li>



<li><code>portrait</code>&nbsp;&#8211; Vertical</li>



<li><code>squarish</code>&nbsp;&#8211; Square-ish</li>
</ul>



<p><strong>Color options:</strong></p>



<ul class="wp-block-list">
<li><code>black_and_white</code>,&nbsp;<code>black</code>,&nbsp;<code>white</code>,&nbsp;<code>yellow</code>,&nbsp;<code>orange</code>,&nbsp;<code>red</code>,&nbsp;<code>purple</code>,&nbsp;<code>magenta</code>,&nbsp;<code>green</code>,&nbsp;<code>teal</code>,&nbsp;<code>blue</code></li>
</ul>



<h3 class="wp-block-heading" id="downloading-images-downloading">Downloading Images</h3>



<h4 class="wp-block-heading" id="download-image-to-filesystem">Download Image to Filesystem</h4>



<pre class="wp-block-code"><code>download_image() {
		local image_url=$1
		local output_file=$2

		if curl -s -o "$output_file" "$image_url"; then
				echo "Downloaded: ${output_file}"
				return 0
		else
				echo "Error: Download failed" &gt;&amp;2
				return 1
		fi
}

<em># Usage</em>
image_url="https://images.unsplash.com/photo-xyz?w=1080"
output="/tmp/unsplash-image.jpg"

download_image "$image_url" "$output"
</code></pre>



<h4 class="wp-block-heading" id="generate-unique-filename">Generate Unique Filename</h4>



<pre class="wp-block-code"><code>generate_filename() {
		local query=$1
		local timestamp=$(date +%Y%m%d_%H%M%S)
		local random=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 6)

		<em># Sanitize query (remove spaces, special chars)</em>
		local clean_query=$(echo "$query" | tr ' ' '-' | tr -cd '&#91;:alnum:]-')

		echo "unsplash-${clean_query}-${timestamp}-${random}.jpg"
}

<em># Usage</em>
filename=$(generate_filename "mountain landscape")
<em># Output: unsplash-mountain-landscape-20250325_143022-aB3xY9.jpg</em>
</code></pre>



<h4 class="wp-block-heading" id="complete-download-function">Complete Download Function</h4>



<pre class="wp-block-code"><code>fetch_and_download() {
		local query=$1
		local output_dir=${2:-/tmp}

		<em># Fetch image data</em>
		local response=$(curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" \
			"https://api.unsplash.com/photos/random?query=${query}&amp;orientation=landscape")

		<em># Parse response</em>
		local image_url=$(echo "$response" | jq -r '.urls.regular')
		local photo_id=$(echo "$response" | jq -r '.id')

		if &#91; "$image_url" = "null" ] || &#91; -z "$image_url" ]; then
				echo "Error: No image found for query '${query}'" &gt;&amp;2
				return 1
		fi

		<em># Generate filename</em>
		local filename=$(generate_filename "$query")
		local filepath="${output_dir}/${filename}"

		<em># Download image</em>
		if curl -s -o "$filepath" "$image_url"; then
				echo "$filepath"
				return 0
		else
				echo "Error: Download failed" &gt;&amp;2
				return 1
		fi
}

<em># Usage</em>
image_file=$(fetch_and_download "workspace" "/tmp")
echo "Image saved: ${image_file}"
</code></pre>



<h3 class="wp-block-heading" id="importing-to-wordpress-media-library-importing-media">Importing to WordPress Media Library</h3>



<h4 class="wp-block-heading" id="wp-cli-media-import">WP-CLI Media Import</h4>



<p>WP-CLI provides&nbsp;<code>wp media import</code>&nbsp;for adding images to media library.</p>



<p><strong>Basic import:</strong></p>



<pre class="wp-block-code"><code>wp media import /tmp/image.jpg --title="My Image"
</code></pre>



<p><strong>With metadata:</strong></p>



<pre class="wp-block-code"><code>wp media import /tmp/image.jpg \
	--title="Mountain Landscape" \
	--alt="Beautiful mountain sunset" \
	--caption="Photo by John Doe on Unsplash" \
	--porcelain  <em># Returns attachment ID only</em>
</code></pre>



<h4 class="wp-block-heading" id="import-function-with-metadata">Import Function with Metadata</h4>



<pre class="wp-block-code"><code>import_to_wordpress() {
		local image_file=$1
		local title=$2
		local alt_text=$3
		local caption=$4

		<em># Import and get attachment ID</em>
		local attachment_id=$(wp media import "$image_file" \
				--title="$title" \
				--alt="$alt_text" \
				--caption="$caption" \
				--porcelain)

		if &#91; -n "$attachment_id" ]; then
				echo "Imported as attachment ID: ${attachment_id}"
				echo "$attachment_id"
				return 0
		else
				echo "Error: Import failed" &gt;&amp;2
				return 1
		fi
}

<em># Usage</em>
attachment_id=$(import_to_wordpress \
		"/tmp/image.jpg" \
		"Tech Workspace" \
		"Modern laptop on wooden desk" \
		"Photo by Jane Smith on Unsplash")
</code></pre>



<h4 class="wp-block-heading" id="complete-fetch-and-import">Complete Fetch and Import</h4>



<pre class="wp-block-code"><code>fetch_and_import() {
		local query=$1

		<em># Fetch image from Unsplash</em>
		local response=$(curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" \
			"https://api.unsplash.com/photos/random?query=${query}&amp;orientation=landscape")

		<em># Parse metadata</em>
		local image_url=$(echo "$response" | jq -r '.urls.regular')
		local photographer=$(echo "$response" | jq -r '.user.name')
		local photographer_url=$(echo "$response" | jq -r '.user.links.html')
		local alt_text=$(echo "$response" | jq -r '.alt_description')
		local description=$(echo "$response" | jq -r '.description // .alt_description')

		<em># Download to temp file</em>
		local temp_file="/tmp/unsplash-$(date +%s).jpg"
		curl -s -o "$temp_file" "$image_url"

		<em># Prepare metadata</em>
		local title="$description"
		local caption="Photo by ${photographer} on Unsplash (${photographer_url})"

		<em># Import to WordPress</em>
		local attachment_id=$(wp media import "$temp_file" \
				--title="$title" \
				--alt="$alt_text" \
				--caption="$caption" \
				--porcelain)

		<em># Clean up temp file</em>
		rm -f "$temp_file"

		echo "$attachment_id"
}

<em># Usage</em>
attachment_id=$(fetch_and_import "coffee shop")
echo "Imported image: ${attachment_id}"
</code></pre>



<h3 class="wp-block-heading" id="setting-featured-images-featured-images">Setting Featured Images</h3>



<h4 class="wp-block-heading" id="set-featured-image-for-post">Set Featured Image for Post</h4>



<pre class="wp-block-code"><code>wp post meta update POST_ID _thumbnail_id ATTACHMENT_ID
</code></pre>



<p><strong>Example:</strong></p>



<pre class="wp-block-code"><code><em># Post ID 123, Attachment ID 456</em>
wp post meta update 123 _thumbnail_id 456
</code></pre>



<h4 class="wp-block-heading" id="complete-function">Complete Function</h4>



<pre class="wp-block-code"><code>set_featured_image() {
		local post_id=$1
		local attachment_id=$2

		if wp post meta update "$post_id" _thumbnail_id "$attachment_id" &amp;&gt;/dev/null; then
				echo "Featured image set for post ${post_id}"
				return 0
		else
				echo "Error: Failed to set featured image" &gt;&amp;2
				return 1
		fi
}

<em># Usage</em>
set_featured_image 123 456
</code></pre>



<h4 class="wp-block-heading" id="one-command-solution">One-Command Solution</h4>



<p>Combine everything:</p>



<pre class="wp-block-code"><code>set_unsplash_featured() {
		local post_id=$1
		local query=$2

		echo "Fetching image for: ${query}"

		<em># Fetch and import</em>
		local attachment_id=$(fetch_and_import "$query")

		if &#91; -z "$attachment_id" ]; then
				echo "Error: Failed to fetch/import image" &gt;&amp;2
				return 1
		fi

		<em># Set as featured</em>
		if set_featured_image "$post_id" "$attachment_id"; then
				echo "✓ Featured image set successfully"
				echo "Post ID: ${post_id}"
				echo "Attachment ID: ${attachment_id}"
				return 0
		else
				return 1
		fi
}

<em># Usage</em>
set_unsplash_featured 123 "technology workspace"
</code></pre>



<h3 class="wp-block-heading" id="handling-attribution-attribution">Handling Attribution</h3>



<h4 class="wp-block-heading" id="unsplash-attribution-requirements">Unsplash Attribution Requirements</h4>



<p>Per&nbsp;<a href="https://unsplash.com/license">Unsplash License</a>:</p>



<p><strong>Required:</strong></p>



<ul class="wp-block-list">
<li>Credit photographer by name</li>



<li>Link to photographer&#8217;s Unsplash profile</li>
</ul>



<p><strong>Good attribution:</strong></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>&#8220;Photo by&nbsp;<a href="#">Photographer Name</a>&nbsp;on Unsplash&#8221;</p>
</blockquote>



<p><strong>Bad attribution:</strong></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>&#8220;From Unsplash&#8221; (missing photographer credit)</p>
</blockquote>



<h4 class="wp-block-heading" id="add-attribution-to-caption">Add Attribution to Caption</h4>



<pre class="wp-block-code"><code>create_attribution() {
		local photographer=$1
		local photographer_url=$2

		echo "Photo by ${photographer} on Unsplash (${photographer_url})"
}

<em># Usage</em>
photographer="John Doe"
url="https://unsplash.com/@johndoe"
caption=$(create_attribution "$photographer" "$url")
<em># Output: Photo by John Doe on Unsplash (https://unsplash.com/@johndoe)</em>
</code></pre>



<h4 class="wp-block-heading" id="add-attribution-to-post-content">Add Attribution to Post Content</h4>



<p>Optionally add attribution directly in post content:</p>



<pre class="wp-block-code"><code>add_attribution_to_post() {
		local post_id=$1
		local photographer=$2
		local photographer_url=$3

		<em># Get current content</em>
		local content=$(wp post get "$post_id" --field=content)

		<em># Append attribution</em>
		local attribution="&lt;p&gt;&lt;em&gt;Featured image by &lt;a href=\"${photographer_url}\"&gt;${photographer}&lt;/a&gt; on &lt;a href=\"https://unsplash.com\"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;"

		local new_content="${content}\n\n${attribution}"

		<em># Update post</em>
		wp post update "$post_id" --post_content="$new_content"
}
</code></pre>



<h4 class="wp-block-heading" id="trigger-download-tracking">Trigger Download Tracking</h4>



<p>Unsplash requires triggering download endpoint for analytics:</p>



<pre class="wp-block-code"><code>trigger_download() {
		local download_url=$1

		curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" "$download_url" &gt; /dev/null
}

<em># Get download URL from API response</em>
download_url=$(echo "$response" | jq -r '.links.download_location')
trigger_download "$download_url"
</code></pre>



<p><strong>Important</strong>: This is required by Unsplash API guidelines.</p>



<h3 class="wp-block-heading" id="complete-automation-script-complete-script">Complete Automation Script</h3>



<p>Here&#8217;s the full production-ready script:</p>



<pre class="wp-block-code"><code>#!/bin/bash
<em>#</em>
<em># Unsplash WordPress Integration Script</em>
<em># Fetches images from Unsplash and sets as WordPress featured images</em>
<em>#</em>

set -euo pipefail

<em>#############################################</em>
<em># CONFIGURATION</em>
<em>#############################################</em>

<em># Load API key from config file</em>
if &#91; -f ~/.unsplash-config ]; then
		source ~/.unsplash-config
fi

UNSPLASH_KEY="${UNSPLASH_ACCESS_KEY:-}"
TEMP_DIR="/tmp/unsplash-wp"

<em>#############################################</em>
<em># FUNCTIONS</em>
<em>#############################################</em>

check_dependencies() {
		local missing=()

		command -v curl &amp;&gt;/dev/null || missing+=("curl")
		command -v jq &amp;&gt;/dev/null || missing+=("jq")
		command -v wp &amp;&gt;/dev/null || missing+=("wp-cli")

		if &#91;  then
				echo "Error: Missing dependencies: ${missing&#91;*]}" &gt;&amp;2
				exit 1
		fi

		if &#91; -z "$UNSPLASH_KEY" ]; then
				echo "Error: UNSPLASH_ACCESS_KEY not set" &gt;&amp;2
				echo "Set it in ~/.unsplash-config or environment" &gt;&amp;2
				exit 1
		fi
}

fetch_unsplash_image() {
		local query=$1
		local orientation=${2:-landscape}

		local url="https://api.unsplash.com/photos/random"
		url="${url}?query=${query}&amp;orientation=${orientation}"

		local response=$(curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" "$url")

		<em># Check for errors</em>
		local errors=$(echo "$response" | jq -r '.errors // empty')
		if &#91; -n "$errors" ]; then
				echo "API Error: $errors" &gt;&amp;2
				return 1
		fi

		echo "$response"
}

download_image() {
		local image_url=$1
		local output_file=$2

		if curl -s -L -o "$output_file" "$image_url"; then
				return 0
		else
				return 1
		fi
}

import_to_media_library() {
		local image_file=$1
		local metadata=$2

		local title=$(echo "$metadata" | jq -r '.title')
		local alt=$(echo "$metadata" | jq -r '.alt')
		local caption=$(echo "$metadata" | jq -r '.caption')

		local attachment_id=$(wp media import "$image_file" \
				--title="$title" \
				--alt="$alt" \
				--caption="$caption" \
				--porcelain 2&gt;/dev/null)

		echo "$attachment_id"
}

set_featured_image_for_post() {
		local post_id=$1
		local attachment_id=$2

		wp post meta update "$post_id" _thumbnail_id "$attachment_id" &amp;&gt;/dev/null
}

trigger_download_endpoint() {
		local download_url=$1

		curl -s -H "Authorization: Client-ID ${UNSPLASH_KEY}" "$download_url" &gt; /dev/null
}

<em>#############################################</em>
<em># MAIN FUNCTION</em>
<em>#############################################</em>

set_unsplash_featured() {
		local post_id=$1
		local query=$2
		local orientation=${3:-landscape}

		echo "================================================"
		echo "Unsplash Featured Image Automation"
		echo "================================================"
		echo "Post ID: ${post_id}"
		echo "Query: ${query}"
		echo "Orientation: ${orientation}"
		echo "================================================"

		<em># Verify post exists</em>
		if ! wp post get "$post_id" &amp;&gt;/dev/null; then
				echo "Error: Post ${post_id} not found" &gt;&amp;2
				return 1
		fi

		<em># Fetch image from Unsplash</em>
		echo "Fetching image from Unsplash..."
		local response=$(fetch_unsplash_image "$query" "$orientation")

		if &#91; $? -ne 0 ]; then
				echo "Error: Failed to fetch image" &gt;&amp;2
				return 1
		fi

		<em># Parse response</em>
		local image_url=$(echo "$response" | jq -r '.urls.regular')
		local photographer=$(echo "$response" | jq -r '.user.name')
		local photographer_url=$(echo "$response" | jq -r '.user.links.html')
		local alt_text=$(echo "$response" | jq -r '.alt_description // "Image from Unsplash"')
		local description=$(echo "$response" | jq -r '.description // .alt_description')
		local download_endpoint=$(echo "$response" | jq -r '.links.download_location')

		echo "Found: ${description}"
		echo "By: ${photographer}"

		<em># Create temp directory</em>
		mkdir -p "$TEMP_DIR"

		<em># Download image</em>
		local temp_file="${TEMP_DIR}/unsplash-$(date +%s).jpg"
		echo "Downloading image..."

		if ! download_image "$image_url" "$temp_file"; then
				echo "Error: Download failed" &gt;&amp;2
				return 1
		fi

		<em># Prepare metadata</em>
		local caption="Photo by &lt;a href=\"${photographer_url}\"&gt;${photographer}&lt;/a&gt; on &lt;a href=\"https://unsplash.com\"&gt;Unsplash&lt;/a&gt;"

		local metadata=$(jq -n \
				--arg title "$description" \
				--arg alt "$alt_text" \
				--arg caption "$caption" \
				'{title: $title, alt: $alt, caption: $caption}')

		<em># Import to WordPress</em>
		echo "Importing to media library..."
		local attachment_id=$(import_to_media_library "$temp_file" "$metadata")

		if &#91; -z "$attachment_id" ]; then
				echo "Error: Import failed" &gt;&amp;2
				rm -f "$temp_file"
				return 1
		fi

		echo "Imported as attachment ${attachment_id}"

		<em># Set as featured image</em>
		echo "Setting as featured image..."
		if set_featured_image_for_post "$post_id" "$attachment_id"; then
				echo "✓ Featured image set successfully"
		else
				echo "Error: Failed to set featured image" &gt;&amp;2
				rm -f "$temp_file"
				return 1
		fi

		<em># Trigger download tracking (required by Unsplash)</em>
		trigger_download_endpoint "$download_endpoint"

		<em># Clean up</em>
		rm -f "$temp_file"

		echo "================================================"
		echo "SUCCESS!"
		echo "Post: ${post_id}"
		echo "Attachment: ${attachment_id}"
		echo "Photographer: ${photographer}"
		echo "================================================"

		return 0
}

<em>#############################################</em>
<em># SCRIPT ENTRY POINT</em>
<em>#############################################</em>

<em># Check dependencies</em>
check_dependencies

<em># Parse arguments</em>
if &#91; $# -lt 2 ]; then
		echo "Usage: $0 &lt;post_id&gt; &lt;search_query&gt; &#91;orientation]"
		echo ""
		echo "Examples:"
		echo "  $0 123 'technology workspace'"
		echo "  $0 456 'coffee shop' portrait"
		echo ""
		exit 1
fi

POST_ID=$1
QUERY=$2
ORIENTATION=${3:-landscape}

<em># Run main function</em>
set_unsplash_featured "$POST_ID" "$QUERY" "$ORIENTATION"

exit $?
</code></pre>



<h4 class="wp-block-heading" id="usage">Usage</h4>



<pre class="wp-block-code"><code><em># Save as unsplash-wp.sh</em>
chmod +x unsplash-wp.sh

<em># Set featured image for post</em>
./unsplash-wp.sh 123 "technology workspace"

<em># Portrait orientation</em>
./unsplash-wp.sh 456 "coffee shop interior" portrait

<em># Multiple keywords</em>
./unsplash-wp.sh 789 "mountain sunset landscape"
</code></pre>



<h3 class="wp-block-heading" id="advanced-features-advanced">Advanced Features</h3>



<h4 class="wp-block-heading" id="bulk-set-featured-images">Bulk Set Featured Images</h4>



<p>Process multiple posts:</p>



<pre class="wp-block-code"><code><em># Get all posts without featured images</em>
posts=$(wp post list --post_type=post --meta_key=_thumbnail_id --meta_compare=NOT EXISTS --field=ID)

for post_id in $posts; do
		<em># Get post title or category for query</em>
		title=$(wp post get $post_id --field=title)

		<em># Set featured image</em>
		./unsplash-wp.sh $post_id "$title"

		sleep 2  <em># Rate limiting</em>
done
</code></pre>



<h4 class="wp-block-heading" id="smart-query-from-post-content">Smart Query from Post Content</h4>



<p>Extract keywords from post:</p>



<pre class="wp-block-code"><code>get_query_from_post() {
		local post_id=$1

		<em># Get post title</em>
		local title=$(wp post get $post_id --field=title)

		<em># Get first category</em>
		local category=$(wp post term list $post_id category --field=name --format=csv | head -1)

		<em># Combine for better results</em>
		echo "${category} ${title}"
}

<em># Usage</em>
query=$(get_query_from_post 123)
./unsplash-wp.sh 123 "$query"
</code></pre>



<h4 class="wp-block-heading" id="fallback-to-default-images">Fallback to Default Images</h4>



<pre class="wp-block-code"><code>set_featured_with_fallback() {
		local post_id=$1
		local query=$2
		local fallback_query="abstract background"

		if ! ./unsplash-wp.sh $post_id "$query"; then
				echo "Primary query failed, trying fallback..."
				./unsplash-wp.sh $post_id "$fallback_query"
		fi
}
</code></pre>



<h3 class="wp-block-heading" id="error-handling-error-handling">Error Handling</h3>



<h4 class="wp-block-heading" id="api-error-responses">API Error Responses</h4>



<p>Handle common errors:</p>



<pre class="wp-block-code"><code>handle_api_response() {
		local response=$1

		<em># Check for rate limit</em>
		local rate_limit=$(echo "$response" | jq -r '.errors&#91;0] // empty' | grep -i "rate limit")
		if &#91; -n "$rate_limit" ]; then
				echo "Error: API rate limit reached" &gt;&amp;2
				echo "Wait 1 hour or upgrade to production API" &gt;&amp;2
				return 1
		fi

		<em># Check for invalid query</em>
		local invalid=$(echo "$response" | jq -r '.errors&#91;0] // empty')
		if &#91; -n "$invalid" ]; then
				echo "Error: $invalid" &gt;&amp;2
				return 1
		fi

		return 0
}
</code></pre>



<h4 class="wp-block-heading" id="network-errors">Network Errors</h4>



<pre class="wp-block-code"><code>download_with_retry() {
		local url=$1
		local output=$2
		local max_attempts=3
		local attempt=1

		while &#91; $attempt -le $max_attempts ]; do
				echo "Download attempt ${attempt}/${max_attempts}"

				if curl -s -L -o "$output" --connect-timeout 10 "$url"; then
						return 0
				fi

				attempt=$((attempt + 1))
				sleep 2
		done

		echo "Error: Download failed after ${max_attempts} attempts" &gt;&amp;2
		return 1
}
</code></pre>



<h3 class="wp-block-heading" id="rate-limiting-rate-limiting">Rate Limiting</h3>



<h4 class="wp-block-heading" id="unsplash-rate-limits">Unsplash Rate Limits</h4>



<ul class="wp-block-list">
<li><strong>Demo</strong>: 50 requests/hour</li>



<li><strong>Production</strong>: 5,000 requests/hour</li>
</ul>



<h4 class="wp-block-heading" id="implement-rate-limiting">Implement Rate Limiting</h4>



<pre class="wp-block-code"><code>check_rate_limit() {
		local last_request_file="/tmp/unsplash-last-request"
		local min_interval=72  <em># 50 requests/hour = 72 seconds between requests</em>

		if &#91; -f "$last_request_file" ]; then
				local last_request=$(cat "$last_request_file")
				local now=$(date +%s)
				local elapsed=$((now - last_request))

				if &#91; $elapsed -lt $min_interval ]; then
						local wait=$((min_interval - elapsed))
						echo "Rate limiting: waiting ${wait} seconds..."
						sleep $wait
				fi
		fi

		<em># Update last request time</em>
		date +%s &gt; "$last_request_file"
}

<em># Call before API requests</em>
check_rate_limit
</code></pre>



<h4 class="wp-block-heading" id="monitor-usage">Monitor Usage</h4>



<p>Check remaining requests:</p>



<pre class="wp-block-code"><code>response=$(curl -I -H "Authorization: Client-ID ${UNSPLASH_KEY}" \
	"https://api.unsplash.com/photos/random")

remaining=$(echo "$response" | grep -i "X-Ratelimit-Remaining" | cut -d: -f2 | tr -d ' \r')

echo "Remaining requests: ${remaining}"
</code></pre>



<h3 class="wp-block-heading" id="integration-with-publishing-pipeline-integration">Integration with Publishing Pipeline</h3>



<h4 class="wp-block-heading" id="automated-blog-publishing">Automated Blog Publishing</h4>



<p>Combine with content automation:</p>



<pre class="wp-block-code"><code>publish_post_with_image() {
		local title=$1
		local content=$2
		local query=$3

		<em># Create post</em>
		local post_id=$(wp post create \
				--post_title="$title" \
				--post_content="$content" \
				--post_status=publish \
				--porcelain)

		<em># Set featured image from Unsplash</em>
		./unsplash-wp.sh $post_id "$query"

		echo "Published post: ${post_id}"
}

<em># Usage</em>
publish_post_with_image \
		"10 Best Productivity Tools" \
		"Content here..." \
		"productivity workspace"
</code></pre>



<h4 class="wp-block-heading" id="integration-with-ai-content">Integration with AI Content</h4>



<pre class="wp-block-code"><code><em># Get AI-generated content</em>
content=$(call_ai_api "Write about productivity tools")

<em># Extract keywords for image</em>
keywords=$(echo "$content" | extract_keywords)  <em># Custom function</em>

<em># Create post</em>
post_id=$(wp post create --post_title="..." --post_content="$content" --porcelain)

<em># Set Unsplash featured image</em>
./unsplash-wp.sh $post_id "$keywords"
</code></pre>



<p>Learn more:&nbsp;<a href="#">Automated Blog Publishing with AI</a></p>



<h3 class="wp-block-heading" id="troubleshooting-troubleshooting">Troubleshooting</h3>



<h4 class="wp-block-heading" id="issue-1-jq-command-not-found">Issue 1: &#8220;jq: command not found&#8221;</h4>



<p><strong>Solution:</strong></p>



<pre class="wp-block-code"><code><em># Ubuntu/Debian</em>
sudo apt-get install jq

<em># macOS</em>
brew install jq

<em># CentOS</em>
sudo yum install jq
</code></pre>



<h4 class="wp-block-heading" id="issue-2-401-unauthorized">Issue 2: &#8220;401 Unauthorized&#8221;</h4>



<p><strong>Problem</strong>: Invalid API key</p>



<p><strong>Solutions:</strong></p>



<ol class="wp-block-list">
<li>Verify API key is correct</li>



<li>Check environment variable is set:</li>
</ol>



<pre class="wp-block-code"><code>echo $UNSPLASH_ACCESS_KEY
</code></pre>



<ol start="3" class="wp-block-list">
<li>Regenerate API key in Unsplash dashboard</li>
</ol>



<h4 class="wp-block-heading" id="issue-3-no-images-found">Issue 3: No Images Found</h4>



<p><strong>Problem</strong>: Query returns no results</p>



<p><strong>Solutions:</strong></p>



<ol class="wp-block-list">
<li>Simplify query (use broader terms)</li>



<li>Try different keywords</li>



<li>Check query isn&#8217;t too specific</li>
</ol>



<pre class="wp-block-code"><code><em># Too specific (may fail)</em>
query="red ferrari on mountain road at sunset"

<em># Better (broader)</em>
query="sports car"
</code></pre>



<h4 class="wp-block-heading" id="issue-4-rate-limit-exceeded">Issue 4: Rate Limit Exceeded</h4>



<p><strong>Problem</strong>: &#8220;Rate Limit Exceeded&#8221; error</p>



<p><strong>Solutions:</strong></p>



<ol class="wp-block-list">
<li>Wait 1 hour for demo API reset</li>



<li>Apply for production API (5,000 req/hour)</li>



<li>Implement rate limiting in your script</li>
</ol>



<h4 class="wp-block-heading" id="issue-5-import-failed">Issue 5: Import Failed</h4>



<p><strong>Problem</strong>:&nbsp;<code>wp media import</code>&nbsp;fails</p>



<p><strong>Solutions:</strong></p>



<ol class="wp-block-list">
<li>Check file permissions:</li>
</ol>



<pre class="wp-block-code"><code>ls -la /tmp/image.jpg
chmod 644 /tmp/image.jpg
</code></pre>



<ol start="2" class="wp-block-list">
<li>Verify uploads directory is writable:</li>
</ol>



<pre class="wp-block-code"><code>wp media regenerate --dry-run
</code></pre>



<ol start="3" class="wp-block-list">
<li>Check file size (Unsplash regular = ~500KB, should be fine)</li>
</ol>



<h3 class="wp-block-heading" id="next-steps-next-steps">Next Steps</h3>



<p>Congratulations! You&#8217;ve built a complete Unsplash + WordPress automation system.</p>



<h4 class="wp-block-heading" id="enhance-your-integration">Enhance Your Integration</h4>



<ol class="wp-block-list">
<li><strong><a href="#">Automated Blog Publishing Pipeline</a></strong>&nbsp;&#8211; Combine with AI content</li>



<li><strong><a href="#">Custom WP-CLI Commands</a></strong>&nbsp;&#8211; Build&nbsp;<code>wp unsplash</code>&nbsp;command</li>



<li><strong><a href="#">Bash Functions</a></strong>&nbsp;&#8211; Refactor into reusable library</li>
</ol>



<h4 class="wp-block-heading" id="related-guides">Related Guides</h4>



<ul class="wp-block-list">
<li><strong><a href="#"">WordPress REST API Integration</a></strong>&nbsp;&#8211; Advanced API techniques</li>



<li><strong><a href="#">AI Content Generation</a></strong>&nbsp;&#8211; Complete publishing automation</li>



<li><strong><a href="#">WordPress Automation</a></strong>&nbsp;&#8211; More automation examples</li>
</ul>



<h4 class="wp-block-heading" id="build-the-complete-pipeline">Build the Complete Pipeline</h4>



<p>This Unsplash integration is one piece of a complete automated publishing system:</p>



<ol class="wp-block-list">
<li>Generate content with AI</li>



<li><strong>Fetch featured image from Unsplash</strong>&nbsp;← You just learned this</li>



<li>Schedule and publish post</li>



<li>Optimize SEO automatically</li>
</ol>



<p><strong><a href="/#get-started">Join WPCLI Mastery</a></strong>&nbsp;to build the complete system:</p>



<ul class="wp-block-list">
<li>Full automated blog publishing pipeline</li>



<li>AI + Unsplash + WP-CLI integration</li>



<li>Production-ready scripts and templates</li>



<li>Early bird pricing ($99 vs $199)</li>
</ul>



<h3 class="wp-block-heading" id="conclusion">Conclusion</h3>



<p>Automating featured images with Unsplash API and WP-CLI saves hours of manual work while ensuring every post has professional, high-quality imagery. The script you built today can process thousands of posts automatically.</p>



<p><strong>Key takeaways:</strong></p>



<ul class="wp-block-list">
<li>Unsplash API provides free, high-quality images</li>



<li>curl + jq makes API integration simple</li>



<li>WP-CLI&nbsp;<code>media import</code>&nbsp;handles WordPress integration</li>



<li>Proper attribution is required (and easy to automate)</li>



<li>Rate limiting prevents API issues</li>



<li>Integration with publishing pipelines creates powerful automation</li>
</ul>



<p>The image automation you built today becomes even more powerful when combined with AI content generation for a complete hands-free publishing system.</p>



<p><strong>Ready to implement?</strong>&nbsp;Start with the complete script and customize for your workflow.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Questions about Unsplash + WordPress automation?</strong>&nbsp;Drop a comment below!</p>



<p><strong>Found this helpful?</strong>&nbsp;Share with WordPress developers automating content.</p>



<p><strong>Next:</strong>&nbsp;Build a complete&nbsp;<a href="#">WordPress CI/CD pipeline with GitHub Actions</a>&nbsp;that includes automated image fetching.</p>
<p>The post <a href="https://wpclimastery.com/blog/integrate-unsplash-api-with-wordpress-using-wp-cli-and-bash/">Integrate Unsplash API with WordPress Using WP-CLI and Bash</a> appeared first on <a href="https://wpclimastery.com">WP-CLI Mastery</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
