Create and publish SEO-optimized blog posts about image upscaling, AI enhancement, and photo editing. Use when asked to write blog posts, publish content, or create SEO content.
Create SEO-optimized blog posts about image upscaling, AI photo enhancement, and related topics.
| Endpoint | Purpose |
|---|---|
GET /api/blog/images | Search existing images |
POST /api/blog/posts | Create draft post |
POST /api/blog/posts/[slug]/publish | Publish post |
POST /api/blog/images/upload | Upload featured image |
GET /api/blog/posts | List posts |
Authentication: Use x-api-key header with BLOG_API_KEY from .env.api
Before starting: Read recent entries to avoid repeating work or conflicting with recent changes.
tail -60 .claude/skills/blog-changelog.md
After publishing: Append a brief entry.
cat >> .claude/skills/blog-changelog.md << 'EOF'
## YYYY-MM-DD
### Publish: [slug]
**Why:** [keyword opportunity / user intent]
**Changes:**
- Published `slug` — [topic summary, target keyword]
EOF
0. CHANGELOG → Read recent entries first
1. ROADMAP CHECK → Read keyword-strategy-roadmap-*.md for prioritized topics
2. TRACKING → Check topics-covered.md to avoid duplication
3. SELECT TOPIC → Choose from roadmap Segment A/B (highest priority)
4. SEARCH IMAGES → GET /api/blog/images (check for reusable images first)
5. GENERATE IMAGES → Generate ONLY if no suitable images found (1 featured + 2-3 inline)
6. UPLOAD IMAGES → POST /api/blog/images/upload (with metadata: tags, description, prompt)
7. CREATE POST → POST /api/blog/posts (include inline image URLs in markdown content)
8. INTERNAL LINKS → Scan pSEO sitemaps for relevant pages; embed 2-3 contextual links in content
9. UPDATE → PATCH /api/blog/posts/[slug] (add featured image URL + updated content)
10. PUBLISH → POST /api/blog/posts/[slug]/publish
11. VERIFY → Check at /blog/[slug]
12. TRACK → Update topics-covered.md with completed topic
13. CHANGELOG → Append entry with slug, topic, and reasoning
IMPORTANT Changes:
CRITICAL: Before researching keywords manually, read the long-tail keyword roadmap. This contains pre-analyzed keywords that our DR 18 can realistically rank for.
# Read the long-tail keyword roadmap
ROADMAP="docs/SEO/long-tail-keyword-roadmap.md"
if [ -f "$ROADMAP" ]; then
echo "✅ Found long-tail keyword roadmap: $ROADMAP"
# Show priority topics
echo "=== PRIORITY 1: Platform-Specific (Immediate) ==="
grep -A 10 "## Priority 1: Platform-Specific" "$ROADMAP" | head -15
echo "=== PRIORITY 2: Format-Specific (Immediate) ==="
grep -A 10 "## Priority 2: Format-Specific" "$ROADMAP" | head -15
echo "=== PRIORITY 3: Use-Case Specific (This Month) ==="
grep -A 10 "## Priority 3: Use-Case Specific" "$ROADMAP" | head -15
echo "=== ALREADY COVERED (Don't Duplicate) ==="
grep -A 30 "## Topics Already Covered" "$ROADMAP" | head -35
else
echo "⚠️ No keyword roadmap found at $ROADMAP"
echo "Please ensure the file exists before proceeding."
exit 1
fi
IMPORTANT: We have DR 18 with 75 referring domains. We CANNOT rank for high-volume head terms (500K+ searches). Focus on:
| Tier | Volume Range | Competition | Can We Rank? | Priority |
|---|---|---|---|---|
| Long-tail | 300-2,000 | Low | YES (DR 15-25 needed) | P1 |
| Mid-tail | 2,000-10,000 | Low-Med | MAYBE (DR 25-35 needed) | P2 |
| Head terms | 50,000+ | High | NO (DR 50+ needed) | AVOID |
DO target:
DON'T target (yet):
# Create content tracking directory
mkdir -p docs/SEO/blog-content-tracking
# Create tracking file if it doesn't exist
if [ ! -f "docs/SEO/blog-content-tracking/topics-covered.md" ]; then
cat > docs/SEO/blog-content-tracking/topics-covered.md << 'EOF'
# Blog Content Tracking - MyImageUpscaler
**Last Updated**: $(date +%Y-%m-%d)
## Topics Covered (Blog Posts Published)
| Date | Keyword/Topic | Blog Slug | Roadmap Segment | Status |
|------|---------------|-----------|-----------------|--------|
| YYYY-MM-DD | Example keyword | example-slug | Segment A | ✅ Published |
## Topics In Progress
| Started | Keyword/Topic | Target Slug | Roadmap Segment | Assignee |
|---------|---------------|-------------|-----------------|----------|
| YYYY-MM-DD | Example keyword | example-slug | Segment B | Claude |
## Topics Planned (From Roadmap)
| Priority | Keyword/Topic | Search Vol | Competition | Roadmap Segment | Est. Impact |
|----------|---------------|------------|-------------|-----------------|-------------|
| P1 | ... | 500 | Low | Segment A | +50 clicks/mo |
EOF
fi
# Display tracking status
cat docs/SEO/blog-content-tracking/topics-covered.md
# Check for conflicts
echo "=== DUPLICATION CHECK ==="
read -p "Enter your target keyword: " TARGET_KEYWORD
grep -i "$TARGET_KEYWORD" docs/SEO/blog-content-tracking/topics-covered.md && \
echo "⚠️ WARNING: Similar topic may already be covered!" || \
echo "✅ No conflicts found - safe to proceed"
Decision Matrix:
| Source | Priority | When to Use |
|---|---|---|
| Priority 1: Platform-Specific | P1 | Platform upscaler pages need blog support |
| Priority 2: Format-Specific | P1 | Format pages (HEIC, TIFF, WebP) need content |
| Priority 3: Use-Case Specific | P1 | Use case pages (logo, real estate, NFT) |
| Priority 4: Scale-Specific | P2 | Scale pages (8x, 16x, 4x sweet spot) |
| Priority 5: Free + Long-Tail | P2 | Free modifier keywords |
| Priority 6: Question-Based | P2 | Featured snippet opportunities |
| Priority 7: Comparison | P3 | Alternative/comparison posts |
| Topics Already Covered | AVOID | Check topics-covered.md to prevent duplication |
docs/SEO/long-tail-keyword-roadmap.mddocs/SEO/blog-content-tracking/topics-covered.md for duplicatesCRITICAL: Before generating any new images, search for existing reusable images. This saves ~$0.05-0.12 and ~60-120s per image.
Use these standardized tags when searching and uploading. Each image should have 3-6 tags.
| Category | Tags |
|---|---|
| Theme | before-after, ai-processing, workflow, print-result, comparison, workspace, tutorial, ecommerce, social-media, restoration, upscaling |
| Subject | laptop, phone, printer, photo, screenshot, artwork, product-photo, infographic, diagram |
| Style | photorealistic, clean, professional, split-screen, side-by-side, step-by-step |
| Blog Category | guides, tips, comparisons, news, technical |
| Image Type | featured, inline |
# Load environment
source scripts/load-env.sh
API_KEY=$(grep BLOG_API_KEY .env.api | cut -d'=' -f2)
# Search for featured images with before-after comparison theme
curl -s "http://localhost:3000/api/blog/images?tags=before-after,upscaling&image_type=featured&limit=5" \
-H "x-api-key: $API_KEY" | jq '.data[] | {url, alt_text, tags, prompt}'
# Search for inline images showing AI processing
curl -s "http://localhost:3000/api/blog/images?tags=ai-processing,workflow&image_type=inline&limit=5" \
-H "x-api-key: $API_KEY" | jq '.data[] | {url, alt_text, tags, prompt}'
# Search for print-related images
curl -s "http://localhost:3000/api/blog/images?tags=print-result,printer&limit=5" \
-H "x-api-key: $API_KEY" | jq '.data[] | {url, alt_text, tags, prompt}'
# Search for ecommerce/product images
curl -s "http://localhost:3000/api/blog/images?tags=ecommerce,product-photo&limit=5" \
-H "x-api-key: $API_KEY" | jq '.data[] | {url, alt_text, tags, prompt}'
# Browse all available images
curl -s "http://localhost:3000/api/blog/images?limit=20" \
-H "x-api-key: $API_KEY" | jq '.data[] | {url, alt_text, tags, image_type}'
When to reuse:
before-after for comparison posts)When to generate new:
# 1. Search for a featured image for an upscaling guide
FEATURED_SEARCH=$(curl -s "http://localhost:3000/api/blog/images?tags=before-after,upscaling&image_type=featured&limit=3" \
-H "x-api-key: $API_KEY")
FEATURED_COUNT=$(echo "$FEATURED_SEARCH" | jq '.data | length')
if [ "$FEATURED_COUNT" -gt 0 ]; then
# Reuse the first matching image
FEATURED_URL=$(echo "$FEATURED_SEARCH" | jq -r '.data[0].url')
echo "Reusing existing featured image: $FEATURED_URL"
else
echo "No suitable featured image found, will generate new one"
# Continue to Step 1 to generate
fi
# 2. Search for inline images
INLINE_SEARCH=$(curl -s "http://localhost:3000/api/blog/images?tags=ai-processing,comparison&image_type=inline&limit=5" \
-H "x-api-key: $API_KEY")
INLINE_COUNT=$(echo "$INLINE_SEARCH" | jq '.data | length')
if [ "$INLINE_COUNT" -ge 2 ]; then
# Reuse existing inline images
INLINE1_URL=$(echo "$INLINE_SEARCH" | jq -r '.data[0].url')
INLINE2_URL=$(echo "$INLINE_SEARCH" | jq -r '.data[1].url')
echo "Reusing inline images: $INLINE1_URL, $INLINE2_URL"
else
echo "Not enough inline images found, will generate new ones"
# Continue to Step 1 to generate
fi
CRITICAL: Every blog post needs 1 featured image + 2-3 inline images embedded in the markdown content.
# Load environment
source scripts/load-env.sh
API_KEY=$(grep BLOG_API_KEY .env.api | cut -d'=' -f2)
# Generate featured image (1200x630 - social sharing optimized)
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"Modern laptop showing AI image upscaling interface, before and after comparison, professional setup, blue lighting, photorealistic" \
./featured.png \
1200 630
# Generate inline image 1 (800x600 - content width)
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"Split screen comparison: pixelated blurry photo on left, crystal clear enhanced photo on right, dramatic before after" \
./inline-1.png \
800 600
# Generate inline image 2 (800x600)
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"Step-by-step visual showing image upload to AI processing to enhanced output, clean infographic style" \
./inline-2.png \
800 600
# Generate inline image 3 (800x600) - optional but recommended
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"Photo printer producing sharp print from upscaled image, professional photography studio, warm lighting" \
./inline-3.png \
800 600
See /ai-image-generation skill for prompt templates and best practices.
CRITICAL: Always include metadata when uploading images so they can be found and reused later.
# Upload featured image WITH METADATA
FEATURED=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./featured.png" \
-F "alt_text=AI image upscaling before and after comparison" \
-F "tags=before-after,upscaling,ai-processing,featured,laptop" \
-F "image_type=featured" \
-F "description=Featured image showing AI upscaling interface with before after comparison" \
-F "prompt=Modern laptop showing AI image upscaling interface, before and after comparison, professional setup, blue lighting, photorealistic")
FEATURED_URL=$(echo "$FEATURED" | jq -r '.data.url')
# Upload inline image 1 WITH METADATA
INLINE1=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./inline-1.png" \
-F "alt_text=Before and after image quality comparison" \
-F "tags=before-after,comparison,split-screen,inline,photo" \
-F "image_type=inline" \
-F "description=Split screen comparison of pixelated blurry photo versus crystal clear enhanced photo" \
-F "prompt=Split screen comparison: pixelated blurry photo on left, crystal clear enhanced photo on right, dramatic before after")
INLINE1_URL=$(echo "$INLINE1" | jq -r '.data.url')
# Upload inline image 2 WITH METADATA
INLINE2=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./inline-2.png" \
-F "alt_text=AI upscaling process workflow diagram" \
-F "tags=ai-processing,workflow,step-by-step,inline,infographic" \
-F "image_type=inline" \
-F "description=Step-by-step visual showing image upload to AI processing to enhanced output" \
-F "prompt=Step-by-step visual showing image upload to AI processing to enhanced output, clean infographic style")
INLINE2_URL=$(echo "$INLINE2" | jq -r '.data.url')
# Upload inline image 3 WITH METADATA
INLINE3=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./inline-3.png" \
-F "alt_text=High quality print from upscaled image" \
-F "tags=print-result,printer,professional,inline,photo" \
-F "image_type=inline" \
-F "description=Photo printer producing sharp print from upscaled image in professional studio" \
-F "prompt=Photo printer producing sharp print from upscaled image, professional photography studio, warm lighting")
INLINE3_URL=$(echo "$INLINE3" | jq -r '.data.url')
echo "Featured: $FEATURED_URL"
echo "Inline 1: $INLINE1_URL"
echo "Inline 2: $INLINE2_URL"
echo "Inline 3: $INLINE3_URL"
| Field | Required | Description |
|---|---|---|
file | Yes | Image file (PNG, JPG, WebP) |
alt_text | Recommended | Alt text for accessibility and SEO |
tags | Recommended | Comma-separated tags from vocabulary (3-6 tags) |
image_type | Recommended | featured or inline |
description | Optional | Brief description of image content |
prompt | Optional | Original AI prompt used to generate |
Response format:
{
"success": true,
"data": {
"url": "https://xxx.supabase.co/storage/v1/object/public/blog-images/2026/01/timestamp-filename.webp",
"key": "2026/01/timestamp-filename.webp",
"filename": "2026/01/timestamp-filename.webp",
"metadata_id": "uuid-of-metadata-record"
}
}
Every post must inject the exact target keyword into the Three Kings before publishing. This is how new posts rank from day one instead of needing a refresh later.
| King | Field | Rule |
|---|---|---|
| King 1 — Title Tag | seo_title | Keyword must appear, front-loaded. Max 60 chars. |
| King 2 — H1 | First # heading in content | Keyword in the heading. Can be slightly reworded but must contain the core phrase. |
| King 3 — First Paragraph | First <p> after the H1 | Keyword in the first sentence naturally. Not stuffed. |
Optional but high-impact: slug and seo_description also contain the keyword.
Self-check before submitting the POST request:
seo_title contains exact target keyword# Heading in content contains target keywordseo_description contains keyword + CTA (under 155 chars)Reference: seo-content-3-kings-technique skill — for existing pages that missed this, run /seo-content-3-kings-technique [domain] to identify and fix them.
Include the inline image URLs directly in the markdown content using standard markdown syntax.
# Create draft post with inline images in content
curl -s -X POST http://localhost:3000/api/blog/posts \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "how-to-upscale-images-4x",
"title": "How to Upscale Images 4x: AI Photo Enhancement Guide [2026]",
"description": "Learn how to upscale images 4x quality using AI. Free online tool for photos, graphics, and artwork. No quality loss, instant results.",
"content": "# How to Upscale Images 4x\n\nLow-res photos hurt your credibility...\n\n## The Problem with Low Resolution\n\nPixelated images look unprofessional...\n\n\n\n## How AI Upscaling Works\n\nUnlike simple resizing, AI upscaling adds real detail...\n\n\n\n## Perfect for Printing\n\nUpscaled images are ideal for large prints...\n\n\n\n## Conclusion\n\n[Start upscaling your images now](https://myimageupscaler.com) - free, no signup required.",
"author": "MyImageUpscaler Team",
"category": "Guides",
"tags": ["upscale", "AI", "tutorial"],
"seo_title": "How to Upscale Images 4x Quality Free - AI Photo Enhancer",
"seo_description": "Upscale images 4x quality instantly with AI. Free online photo enhancer for prints, social media, and more. No signup required."
}' | jq .

Placement Guidelines:
CRITICAL: Every blog post must contain 2-3 contextual internal links. Prioritize pages that are already getting GSC impressions but need more clicks — internal links from the blog push them up.
Before picking pages to link to, check which existing pages have impressions but low CTR. These are the highest-leverage internal link targets.
# Run GSC analysis to find pages worth supporting
# Use the /gsc-analysis skill or check the latest report:
cat docs/SEO/reports/gsc-*.md 2>/dev/null | grep -A3 "impression" | head -40
Target pages with:
These benefit most from internal link juice. Prefer linking to them over arbitrary pSEO pages.
Scan the pSEO data files to find pages that match the blog post topic, then cross-reference with the GSC high-impression pages above. Pages that appear in both lists are the highest-priority link targets. Available categories:
# List all available pSEO categories
ls app/seo/data/*.json
# Search for pages relevant to your topic keyword
# Replace KEYWORD with your topic (e.g., "background", "4k", "jpeg", "ecommerce")
node -e "
const fs = require('fs');
const files = ['tools','free','formats','scale','use-cases','guides','alternatives','compare'];
const keyword = 'KEYWORD';
files.forEach(f => {
try {
const data = JSON.parse(fs.readFileSync(\`app/seo/data/\${f}.json\`,'utf-8'));
const matches = data.pages.filter(p =>
p.slug.includes(keyword) ||
(p.primaryKeyword && p.primaryKeyword.toLowerCase().includes(keyword)) ||
(p.metaTitle && p.metaTitle.toLowerCase().includes(keyword))
);
if (matches.length) console.log(\`[\${f}]\`, matches.map(p => \`/\${f}/\${p.slug}\`).join(', '));
} catch(e) {}
});
"
| Category file | URL prefix | Good for posts about... |
|---|---|---|
scale.json | /scale/ | Resolution, 4K, upscaling, print size |
free.json | /free/ | Free tools, no signup, trial, credits |
formats.json | /formats/ | JPEG, PNG, WebP, AVIF, HEIC, file formats |
use-cases.json | /use-cases/ | E-commerce, real estate, portraits, anime |
tools.json | /tools/ | Specific AI tools (enhancer, upscaler, bg) |
alternatives.json | /alternatives/ | Tool comparisons, vs, alternatives |
compare.json | /compare/ | Comparisons, head-to-head |
guides.json | /guides/ | How-to guides, tutorials |
| URL | Target anchor text ideas |
|---|---|
/scale/upscale-to-4k | "4K resolution", "upscale to 4K" |
/scale/upscale-to-1080p | "1920x1080", "HD resolution", "1080p" |
/free/free-image-upscaler | "free image upscaler", "free upscaling" |
/free/free-background-remover | "free background remover" |
/free | "free tools", "free credits" |
/formats/upscale-jpeg-images | "JPEG images", "upscale JPG" |
/formats/upscale-png-images | "PNG images" |
/formats/upscale-webp-images | "WebP images" |
/formats/upscale-avif-images | "AVIF images" |
/use-cases/ecommerce-product-photos | "product photos", "e-commerce photos" |
/use-cases/old-photo-restoration | "photo restoration", "restore old photos" |
/use-cases/real-estate-photo-enhancement | "real estate photos" |
/use-cases/anime-image-upscaler | "anime upscaling", "illustration upscaling" |
/tools/ai-background-remover | "remove backgrounds", "background removal" |
/tools/ai-photo-enhancer | "photo enhancer", "enhance photo quality" |
/alternatives | "tool alternatives", "comparing tools" |
/ai-features//tools/ai-background-remover (not /tools/remove-bg)<!-- Original -->
AI upscalers can enlarge images to 4K resolution.
<!-- With link -->
AI upscalers can enlarge images to [4K resolution](/scale/upscale-to-4k).
<!-- Original -->
JPEG files can still be upscaled without losing quality.
<!-- With link -->
[JPEG files](/formats/upscale-jpeg-images) can still be upscaled without losing quality.
<!-- Original -->
For e-commerce sellers, product photo quality matters.
<!-- With link -->
For e-commerce sellers, [product photo quality](/use-cases/ecommerce-product-photos) matters.
<!-- Original -->
Start with our free tools if you're new.
<!-- With link -->
Start with our [free upscaling tools](/free) if you're new.
After identifying insertion points, PATCH the post with the updated content:
# After updating the markdown content with internal links, PATCH the post
curl -s -X PATCH http://localhost:3000/api/blog/posts/YOUR-SLUG \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "...updated content with internal pSEO links..."
}' | jq .
curl -s -X PATCH http://localhost:3000/api/blog/posts/how-to-upscale-images-4x \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"featured_image_url": "'"$FEATURED_URL"'",
"featured_image_alt": "AI image upscaling comparison showing original vs upscaled result"
}' | jq .
curl -s -X POST http://localhost:3000/api/blog/posts/how-to-upscale-images-4x/publish \
-H "x-api-key: $API_KEY" | jq .
# Check API
curl -s http://localhost:3000/api/blog/posts/how-to-upscale-images-4x \
-H "x-api-key: $API_KEY" | jq '{title, status, published_at}'
# Check frontend
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/blog/how-to-upscale-images-4x
CRITICAL: After publishing, update the tracking file to prevent future duplication.
# Variables from your published post
PUBLISHED_DATE=$(date +%Y-%m-%d)
KEYWORD="your target keyword" # e.g., "upscale image 4x"
BLOG_SLUG="your-blog-slug" # e.g., "how-to-upscale-images-4x"
ROADMAP_SEGMENT="Segment B" # From Step -1
ESTIMATED_IMPACT="+30 clicks/mo" # From roadmap
# Add to "Topics Covered" section
cat >> docs/SEO/blog-content-tracking/topics-covered.md << EOF
| $PUBLISHED_DATE | $KEYWORD | $BLOG_SLUG | $ROADMAP_SEGMENT | ✅ Published |
EOF
echo "✅ Tracking file updated!"
echo "File: docs/SEO/blog-content-tracking/topics-covered.md"
Weekly: Review and update the "Topics Planned" section from the latest keyword roadmap:
# Get latest roadmap
LATEST_ROADMAP=$(ls -t docs/SEO/keyword-strategy-roadmap-*.md | head -1)
# Extract top 10 uncovered opportunities
echo "Updating planned topics from roadmap..."
# Manual step: Copy Segment A and B opportunities from roadmap
# Add them to "Topics Planned" table if not already covered
| Field | Requirement |
|---|---|
| Title | 5-200 chars |
| Description | 20-500 chars |
| Slug | 3-100 chars, lowercase with hyphens only |
| Content | Min 100 chars |
| Featured Image | Recommended for better engagement |
| Field | Optimal |
|---|---|
| Title | 50-70 chars, has brackets [2026] |
| Description | 150-160 chars, ends with CTA |
| Slug | 3-5 words, contains main keyword |
| Content | 1000+ words, 4+ H2s |
| Featured img | 1 AI-generated (1200x630) |
| Inline images | 2-3 AI-generated (800x600) in markdown |
🚨 HARD REQUIREMENT — DO NOT PUBLISH WITHOUT CTAs
Every blog post MUST have at least 2 BlogCTA component markers embedded in the content. A post without CTAs gets impressions but zero clicks. This is the #1 reason posts fail to convert.
The blog renderer converts blockquote markers into fully-styled CTA components automatically. Use these markers in your markdown content:
| Marker | Renders As | When to Use |
|---|---|---|
> [!CTA_TRY] | Inline banner with "Try Free" button | After explaining a benefit or completing a section |
> [!CTA_DEMO] | Feature highlights card with demo CTA | Before FAQ or Conclusion — high-intent position |
> [!CTA_PRICING] | Pricing-focused CTA | When discussing plans or paid features |
> [!CTA_TOOL:slug] | Tool-specific CTA (links to /tools/slug) | Posts about a specific tool (e.g. background remover) |
How to write them in markdown:
## After this section I want a CTA
Some content explaining value...
> [!CTA_TRY]
## Next section continues here
<!-- Tool-specific: links to /tools/transparent-background-maker -->
> [!CTA_TOOL:transparent-background-maker]
<!-- Tool-specific: links to /tools/ai-image-upscaler -->
> [!CTA_TOOL:ai-image-upscaler]
Every post MUST have ALL THREE of the following:
> [!CTA_TRY] after the first major value section (before the halfway point)> [!CTA_DEMO] immediately before ## Conclusion or ## FAQ# H1 Title
Introduction paragraph...
## Section 1 — Explain the problem
Content...
## Section 2 — Show the value
Content...
> [!CTA_TRY]
## Section 3 — How it works / Step-by-step
Content...

## Section 4 — Use cases / Tips
Content...
> [!CTA_DEMO]
## Conclusion
Summary sentence.
[Start upscaling your images for free](https://myimageupscaler.com) — no signup required.
---
## Frequently Asked Questions
If the post is about a specific tool (background remover, face restore, etc.), use CTA_TOOL instead of CTA_TRY for the mid-article CTA:
> [!CTA_TOOL:transparent-background-maker]
> [!CTA_TOOL:ai-image-upscaler]
> [!CTA_TOOL:ai-face-restorer]
In addition to the component CTAs, embed 1-2 natural inline links in the body:
[Try our AI upscaler](https://myimageupscaler.com) and see the difference instantly.
[Upload your photo free](https://myimageupscaler.com) — 4x enhancement in seconds.
[Start upscaling now](https://myimageupscaler.com) — no credit card required.
The free plan has limits. Always be accurate:
Before calling the publish endpoint, verify:
# Check that CTA markers exist in the content
echo "$POST_CONTENT" | grep -c "\[!CTA_" && echo "✅ CTA markers found" || echo "❌ BLOCKED: No CTA markers — do not publish"
# Should return at least 2
CTA_COUNT=$(echo "$POST_CONTENT" | grep -c "\[!CTA_")
[ "$CTA_COUNT" -ge 2 ] || { echo "❌ Need at least 2 CTAs, found $CTA_COUNT"; exit 1; }
Available Categories:
Guides - How-to tutorials and step-by-step instructionsTips - Quick tips and tricksComparisons - Tool comparisons, before/afterNews - Industry news and updatesTechnical - Deep technical explanationsAvailable Tags:
upscale, AI, tutorial, photo, image, enhancement, resolution, prints, social-media, graphics, artwork, logo, product-photos, ecommerce, restoration, batch, free, onlineUse this pattern: [Keyword]: [Benefit] [Year]
Examples:
# H1 Title (matches page title)
Engaging introduction paragraph (3-4 sentences). Mention the problem and promise solution.
## Understanding the Concept
Explain the core topic. Use examples.

## Why It Matters
Benefits and use cases. Real-world applications.
## Step-by-Step Guide
Numbered steps with clear instructions.

## Tips for Best Results
Actionable tips and recommendations.
## Common Mistakes to Avoid
What not to do, with explanations.

## Conclusion
Summary + [Primary CTA link](https://myimageupscaler.com).
Image Placement Rules:
| Category | Words to Avoid |
|---|---|
| Overused | delve, tapestry, nuanced, multifaceted, landscape |
| Corporate | leverage, facilitate, streamline, optimize, utilize |
| Filler | "It's important to note", "worth noting" |
| Hype | groundbreaking, revolutionary, game-changing |
| Throat-clearing | "In today's world", "Here's the thing" |
❌ AI: "Image upscaling represents a significant advancement in AI technology."
✅ Human: "I've tried dozens of upscalers. Most make your photos look like plastic."
❌ AI: "This solution offers numerous benefits for users."
✅ Human: "Here's what makes this different: it actually preserves details."
❌ AI: "The process facilitates enhanced image quality."
✅ Human: "Your photos get sharper. Period."
Writing Rules:
| Image Type | Dimensions | Purpose |
|---|---|---|
| Featured | 1200x630 | Social sharing, post header |
| Inline | 800x600 | Content illustrations (2-3 each) |
All images must be:
/ai-image-generation skillFor "How to upscale images" posts:
Featured: "Modern laptop screen showing AI photo upscaling interface, before and after comparison, professional setup, blue lighting, photorealistic"
Inline 1: "Split screen: pixelated blurry photo on left, crystal clear enhanced photo on right, dramatic comparison"
Inline 2: "Step-by-step visual: image upload to AI processing to enhanced output, clean infographic style"
Inline 3: "Person examining sharp enlarged photo on screen, professional workspace, satisfied expression"
For "Image resolution" posts:
Featured: "Computer monitor showing pixelated vs sharp image comparison, professional photo editing workspace"
Inline 1: "Magnified pixel grid next to smooth high-res detail, educational comparison"
Inline 2: "Digital image being transformed from blocky to smooth, visualization of upscaling process"
For "Print preparation" posts:
Featured: "Photo printer producing high-quality print, professional photography studio"
Inline 1: "Side by side: small low-res image next to large crisp printed poster"
Inline 2: "Hands holding sharp printed photo, professional quality result"
The BLOG_API_KEY is stored in .env.api:
# Development
BLOG_API_KEY=test-blog-api-key-xxx
# Load with:
source scripts/load-env.sh
API_KEY=$(grep BLOG_API_KEY .env.api | cut -d'=' -f2)
Either delete the existing post or use a different slug:
# Delete existing
curl -s -X DELETE http://localhost:3000/api/blog/posts/[slug] \
-H "x-api-key: $API_KEY"
featured_image_url is set correctlyOnly published posts appear. Drafts are only accessible via direct slug URL.
# 0. Load environment
source scripts/load-env.sh
API_KEY=$(grep BLOG_API_KEY .env.api | cut -d'=' -f2)
# =========================================
# STEP 0: SEARCH FOR EXISTING IMAGES FIRST
# =========================================
# Search for featured image (before-after theme)
FEATURED_SEARCH=$(curl -s "http://localhost:3000/api/blog/images?tags=before-after,upscaling&image_type=featured&limit=3" \
-H "x-api-key: $API_KEY")
FEATURED_COUNT=$(echo "$FEATURED_SEARCH" | jq '.data | length')
# Search for inline images (ai-processing theme)
INLINE_SEARCH=$(curl -s "http://localhost:3000/api/blog/images?tags=ai-processing,comparison&image_type=inline&limit=5" \
-H "x-api-key: $API_KEY")
INLINE_COUNT=$(echo "$INLINE_SEARCH" | jq '.data | length')
# Decision: Reuse or generate
if [ "$FEATURED_COUNT" -gt 0 ] && [ "$INLINE_COUNT" -ge 2 ]; then
echo "Found suitable existing images - reusing them"
FEATURED_URL=$(echo "$FEATURED_SEARCH" | jq -r '.data[0].url')
INLINE1_URL=$(echo "$INLINE_SEARCH" | jq -r '.data[0].url')
INLINE2_URL=$(echo "$INLINE_SEARCH" | jq -r '.data[1].url')
else
echo "No suitable images found - generating new ones"
# =========================================
# STEP 1: GENERATE IMAGES (only if needed)
# =========================================
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"Modern laptop showing AI photo upscaling, before after comparison, blue lighting" \
./featured.png 1200 630
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"Split screen: pixelated photo left, crystal clear photo right, dramatic comparison" \
./inline-1.png 800 600
yarn tsx .claude/skills/ai-image-generation/scripts/generate-ai-image.ts \
"AI neural network processing image, visualization of enhancement process" \
./inline-2.png 800 600
# =========================================
# STEP 2: UPLOAD WITH METADATA
# =========================================
FEATURED_URL=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./featured.png" \
-F "alt_text=AI upscaling comparison" \
-F "tags=before-after,upscaling,ai-processing,featured,laptop" \
-F "image_type=featured" \
-F "prompt=Modern laptop showing AI photo upscaling, before after comparison, blue lighting" | jq -r '.data.url')
INLINE1_URL=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./inline-1.png" \
-F "alt_text=Before after comparison" \
-F "tags=before-after,comparison,split-screen,inline,photo" \
-F "image_type=inline" \
-F "prompt=Split screen: pixelated photo left, crystal clear photo right, dramatic comparison" | jq -r '.data.url')
INLINE2_URL=$(curl -s -X POST http://localhost:3000/api/blog/images/upload \
-H "x-api-key: $API_KEY" \
-F "file=@./inline-2.png" \
-F "alt_text=AI processing visualization" \
-F "tags=ai-processing,workflow,step-by-step,inline,infographic" \
-F "image_type=inline" \
-F "prompt=AI neural network processing image, visualization of enhancement process" | jq -r '.data.url')
fi
echo "Using images:"
echo " Featured: $FEATURED_URL"
echo " Inline 1: $INLINE1_URL"
echo " Inline 2: $INLINE2_URL"
# =========================================
# STEP 3: CREATE DRAFT WITH INLINE IMAGES
# =========================================
curl -s -X POST http://localhost:3000/api/blog/posts \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "ai-image-upscaling-guide",
"title": "AI Image Upscaling: Complete Guide to Better Photos [2026]",
"description": "Learn how AI image upscaling works and can transform your low-res photos into print-quality images. Free online tool.",
"content": "# AI Image Upscaling: The Complete Guide\n\nLow-resolution photos look unprofessional. AI upscaling changes that.\n\n## What Is AI Image Upscaling?\n\nTraditional upscaling just copies pixels. AI upscaling adds real detail.\n\n\n\n## How It Works\n\nNeural networks analyze patterns and generate new pixels.\n\n\n\n## Conclusion\n\n[Start upscaling your images now](https://myimageupscaler.com) - free, instant results.",
"author": "MyImageUpscaler Team",
"category": "Guides",
"tags": ["upscale", "AI", "tutorial", "photo"],
"seo_title": "AI Image Upscaling Guide - Free Photo Enhancer Tool",
"seo_description": "Transform low-res photos into print-quality images with AI upscaling. Free online tool - instant results, no signup required."
}' | jq .
# =========================================
# STEP 4: ADD FEATURED IMAGE
# =========================================
curl -s -X PATCH http://localhost:3000/api/blog/posts/ai-image-upscaling-guide \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"featured_image_url": "'"$FEATURED_URL"'",
"featured_image_alt": "AI image upscaling before and after comparison"
}' | jq .
# =========================================
# STEP 5: PUBLISH
# =========================================
curl -s -X POST http://localhost:3000/api/blog/posts/ai-image-upscaling-guide/publish \
-H "x-api-key: $API_KEY" | jq .
# =========================================
# STEP 6: VERIFY
# =========================================
curl -s http://localhost:3000/blog/ai-image-upscaling-guide | grep -o "<title>.*</title>"
blog_posts tableupdated_at is auto-updated on any changeblog-images (Supabase Storage)YYYY/MM/timestamp-filename.webp/ai-image-generation - Generate featured and inline images with AI/blog-edit - Edit existing blog posts/internal-linking-optimizer - Analyze and optimize internal link structure site-wideTo browse all available pSEO pages for linking, check the data files:
app/seo/data/tools.json → /tools/* pagesapp/seo/data/free.json → /free/* pagesapp/seo/data/formats.json → /formats/* pagesapp/seo/data/scale.json → /scale/* pagesapp/seo/data/use-cases.json → /use-cases/* pagesapp/seo/data/alternatives.json → /alternatives/* pagesapp/seo/data/compare.json → /compare/* pagesapp/seo/data/guides.json → /guides/* pages