Upstreet Docs
    Platform

    AI-generated websites—create projects, let AI build pages, and host them on the platform. The client.web SDK subclient powers it all.

    Web

    Describe your site. AI generates it. We host it. From idea to live website in minutes.

    Web projects let you create AI-generated websites on Upstreet. Define a project with a name and prompt—AI produces HTML, CSS, JavaScript, and images on demand. Pages are hosted and served by the platform. Perfect for landing pages, portfolios, documentation, and NPC-authored sites.

    AI-generated website preview with modern design—hero section, cards, and dynamic content


    Web Projects Overview

    ConceptDescription
    Projects PageMain hub at /web—list, create, and manage web projects
    ProjectA named site with a project prompt; AI uses it to generate pages
    AssetsPages and files (HTML, CSS, JS, images) produced by AI
    HostingPlatform serves content at /api/web/[projectId]/serve/[path]
    SDKclient.web subclient for projects and assets

    Web projects use AI to generate content on the fly. Request a path (e.g. /index.html) and if it doesn't exist, AI generates it based on the project prompt. Once generated, assets are cached and served quickly.


    Web Projects Page (/web)

    The web page at /web is your control center:

    ActionDescription
    List ProjectsSee all your web projects (name, description, visibility)
    Create ProjectAdd a new project with name, description, and optional visibility
    Open ProjectEnter a project to browse assets, edit settings, or preview
    SettingsConfigure project prompt, text model, image model, visibility

    Placeholder: Web projects list with AI-generated site previews


    Creating AI-Generated Websites

    1. Create a project

    Create a web project with a name and optional description. The project prompt (set in settings) guides AI when generating pages.

    import { PUClient } from 'pu-client';
    
    const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
    
    const project = await client.web.projects.create({
      name: 'My Portfolio',
      description: 'A personal portfolio site',
      visibility: 'public',
    });

    2. Set the project prompt

    Update the project with a prompt that describes the site's purpose, style, and structure. AI uses this when generating pages.

    await client.web.projects.update({
      id: project.id,
      project_prompt: 'A minimal portfolio for a 3D artist. Dark theme, hero with work samples, project grid, contact section.',
    });

    3. Request pages

    Request a path like /index.html or /about.html. If the asset doesn't exist, AI generates it. If it exists, it's served from cache.

    const asset = await client.web.assets.get(project.id, '/index.html');
    // asset.status: 'pending' | 'generating' | 'completed' | 'failed'

    4. Serve content

    Fetch the rendered content for a path. Use this for iframes, SSR, or direct links.

    const res = await client.web.getContent(project.id, '/index.html');
    // res is a fetch Response (HTML, CSS, etc.)

    Project Pages and Settings

    Each project has assets—files at paths like /index.html, /styles.css, /about.html. List assets with client.web.assets.list(projectId). Get a specific asset with client.web.assets.get(projectId, path). Requesting a missing path triggers AI generation.

    Project settings include project_prompt (guides generation), text_model, text_model_reasoning, image_model (optional overrides), and members (viewers, editors, owners). Update via client.web.projects.update().

    Projects can be public or private. Public projects appear in client.web.projects.listPublic(). Private projects require authentication to access.

    SettingDescription
    project_promptHigh-level description of the site; AI uses it for all page generation
    text_modelOptional override for text generation model
    text_model_reasoningOptional reasoning model for complex pages
    image_modelOptional override for image generation
    visibilitypublic or private
    membersUser IDs and roles (viewer, editor, owner)

    How Websites Are Hosted and Served

    flowchart LR
        subgraph client [Client]
            Request["Request /path"]
            SDK["client.web"]
        end
    
        subgraph api [API Layer]
            Assets["Assets API"]
            Serve["Serve Endpoint"]
        end
    
        subgraph ai [AI Pipeline]
            Gen["AI Generation"]
            Cache["Asset Cache"]
        end
    
        Request --> SDK
        SDK --> Assets
        Assets --> |"Asset exists?"| Cache
        Cache --> |No| Gen
        Gen --> Cache
        Cache --> Serve
        Serve --> Client
    StepDescription
    1. RequestClient requests get(projectId, path) or getContent(projectId, path)
    2. LookupAPI checks if asset exists at path for project
    3. GenerateIf missing, AI generates based on project prompt and path
    4. StoreGenerated asset is stored and cached
    5. ServeContent returned via /api/web/[projectId]/serve/[path]

    Serve URL format:

    GET /api/web/{projectId}/serve{path}

    Example: /api/web/abc123/serve/index.html returns the HTML for the project's index page.


    SDK Subclient: client.web

    The client.web subclient exposes the full web project lifecycle:

    MethodDescription
    client.web.projects.list()List all your projects
    client.web.projects.listPublic()List public projects
    client.web.projects.getById(id)Get project by ID
    client.web.projects.getByName(name)Get project by name
    client.web.projects.create({ name, description?, visibility? })Create a new project
    client.web.projects.update(params)Update project settings
    client.web.projects.delete({ id })Delete a project
    client.web.assets.list(projectId, opts?)List assets in a project
    client.web.assets.get(projectId, path)Get asset (triggers generation if missing)
    client.web.assets.delete(projectId, path)Delete an asset
    client.web.getContent(projectId, path)Fetch raw content (Response)
    // Full workflow example
    const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
    
    // Create and configure
    const project = await client.web.projects.create({
      name: 'Doc Site',
      visibility: 'public',
    });
    await client.web.projects.update({
      id: project.id,
      project_prompt: 'Technical documentation site. Clean layout, code blocks, search.',
    });
    
    // Trigger generation and fetch
    const asset = await client.web.assets.get(project.id, '/index.html');
    if (asset?.status === 'completed') {
      const res = await client.web.getContent(project.id, '/index.html');
      const html = await res.text();
    }

    Asset Lifecycle

    StatusDescription
    pendingAsset requested but not yet started
    generatingAI is producing the asset
    completedAsset ready; URL available
    failedGeneration failed; check error field

    Routes Quick Reference

    RoutePurpose
    /webWeb projects list and management
    /api/webREST API base for web projects and assets

    Next Steps