VISIMADE

AI Agents


VISIMADE.md

This is the complete reference document for AI agents. Point your AI assistant to this page when working with Visimade.

Raw Markdown Content

AI agents can read this page directly


# VISIMADE.md - AI Agent Instructions

This document contains everything you need to work with the Visimade platform.
Visimade is a platform for creating interactive web pages with built-in data storage.

## Authentication

All API requests require a Bearer token in the Authorization header:
```
Authorization: Bearer vm_your_token_here
```

## Base URL

All API endpoints use: `https://visimade.com/api/`
For staging: `https://staging.visimade.com/api/`

---

## Creating a New Page

**Endpoint:** `POST /api/pages`
**Required Scope:** `pages:write`

### Request Body
```json
{
  "name": "Page Title",
  "html_content": "<!DOCTYPE html>...",
  "description": "Optional description (max 500 chars)",
  "storage_mode": "page" | "solo_app" | "team_app" | "social_app",
  "is_published": true
}
```

### Storage Modes
- `page`: No data storage (static pages)
- `solo_app`: Private data per user (personal apps)
- `team_app`: Shared data for invited team members
- `social_app`: Public data with ownership (anyone can read, users edit own records)

### HTML Requirements
1. Must be a complete HTML document with DOCTYPE
2. Include `data-page-id="{{PAGE_ID}}"` in the body tag (required for data APIs)
3. The `{{PAGE_ID}}` placeholder is replaced with the actual ID when served

### Example
```bash
curl -X POST https://visimade.com/api/pages \
  -H "Authorization: Bearer vm_token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My App",
    "html_content": "<!DOCTYPE html><html><head><title>My App</title></head><body data-page-id=\"{{PAGE_ID}}\"><h1>Hello</h1></body></html>",
    "storage_mode": "solo_app"
  }'
```

### Response
```json
{
  "page": {
    "id": 123,
    "name": "My App",
    "slug": "my-app",
    "url": "https://visimade.com/p/my-app"
  }
}
```

---

## Looking Up a Page by Slug

**Endpoint:** `GET /api/pages/lookup?slug=page-slug`
**Required Scope:** `pages:read`

Use this when you have a page URL like `/p/my-page-slug` and need the page ID.

### Response
```json
{
  "id": 123,
  "name": "My Page",
  "slug": "my-page-slug",
  "isPublished": true
}
```

---

## Reading a Page

**Endpoint:** `GET /api/pages/:id`
**Required Scope:** `pages:read`

### Response
```json
{
  "page": {
    "id": 123,
    "name": "My Page",
    "slug": "my-page",
    "html_content": "<!DOCTYPE html>...",
    "is_published": true,
    "description": "...",
    "views": 1250
  },
  "storageMode": "team_app"
}
```

---

## Updating a Page

**Endpoint:** `PATCH /api/pages/:id`
**Required Scope:** `pages:write`

Updates automatically create a version backup.

### Request Body (all fields optional)
```json
{
  "html_content": "<!DOCTYPE html>...",
  "name": "New Title",
  "description": "New description"
}
```

### IMPORTANT: How to Read Page HTML Before Editing

When editing a page, you MUST fetch the raw HTML content using the API:

```
GET /api/pages/:id  →  response.page.html_content
```

**NEVER fetch page HTML from the public URL** (`/p/[slug]`). The public URL returns the page with runtime-injected scripts (analytics, tracking, badges, engagement trackers, data APIs, etc.) that are NOT part of the page content. If you save this rendered output back via PATCH, you will corrupt the page with duplicate scripts that compound on every subsequent save.

---

## Working with Data

### List Collections
**Endpoint:** `GET /api/pages/:id/team-data` (or solo-data, social-data)

Returns all collections and record counts.

### List Records
**Endpoint:** `GET /api/pages/:id/team-data/:collection`

Query parameters:
- `where`: JSON filter, e.g., `{"status":"active"}`
- `orderBy`: `created_at` or `updated_at`
- `order`: `asc` or `desc`
- `limit`: Max records (default 50, max 100)
- `offset`: Skip records for pagination
- `mine`: Only records by current user

### Create Record
**Endpoint:** `POST /api/pages/:id/team-data/:collection`
```json
{
  "data": {
    "title": "New Item",
    "status": "pending"
  }
}
```

### Update Record
**Endpoint:** `PATCH /api/pages/:id/team-data/:collection/:recordId`
```json
{
  "data": {
    "status": "completed"
  }
}
```

### Delete Record
**Endpoint:** `DELETE /api/pages/:id/team-data/:collection/:recordId`

---

## Client-Side JavaScript APIs

When creating pages, these APIs are automatically available based on storage mode:

### SoloData (solo_app mode)
```javascript
await SoloData.ready;  // Always await before using
await SoloData.create('todos', { text: 'Buy milk' });
const { records } = await SoloData.find('todos');
await SoloData.update('todos', recordId, { completed: true });
await SoloData.delete('todos', recordId);
SoloData.getCurrentUser();  // { id, username } or null
SoloData.promptLogin();     // Open login modal
```

### TeamData (team_app mode)
```javascript
await TeamData.ready;
await TeamData.create('tasks', { title: 'New task' });
const { records } = await TeamData.find('tasks', { where: { status: 'active' } });
await TeamData.findMine('tasks');  // Only user's records
await TeamData.update('tasks', recordId, { status: 'done' });
await TeamData.delete('tasks', recordId);
TeamData.isMember();        // Is team member
TeamData.getRole();         // 'owner' | 'admin' | 'member' | 'viewer'
TeamData.canEdit(record);   // Check permission
```

### SocialData (social_app mode)
```javascript
await SocialData.ready;
await SocialData.create('posts', { content: 'Hello!' });
const { records } = await SocialData.find('posts');  // All public records
await SocialData.findMine('posts');  // Only user's records
await SocialData.update('posts', recordId, { content: 'Updated' });  // Owner only
await SocialData.delete('posts', recordId);  // Owner only
SocialData.getCurrentUser();
SocialData.isAuthenticated();
```

### CmsData (page_api_cms capability)

Creator-managed content. Only the page owner can write; all visitors can read.
Paid content can be gated behind membership plans.

```javascript
await CmsData.ready;

// Reading (everyone)
const { records } = await CmsData.find('posts', {
  where: { category: 'news' },
  orderBy: 'created_at',
  order: 'desc',
  limit: 10
});
const post = await CmsData.findById('posts', recordId);

// Writing (creator only)
await CmsData.create('posts', { title: 'Hello', content: '<p>World</p>' });
await CmsData.create('posts', { title: 'Premium' }, { planId: 42 });  // Paid content
await CmsData.update('posts', recordId, { title: 'Updated' });
await CmsData.delete('posts', recordId);

// Identity
CmsData.isCreator();       // true if page owner
CmsData.isAuthenticated(); // true if logged in
CmsData.getCurrentUser();  // { id, username } or null
CmsData.promptLogin();     // open login modal
```

---

## HTML Template

Use this as a starting point for new pages:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Page Title</title>
  <meta name="description" content="Page description">
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      line-height: 1.6;
      color: #1e293b;
      background: #f8fafc;
    }
    .container {
      max-width: 800px;
      margin: 0 auto;
      padding: 40px 20px;
    }
  </style>
</head>
<body data-page-id="{{PAGE_ID}}">
  <div class="container">
    <h1>Hello World</h1>
  </div>

  <script>
    // Your JavaScript here
    // For data storage, use SoloData, TeamData, or SocialData based on storage_mode
  </script>
</body>
</html>
```

---

## Common Patterns

### Wait for SDK and Check Auth
```javascript
async function init() {
  await SocialData.ready;  // MUST await before checking auth

  const user = SocialData.getCurrentUser();
  if (user) {
    console.log('Logged in as', user.username);
    loadUserData();
  } else {
    showLoginPrompt();
  }
}
init();
```

### CRUD with Loading States
```javascript
async function loadItems() {
  showLoading();
  try {
    const { records } = await TeamData.find('items', {
      orderBy: 'created_at',
      order: 'desc'
    });
    renderItems(records);
  } catch (error) {
    showError('Failed to load items');
  } finally {
    hideLoading();
  }
}
```

### Check Ownership for Edit/Delete
```javascript
function renderItem(record) {
  const user = SocialData.getCurrentUser();
  const canModify = user && user.id === record.createdBy.id;

  return `
    <div class="item">
      <span>${record.data.title}</span>
      ${canModify ? '<button onclick="editItem()">Edit</button>' : ''}
    </div>
  `;
}
```

---

## Error Handling

| Status | Meaning |
|--------|---------|
| 200 | Success |
| 201 | Created |
| 400 | Bad request - check parameters |
| 401 | Unauthorized - invalid token |
| 403 | Forbidden - insufficient permissions |
| 404 | Not found |
| 429 | Rate limited - wait and retry |

---

## Full API Reference

For complete endpoint documentation, parameter details, and advanced features, see:
https://visimade.com/developers/api
Using with Claude Code

Start your conversation with Claude Code like this:

My Visimade API token is: vm_your_token_here

See the Visimade documentation at: https://visimade.com/ai-agents/visimade-md

[Your request here - create a page, edit a page, work with data, etc.]

Claude will fetch this page and understand how to work with the Visimade API.

Example Prompts
Create a new page:
My Visimade API token is: vm_abc123...

See the Visimade documentation at: https://visimade.com/ai-agents/visimade-md

Create a habit tracker app with:
- Daily checklist of habits
- Streak counter for each habit
- Weekly overview chart
- Use Solo App mode for private user data
Edit an existing page:
My Visimade API token is: vm_abc123...

See the Visimade documentation at: https://visimade.com/ai-agents/visimade-md

I want to improve this page: /p/my-dashboard

Add dark mode support with a toggle button in the header.
Work with page data:
My Visimade API token is: vm_abc123...

See the Visimade documentation at: https://visimade.com/ai-agents/visimade-md

Look at the tasks in /p/project-board

Find all tasks marked as "blocked" and create a summary
of what's blocking them and suggested next steps.
Full API Reference →Creating Pages GuideEditing Pages GuideWorking with Data Guide
VISIMADE.md - AI Agent Reference