Code Examples
Copy-paste examples for integrating the WUDO Blogs and Products API into your application. All examples use the public API with API key authentication.
cURL
List published blogsbash
curl -H "X-Api-Key: wudo_pk_your_key_here" \
"https://wudoseo.com/api/v1/blogs?page=1&pageSize=10"Get a single blogbash
curl -H "X-Api-Key: wudo_pk_your_key_here" \
"https://wudoseo.com/api/v1/blogs/10-web-design-trends-2026"Trigger visual checkbash
curl -X POST \
-H "X-Api-Key: wudo_pk_your_key_here" \
-H "Content-Type: application/json" \
-d '{"url": "https://yoursite.com/blog/my-post"}' \
"https://wudoseo.com/api/v1/blogs/BLOG_ID/visual-check"Create/update a productbash
curl -X POST \
-H "X-Api-Key: wudo_pk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"projectId": "YOUR_PROJECT_ID",
"externalId": "prod-123",
"sku": "SHIRT-001",
"title": "Blue Cotton T-Shirt",
"description": "Comfortable everyday tee",
"price": 29.99,
"category": "Apparel > Shirts"
}' \
"https://wudoseo.com/api/v1/products"List productsbash
curl -H "X-Api-Key: wudo_pk_your_key_here" \
"https://wudoseo.com/api/v1/products?projectId=YOUR_PROJECT_ID&page=1&pageSize=20"JavaScript / TypeScript
API client classTypeScript
const API_KEY = process.env.WUDO_API_KEY;
const BASE_URL = 'https://wudoseo.com';
async function wudoFetch(path: string, options?: RequestInit) {
const res = await fetch(`${BASE_URL}${path}`, {
...options,
headers: {
'X-Api-Key': API_KEY!,
'Content-Type': 'application/json',
...options?.headers,
},
});
if (!res.ok) throw new Error(`WUDO API ${res.status}: ${res.statusText}`);
return res.json();
}
// List blogs
const { blogs, total } = await wudoFetch('/api/v1/blogs?page=1&pageSize=10');
// Get blog by slug
const blog = await wudoFetch('/api/v1/blogs/my-blog-slug');
// Get related posts
const { blogs: related } = await wudoFetch('/api/v1/blogs/my-blog-slug/related?limit=3');
// Get categories
const { categories } = await wudoFetch('/api/v1/blogs/categories');Next.js blog page (App Router)TypeScript
// app/blog/[slug]/page.tsx
import { Metadata } from 'next';
const API_KEY = process.env.WUDO_API_KEY!;
const API_URL = 'https://wudoseo.com';
async function getBlog(slug: string) {
const res = await fetch(`${API_URL}/api/v1/blogs/${slug}`, {
headers: { 'X-Api-Key': API_KEY },
next: { revalidate: 300 }, // ISR: revalidate every 5 min
});
if (!res.ok) return null;
return res.json();
}
export async function generateMetadata({ params }): Promise<Metadata> {
const blog = await getBlog(params.slug);
if (!blog) return { title: 'Not Found' };
return {
title: blog.title,
description: blog.metaDescription,
openGraph: {
title: blog.title,
images: [blog.ogImageUrl],
type: 'article',
publishedTime: blog.publishedAt,
},
};
}
export default async function BlogPage({ params }) {
const blog = await getBlog(params.slug);
if (!blog) return notFound();
return (
<>
<style dangerouslySetInnerHTML={{ __html: blog.cssContent }} />
<article dangerouslySetInnerHTML={{ __html: blog.htmlContent }} />
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: blog.schemaOrgJson }}
/>
</>
);
}Product Webhook Receiver (Next.js)
app/api/webhooks/products/route.tsTypeScript
// Webhook receiver for products.optimized events
import { NextRequest, NextResponse } from 'next/server';
import crypto from 'crypto';
const WEBHOOK_SECRET = process.env.WUDO_WEBHOOK_SECRET!;
function verifySignature(body: string, signature: string): boolean {
const expected = 'sha256=' + crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
export async function POST(req: NextRequest) {
const body = await req.text();
const signature = req.headers.get('x-wudo-signature') ?? '';
const event = req.headers.get('x-wudo-event') ?? '';
if (!verifySignature(body, signature)) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
}
const payload = JSON.parse(body);
if (event === 'products.optimized') {
for (const product of payload.data.products) {
// Update your database with the optimized SEO data
await updateProductSeo(product.external_id, {
metaTitle: product.meta_title,
metaDescription: product.meta_description,
pageTitle: product.page_title,
});
}
}
return NextResponse.json({ received: true });
}Python
requests libraryPython
import requests
import os
API_KEY = os.environ['WUDO_API_KEY']
BASE_URL = 'https://wudoseo.com'
HEADERS = {'X-Api-Key': API_KEY}
# List blogs
response = requests.get(f'{BASE_URL}/api/v1/blogs', headers=HEADERS)
data = response.json()
for blog in data['blogs']:
print(f"{blog['title']} - /blog/{blog['slug']}")
# Get single blog
response = requests.get(
f'{BASE_URL}/api/v1/blogs/my-blog-slug',
headers=HEADERS
)
blog = response.json()
print(blog['title'])
print(f"Word count: {blog['wordCount']}")
# Trigger visual check
response = requests.post(
f'{BASE_URL}/api/v1/blogs/{blog_id}/visual-check',
headers=HEADERS,
json={'url': 'https://yoursite.com/blog/my-post'}
)
result = response.json()
print(f"Score: {result['overallScore']}/100")Import products via APIPython
import requests
import os
API_KEY = os.environ['WUDO_API_KEY']
PROJECT_ID = os.environ['WUDO_PROJECT_ID']
BASE_URL = 'https://wudoseo.com'
HEADERS = {'X-Api-Key': API_KEY, 'Content-Type': 'application/json'}
# Batch import products
products = [
{
'externalId': 'prod-001',
'sku': 'SHIRT-001',
'title': 'Blue Cotton T-Shirt',
'price': 29.99,
'category': 'Apparel > Shirts'
},
{
'externalId': 'prod-002',
'sku': 'SHIRT-002',
'title': 'Red Cotton T-Shirt',
'price': 29.99,
'category': 'Apparel > Shirts'
}
]
response = requests.post(
f'{BASE_URL}/api/v1/products/batch',
headers=HEADERS,
json={'projectId': PROJECT_ID, 'products': products}
)
result = response.json()
print(f"Created: {result['created']}, Updated: {result['updated']}")Django viewPython
# views.py
import requests
from django.shortcuts import render
from django.conf import settings
def blog_list(request):
response = requests.get(
f'{settings.WUDO_API_URL}/api/v1/blogs',
headers={'X-Api-Key': settings.WUDO_API_KEY},
params={'page': request.GET.get('page', 1)}
)
data = response.json()
return render(request, 'blog/list.html', {
'blogs': data['blogs'],
'total': data['total'],
})
def blog_detail(request, slug):
response = requests.get(
f'{settings.WUDO_API_URL}/api/v1/blogs/{slug}',
headers={'X-Api-Key': settings.WUDO_API_KEY}
)
if response.status_code == 404:
raise Http404
blog = response.json()
return render(request, 'blog/detail.html', {'blog': blog})PHP
WordPress integrationPHP
<?php
// functions.php
define('WUDO_API_KEY', getenv('WUDO_API_KEY'));
define('WUDO_API_URL', 'https://wudoseo.com');
function wudo_fetch($path) {
$response = wp_remote_get(WUDO_API_URL . $path, [
'headers' => ['X-Api-Key' => WUDO_API_KEY],
'timeout' => 15,
]);
if (is_wp_error($response)) {
return null;
}
return json_decode(wp_remote_retrieve_body($response), true);
}
// In your template:
$blogs = wudo_fetch('/api/v1/blogs?pageSize=6');
if ($blogs && !empty($blogs['blogs'])) {
foreach ($blogs['blogs'] as $blog) {
echo '<article>';
echo '<h2><a href="/blog/' . esc_attr($blog['slug']) . '">';
echo esc_html($blog['title']);
echo '</a></h2>';
echo '<p>' . esc_html($blog['metaDescription']) . '</p>';
echo '</article>';
}
}
// Single blog:
$blog = wudo_fetch('/api/v1/blogs/' . $slug);
if ($blog) {
echo '<style>' . $blog['cssContent'] . '</style>';
echo $blog['htmlContent'];
}Environment Variables
Always store your API key in environment variables, never in source code.
.env
WUDO_API_KEY=wudo_pk_your_key_here WUDO_API_URL=https://wudoseo.com