Build an AI Photo Enhancer App - Complete Tutorial
Build an AI Photo Enhancer App - Complete Tutorial
Learn how to build an AI photo enhancer web app using the AI Pass SDK. This step-by-step guide covers everything from account setup to deployment, with real code examples.
What We're Building
An AI photo enhancer that:
- Accepts image uploads from users
- Enhances photo quality using AI
- Downloads the improved image
- Handles errors gracefully
Users pay AI Pass directly—you earn 50% commission on every API call.
Prerequisites
- Basic HTML/CSS/JavaScript knowledge
- An AI Pass account (free to create)
- A text editor or IDE
Step 1: Create Your AI Pass Account
- Go to https://aipass.one
- Click "Sign Up" in the top-right corner
- Enter your email and create a password
- Verify your email address
- You get $1 free credit automatically
Step 2: Create an OAuth2 Client
To use the SDK and earn commission, you need an OAuth2 client:
- Go to the Developer Dashboard
- Click "OAuth2 Clients" in the sidebar
- Click "Create New Client"
- Enter a name (e.g., "My Photo Enhancer App")
- Copy your Client ID (looks like
client_abc123xyz...)
Important: This Client ID is from the OAuth2 Clients page—NOT your app slug!
Step 3: Initialize the AI Pass SDK
Create an index.html file and add the SDK:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Photo Enhancer</title>
<link href="https://aipass.one/aipass-ui.css" rel="stylesheet">
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
text-align: center;
}
.upload-area {
border: 3px dashed #ccc;
padding: 40px;
margin: 20px 0;
border-radius: 10px;
cursor: pointer;
}
.upload-area:hover {
border-color: #007bff;
background-color: #f8f9fa;
}
.result-area {
margin: 20px 0;
display: none;
}
.image-container {
display: flex;
gap: 20px;
justify-content: center;
flex-wrap: wrap;
}
.image-box {
border: 1px solid #ddd;
padding: 10px;
border-radius: 5px;
}
.image-box img {
max-width: 300px;
max-height: 300px;
}
button {
padding: 12px 24px;
font-size: 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin: 10px 5px;
}
button:hover {
background-color: #0056b3;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.error {
color: red;
margin: 10px 0;
}
#loading {
display: none;
margin: 20px 0;
}
</style>
</head>
<body>
<h1>📷 AI Photo Enhancer</h1>
<p>Upload a photo to enhance its quality automatically</p>
<div class="upload-area" id="uploadArea">
<p>📁 Drop your photo here or click to upload</p>
<input type="file" id="fileInput" accept="image/*" style="display: none;">
</div>
<button id="enhanceBtn" disabled>✨ Enhance Photo</button>
<div id="loading">⏳ Processing...</div>
<div id="error" class="error"></div>
<div class="result-area" id="resultArea">
<div class="image-container">
<div class="image-box">
<h3>Original</h3>
<img id="originalImage" alt="Original photo">
</div>
<div class="image-box">
<h3>Enhanced</h3>
<img id="enhancedImage" alt="Enhanced photo">
</div>
</div>
<br>
<button id="downloadBtn">⬇️ Download Enhanced</button>
</div>
<script src="https://aipass.one/aipass-sdk.js"></script>
<script>
// Initialize SDK with your Client ID
// Replace YOUR_CLIENT_ID with your actual OAuth2 Client ID from Developer Dashboard
AiPass.initialize({
clientId: 'YOUR_CLIENT_ID',
requireLogin: true, // Shows built-in login modal automatically
darkMode: false
});
// DOM elements
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('fileInput');
const enhanceBtn = document.getElementById('enhanceBtn');
const loading = document.getElementById('loading');
const error = document.getElementById('error');
const resultArea = document.getElementById('resultArea');
const originalImage = document.getElementById('originalImage');
const enhancedImage = document.getElementById('enhancedImage');
const downloadBtn = document.getElementById('downloadBtn');
let uploadedFile = null;
let enhancedImageUrl = null;
// Handle file upload
uploadArea.addEventListener('click', () => fileInput.click());
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.style.borderColor = '#007bff';
});
uploadArea.addEventListener('dragleave', () => {
uploadArea.style.borderColor = '#ccc';
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.style.borderColor = '#ccc';
if (e.dataTransfer.files.length) {
handleFile(e.dataTransfer.files[0]);
}
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length) {
handleFile(e.target.files[0]);
}
});
function handleFile(file) {
if (!file.type.startsWith('image/')) {
showError('Please upload an image file');
return;
}
uploadedFile = file;
enhanceBtn.disabled = false;
error.textContent = '';
resultArea.style.display = 'none';
// Show preview
const reader = new FileReader();
reader.onload = (e) => {
originalImage.src = e.target.result;
};
reader.readAsDataURL(file);
}
// Enhance photo
enhanceBtn.addEventListener('click', async () => {
if (!uploadedFile) return;
enhanceBtn.disabled = true;
loading.style.display = 'block';
error.textContent = '';
resultArea.style.display = 'none';
try {
// Read file as base64
const base64 = await fileToBase64(uploadedFile);
// Use AI image enhancement via chat completions
const response = await AiPass.generateCompletion({
model: 'gemini/gemini-3-pro-image-preview',
messages: [{
role: 'user',
content: [
{
type: 'text',
text: 'Enhance this photo quality. Improve sharpness, reduce noise, fix lighting issues. Return the enhanced image URL.'
},
{
type: 'image_url',
image_url: {
url: base64
}
}
]
}],
temperature: 1,
max_tokens: 16000
});
// Parse response - Gemini returns image URL in text
const enhancedUrl = extractImageUrl(response.choices[0].message.content);
if (enhancedUrl) {
enhancedImage.src = enhancedUrl;
enhancedImageUrl = enhancedUrl;
resultArea.style.display = 'block';
} else {
showError('Failed to enhance photo. Please try again.');
}
} catch (err) {
console.error('Error:', err);
showError(err.message || 'Failed to enhance photo. Please try again.');
} finally {
enhanceBtn.disabled = false;
loading.style.display = 'none';
}
});
// Download enhanced image
downloadBtn.addEventListener('click', () => {
if (enhancedImageUrl) {
const a = document.createElement('a');
a.href = enhancedImageUrl;
a.download = 'enhanced-photo.png';
a.click();
}
});
// Helper functions
function fileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
function extractImageUrl(text) {
// Try to extract URL from response
const urlMatch = text.match(/https?:\/\/[^\s\)]+\.(png|jpg|jpeg|webp)/i);
return urlMatch ? urlMatch[0] : null;
}
function showError(message) {
error.textContent = message;
}
</script>
</body>
</html>
Critical: Replace YOUR_CLIENT_ID with your actual Client ID from the Developer Dashboard → OAuth2 Clients page.
Step 4: Test Your App
- Open
index.htmlin your browser - Click the "AI Pass" button (bottom-right) to sign in
- Upload a photo
- Click "Enhance Photo"
- Wait for AI to process
- Download your enhanced image
The first time you click the AI Pass button, it will show a login modal. After signing in, your balance appears on the button.
Step 5: Deploy Your App
You have two deployment options:
Option A: Self-Host Anywhere
Host your app wherever you want:
- GitHub Pages (free)
- Netlify (free tier)
- Vercel (free tier)
- Your own server
- Any static hosting
Just upload index.html and the SDK handles everything else—billing, authentication, API calls.
Option B: Publish on AI Pass Catalog
Get a dedicated page on aipass.one with embed functionality:
- Go to the Apps Dashboard
- Click "Create New App"
- Fill in details (name: "My Photo Enhancer", category: "utility")
- Upload your HTML as "Hosted" content
- Publish the app
Users can then access your app at https://aipass.one/apps/your-app-slug and use the </> embed button.
How the Revenue Model Works
- Users pay AI Pass directly for API calls
- AI Pass adds a commission on each call
- You earn 50% of that commission
Example: If a user generates 10 enhanced photos and AI Pass charges $0.10 total:
- Commission: $0.02 (20%)
- Your earnings: $0.01 (50% of commission)
Payments are sent to your verified email address.
SDK Methods Used
AiPass.initialize(config)
clientId: Your OAuth2 Client ID (from Developer Dashboard)requireLogin: true: Shows login modal automaticallydarkMode: Enable dark mode for modals
AiPass.generateCompletion(options)
model: AI model to usemessages: Array of message objectstemperature: 1: Required for GPT-5 modelsmax_tokens: 16000: Required for GPT-5 models- Returns:
response.choices[0].message.content
AiPassUI (Automatic)
The requireLogin: true setting automatically:
- Shows login modal when needed
- Displays user balance on the button
- Shows payment modal when budget exceeded
- Handles all authentication state
Troubleshooting
"Client ID not found"
Make sure you're using the Client ID from OAuth2 Clients page, not the app slug.
"Login required"
The SDK should show a login modal automatically. If not, check that requireLogin: true is set in initialization.
No response from API
Check your browser console for errors. Verify your Client ID is correct and you have sufficient balance.
Image not enhancing
Make sure you're using a valid image format (JPG, PNG, WEBP) and the file size is reasonable (<10MB recommended).
Next Steps
- Add more features: Batch processing, different enhancement levels, comparison slider
- Improve UI: Better loading states, progress indicators, error handling
- Add analytics: Track usage, popular features, user behavior
- Promote your app: Share on social media, submit to directories
Full Code Reference
All code is available above. Copy-paste into index.html and replace YOUR_CLIENT_ID with your OAuth2 Client ID.
Happy building! 🚀
SDK Documentation: https://aipass.one/docs/sdk/reference.html Developer Dashboard: https://aipass.one/panel/developer.html Related App: AI Photo Enhancer