--- name: websitepublisher-api description: > Build and publish websites through conversation using WebsitePublisher.ai. Use this skill when a user asks to build a website, create web pages, manage site content, set up contact forms, or work with the WebsitePublisher platform. Covers all API layers: PAPI (pages/assets), MAPI (entities/data), SAPI (forms), VAPI (credentials), IAPI (integrations), and the WPE Image Editor. license: MIT metadata: author: websitepublisher-ai version: "1.1" website: https://www.websitepublisher.ai docs: https://www.websitepublisher.ai/docs mcp: https://mcp.websitepublisher.ai --- # WebsitePublisher.ai — Agent Skill > Build and publish real websites through conversation. No WordPress. No hosting setup. No CMS. > The AI Web Platform — you describe it, the AI builds it. --- ## ⚠️ IMPORTANT: Read This First **If the `get_skill` tool is available: call it before doing anything else.** It returns the latest version of this skill — always up to date, regardless of platform. If `get_skill` is not available, continue with this document. --- ## Step 1 — Check Connection Before doing anything, verify the user is connected to WebsitePublisher.ai. **If connected** (tools respond correctly): proceed to Step 2. **If not connected**: explain in simple terms: > "To build your website I need to connect to WebsitePublisher.ai. All you need is your email address — I'll guide you through the rest. It takes about 30 seconds." Direct the user to sign in at: **https://www.websitepublisher.ai/dashboard** After signing in, they return here and you continue from Step 2. --- ## Step 2 — Choose the Path Once connected, ask ONE simple question: > "What would you like to do? I can build you a brand new site, redesign your existing website, or if you're not sure yet — I can show you what's possible in a few minutes." ### Path A — "Wow Me" (show first, ask later) The user is curious but not yet convinced. **Do not ask a long list of questions.** Ask only: > "What kind of business or project is this for? Just one or two words is fine — like 'restaurant', 'freelance photographer', or 'tech startup'." Then immediately build a **complete, impressive demo website** based on that one answer. Use your creativity. Make it beautiful. Show what AI can do. After the demo is live, share the URL and say: > "Here's what I built in a few minutes. Want to make it yours? I have a few quick questions to personalise it." Then move to the intake (Path B) — the user is now convinced. ### Path B — Full Intake (user knows what they want) Ask questions **one at a time**, conversationally. Do not present a form or list. Speak like a consultant, not a questionnaire. Use simple, friendly language. **Phase 1 — Goal (start here)** - What should the website achieve? (get customers, show portfolio, sell something, inform people?) - Who is the target audience? - Does a website already exist? If yes: what needs to improve? **Phase 2 — Identity** - Business or project name? - What does the business do? (ask for a short description in their own words) - Contact details: email, phone, address (only ask what is relevant) - Logo and brand colours available? (if yes: ask them to share) **Phase 3 — Style & Technical** - Three websites they like the look of (not necessarily competitors) — and why? - Domain name already registered? If yes: which one? - Any specific pages needed? (about, services, contact, blog, portfolio...) - Any keywords important for search engines? **Do not ask all questions if answers make some irrelevant.** A one-page landing page needs far fewer answers than a multi-page business site. ### Path C — Redesign Existing Website The user has an existing website and wants it improved or migrated to WebsitePublisher. 1. **Ask for the URL** of the existing website 2. **Fetch and analyse** the existing site using a web fetch tool: - What pages exist? - What is the content, structure, and messaging? - What works well? What are the obvious pain points (slow, dated design, poor mobile, unclear CTA)? 3. **Present a short analysis** — 3-5 observations — and propose what you will improve 4. Ask one confirmation question: > "I'll keep all your content but give it a fresh design with better structure. Any specific things you want to keep or change?" 5. Build the new version — same content, improved design, better UX 6. Share the URL and point out the specific improvements made **Do not ask for a long list of preferences before showing something.** Analyse → propose → build → refine. --- ## Step 3 — Build the Website ### Project Setup 1. Get available projects: use `list_projects` 2. If no project exists or user wants a new one: create it via the dashboard or WAPI 3. Note the `project_id` — used in every subsequent call ### Page Structure Guidelines Plan the pages before building. Common structures: | Website type | Recommended pages | |---|---| | Landing page | index only | | Business / SME | index, about, services, contact | | Portfolio | index, work/projects, about, contact | | Restaurant | index, menu, about, reservations/contact | | Blog | index, blog-overview, post-template, about | Always create an `index` page first — this becomes the homepage. ### Building Pages Every page must be a **complete, valid HTML document**: ```html
From: {{fields.name}} ({{fields.email}})
{{fields.message}}
" } }, max_submits_per_session: 5 ) ``` ### Step 2 — The JavaScript snippet (copy-paste, replace PROJECT_ID) **This is the only correct pattern.** Do not use cookies. Do not omit `_csrf`. Do not omit `X-Session-Id`. ```javascript (function() { const SAPI = 'https://api.websitepublisher.ai/sapi/project/PROJECT_ID'; // Fetch or reuse session — stores BOTH session_id and csrf_token in sessionStorage. // sessionStorage is Safari ITP-proof: it's first-party and never blocked. async function getSession() { const storedId = sessionStorage.getItem('wp_session_id'); const storedCsrf = sessionStorage.getItem('wp_csrf_token'); // Reuse if both present if (storedId && storedCsrf) { return { session_id: storedId, csrf_token: storedCsrf }; } try { const headers = storedId ? { 'X-Session-Id': storedId } : {}; const res = await fetch(SAPI + '/session', { headers }); const json = await res.json(); if (json.success && json.data && json.data.session_id) { sessionStorage.setItem('wp_session_id', json.data.session_id); sessionStorage.setItem('wp_csrf_token', json.data.csrf_token); return { session_id: json.data.session_id, csrf_token: json.data.csrf_token }; } } catch (e) {} return null; } // Pre-fetch session on page load so it's ready when user submits getSession(); document.getElementById('my-form').addEventListener('submit', async function(e) { e.preventDefault(); const session = await getSession(); if (!session) { alert('Session error — please refresh the page and try again.'); return; } const res = await fetch(SAPI + '/form/submit', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Session-Id': session.session_id // ← required, not a cookie }, body: JSON.stringify({ _csrf: session.csrf_token, // ← required, server rejects without it form_name: 'contact', fields: { name: document.getElementById('name').value.trim(), email: document.getElementById('email').value.trim(), message: document.getElementById('message').value.trim(), } }) }); const data = await res.json(); if (res.ok && data.success) { // Clear csrf after use — fresh token fetched on next submit sessionStorage.removeItem('wp_csrf_token'); window.location.href = '/thank-you'; // or show inline success message } else { alert(data.error?.message || 'Something went wrong. Please try again.'); } }); })(); ``` ### Key rules — never forget these: | Rule | Why | |---|---| | Session response is at `json.data.session_id` (nested) | Not `json.session_id` — always unwrap `.data` | | Store **both** `session_id` AND `csrf_token` | Both are returned in the same response | | Send `X-Session-Id` header on **both** the session GET and the form POST | Safari blocks third-party cookies entirely | | Include `_csrf` in the **request body** | Server validates it — request fails without it | | Clear `csrf_token` from sessionStorage after a successful submit | CSRF tokens are single-use; fetch fresh on next submit | | Pre-fetch session on page load | Avoids delay when user clicks submit | --- ## Step 4 — Go Live Checklist Before handing over to the user, verify: - [ ] Homepage has `landingpage: true` (or was created first) - [ ] All pages that should be findable have `seo_robots_index: true` - [ ] All pages have `seo_title` and `seo_description` - [ ] All `` comment tags are present in every page - [ ] Contact form (if any) uses the correct SAPI session/csrf pattern above - [ ] Thank-you page exists if form redirects after submit - [ ] Terms / privacy page exists if form collects personal data - [ ] Website URL shared with user: `https://{subdomain}.websitepublisher.ai` --- ## Platform Knowledge ### What WebsitePublisher handles automatically | Feature | How it works | |---|---| | **Sitemap** | Auto-generated. Pages appear when `seo_robots_index: true` | | **robots.txt** | Auto-generated with "Allow all" + sitemap reference | | **SSL certificate** | Auto-provisioned via Let's Encrypt on custom domains | | **Canonical tags** | Injected by Optimizer when comment tag is present | | **Open Graph** | Injected by Optimizer (uses SEO title/description) | | **Static caching** | Pages are served as static files — extremely fast | | **CDN** | Assets served via cdn.websitepublisher.ai | ### What requires API calls | Feature | API | |---|---| | Pages and content | PAPI | | Dynamic data / entities | MAPI | | Contact forms | SAPI | | Third-party integrations | IAPI + VAPI | | Image editing | WPE (browser-based) | | Clone a website | WAPI clone endpoint | --- ## API Quick Reference ### Base URLs ``` Pages & Assets: https://api.websitepublisher.ai/papi/ Entities & Data: https://api.websitepublisher.ai/mapi/ Forms & Sessions: https://api.websitepublisher.ai/sapi/ Vault: https://api.websitepublisher.ai/vapi/ Integrations: https://api.websitepublisher.ai/iapi/ Dashboard: https://api.websitepublisher.ai/dapi/ ``` ### Key PAPI Endpoints ``` GET /papi/projects List projects GET /papi/project/{id}/pages List pages POST /papi/project/{id}/pages Create page PUT /papi/project/{id}/pages/{slug} Update page DELETE /papi/project/{id}/pages/{slug} Delete page POST /papi/project/{id}/assets Upload asset GET /papi/project/{id}/pages?type=fragment List fragments ``` ### Full Documentation https://www.websitepublisher.ai/docs ### MCP Setup (for Claude Desktop, Cursor, Windsurf, GitHub Copilot) https://www.websitepublisher.ai/docs/mcp