API Documentation

Quick Start

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);

Authentication

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 Endpoints

POST/auth/registerCreate a new account and get your API key
Request Body
{
  "email": "dev@example.com",     // required
  "password": "securepass123",    // required
  "name": "Jane Developer"       // optional
}
Response
{
  "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
}
Example
// 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"}'
POST/auth/loginLog in and receive a JWT token
Request Body
{
  "email": "dev@example.com",     // required
  "password": "securepass123"     // required
}
Response
{
  "user": {
    "id": "clx...",
    "email": "dev@example.com",
    "name": "Jane Developer",
    "plan": "credits",
    "creditBalance": 40
  },
  "token": "eyJhbG..."
}
Example
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"dev@example.com","password":"securepass123"}'
GET/auth/meGet current user info
Response
{
  "user": {
    "id": "clx...",
    "email": "dev@example.com",
    "name": "Jane Developer",
    "plan": "credits",
    "creditBalance": 40,
    "apiKey": "wl_abc123...",
    "isFounding": false,
    "createdAt": "2025-01-15T..."
  }
}
Example
curl http://localhost:3000/auth/me \
  -H "x-api-key: your-api-key"

Credits Endpoints

GET/credits/balanceCheck your current credit balance
Response
{
  "balance": 40,
  "plan": "credits"
}
Example
// 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
POST/credits/purchaseBuy credits — returns a Stripe checkout URL
Request Body
{
  "bundle": "pro"   // "starter" | "builder" | "pro" | "agency"
}
Response
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/..."
}
Example
curl -X POST http://localhost:3000/credits/purchase \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"bundle":"pro"}'
GET/credits/historyGet your 50 most recent transactions
Response
[
  {
    "id": "clx...",
    "amount": 50,
    "credits": 230,
    "type": "purchase",
    "createdAt": "2025-01-20T..."
  }
]
Example
curl http://localhost:3000/credits/history \
  -H "x-api-key: your-api-key"

Page Generation

POST/v1/generateGenerate a page with AI
1 credit (standard) · 2 credits (premium)
Request Body
{
  "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
}
Response
{
  "html": "<!DOCTYPE html>\n<html>...",
  "model_used": "standard",
  "qa": {                // null if QA is unavailable
    "passed": true,
    "score": 8,
    "brandCompliance": { ... },
    "issues": []
  },
  "credits_used": 1
}
Example
// 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);
PUT/v1/editEdit an existing page
1 credit (standard) · 2 credits (premium)
Request Body
{
  "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
}
Response
{
  "html": "<!DOCTYPE html>\n<html>...",
  "model_used": "standard",
  "qa": { ... },
  "credits_used": 1
}
Example
const edited = await wapuu.pages.edit({
  currentHtml: existingHtml,
  instructions: 'Add a testimonials section below the hero',
  model: 'standard'
});

console.log(edited.html);

Plugin Builder

POST/v1/plugin/buildBuild a WordPress plugin from a prompt
2 credits
Request Body
{
  "prompt": "Build a plugin that adds a custom admin dashboard widget showing recent posts with thumbnails",  // required
  "siteContext": {         // optional
    "siteName": "My Blog"
  }
}
Response
{
  "pluginName": "recent-posts-widget",
  "files": { ... },
  "credits_used": 2
}
Example
const plugin = await wapuu.plugins.build({
  prompt: 'Build a plugin that adds a custom admin dashboard widget showing recent posts',
  siteContext: { siteName: 'My Blog' }
});
POST/v1/plugin/editEdit an existing plugin
1 credit
Request Body
{
  "pluginFiles": {          // required — object of filename: content
    "my-plugin.php": "<?php ..."
  },
  "editPrompt": "Add settings page to control widget visibility",  // required
  "siteContext": { ... }    // optional
}
Response
{
  "files": { ... },
  "credits_used": 1
}
Example
const edited = await wapuu.plugins.edit({
  pluginFiles: { 'my-plugin.php': existingCode },
  editPrompt: 'Add settings page to control widget visibility'
});
POST/v1/plugin/validateValidate a plugin (free)
Free
Request Body
{
  "downloadUrl": "https://example.com/my-plugin.zip",  // required
  "pluginName": "My Plugin",                           // required
  "pluginSlug": "my-plugin"                            // required
}
Response
{
  "passed": true,
  "pluginName": "My Plugin",
  "pluginSlug": "my-plugin",
  "errors": [],
  "warnings": [],
  "credits_used": 0
}
Example
const result = await wapuu.plugins.validate({
  downloadUrl: 'https://example.com/my-plugin.zip',
  pluginName: 'My Plugin',
  pluginSlug: 'my-plugin'
});

console.log(result.passed); // true

Visual QA

POST/v1/qa/screenshotScreenshot and score a page for quality
0.5 credits
Request Body
{
  "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"
  }
}
Response
{
  "passed": true,          // true if score >= 7
  "score": 8,              // 1-10 quality score
  "brandCompliance": { ... },
  "issues": [],
  "credits_used": 0.5
}
Example
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
POST/v1/qa/diffCompare before/after screenshots
0.5 credits
Request Body
{
  "beforeHtml": "<html>...</html>",   // required
  "afterHtml": "<html>...</html>",    // required
  "prompt": "Added a testimonials section"  // required — what changed
}
Response
{
  "changed": true,
  "improvements": [ ... ],
  "regressions": [ ... ],
  "credits_used": 0.5
}
Example
const diff = await wapuu.qa.diff({
  beforeHtml: originalHtml,
  afterHtml: editedHtml,
  prompt: 'Added a testimonials section'
});

console.log(diff.improvements);

WordPress Automation

All WP endpoints require a wpPath — the absolute path to your WordPress installation on the server running WP-CLI.

POST/v1/wp/healthRun a full WordPress health check
0.3 credits
Request Body
{
  "wpPath": "/var/www/html"   // required — path to WP install
}
Response
{
  "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
}
Example
const health = await wapuu.wp.health({
  wpPath: '/var/www/html'
});

console.log(health.healthy); // true
console.log(health.issues);  // []
POST/v1/wp/pluginsList installed plugins
0.1 credits
Request Body
{
  "wpPath": "/var/www/html"   // required
}
Response
{
  "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
}
Example
const result = await wapuu.wp.plugins({
  wpPath: '/var/www/html'
});

result.plugins.forEach(p =>
  console.log(`${p.name} v${p.version} (${p.status})`)
);
POST/v1/wp/update-checkCheck if plugin updates are safe to apply
1 credit
Request Body
{
  "wpPath": "/var/www/html",         // required
  "plugins": ["akismet", "woocommerce"]  // optional — omit to check all
}
Response
{
  "safe": true,
  "risks": [],
  "recommendation": "Review changelogs before updating",
  "plugins": [
    { "name": "akismet", "version": "5.3", "updateAvailable": false, "status": "active" }
  ],
  "credits_used": 1
}
Example
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"
POST/v1/wp/cache-clearFlush WordPress object cache
0.1 credits
Request Body
{
  "wpPath": "/var/www/html"   // required
}
Response
{
  "cleared": true,
  "caches": ["object-cache"],
  "output": "Success: The cache was flushed.",
  "credits_used": 0.1
}
Example
const result = await wapuu.wp.cacheClear({
  wpPath: '/var/www/html'
});

console.log(result.cleared); // true
POST/v1/wp/search-replaceSearch and replace in the WordPress database
0.2 credits
Request Body
{
  "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
}
Response
{
  "replacements": "Success: 42 replacements to be made.",
  "dryRun": true,
  "exitCode": 0,
  "credits_used": 0.2
}
Example
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);

Workflows

Orchestrated pipelines that chain multiple operations together. Credits are charged only for steps that execute.

POST/v1/workflow/deployGenerate → QA → deploy to WP → screenshot → diff
2.7 credits (standard) · 3.7 credits (premium) — max
Request Body
{
  "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)
}
Response
{
  "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
}
Example
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"
POST/v1/workflow/auditFull site health report — 4 checks in parallel
1.9 credits max
Request Body
{
  "wpPath": "/var/www/html",                        // required
  "siteUrl": "https://mysite.com",                  // required
  "plugins": ["akismet", "woocommerce"]             // optional — filter update check
}
Response
{
  "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
}
Example
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
POST/v1/workflow/plugin/build-and-validateBuild plugin with AI → validate with Playwright
2 credits
Request Body
{
  "prompt": "Build a plugin that adds reading time to posts",   // required
  "siteContext": { "siteName": "My Blog" }                      // optional
}
Response
{
  "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
}
Example
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"]
POST/v1/workflow/migrateScreenshot → search-replace → cache clear → screenshot → diff
0.3–1.3 credits (dynamic)
Request Body
{
  "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
}
Response
{
  "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
}
Example
// 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
});

Composition Guide

You can chain individual endpoints yourself for custom workflows. Here are common patterns:

Generate → QA Loop (retry until score passes)

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 Plugin → Edit → Validate

// 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); // true

Full Site Audit → Conditional Updates

const 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'
});

Safe Migration with Rollback Check

// 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);

Credit Costs

OperationCreditsCost
Page (Standard)1$0.25
Page (Premium)2$0.50
Plugin Build2$0.50
Plugin Edit1$0.25
Plugin Validate0Free
QA Screenshot0.5$0.125
QA Diff0.5$0.125
WP Command0.1$0.025
Update Check1$0.25
Workflow: Deploy2.7$0.675
Workflow: Deploy (Premium)3.7$0.925
Workflow: Audit1.9$0.475
Workflow: Plugin Build + Validate2$0.50
Workflow: Migrate0.3–1.3$0.075–$0.325

Error Handling

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!');
  }
}