Build an AI Headshot Generator App with AI Pass SDK — Complete Tutorial
Build an AI Headshot Generator App with AI Pass SDK — Complete Tutorial
AI headshot generators are high-demand, easy to build, and generate consistent revenue. This tutorial walks you through building one with the AI Pass SDK.
Why AI Pass SDK?
- Users authenticate with AI Pass — your app never manages billing
- Users pay for their own usage — zero infrastructure overhead for you
- You earn 50% commission on every API call via your Client ID
- Deploy anywhere — GitHub Pages, Netlify, Vercel, or your own server
Step 1: Get Your Client ID
- Sign up at aipass.one and verify your email
- Go to Developer Dashboard → OAuth2 Clients
- Create a new client → copy your Client ID (format:
client_XXXX...)
⚠️ Your Client ID is what tracks commissions. Never use your app slug or API key here.
Step 2: The Core App
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Headshot Generator</title>
<link href="https://aipass.one/aipass-ui.css" rel="stylesheet">
<style>
body { font-family: sans-serif; background: #0f0f10; color: #f0f0f0; max-width: 700px; margin: 0 auto; padding: 40px 20px; }
.upload-zone { border: 2px dashed #444; border-radius: 12px; padding: 40px; text-align: center; cursor: pointer; margin-bottom: 20px; }
.upload-zone:hover { border-color: #16a085; }
.style-btns { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
.style-btn { padding: 10px 16px; border: 2px solid #333; border-radius: 8px; background: #1a1a1c; color: #f0f0f0; cursor: pointer; }
.style-btn.active { border-color: #16a085; background: #1a3a32; }
.gen-btn { width: 100%; padding: 16px; background: #16a085; border: none; border-radius: 10px; color: white; font-size: 1.1rem; font-weight: 600; cursor: pointer; }
.gen-btn:disabled { background: #333; cursor: not-allowed; }
#result { display: none; margin-top: 24px; text-align: center; }
#result img { max-width: 100%; border-radius: 12px; }
.loading { display: none; text-align: center; padding: 30px; color: #888; }
</style>
</head>
<body>
<h1>🎯 AI Headshot Generator</h1>
<p style="color:#888; margin-bottom:24px;">Professional portraits from any photo — in seconds</p>
<div class="upload-zone" onclick="document.getElementById('fileInput').click()">
<div id="uploadPrompt">📷 Click to upload your photo</div>
<img id="preview" style="display:none; max-width:100%; border-radius:8px; margin-top:12px;" />
</div>
<input type="file" id="fileInput" accept="image/*" style="display:none;" onchange="handleFile(this)">
<div class="style-btns">
<button class="style-btn active" onclick="setStyle(this,'corporate')">💼 Corporate</button>
<button class="style-btn" onclick="setStyle(this,'creative')">🎨 Creative</button>
<button class="style-btn" onclick="setStyle(this,'casual')">😊 Casual Pro</button>
<button class="style-btn" onclick="setStyle(this,'executive')">👔 Executive</button>
</div>
<button class="gen-btn" id="genBtn" onclick="generate()" disabled>✨ Generate Headshot</button>
<div class="loading" id="loading">Generating your headshot...</div>
<div id="result">
<img id="resultImg" src="" />
<br>
<a id="dlLink" href="#" download="headshot.png" style="display:inline-block;margin-top:12px;padding:10px 24px;background:#16a085;color:white;border-radius:8px;text-decoration:none;">⬇ Download</a>
</div>
<script src="https://aipass.one/aipass-sdk.js"></script>
<script>
AiPass.initialize({
clientId: 'YOUR_CLIENT_ID', // From Developer Dashboard → OAuth2 Clients
requireLogin: true,
darkMode: true
});
let style = 'corporate', b64 = null, mime = 'image/jpeg';
const prompts = {
corporate: 'Transform into professional corporate headshot. Clean white/gray background, studio lighting, business professional. Keep face exactly.',
creative: 'Transform into creative professional headshot. Soft gradient background, artistic lighting, modern approachable look. Keep face exactly.',
casual: 'Transform into casual professional headshot. Natural blurred background, warm lighting, friendly expression. Keep face exactly.',
executive: 'Transform into executive headshot. Dark premium background, dramatic lighting, authoritative look. Keep face exactly.'
};
function setStyle(btn, s) {
document.querySelectorAll('.style-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active'); style = s;
}
function handleFile(input) {
const file = input.files[0]; if (!file) return;
mime = file.type;
const reader = new FileReader();
reader.onload = e => {
b64 = e.target.result.split(',')[1];
document.getElementById('uploadPrompt').style.display = 'none';
const p = document.getElementById('preview'); p.src = e.target.result; p.style.display = 'block';
document.getElementById('genBtn').disabled = false;
};
reader.readAsDataURL(file);
}
async function generate() {
if (!b64) return;
document.getElementById('genBtn').disabled = true;
document.getElementById('loading').style.display = 'block';
document.getElementById('result').style.display = 'none';
try {
// Use generateCompletion with vision for headshot transformation
const r = await AiPass.generateCompletion({
model: 'gpt-5-mini',
temperature: 1,
max_tokens: 16000,
messages: [{
role: 'user',
content: [
{ type: 'text', text: prompts[style] },
{ type: 'image_url', image_url: { url: `data:${mime};base64,${b64}` } }
]
}]
});
// For image editing, use editImage
const imgResult = await AiPass.editImage({
model: 'gemini/gemini-3-pro-image-preview',
messages: [{
role: 'user',
content: [
{ type: 'text', text: prompts[style] },
{ type: 'image_url', image_url: { url: `data:${mime};base64,${b64}` } }
]
}]
});
const url = imgResult?.data?.[0]?.url;
if (url) {
document.getElementById('resultImg').src = url;
document.getElementById('dlLink').href = url;
document.getElementById('result').style.display = 'block';
}
} catch(e) { console.error(e); alert('Generation failed. Please try again.'); }
finally { document.getElementById('loading').style.display = 'none'; document.getElementById('genBtn').disabled = false; }
}
</script>
</body>
</html>
Key SDK Methods
// Initialize — requireLogin: true shows auth automatically
AiPass.initialize({ clientId: 'YOUR_CLIENT_ID', requireLogin: true, darkMode: true });
// Image editing (for headshot transformation)
const result = await AiPass.editImage({ model: 'gemini/gemini-3-pro-image-preview', messages: [...] });
// → result.data[0].url
// Text + vision (for analysis)
const r = await AiPass.generateCompletion({
model: 'gpt-5-mini',
temperature: 1, // REQUIRED for GPT-5
max_tokens: 16000, // REQUIRED for complete responses
messages: [...]
});
// → r.choices[0].message.content
Deploy Options
Option A: Self-host anywhere
# Netlify (instant)
netlify deploy --dir . --prod
# GitHub Pages: push to repo, enable Pages in settings
Option B: Publish on AI Pass catalog
Publish directly at aipass.one/apps/your-app — includes an embed </> button for iframe code.
curl -X POST https://aipass.one/api/v1/apps \
-H "Authorization: Bearer $AIPASS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"My Headshot App","slug":"my-headshot","appType":"HOSTED","htmlContent":"<html>..."}'
curl -X POST https://aipass.one/api/v1/apps/my-headshot/publish \
-H "Authorization: Bearer $AIPASS_API_KEY"
Earning Commission
Every headshot generation via your app earns you 50% commission on the API call margin. Verified email required for payouts.
Live demo: aipass.one/apps/ai-headshot SDK docs: aipass.one/docs/sdk/reference.html Developer Dashboard: aipass.one/panel/developer.html