As a photographer with a website, you already know the drill: upload image, fill in alt text, write a description, add keywords — repeat for every single photo. It's tedious, and most photographers skip it entirely.
LucidSEO automates all of that. You send an image URL, and the API returns SEO-ready alt text, a meta description, a caption, and keywords — in seconds. Here's how to integrate it with PHP in under 10 minutes.
LucidSEO works asynchronously — you submit a job and receive the result via webhook. This keeps your page load fast and lets the AI do its work in the background.
<?php
$apiKey = 'your_api_key_here';
$imageUrl = 'https://yoursite.com/photos/mountain-sunrise.jpg';
$webhookUrl = 'https://yoursite.com/webhook/lucidseo';
$context = 'Landscape photography, golden hour';
$response = file_get_contents('https://lucidseo.net/api/photos/analyze', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => implode("
", [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey,
]),
'content' => json_encode([
'url' => $imageUrl,
'webhook_url' => $webhookUrl,
'context' => $context,
]),
],
]));
$result = json_decode($response, true);
// $result['photo_id'] — save this to match the webhook response later
echo 'Analysis started. Photo ID: ' . $result['photo_id'];
The context field is optional but recommended — it helps the AI produce more relevant keywords. A short phrase like "product photography, white background" or "wedding portrait, outdoor" makes a noticeable difference.
Once the analysis is done (usually within 1–2 seconds), LucidSEO calls your webhook_url with the results. Create a PHP file at that URL to handle the incoming data:
<?php
// webhook/lucidseo.php
$webhookSecret = 'your_webhook_secret_here'; // found in your LucidSEO API key settings
$rawBody = file_get_contents('php://input');
$expected = hash_hmac('sha256', $rawBody, $webhookSecret);
$received = $_SERVER['HTTP_X_LUCIDSEO_SIGNATURE'] ?? '';
if (!hash_equals($expected, $received)) {
http_response_code(401);
exit;
}
$payload = json_decode($rawBody, true);
if (!$payload || !isset($payload['photo_id'])) {
http_response_code(400);
exit;
}
$photoId = $payload['photo_id'];
$altText = $payload['alt_text'];
$description = $payload['description'];
$caption = $payload['caption'];
$keywords = $payload['keywords']; // array
// Save to your database, update your CMS, or write to a file
file_put_contents(
__DIR__ . '/seo_results.json',
json_encode($payload, JSON_PRETTY_PRINT)
);
http_response_code(200);
Every webhook request is signed with X-LucidSeo-Signature — an HMAC-SHA256 hash of the request body using your webhook secret. The hash_equals() comparison is timing-safe, which prevents timing attacks. Always verify the signature before trusting the payload.
The webhook payload looks like this:
{
"photo_id": 42,
"alt_text": "Golden sunrise over mountain peaks with orange sky reflecting on alpine lake",
"description": "Capture the magic of golden hour with this stunning alpine sunrise. Perfect for nature and landscape photography collections.",
"caption": "Alpine lake at sunrise, Swiss Alps",
"keywords": ["landscape photography", "golden hour", "alpine lake", "mountain sunrise", "nature photography"]
}
All fields are character-limit compliant out of the box: alt text stays under 120 characters, description under 155, caption under 80. You can paste them straight into WordPress, Lightroom publish services, or any CMS without editing.
For a photography portfolio or gallery site, the typical flow looks like this:
No manual work. No copy-pasting. Every photo gets proper alt text and a description the moment it's uploaded.
The free plan includes 50 analyses per month — more than enough to test the integration and see the results on your own images before committing to a paid plan.
Ready to optimize your photos?
Generate SEO-optimized alt texts, descriptions, and keywords automatically — via API.
Start for free