Web subclient deep dive—projects, assets, and content fetching. Create, manage, and serve AI-generated websites.
Web Subclient
The client.web subclient lets you manage web projects and assets—AI-generated websites with HTML, CSS, JavaScript, and images. Create projects, list and manage assets, and fetch raw content for serving or embedding.
Projects API
| Method | Signature | Description |
|---|---|---|
list | () => Promise<WebProject[]> | List all your web projects |
listPublic | () => Promise<WebProject[]> | List public web projects |
getById | (id: string) => Promise<WebProject | null> | Get project by ID |
getByName | (name: string) => Promise<WebProject | null> | Get project by name |
create | (params) => Promise<WebProject> | Create a new project |
update | (params) => Promise<WebProject> | Update project settings |
delete | (params: { id }) => Promise<void> | Delete a project |
Assets API
| Method | Signature | Description |
|---|---|---|
list | (projectId, opts?) => Promise<WebAsset[]> | List assets in a project |
get | (projectId, path) => Promise<WebAsset | null> | Get asset by path (triggers generation if missing) |
delete | (projectId, path) => Promise<void> | Delete an asset at path |
Content Fetching
| Method | Signature | Description |
|---|---|---|
getContent | (projectId, path) => Promise<Response> | Fetch raw content as a Response (HTML, CSS, etc.) |
WebAsset Fields
| Field | Type | Description |
|---|---|---|
id | string | Asset ID |
project_id | string | Project ID |
path | string | File path (e.g. /index.html) |
content_type | string | MIME type (e.g. text/html) |
text_content | string | null | Text content when applicable |
status | string | pending, generating, completed, or failed |
url | string | null | Direct URL when completed |
Quick Start
1. Create a project
const project = await client.web.projects.create({
name: 'My Site',
description: 'A minimal portfolio',
visibility: 'public',
});2. List or fetch assets
const assets = await client.web.assets.list(project.id, { limit: 20, offset: 0 });
const asset = await client.web.assets.get(project.id, '/index.html');3. Fetch raw content
const res = await client.web.getContent(project.id, '/index.html');
const html = await res.text();Projects Methods
web.projects.list()
web.projects.list(): Promise<WebProject[]>Returns all web projects for the authenticated user.
const projects = await client.web.projects.list();web.projects.listPublic()
web.projects.listPublic(): Promise<WebProject[]>Returns all public web projects (no auth required for read).
const publicProjects = await client.web.projects.listPublic();web.projects.getById(id)
web.projects.getById(id: string): Promise<WebProject | null>Fetches a project by ID. Returns null if not found.
const project = await client.web.projects.getById('project-uuid');web.projects.getByName(name)
web.projects.getByName(name: string): Promise<WebProject | null>Fetches a project by name. Returns null if not found.
const project = await client.web.projects.getByName('My Site');web.projects.create(params)
web.projects.create(params: {
name: string;
description?: string;
visibility?: 'public' | 'private';
}): Promise<WebProject>Creates a new web project.
const project = await client.web.projects.create({
name: 'Doc Site',
description: 'API documentation',
visibility: 'public',
});web.projects.update(params)
web.projects.update(params: UpdateWebProjectParams): Promise<WebProject>Updates project settings (prompt, models, visibility, etc.). Include id in params.
await client.web.projects.update({
id: project.id,
project_prompt: 'Clean tech docs with code blocks',
});web.projects.delete(params)
web.projects.delete(params: { id: string }): Promise<void>Deletes a web project.
await client.web.projects.delete({ id: project.id });Assets Methods
web.assets.list(projectId, opts?)
web.assets.list(
projectId: string,
opts?: { limit?: number; offset?: number }
): Promise<WebAsset[]>Lists assets in a project with optional pagination.
const assets = await client.web.assets.list(project.id, { limit: 10, offset: 0 });web.assets.get(projectId, path)
web.assets.get(projectId: string, path: string): Promise<WebAsset | null>Gets an asset by path. If the asset doesn't exist, requesting it may trigger AI generation.
Requesting a non-existent path can trigger on-demand AI generation based on the project prompt. Poll get() until status is completed or failed.
const asset = await client.web.assets.get(project.id, '/about.html');
if (asset?.status === 'completed') {
console.log(asset.url);
}web.assets.delete(projectId, path)
web.assets.delete(projectId: string, path: string): Promise<void>Deletes an asset at the given path.
await client.web.assets.delete(project.id, '/old-page.html');getContent(projectId, path)
web.getContent(projectId: string, path: string): Promise<Response>Fetches raw content for a path. Returns a standard Response (from fetch) so you can use .text(), .json(), .blob(), etc. Useful for iframes, SSR, or direct serving.
const res = await client.web.getContent(project.id, '/index.html');
const html = await res.text();
// or
const cssRes = await client.web.getContent(project.id, '/styles.css');
const css = await cssRes.text();Code Examples
import { PUClient } from 'pu-client';
const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
const project = await client.web.projects.create({
name: 'Landing Page',
description: 'Product landing',
visibility: 'public',
});
await client.web.projects.update({
id: project.id,
project_prompt: 'Modern SaaS landing with hero, features, CTA.',
});
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();
}import { PUClient } from 'pu-client';
const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
const projects = await client.web.projects.list();
const project = projects[0];
const assets = await client.web.assets.list(project.id, { limit: 50 });
for (const a of assets) {
if (a.status === 'completed') {
const res = await client.web.getContent(project.id, a.path);
console.log(`${a.path}: ${(await res.text()).slice(0, 100)}...`);
}
}Asset Status
| Status | Description |
|---|---|
pending | Requested but not yet started |
generating | AI is producing the asset |
completed | Ready; url and content available |
failed | Generation failed |