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.

Web Projects Overview
| Concept | Description |
|---|---|
| Projects Page | Main hub at /web—list, create, and manage web projects |
| Project | A named site with a project prompt; AI uses it to generate pages |
| Assets | Pages and files (HTML, CSS, JS, images) produced by AI |
| Hosting | Platform serves content at /api/web/[projectId]/serve/[path] |
| SDK | client.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:
| Action | Description |
|---|---|
| List Projects | See all your web projects (name, description, visibility) |
| Create Project | Add a new project with name, description, and optional visibility |
| Open Project | Enter a project to browse assets, edit settings, or preview |
| Settings | Configure project prompt, text model, image model, visibility |

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.
| Setting | Description |
|---|---|
project_prompt | High-level description of the site; AI uses it for all page generation |
text_model | Optional override for text generation model |
text_model_reasoning | Optional reasoning model for complex pages |
image_model | Optional override for image generation |
visibility | public or private |
members | User 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| Step | Description |
|---|---|
| 1. Request | Client requests get(projectId, path) or getContent(projectId, path) |
| 2. Lookup | API checks if asset exists at path for project |
| 3. Generate | If missing, AI generates based on project prompt and path |
| 4. Store | Generated asset is stored and cached |
| 5. Serve | Content 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:
| Method | Description |
|---|---|
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
| Status | Description |
|---|---|
pending | Asset requested but not yet started |
generating | AI is producing the asset |
completed | Asset ready; URL available |
failed | Generation failed; check error field |
Routes Quick Reference
| Route | Purpose |
|---|---|
/web | Web projects list and management |
/api/web | REST API base for web projects and assets |