VISIMADE
← Developer Hub

Getting Started

  • Authentication
  • AI Coding Agents

Core APIs

  • Pages API
  • Page Assets API
  • Page API Features
  • Functions API

Data APIs

Guides

Reference

Page API Features

AI-powered features that visitors can use on your pages, including AI Chat, Image Generation, and Image Search.

Pages can include AI-powered features that visitors can use. These features are accessed via JavaScript in your page's HTML. To enable them, your page must include data-page-id="{{PAGE_ID}}" in the body tag. Enable each feature via the dashboard toggle or the page_api_*_enabled fields in the Pages API.

Required Setup

All Page API features require the page ID to be embedded in the HTML:

<!-- In your HTML body tag -->
<body data-page-id="{{PAGE_ID}}">

<script>
  // In your JavaScript
  const PAGE_ID = document.body.dataset.pageId;
</script>

AI Chat API

Add AI chat/completion features to your page. Users must be logged in and have credits. 1 credit = 2,500 tokens. A typical request uses ~500-1500 tokens.

Endpoint
POST

/api/pages/:id/page-api-ai

Send messages to AI and get responses

Request Body
FieldTypeDescription
system_promptstringInstructions for the AI (required)
messagesarrayChat history: [{role: 'user', content: '...'}]
streambooleanWhether to stream the response (default: false)
maxTokensnumberMax output tokens: 1024 (default) to 4096 (max)
Example
async function callAI(messages) {
  const response = await fetch('/api/pages/' + PAGE_ID + '/page-api-ai', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({
      system_prompt: 'You are a helpful assistant. Respond in JSON format.',
      messages: messages,
      stream: false,
      maxTokens: 1024
    })
  });

  if (response.status === 401) return { error: 'auth_required' };
  if (response.status === 402) {
    const data = await response.json();
    if (data.consent_required) return { error: 'consent_required' };
    if (data.insufficient_credits) return { error: 'insufficient_credits' };
  }

  return await response.json();
}

AI Image Generation API

Generate AI images from text prompts. Users must be logged in and have credits.

Endpoint
POST

/api/pages/:id/page-api-image-gen

Generate an AI image from a prompt

Request Body
FieldTypeDescription
promptstringDescription of the image to generate (required)
aspectRatiostringAspect ratio: "1:1", "16:9", "9:16", "4:3", "3:4" (default: "1:1")
Example
async function generateImage(prompt, aspectRatio) {
  const response = await fetch('/api/pages/' + PAGE_ID + '/page-api-image-gen', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ prompt: prompt, aspectRatio: aspectRatio || '1:1' })
  });

  if (response.status === 401) return { error: 'auth_required' };
  if (response.status === 402) {
    const data = await response.json();
    if (data.consent_required) return { error: 'consent_required' };
    if (data.insufficient_credits) return { error: 'insufficient_credits' };
  }
  if (!response.ok) return { error: 'generation_failed' };

  return await response.json();  // { image_url: '...' }
}

// Usage:
const result = await generateImage('A sunset over mountains', '16:9');
if (!result.error) {
  document.getElementById('myImage').src = result.image_url;
}

Search for real images from the web (logos, photos, etc.). Rate limited but no credits required. Use this for existing images like company logos; use Image Generation for custom/artistic images.

Endpoint
POST

/api/pages/:id/page-api-image-search

Search for images from Google

Request Body
FieldTypeDescription
querystringSearch query (required), e.g., "Microsoft logo"
countnumberNumber of results: 1-10 (default: 10)
Response
{
  "success": true,
  "query": "Microsoft logo",
  "results": [
    {
      "title": "Microsoft Logo PNG",
      "thumbnail": "https://...",   // Small, reliable
      "original": "https://...",    // Full-size (may break)
      "source": "microsoft.com",
      "link": "https://...",
      "width": 1200,
      "height": 630
    }
  ]
}
Example
async function searchImages(query, count = 10) {
  const response = await fetch('/api/pages/' + PAGE_ID + '/page-api-image-search', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ query, count })
  });

  if (response.status === 401) return { error: 'auth_required' };
  if (response.status === 429) return { error: 'rate_limited' };
  if (!response.ok) return { error: 'search_failed' };

  return await response.json();
}

// Usage:
const result = await searchImages('Apple logo official PNG', 5);
if (result.results?.length > 0) {
  const img = document.getElementById('logo');
  img.src = result.results[0].original;
  img.onerror = () => { img.src = result.results[0].thumbnail; };
}

Tip: Original URLs are from third-party sites and may break. Always add onerror fallback to thumbnail.


Image Recognition API

Analyze images with AI using Google Gemini vision. Extract text (OCR), classify objects, describe scenes, read handwriting, parse documents, and more. Users must be logged in and have credits. Costs 1 credit per call.

Endpoint
POST

/api/pages/:id/page-api-image-recognition

Analyze an image with AI vision

Request Body
FieldTypeDescription
promptstringInstructions for what to analyze/extract (required, max 4000 chars)
image_urlstringURL of the image to analyze (provide this OR image_base64)
image_base64stringBase64-encoded image data (provide this OR image_url)
mime_typestringMIME type of the image (default: "image/jpeg"). Use with image_base64.
Prefer image_url over image_base64

Base64-encoded images can be very large (5-15MB for phone photos). Use image_url when possible to avoid request size limits. If your page uploads images via TeamData, pass the uploaded file's URL instead of re-encoding it.

Response
{
  "success": true,
  "text": "The image shows a handwritten note with the following text...",
  "credits": { "deducted": 1, "remaining": 49 }
}
Error Responses
StatusBodyMeaning
401{error: 'auth_required'}User not logged in
402{consent_required: true}User must consent to credit usage (first time)
402{insufficient_credits: true}User has no credits remaining
403{error: 'image_recognition_disabled'}Feature not enabled for this page
429{error: 'rate_limited'}Too many requests (30/min per user per page)
Example: Analyze Image from URL
async function analyzeImage(prompt, imageInput) {
  const response = await fetch('/api/pages/' + PAGE_ID + '/page-api-image-recognition', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ prompt, ...imageInput })
  });

  if (response.status === 401) return { error: 'auth_required' };
  if (response.status === 402) {
    const data = await response.json();
    if (data.consent_required) return { error: 'consent_required', ...data };
    if (data.insufficient_credits) return { error: 'insufficient_credits' };
  }
  if (response.status === 429) return { error: 'rate_limited' };
  if (!response.ok) return { error: 'recognition_failed' };

  return await response.json();
}

// Usage with image URL (preferred):
const result = await analyzeImage(
  'Extract all text from this document',
  { image_url: 'https://example.com/receipt.jpg' }
);
console.log(result.text);
Example: Analyze from File Upload
// When user selects a file via <input type="file">
fileInput.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  if (!file) return;

  const reader = new FileReader();
  reader.onload = async () => {
    const base64 = reader.result.split(',')[1];
    const result = await analyzeImage(
      'Describe what you see in this image',
      { image_base64: base64, mime_type: file.type }
    );
    if (result.text) {
      document.getElementById('output').textContent = result.text;
    }
  };
  reader.readAsDataURL(file);
});
Example: Using with TeamData Uploads

If your page uploads files via TeamData, pass the file URL directly — no need to re-send the bytes:

// After uploading a file via TeamData
const uploaded = await TeamData.uploadFile('photos', file);
// uploaded.url contains the file URL

// Analyze it without re-sending the image bytes
const result = await analyzeImage(
  'Identify all items in this photo and estimate quantities',
  { image_url: uploaded.url }
);
Use Cases
  • OCR / text extraction from images and documents
  • Receipt and invoice parsing
  • Handwriting recognition
  • Object detection and classification
  • Scene description
  • Chart and diagram interpretation
  • Product identification

On this page

  • Required Setup
  • AI Chat API
  • AI Image Generation
  • Image Search API
  • Image Recognition API