Skybox AI Quick Start: Building Your First Integration Skybox AI Quick Start: Building Your First Integration

Skybox AI Quick Start: Building Your First Integration

Overview

This tutorial walks you through building a simple web application that generates 360° skyboxes using the Skybox AI API. You'll learn the core concepts and build a working prototype in under 30 minutes.

What You'll Build:

  • A simple web form for text prompt input
  • API integration with proper authentication
  • Generation status tracking
  • Display of the completed skybox

Prerequisites:

  • Basic JavaScript/Node.js knowledge
  • A Skybox AI account with API access
  • Node.js installed on your machine

Step 1: Get Your API Key (5 minutes)

  1. Log in to skybox.blockadelabs.com
  2. Navigate to your API settings https://skybox.blockadelabs.com/api
  3. Create and copy your API key (keep this secure!)

Important: Never expose your API key in client-side code. Always use it server-side.


Step 2: Set Up Your Project (5 minutes)

Create a new directory and initialize your project:

 
bash
mkdir skybox-demo
cd skybox-demo
npm init -y
npm install express axios dotenv

Create a .env file for your API key:

 
SKYBOX_API_KEY=your_api_key_here

Security Note: Add .env to your .gitignore file immediately.


Step 3: Create Your Backend (10 minutes)

Create server.js:

 
javascript
require('dotenv').config();
const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json());
app.use(express.static('public'));

const SKYBOX_API = 'https://backend.blockadelabs.com/api/v1';
const API_KEY = process.env.SKYBOX_API_KEY;

// Generate skybox endpoint
app.post('/api/generate', async (req, res) => {
  try {
    const { prompt, styleId } = req.body;
    
    const response = await axios.post(
      `${SKYBOX_API}/skybox`,
      {
        prompt: prompt,
        skybox_style_id: styleId || 1
      },
      {
        headers: {
          'x-api-key': API_KEY,
          'Content-Type': 'application/json'
        }
      }
    );
    
    res.json(response.data);
  } catch (error) {
    console.error('Generation error:', error.response?.data || error.message);
    res.status(500).json({ 
      error: 'Failed to generate skybox',
      details: error.response?.data 
    });
  }
});

// Check status endpoint
app.get('/api/status/:id', async (req, res) => {
  try {
    const response = await axios.get(
      `${SKYBOX_API}/imagine/requests/${req.params.id}`,
      {
        headers: {
          'x-api-key': API_KEY
        }
      }
    );
    
    res.json(response.data);
  } catch (error) {
    console.error('Status check error:', error.response?.data || error.message);
    res.status(500).json({ error: 'Failed to check status' });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

Step 4: Create Your Frontend (10 minutes)

Create a public directory, then create public/index.html:

 
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Skybox AI Demo</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input, select, button {
            width: 100%;
            padding: 10px;
            font-size: 16px;
        }
        button {
            background-color: #007bff;
            color: white;
            border: none;
            cursor: pointer;
            margin-top: 10px;
        }
        button:hover {
            background-color: #0056b3;
        }
        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        #status {
            margin-top: 20px;
            padding: 15px;
            border-radius: 5px;
        }
        .info { background-color: #d1ecf1; }
        .success { background-color: #d4edda; }
        .error { background-color: #f8d7da; }
        #result {
            margin-top: 20px;
        }
        #skybox-image {
            width: 100%;
            border-radius: 10px;
        }
    </style>
</head>
<body>
    <h1>Skybox AI Generator</h1>
    
    <div class="form-group">
        <label for="prompt">Scene Description:</label>
        <input 
            type="text" 
            id="prompt" 
            placeholder="e.g., A futuristic city at sunset with neon lights"
        >
    </div>
    
    <div class="form-group">
        <label for="style">Style:</label>
        <select id="style">
            <option value="1">Fantasy Landscape</option>
            <option value="2">Sci-Fi</option>
            <option value="3">Modern Interior</option>
            <option value="10">Digital Painting</option>
        </select>
    </div>
    
    <button id="generateBtn" onclick="generateSkybox()">Generate Skybox</button>
    
    <div id="status"></div>
    <div id="result"></div>
    
    <script>
        let checkInterval;
        
        async function generateSkybox() {
            const prompt = document.getElementById('prompt').value;
            const styleId = document.getElementById('style').value;
            const statusDiv = document.getElementById('status');
            const resultDiv = document.getElementById('result');
            const generateBtn = document.getElementById('generateBtn');
            
            if (!prompt) {
                alert('Please enter a scene description');
                return;
            }
            
            // Reset UI
            resultDiv.innerHTML = '';
            statusDiv.className = 'info';
            statusDiv.textContent = 'Submitting request...';
            generateBtn.disabled = true;
            
            try {
                // Submit generation request
                const response = await fetch('/api/generate', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ prompt, styleId: parseInt(styleId) })
                });
                
                const data = await response.json();
                
                if (!response.ok) {
                    throw new Error(data.error || 'Generation failed');
                }
                
                // Start checking status
                checkStatus(data.obfuscated_id);
                
            } catch (error) {
                statusDiv.className = 'error';
                statusDiv.textContent = `Error: ${error.message}`;
                generateBtn.disabled = false;
            }
        }
        
        async function checkStatus(skyboxId) {
            const statusDiv = document.getElementById('status');
            const resultDiv = document.getElementById('result');
            const generateBtn = document.getElementById('generateBtn');
            
            statusDiv.className = 'info';
            statusDiv.textContent = 'Generation in progress...';
            
            checkInterval = setInterval(async () => {
                try {
                    const response = await fetch(`/api/status/${skyboxId}`);
                    const data = await response.json();
                    
                    if (data.status === 'pending' || data.status === 'dispatched') {
                        statusDiv.textContent = `Status: ${data.status}... Please wait.`;
                    } else if (data.status === 'processing') {
                        statusDiv.textContent = 'Processing your skybox... Almost there!';
                    } else if (data.status === 'complete') {
                        clearInterval(checkInterval);
                        statusDiv.className = 'success';
                        statusDiv.textContent = 'Skybox generated successfully!';
                        
                        resultDiv.innerHTML = `
                            <h3>Your Skybox:</h3>
                            <img id="skybox-image" src="${data.file_url}" alt="Generated Skybox">
                            <p><a href="${data.file_url}" target="_blank">Open Full Size</a></p>
                        `;
                        
                        generateBtn.disabled = false;
                    } else if (data.status === 'error' || data.status === 'abort') {
                        clearInterval(checkInterval);
                        statusDiv.className = 'error';
                        statusDiv.textContent = `Generation failed: ${data.error_message || data.status}`;
                        generateBtn.disabled = false;
                    }
                    
                } catch (error) {
                    clearInterval(checkInterval);
                    statusDiv.className = 'error';
                    statusDiv.textContent = `Error checking status: ${error.message}`;
                    generateBtn.disabled = false;
                }
            }, 3000); // Check every 3 seconds
        }
    </script>
</body>
</html>

Step 5: Run Your Application

Start the server:

 
bash
node server.js

Open your browser to http://localhost:3000


Understanding the Code

Backend (server.js):

  • /api/generate - Submits a generation request to Skybox AI
  • /api/status/:id - Polls for generation status
  • API key is kept secure on the server side

Frontend (index.html):

  • Simple form for prompt and style input
  • Submits request via backend
  • Polls status every 3 seconds
  • Displays completed skybox image

What's Happening Behind the Scenes

  1. User submits prompt → Frontend sends to your backend
  2. Backend calls Skybox AI API → Returns generation ID and initial status
  3. Frontend polls status → Checks every 3 seconds for completion
  4. Generation completes → Display the skybox image URL

Typical Timeline:

  • Queue time: 0-30 seconds (depends on traffic)
  • Generation time: 25-45 seconds
  • Total: ~30-75 seconds

Common Issues and Solutions

"Failed to generate skybox"

  • Check your API key is correct in .env
  • Verify you have available generations in your quota
  • Check the console for detailed error messages

Status stuck on "pending"

  • Normal during high traffic periods
  • The queue system is working as expected
  • Generation will process when capacity available

"Rate limit exceeded"

  • You've hit your generations per minute limit
  • Wait for the next minute window
  • Consider upgrading your plan

"Cannot GET /"

  • Make sure you created the public directory
  • Verify index.html is inside the public folder
  • Check that app.use(express.static('public')); is in your server.js

Next Steps

Now that you have a working integration, consider:

Enhanced Integration Guide - Check out our follow-up guide for more enhanced integrations

  1. Enhance Prompt and Strict Prompt - Moderate customer prompt requests.
  2. Style selection - Fetch styles via API and populate dropdown
  3. Image caching - Store generated skyboxes locally
  4. Remix functionality - Allow users to remix existing generations
  5. Export options - Add buttons for different export formats

Additional Resources

  • Full API Documentation: api-documentation.blockadelabs.com
  • Service Status: status.blockadelabs.com

Congratulations! You've built your first Skybox AI integration. This foundation can be expanded into full production applications.