🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

WebsitePublisher

by @megberts

Build and publish complete websites via WebsitePublisher.ai. Create pages, upload assets, manage dynamic data (products, team members, blog posts), configure...

TERMINAL
clawhub install websitepublisher

πŸ“– About This Skill


name: websitepublisher description: > Build and publish complete websites via WebsitePublisher.ai. Create pages, upload assets, manage dynamic data (products, team members, blog posts), configure contact forms, and publish to a live URL β€” all through conversation. No WordPress. No hosting setup. No CMS configuration. homepage: https://www.websitepublisher.ai license: MIT metadata: clawdbot: emoji: "🌐" requires: env: - WEBSITEPUBLISHER_TOKEN - WEBSITEPUBLISHER_PROJECT primaryEnv: WEBSITEPUBLISHER_TOKEN openclaw: emoji: "🌐" requires: env: - WEBSITEPUBLISHER_TOKEN - WEBSITEPUBLISHER_PROJECT

WebsitePublisher.ai

Build and publish real websites through conversation. You describe it β€” the AI builds and deploys it.

The user's credentials are set as environment variables:

  • WEBSITEPUBLISHER_TOKEN β€” API token (starts with wpa_)
  • WEBSITEPUBLISHER_PROJECT β€” Project ID (numeric, e.g. 12345)
  • If either variable is missing, stop and instruct the user: 1. Sign up at https://www.websitepublisher.ai/dashboard 2. Copy their API token and Project ID from the dashboard 3. Add to their OpenClaw config:

       {
         "env": {
           "WEBSITEPUBLISHER_TOKEN": "wpa_xxxx...",
           "WEBSITEPUBLISHER_PROJECT": "12345"
         }
       }
       


    Authentication

    Every API call requires these headers:

    Authorization: Bearer $WEBSITEPUBLISHER_TOKEN
    Content-Type: application/json
    Accept: application/json
    

    Base URL: https://api.websitepublisher.ai


    Workflow β€” Build a Complete Website

    When asked to build a website, follow this exact sequence:

    Step 1 β€” Check existing content

    curl -s \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Accept: application/json" \
      "https://api.websitepublisher.ai/papi/project/$WEBSITEPUBLISHER_PROJECT/status"
    

    This returns the project URL, existing pages, and current status. Always do this first.

    Step 2 β€” Create pages (use bulk for multiple pages)

    Single page:

    curl -s -X POST \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "slug": "index.html",
        "content": "...",
        "title": "Homepage",
        "seotitle": "Company Name β€” Tagline",
        "seodescription": "One sentence describing the page for search engines."
      }' \
      "https://api.websitepublisher.ai/papi/project/$WEBSITEPUBLISHER_PROJECT/pages"
    

    Multiple pages at once (preferred β€” saves API calls):

    curl -s -X POST \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "pages": [
          {"slug": "index.html", "content": "...", "title": "Home"},
          {"slug": "about.html", "content": "...", "title": "About"},
          {"slug": "contact.html", "content": "...", "title": "Contact"}
        ]
      }' \
      "https://api.websitepublisher.ai/papi/project/$WEBSITEPUBLISHER_PROJECT/pages/bulk"
    

    Step 3 β€” Upload assets (images, CSS, JS)

    curl -s -X POST \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "slug": "images/logo.png",
        "content": "BASE64_ENCODED_DATA",
        "alt": "Company Logo"
      }' \
      "https://api.websitepublisher.ai/papi/project/$WEBSITEPUBLISHER_PROJECT/assets"
    

    Asset URL pattern: https://cdn.websitepublisher.ai/[path]/[slug] Reference assets in HTML using this CDN URL.

    Step 4 β€” Confirm live URL

    The project URL is returned by the status endpoint. Share it with the user.


    PAPI β€” Pages & Assets (Full Reference)

    Pages

    | Action | Method | Endpoint | |--------|--------|----------| | List pages | GET | /papi/project/{id}/pages | | Get page | GET | /papi/project/{id}/pages/{slug} | | Create page | POST | /papi/project/{id}/pages | | Bulk create | POST | /papi/project/{id}/pages/bulk | | Update page | PUT | /papi/project/{id}/pages/{slug} | | Patch page | PATCH | /papi/project/{id}/pages/{slug} | | Delete page | DELETE | /papi/project/{id}/pages/{slug} | | List versions | GET | /papi/project/{id}/pages/{slug}/versions | | Rollback | POST | /papi/project/{id}/pages/{slug}/rollback |

    Page fields:

    {
      "slug": "about.html",
      "content": "full HTML string",
      "title": "label shown in dashboard",
      "seotitle": "browser tab + search title",
      "seodescription": "meta description for search",
      "seokeywords": "comma,separated,keywords",
      "canonical": "https://example.com/about"
    }
    

    Patch a page (partial update β€” send only changed HTML fragment):

    curl -s -X PATCH \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "patches": [
          {
            "search": "

    Old Title

    ", "replace": "

    New Title

    " } ] }' \ "https://api.websitepublisher.ai/papi/project/$WEBSITEPUBLISHER_PROJECT/pages/index.html"

    Assets

    | Action | Method | Endpoint | |--------|--------|----------| | List assets | GET | /papi/project/{id}/assets | | Get asset | GET | /papi/project/{id}/assets/{slug} | | Upload asset | POST | /papi/project/{id}/assets | | Bulk upload | POST | /papi/project/{id}/assets/bulk | | Delete asset | DELETE | /papi/project/{id}/assets/{slug} |

    Asset fields:

    {
      "slug": "images/hero.jpg",
      "content": "BASE64_STRING or https://example.com/image.jpg",
      "alt": "Description for accessibility",
      "type": "image"
    }
    

    > Tip: You can pass a public image URL as content β€” the platform fetches and stores it automatically.


    MAPI β€” Dynamic Data (Products, Blog, Team, etc.)

    Use MAPI when the website needs structured, repeatable data β€” product listings, blog posts, team members, portfolio items, etc.

    Create an entity (data model)

    curl -s -X POST \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "name": "products",
        "properties": [
          {"name": "name", "type": "string", "required": true},
          {"name": "price", "type": "number"},
          {"name": "description", "type": "text"},
          {"name": "image", "type": "image"}
        ]
      }' \
      "https://api.websitepublisher.ai/mapi/project/$WEBSITEPUBLISHER_PROJECT/entities"
    

    Create records

    curl -s -X POST \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "name": "Wireless Headphones",
        "price": 89.99,
        "description": "Premium noise-cancelling headphones",
        "image": "https://example.com/headphones.jpg"
      }' \
      "https://api.websitepublisher.ai/mapi/project/$WEBSITEPUBLISHER_PROJECT/products"
    

    > Note: MAPI endpoint uses the plural entity name β€” e.g. /products not /product.

    MAPI Reference

    | Action | Method | Endpoint | |--------|--------|----------| | List entities | GET | /mapi/project/{id}/entities | | Create entity | POST | /mapi/project/{id}/entities | | Get entity schema | GET | /mapi/project/{id}/entities/{name}/properties | | List records | GET | /mapi/project/{id}/{entity} | | Get record | GET | /mapi/project/{id}/{entity}/{recordId} | | Create record | POST | /mapi/project/{id}/{entity} | | Update record | PUT | /mapi/project/{id}/{entity}/{recordId} | | Delete record | DELETE | /mapi/project/{id}/{entity}/{recordId} |

    Public read: MAPI records are publicly readable at the same endpoint without a token β€” useful for frontend JavaScript fetching live data.


    SAPI β€” Contact Forms

    Add a working contact form to any page in two steps.

    Step 1 β€” Configure the form

    curl -s -X POST \
      -H "Authorization: Bearer $WEBSITEPUBLISHER_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "page_slug": "contact.html",
        "fields": [
          {"name": "name", "type": "text", "required": true, "label": "Your Name"},
          {"name": "email", "type": "email", "required": true, "label": "Email Address"},
          {"name": "message", "type": "textarea", "required": true, "label": "Message"}
        ],
        "submit_label": "Send Message",
        "success_message": "Thank you! We will get back to you shortly.",
        "notification_email": "hello@example.com"
      }' \
      "https://api.websitepublisher.ai/sapi/project/$WEBSITEPUBLISHER_PROJECT/forms"
    

    > Important: Always send ALL fields on every configure_form call β€” no partial updates.

    Step 2 β€” Add the form HTML to the page

    The API returns a form_id. Use this snippet in the page HTML:

    SAPI Reference

    | Action | Method | Endpoint | |--------|--------|----------| | Configure form | POST | /sapi/project/{id}/forms | | List forms | GET | /sapi/project/{id}/forms | | Remove form | DELETE | /sapi/project/{id}/forms/{form_id} |


    Rate Limits

    | Plan | Limit | |------|-------| | Free | 30 requests/min | | Starter | 60 requests/min | | Pro+ | 150-300 requests/min |

    Always prefer bulk endpoints (/pages/bulk, /assets/bulk) over individual calls to stay within rate limits. A bulk call counts as one request regardless of how many items it creates.


    Common Patterns

    Landing page (one page)

    1. GET /status β€” check project 2. POST /pages β€” create index.html with full content 3. POST /forms β€” configure contact form if needed 4. Share project URL

    Multi-page website

    1. GET /status β€” check project 2. POST /pages/bulk β€” create all pages in one call 3. POST /assets/bulk β€” upload all images in one call 4. POST /forms β€” configure contact form on contact page 5. Share project URL

    Website with dynamic data (e.g. product catalogue)

    1. GET /status β€” check project 2. POST /entities β€” create data model (e.g. "products") 3. POST /{entity} β€” create records (one per product) 4. POST /pages/bulk β€” create pages with JS that fetches MAPI data 5. Share project URL


    Error Handling

    All endpoints return standard HTTP status codes:

    | Code | Meaning | |------|---------| | 200/201 | Success | | 400 | Invalid request β€” check your JSON fields | | 401 | Invalid or missing token | | 404 | Page/asset/entity not found | | 422 | Validation error β€” response body contains field errors | | 429 | Rate limit exceeded β€” use bulk endpoints or wait | | 500 | Server error β€” try again |

    On error, the response body always contains a message field with a description.


    Support & Docs

  • Dashboard: https://www.websitepublisher.ai/dashboard
  • Full API docs: https://www.websitepublisher.ai/docs
  • PAPI docs: https://www.websitepublisher.ai/docs/papi
  • MAPI docs: https://www.websitepublisher.ai/docs/mapi
  • SAPI docs: https://www.websitepublisher.ai/docs/sapi