Dashboard
How it Works Documentation Quick Start PAPI — Pages & Assets MAPI — Dynamic Data Integrations SAPI — Sessions & Forms MCP Server OpenClaw Skill Tools Deploy Dashboard

PAPI Documentation

The Presentation API (PAPI) enables you to create, manage, and publish web pages and assets programmatically.

Authentication

All PAPI requests require authentication via Bearer token in the Authorization header:

Authorization: Bearer {your_api_token}
⚠️ Important Each token is tied to a specific project. The project ID in the URL must match the token's project.

Base URL

https://api.websitepublisher.ai/papi

All PAPI endpoints use the /papi prefix. The full API gateway also provides:

API Base Path Purpose
PAPI /papi/* Pages, assets, publishing
MAPI /mapi/* Dynamic data structures

Status

GET /papi/project/{project_id}/status

Get the current status of a project including page and asset counts.

Response

{
    "success": true,
    "data": {
        "project_id": 12345,
        "domain": "mysite.websitepublisher.ai",
        "pages_count": 5,
        "assets_count": 12,
        "status": "published"
    }
}

Pages

GET /papi/project/{project_id}/pages

List all pages in the project.

POST /papi/project/{project_id}/pages

Create a new page.

Request Body

Field Type Required Description
slug string Yes URL path (e.g., "index.html", "blog/post1.html")
content string Yes Full HTML content
meta object No Page metadata (title, language, etc.)
seo object No SEO settings (description, robots, etc.)

Example Request

{
    "slug": "about.html",
    "content": "<!DOCTYPE html><html>...</html>",
    "meta": {
        "title": "About Us",
        "language": "en"
    },
    "seo": {
        "description": "Learn more about our company",
        "robots": "index, follow"
    }
}
GET /papi/project/{project_id}/pages/{slug}

Get a specific page by slug.

Query Parameters

Parameter Type Default Description
include_version boolean false Include version number and version_hash in the response. Required for PATCH operations.

Example Response (with include_version=true)

{
    "success": true,
    "data": {
        "slug": "about.html",
        "content": "<!DOCTYPE html>...",
        "version": 3,
        "version_hash": "a3f8c2d1",
        "updated_at": "2026-02-13T14:00:00Z"
    }
}
PUT /papi/project/{project_id}/pages/{slug}

Update an existing page. Note: The slug cannot be changed.

ℹ️ Immutable Slugs To change a page's URL, delete the old page and create a new one with the desired slug.
PATCH /papi/project/{project_id}/pages/{slug}

Apply targeted find-and-replace patches to a page without sending the full content. Uses optimistic locking via base_version_hash to prevent conflicts.

Request Body

Field Type Required Description
base_version_hash string Yes Hash from GET ?include_version=true. Prevents overwrites if page changed.
patches array Yes Array of patch operations (see below)
patch_summary string No Human-readable description of the change

Patch Operations

Field Type Description
operation string "replace" — find and replace text
find string Exact text to search for (must exist in current content)
replace string Text to replace it with

Example Request

{
    "base_version_hash": "a3f8c2d1",
    "patches": [
        {
            "operation": "replace",
            "find": "<h1>Old Title</h1>",
            "replace": "<h1>New Title</h1>"
        }
    ],
    "patch_summary": "Updated page title"
}

Success Response

{
    "success": true,
    "data": {
        "slug": "about.html",
        "version": 4,
        "version_hash": "jkl012mn",
        "patches_applied": 1,
        "content_preview": "<!DOCTYPE html>...(first 500 chars)"
    }
}
⚠️ Version Conflict (409) If the page was modified since your last fetch, a VERSION_CONFLICT error is returned. Fetch the latest version and retry.
DELETE /papi/project/{project_id}/pages/{slug}

Delete a page.

Versioning

Every page update (PUT, PATCH, rollback) creates a new version. Versions are forward-only — rollbacks create a new version with the content of the target version. Use PATCH for targeted changes and PUT for full replacements.

GET /papi/project/{project_id}/pages/{slug}/versions

Get version history for a page. Returns metadata (no content) sorted newest-first.

Example Response

{
    "success": true,
    "data": {
        "slug": "about.html",
        "current_version": 4,
        "versions": [
            {
                "version": 4,
                "hash": "jkl012mn",
                "created_by": "patch",
                "patch_summary": "Updated page title",
                "size_bytes": 2340,
                "created_at": "2026-02-13T15:00:00Z"
            },
            {
                "version": 3,
                "hash": "a3f8c2d1",
                "created_by": "update",
                "size_bytes": 2280,
                "created_at": "2026-02-13T14:00:00Z"
            }
        ]
    }
}
ℹ️ created_by values "create" — initial page creation, "update" — full PUT replacement, "patch" — PATCH operation, "rollback" — rollback to earlier version.
POST /papi/project/{project_id}/pages/{slug}/rollback

Rollback a page to a previous version. Creates a new version with the content of the target version (forward-only).

Request Body

Field Type Required Description
target_version integer One of two Version number to rollback to
target_version_hash string One of two Version hash to rollback to (alternative to version number)

Example Request

{
    "target_version": 2
}

Example Response

{
    "success": true,
    "data": {
        "slug": "about.html",
        "rolled_back_to": 2,
        "new_version": 5,
        "new_version_hash": "xyz789ab"
    }
}
ℹ️ Forward-only versioning Rolling back from v4 to v2 creates v5 with v2's content. The version number always increments — no history is lost.

Assets

GET /papi/project/{project_id}/assets

List all assets in the project.

POST /papi/project/{project_id}/assets

Upload a new asset.

Request Body

Field Type Required Description
slug string Yes File path (e.g., "images/logo.png")
content string One of two Base64 encoded binary data
source_url string One of two Public URL to fetch the asset from (alternative to base64). The server downloads and stores the file securely.
alt string No Alt text for images
ℹ️ Two upload methods Provide either content (base64) or source_url (URL fetch). When using source_url, the server fetches the file with SSRF protection, content-type validation, and size limits.

Supported File Types

Category Extensions Max Size
Images jpg, jpeg, png, gif, webp, svg 5 MB
Documents pdf 5 MB
Fonts woff, woff2, ttf 2 MB
Other ico, json 1 MB
GET /papi/project/{project_id}/assets/{slug}

Get a specific asset (returns base64 content).

DELETE /papi/project/{project_id}/assets/{slug}

Delete an asset.

Bulk Operations

For efficiency, use bulk endpoints when creating multiple pages or assets:

POST /papi/project/{project_id}/pages/bulk

Create multiple pages in one request.

{
    "pages": [
        { "slug": "index.html", "content": "...", "meta": {...} },
        { "slug": "about.html", "content": "...", "meta": {...} }
    ]
}
POST /papi/project/{project_id}/assets/bulk

Upload multiple assets in one request.

{
    "assets": [
        { "slug": "images/a.png", "content": "{base64}" },
        { "slug": "images/b.png", "content": "{base64}" }
    ]
}

Error Handling

All errors return a consistent format:

{
    "success": false,
    "error": {
        "message": "Description of the error",
        "code": 400
    }
}

HTTP Status Codes

Code Meaning
200 Success
201 Created
400 Bad Request - Invalid input
401 Unauthorized - Invalid token or project mismatch
404 Not Found - Resource doesn't exist
409 Conflict - Resource already exists or version conflict (PATCH)
422 Validation Error
500 Server Error

Complete Example

Here's a complete example of creating a simple website:

# 1. Check project status
curl -X GET "https://api.websitepublisher.ai/papi/project/{project_id}/status" \
  -H "Authorization: Bearer YOUR_TOKEN"

# 2. Create pages
curl -X POST "https://api.websitepublisher.ai/papi/project/{project_id}/pages/bulk" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pages": [
      {
        "slug": "index.html",
        "content": "<!DOCTYPE html><html><head><title>Home</title></head><body><h1>Welcome</h1></body></html>",
        "meta": {"title": "Home"}
      }
    ]
  }'

# 3. Update a page with PATCH (targeted change)
curl -X PATCH "https://api.websitepublisher.ai/papi/project/{project_id}/pages/index.html" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "base_version_hash": "abc123",
    "patches": [{"operation": "replace", "find": "<h1>Welcome</h1>", "replace": "<h1>Hello World</h1>"}],
    "patch_summary": "Updated heading"
  }'

# 4. Verify
curl -X GET "https://api.websitepublisher.ai/papi/project/{project_id}/pages" \
  -H "Authorization: Bearer YOUR_TOKEN"

Powered by WebSumo