InstantSplat / API_TYPESCRIPT.md
Long Hoang
Use Supabase for outputs and add Python/TS API clients
1575924

A newer version of the Gradio SDK is available: 6.6.0

Upgrade

InstantSplat TypeScript API Client

Complete TypeScript/JavaScript client for InstantSplat API with full type safety.

🚀 Quick Start

Installation

npm install @gradio/client @types/node ts-node tsx

Basic Usage

import { processImages } from "./api_client";

const result = await processImages(
  ["img1.jpg", "img2.jpg", "img3.jpg"],
  "your-username/InstantSplat"
);

if (result.status === "success") {
  console.log("GLB URL:", result.glb_url);
  console.log("PLY URL:", result.ply_url);
}

📦 Available Functions

processImages(imagePaths, spaceUrl?)

Submit images and get back URLs.

async function processImages(
  imagePaths: string[],
  spaceUrl?: string
): Promise<ProcessResult>

Parameters:

  • imagePaths: Array of local image file paths
  • spaceUrl: (Optional) HuggingFace Space URL or env var INSTANTSPLAT_SPACE

Returns:

interface ProcessResult {
  status: "success" | "error";
  glb_url?: string;
  ply_url?: string;
  video_available?: boolean;
  error?: string;
  message?: string;
}

Example:

const result = await processImages(
  ["img1.jpg", "img2.jpg", "img3.jpg"],
  "username/InstantSplat"
);

console.log(result.glb_url); // Supabase URL to GLB file

completeWorkflow(imagePaths, outputDir, spaceUrl?)

Process images and download the GLB file.

async function completeWorkflow(
  imagePaths: string[],
  outputDir?: string,
  spaceUrl?: string
): Promise<string | null>

Parameters:

  • imagePaths: Array of image paths
  • outputDir: Local directory for downloaded file (default: ./outputs)
  • spaceUrl: (Optional) Space URL

Returns: Local path to downloaded GLB file, or null on error

Example:

const localPath = await completeWorkflow(
  ["img1.jpg", "img2.jpg", "img3.jpg"],
  "./my_models"
);

console.log("Model saved to:", localPath);
// Output: Model saved to: ./my_models/model.glb

downloadFile(url, outputPath)

Download a file from URL.

async function downloadFile(
  url: string,
  outputPath: string
): Promise<void>

🛠️ CLI Usage

Using npx

npx tsx api_client.ts img1.jpg img2.jpg img3.jpg

Using npm script

npm run api img1.jpg img2.jpg img3.jpg

With environment variable

export INSTANTSPLAT_SPACE="username/InstantSplat"
npx tsx api_client.ts img1.jpg img2.jpg img3.jpg

📝 Examples

Example 1: Simple Usage

import { processImages } from "./api_client";

async function main() {
  const result = await processImages(
    ["image1.jpg", "image2.jpg", "image3.jpg"],
    "username/InstantSplat"
  );

  if (result.status === "success") {
    console.log("✅ GLB URL:", result.glb_url);
    console.log("✅ PLY URL:", result.ply_url);
  } else {
    console.error("❌ Error:", result.error);
  }
}

main();

Example 2: With Error Handling

import { processImages } from "./api_client";

async function processWithRetry(
  images: string[],
  maxRetries = 3
): Promise<ProcessResult> {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const result = await processImages(images);

    if (result.status === "success") {
      return result;
    }

    if (attempt < maxRetries) {
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }

  throw new Error("All retries failed");
}

Example 3: Batch Processing

import { processImages } from "./api_client";

async function batchProcess(imageSets: string[][]) {
  const results = [];

  for (let i = 0; i < imageSets.length; i++) {
    console.log(`Processing set ${i + 1}/${imageSets.length}...`);
    
    const result = await processImages(imageSets[i]);
    results.push(result);

    // Rate limiting
    await new Promise(resolve => setTimeout(resolve, 2000));
  }

  return results;
}

const sets = [
  ["scene1_img1.jpg", "scene1_img2.jpg"],
  ["scene2_img1.jpg", "scene2_img2.jpg"],
];

const results = await batchProcess(sets);

Example 4: Download and Use

import { completeWorkflow } from "./api_client";

async function processAndDownload() {
  const modelPath = await completeWorkflow(
    ["img1.jpg", "img2.jpg", "img3.jpg"],
    "./models"
  );

  if (modelPath) {
    console.log(`Model ready at: ${modelPath}`);
    // Use the model file...
  }
}

🌐 Integration Examples

Express.js API

import express from "express";
import { processImages } from "./api_client";

const app = express();
app.use(express.json());

app.post("/api/process", async (req, res) => {
  const { images } = req.body;

  const result = await processImages(
    images,
    process.env.INSTANTSPLAT_SPACE
  );

  if (result.status === "success") {
    res.json({
      success: true,
      glb_url: result.glb_url,
      ply_url: result.ply_url
    });
  } else {
    res.status(500).json({
      success: false,
      error: result.error
    });
  }
});

app.listen(3000);

Next.js API Route

// pages/api/process.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { processImages } from "../../api_client";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== "POST") {
    return res.status(405).json({ error: "Method not allowed" });
  }

  const { images } = req.body;

  const result = await processImages(
    images,
    process.env.INSTANTSPLAT_SPACE
  );

  if (result.status === "success") {
    res.status(200).json(result);
  } else {
    res.status(500).json(result);
  }
}

React Hook

import { useState } from "react";
import { processImages } from "./api_client";

function useInstantSplat() {
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState<ProcessResult | null>(null);

  const process = async (images: string[]) => {
    setLoading(true);
    try {
      const res = await processImages(images);
      setResult(res);
      return res;
    } finally {
      setLoading(false);
    }
  };

  return { process, loading, result };
}

// Usage in component:
function MyComponent() {
  const { process, loading, result } = useInstantSplat();

  const handleSubmit = () => {
    process(["img1.jpg", "img2.jpg", "img3.jpg"]);
  };

  return (
    <div>
      {loading && <p>Processing...</p>}
      {result?.glb_url && <a href={result.glb_url}>Download Model</a>}
    </div>
  );
}

Vue.js Composable

import { ref } from "vue";
import { processImages } from "./api_client";

export function useInstantSplat() {
  const loading = ref(false);
  const result = ref(null);

  const process = async (images: string[]) => {
    loading.value = true;
    try {
      result.value = await processImages(images);
    } finally {
      loading.value = false;
    }
  };

  return { process, loading, result };
}

📚 Type Definitions

interface ProcessResult {
  status: "success" | "error";
  glb_url?: string;           // Supabase URL to GLB file
  ply_url?: string;           // Supabase URL to PLY file
  video_available?: boolean;  // Whether video was generated
  error?: string;             // Error message if status is "error"
  message?: string;           // Success message
}

interface InstantSplatResponse {
  video_path: string;    // [0] Path to video
  ply_url: string;       // [1] PLY URL
  ply_download: string;  // [2] PLY download
  ply_model: string;     // [3] PLY model
  glb_model: string;     // [4] GLB model path
  glb_url: string;       // [5] GLB URL (Supabase)
}

⚙️ Configuration

Environment Variables

# .env
INSTANTSPLAT_SPACE=username/InstantSplat

package.json Scripts

Add to your package.json:

{
  "scripts": {
    "api": "npx tsx api_client.ts",
    "process": "npx tsx example_api_usage.ts"
  }
}

🔧 Troubleshooting

"Cannot find module '@gradio/client'"

npm install @gradio/client

"Cannot find name 'require'"

Add to your tsconfig.json:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

TypeScript errors

Make sure you have the types installed:

npm install --save-dev @types/node

Import errors

If using ES modules, change imports:

// CommonJS
const { processImages } = require("./api_client");

// ES Modules
import { processImages } from "./api_client.js";

📦 Building for Production

Compile TypeScript

npx tsc api_client.ts

Bundle with esbuild

npx esbuild api_client.ts --bundle --platform=node --outfile=dist/api_client.js

Use in production

// Import the compiled version
import { processImages } from "./dist/api_client.js";

🎯 Best Practices

  1. Rate Limiting: Add delays between batch requests
  2. Error Handling: Always wrap in try-catch
  3. Retries: Implement exponential backoff
  4. Timeouts: Set reasonable timeouts for large images
  5. Validation: Check image files exist before uploading

📖 More Examples

See example_api_usage.ts for complete working examples including:

  • Simple usage
  • Complete workflow with download
  • Batch processing
  • Error handling with retries
  • Express.js integration
  • React component integration

🆘 Support

  • Check API_GUIDE.md for general API documentation
  • Check API_QUICKSTART.md for quick start guide
  • Review example_api_usage.ts for working examples

🔗 Related Files

  • api_client.ts - Main TypeScript client
  • api_client.py - Python equivalent
  • example_api_usage.ts - Usage examples
  • API_GUIDE.md - Complete API documentation
  • API_QUICKSTART.md - Quick start guide