npm install wapuulink
import { WapuuLink } from 'wapuulink';
const wapuu = new WapuuLink({
apiKey: 'your-api-key',
baseUrl: 'http://localhost:3000'
});
// Generate a page
const page = await wapuu.pages.generate({
prompt: 'Build a homepage for a pizza shop',
siteContext: {
siteName: "Bert's Pizza",
themeSettings: { primaryColor: '#C8102E' }
}
});
console.log(page.html);All API endpoints (except register, login, and webhooks) require authentication. Two methods are supported:
// API Key (recommended for server-to-server)
headers: { 'x-api-key': 'your-api-key' }
// JWT Token (for browser/dashboard)
headers: { 'Authorization': 'Bearer your-jwt-token' }/auth/registerCreate a new account and get your API key{
"email": "dev@example.com", // required
"password": "securepass123", // required
"name": "Jane Developer" // optional
}{
"user": {
"id": "clx...",
"email": "dev@example.com",
"name": "Jane Developer",
"plan": "credits",
"creditBalance": 0
},
"token": "eyJhbG...", // JWT token, expires in 30 days
"apiKey": "wl_abc123..." // save this — used for all API calls
}// No SDK needed — register via the dashboard or curl
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","password":"securepass123"}'/auth/loginLog in and receive a JWT token{
"email": "dev@example.com", // required
"password": "securepass123" // required
}{
"user": {
"id": "clx...",
"email": "dev@example.com",
"name": "Jane Developer",
"plan": "credits",
"creditBalance": 40
},
"token": "eyJhbG..."
}curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","password":"securepass123"}'/auth/meGet current user info{
"user": {
"id": "clx...",
"email": "dev@example.com",
"name": "Jane Developer",
"plan": "credits",
"creditBalance": 40,
"apiKey": "wl_abc123...",
"isFounding": false,
"createdAt": "2025-01-15T..."
}
}curl http://localhost:3000/auth/me \ -H "x-api-key: your-api-key"
/credits/balanceCheck your current credit balance{
"balance": 40,
"plan": "credits"
}// Using the SDK
const me = await fetch('http://localhost:3000/credits/balance', {
headers: { 'x-api-key': 'your-api-key' }
}).then(r => r.json());
console.log(me.balance); // 40/credits/purchaseBuy credits — returns a Stripe checkout URL{
"bundle": "pro" // "starter" | "builder" | "pro" | "agency"
}{
"checkoutUrl": "https://checkout.stripe.com/c/pay/..."
}curl -X POST http://localhost:3000/credits/purchase \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"bundle":"pro"}'/credits/historyGet your 50 most recent transactions[
{
"id": "clx...",
"amount": 50,
"credits": 230,
"type": "purchase",
"createdAt": "2025-01-20T..."
}
]curl http://localhost:3000/credits/history \ -H "x-api-key: your-api-key"
/v1/generateGenerate a page with AI{
"prompt": "Build a landing page for a dog walking service", // required
"siteContext": { // optional — improves output quality
"siteName": "Paws & Go",
"themeSettings": {
"primaryColor": "#2563EB",
"fontFamily": "Inter"
}
},
"model": "standard", // optional — "standard" or "premium"
"siteUrl": "https://example.com" // optional — used for QA scoring
}{
"html": "<!DOCTYPE html>\n<html>...",
"model_used": "standard",
"qa": { // null if QA is unavailable
"passed": true,
"score": 8,
"brandCompliance": { ... },
"issues": []
},
"credits_used": 1
}// Using the npm SDK
const page = await wapuu.pages.generate({
prompt: 'Build a landing page for a dog walking service',
siteContext: {
siteName: 'Paws & Go',
themeSettings: { primaryColor: '#2563EB' }
},
model: 'standard'
});
console.log(page.html);/v1/editEdit an existing page{
"currentHtml": "<html>...", // required — the HTML to modify
"instructions": "Add a testimonials section below the hero", // required
"siteContext": { ... }, // optional
"model": "standard", // optional
"siteUrl": "https://example.com" // optional
}{
"html": "<!DOCTYPE html>\n<html>...",
"model_used": "standard",
"qa": { ... },
"credits_used": 1
}const edited = await wapuu.pages.edit({
currentHtml: existingHtml,
instructions: 'Add a testimonials section below the hero',
model: 'standard'
});
console.log(edited.html);/v1/plugin/buildBuild a WordPress plugin from a prompt{
"prompt": "Build a plugin that adds a custom admin dashboard widget showing recent posts with thumbnails", // required
"siteContext": { // optional
"siteName": "My Blog"
}
}{
"pluginName": "recent-posts-widget",
"files": { ... },
"credits_used": 2
}const plugin = await wapuu.plugins.build({
prompt: 'Build a plugin that adds a custom admin dashboard widget showing recent posts',
siteContext: { siteName: 'My Blog' }
});/v1/plugin/editEdit an existing plugin{
"pluginFiles": { // required — object of filename: content
"my-plugin.php": "<?php ..."
},
"editPrompt": "Add settings page to control widget visibility", // required
"siteContext": { ... } // optional
}{
"files": { ... },
"credits_used": 1
}const edited = await wapuu.plugins.edit({
pluginFiles: { 'my-plugin.php': existingCode },
editPrompt: 'Add settings page to control widget visibility'
});/v1/plugin/validateValidate a plugin (free){
"downloadUrl": "https://example.com/my-plugin.zip", // required
"pluginName": "My Plugin", // required
"pluginSlug": "my-plugin" // required
}{
"passed": true,
"pluginName": "My Plugin",
"pluginSlug": "my-plugin",
"errors": [],
"warnings": [],
"credits_used": 0
}const result = await wapuu.plugins.validate({
downloadUrl: 'https://example.com/my-plugin.zip',
pluginName: 'My Plugin',
pluginSlug: 'my-plugin'
});
console.log(result.passed); // true/v1/qa/screenshotScreenshot and score a page for quality{
"html": "<html>...</html>", // required — full HTML to screenshot
"prompt": "Homepage for a bakery", // required — what the page should look like
"mode": "desktop", // optional
"siteUrl": "https://example.com", // optional
"themeSettings": { // optional — used for brand compliance
"primaryColor": "#C8102E"
}
}{
"passed": true, // true if score >= 7
"score": 8, // 1-10 quality score
"brandCompliance": { ... },
"issues": [],
"credits_used": 0.5
}const qa = await wapuu.qa.screenshot({
html: generatedHtml,
prompt: 'Homepage for a bakery',
themeSettings: { primaryColor: '#C8102E' }
});
console.log(qa.score); // 8
console.log(qa.passed); // true/v1/qa/diffCompare before/after screenshots{
"beforeHtml": "<html>...</html>", // required
"afterHtml": "<html>...</html>", // required
"prompt": "Added a testimonials section" // required — what changed
}{
"changed": true,
"improvements": [ ... ],
"regressions": [ ... ],
"credits_used": 0.5
}const diff = await wapuu.qa.diff({
beforeHtml: originalHtml,
afterHtml: editedHtml,
prompt: 'Added a testimonials section'
});
console.log(diff.improvements);All WP endpoints require a wpPath — the absolute path to your WordPress installation on the server running WP-CLI.
/v1/wp/healthRun a full WordPress health check{
"wpPath": "/var/www/html" // required — path to WP install
}{
"healthy": true,
"issues": [],
"coreUpdate": "WordPress is at the latest version.",
"plugins": [
{ "name": "akismet", "status": "active", "version": "5.3" }
],
"database": "wp_posts: OK\nwp_options: OK",
"credits_used": 0.3
}const health = await wapuu.wp.health({
wpPath: '/var/www/html'
});
console.log(health.healthy); // true
console.log(health.issues); // []/v1/wp/pluginsList installed plugins{
"wpPath": "/var/www/html" // required
}{
"plugins": [
{ "name": "akismet", "status": "active", "version": "5.3", "update": "none" },
{ "name": "hello-dolly", "status": "inactive", "version": "1.7.2", "update": "available" }
],
"credits_used": 0.1
}const result = await wapuu.wp.plugins({
wpPath: '/var/www/html'
});
result.plugins.forEach(p =>
console.log(`${p.name} v${p.version} (${p.status})`)
);/v1/wp/update-checkCheck if plugin updates are safe to apply{
"wpPath": "/var/www/html", // required
"plugins": ["akismet", "woocommerce"] // optional — omit to check all
}{
"safe": true,
"risks": [],
"recommendation": "Review changelogs before updating",
"plugins": [
{ "name": "akismet", "version": "5.3", "updateAvailable": false, "status": "active" }
],
"credits_used": 1
}const check = await wapuu.wp.updateCheck({
wpPath: '/var/www/html',
plugins: ['akismet', 'woocommerce']
});
console.log(check.safe); // true
console.log(check.recommendation); // "Review changelogs before updating"/v1/wp/cache-clearFlush WordPress object cache{
"wpPath": "/var/www/html" // required
}{
"cleared": true,
"caches": ["object-cache"],
"output": "Success: The cache was flushed.",
"credits_used": 0.1
}const result = await wapuu.wp.cacheClear({
wpPath: '/var/www/html'
});
console.log(result.cleared); // true/v1/wp/search-replaceSearch and replace in the WordPress database{
"wpPath": "/var/www/html", // required
"search": "http://old-domain.com", // required
"replace": "https://new-domain.com", // required
"dryRun": true // optional — defaults to true for safety
}{
"replacements": "Success: 42 replacements to be made.",
"dryRun": true,
"exitCode": 0,
"credits_used": 0.2
}const result = await wapuu.wp.searchReplace({
wpPath: '/var/www/html',
search: 'http://old-domain.com',
replace: 'https://new-domain.com',
dryRun: true // always dry-run first!
});
console.log(result.replacements);Orchestrated pipelines that chain multiple operations together. Credits are charged only for steps that execute.
/v1/workflow/deployGenerate → QA → deploy to WP → screenshot → diff{
"prompt": "Build a landing page for a coffee shop", // required
"siteUrl": "https://mysite.com", // required
"wpPath": "/var/www/html", // required
"siteContext": { // optional
"siteName": "Bean Counter Coffee",
"themeSettings": { "primaryColor": "#6F4E37" }
},
"model": "standard", // optional — "standard" or "premium"
"pageSlug": "coffee", // optional — custom URL slug
"skipQA": false // optional — skip QA gate (score >= 7)
}{
"status": "success", // "success" or "partial"
"steps": {
"generate": { "html": "<!DOCTYPE html>..." },
"qa": { "passed": true, "score": 8, ... },
"wpCreate": { "postId": "42", "title": "Build a landing...", "slug": "coffee" },
"liveScreenshot": { "passed": true, "score": 8, ... },
"diff": { "changed": false, ... }
},
"warnings": [],
"credits_used": 2.7
}const result = await wapuu.workflows.deploy({
prompt: 'Build a landing page for a coffee shop',
siteUrl: 'https://mysite.com',
wpPath: '/var/www/html',
siteContext: { siteName: 'Bean Counter Coffee' },
pageSlug: 'coffee'
});
console.log(result.steps.wpCreate.postId); // "42"/v1/workflow/auditFull site health report — 4 checks in parallel{
"wpPath": "/var/www/html", // required
"siteUrl": "https://mysite.com", // required
"plugins": ["akismet", "woocommerce"] // optional — filter update check
}{
"status": "success",
"overallScore": "good", // "good" | "warning" | "critical"
"steps": {
"health": { "healthy": true, "issues": [], ... },
"plugins": { "plugins": [ ... ] },
"updateCheck": { "safe": true, "plugins": [ ... ] },
"screenshot": { "passed": true, "score": 9, ... }
},
"warnings": [],
"credits_used": 1.9
}const audit = await wapuu.workflows.audit({
wpPath: '/var/www/html',
siteUrl: 'https://mysite.com'
});
console.log(audit.overallScore); // "good"
console.log(audit.steps.health.healthy); // true/v1/workflow/plugin/build-and-validateBuild plugin with AI → validate with Playwright{
"prompt": "Build a plugin that adds reading time to posts", // required
"siteContext": { "siteName": "My Blog" } // optional
}{
"status": "success",
"pluginName": "reading-time",
"pluginSlug": "reading-time",
"files": { "reading-time.php": "<?php ...", "readme.txt": "..." },
"validation": {
"passed": true,
"errors": [],
"warnings": []
},
"steps": { "build": { ... }, "validation": { ... } },
"warnings": [],
"credits_used": 2
}const result = await wapuu.workflows.pluginBuildAndValidate({
prompt: 'Build a plugin that adds reading time to posts'
});
console.log(result.validation.passed); // true
console.log(Object.keys(result.files)); // ["reading-time.php", "readme.txt"]/v1/workflow/migrateScreenshot → search-replace → cache clear → screenshot → diff{
"wpPath": "/var/www/html", // required
"siteUrl": "https://old-domain.com", // required
"search": "old-domain.com", // required
"replace": "new-domain.com", // required
"dryRun": true, // optional — defaults to true
"skipScreenshots": false // optional
}{
"status": "success",
"dryRun": true,
"steps": {
"screenshotBefore": { "passed": true, "score": 8, ... },
"searchReplace": { "replacements": "42 replacements to be made.", "dryRun": true },
"cacheClear": { "cleared": true, ... },
"screenshotAfter": { "passed": true, "score": 8, ... }
},
"warnings": [],
"credits_used": 0.7
}// Dry run first
const preview = await wapuu.workflows.migrate({
wpPath: '/var/www/html',
siteUrl: 'https://old-domain.com',
search: 'old-domain.com',
replace: 'new-domain.com',
dryRun: true
});
console.log(preview.steps.searchReplace.replacements);
// Then run for real
const result = await wapuu.workflows.migrate({
wpPath: '/var/www/html',
siteUrl: 'https://old-domain.com',
search: 'old-domain.com',
replace: 'new-domain.com',
dryRun: false
});You can chain individual endpoints yourself for custom workflows. Here are common patterns:
let page, qa;
let attempts = 0;
do {
page = await wapuu.pages.generate({
prompt: 'Build a pricing page for a SaaS product',
siteContext: { siteName: 'Acme SaaS' }
});
qa = await wapuu.qa.screenshot({
html: page.html,
prompt: 'Pricing page for a SaaS product'
});
attempts++;
} while (!qa.passed && attempts < 3);
console.log(`Passed after ${attempts} attempt(s), score: ${qa.score}`);// Build initial plugin
const plugin = await wapuu.plugins.build({
prompt: 'Build a custom post type for testimonials'
});
// Refine it
const edited = await wapuu.plugins.edit({
pluginFiles: plugin.files,
editPrompt: 'Add star ratings (1-5) as a custom field'
});
// Validate final version
const validation = await wapuu.plugins.validate({
downloadUrl: null,
pluginName: plugin.pluginName,
pluginSlug: plugin.pluginSlug
});
console.log(validation.passed); // trueconst health = await wapuu.wp.health({ wpPath: '/var/www/html' });
const updates = await wapuu.wp.updateCheck({ wpPath: '/var/www/html' });
const outdated = updates.plugins.filter(p => p.updateAvailable);
if (outdated.length > 0) {
console.log('Plugins need updating:', outdated.map(p => p.name));
}
if (!health.healthy) {
console.log('Issues found:', health.issues);
}
// Screenshot for visual reference
const qa = await wapuu.qa.screenshot({
html: null,
siteUrl: 'https://mysite.com',
prompt: 'Current site state'
});// 1. Dry run first
const preview = await wapuu.wp.searchReplace({
wpPath: '/var/www/html',
search: 'http://staging.example.com',
replace: 'https://example.com',
dryRun: true
});
console.log(preview.replacements); // "42 replacements to be made."
// 2. Screenshot before
const before = await wapuu.qa.screenshot({
html: null,
siteUrl: 'http://staging.example.com',
prompt: 'Pre-migration state'
});
// 3. Execute migration
const result = await wapuu.wp.searchReplace({
wpPath: '/var/www/html',
search: 'http://staging.example.com',
replace: 'https://example.com',
dryRun: false
});
// 4. Clear cache
await wapuu.wp.cacheClear({ wpPath: '/var/www/html' });
// 5. Screenshot after & compare
const after = await wapuu.qa.screenshot({
html: null,
siteUrl: 'https://example.com',
prompt: 'Post-migration state'
});
console.log('Before score:', before.score, 'After score:', after.score);| Operation | Credits | Cost |
|---|---|---|
| Page (Standard) | 1 | $0.25 |
| Page (Premium) | 2 | $0.50 |
| Plugin Build | 2 | $0.50 |
| Plugin Edit | 1 | $0.25 |
| Plugin Validate | 0 | Free |
| QA Screenshot | 0.5 | $0.125 |
| QA Diff | 0.5 | $0.125 |
| WP Command | 0.1 | $0.025 |
| Update Check | 1 | $0.25 |
| Workflow: Deploy | 2.7 | $0.675 |
| Workflow: Deploy (Premium) | 3.7 | $0.925 |
| Workflow: Audit | 1.9 | $0.475 |
| Workflow: Plugin Build + Validate | 2 | $0.50 |
| Workflow: Migrate | 0.3–1.3 | $0.075–$0.325 |
All endpoints return standard error responses:
// 402 — Insufficient credits
{ "error": "Insufficient credits", "required": 2, "balance": 1.5 }
// 401 — Authentication failed
{ "error": "Invalid credentials" }
// 400 — Missing required fields
{ "error": "wpPath is required" }
// 500 — Server error
{ "error": "Internal server error message" }The SDK throws typed errors you can catch:
import { WapuuLinkInsufficientCreditsError } from 'wapuulink';
try {
const page = await wapuu.pages.generate({ prompt: '...' });
} catch (err) {
if (err instanceof WapuuLinkInsufficientCreditsError) {
console.log('Buy more credits!');
}
}