Build an AI Color Season Analyzer App with AI Pass SDK — Complete Tutorial
Build an AI Color Season Analyzer App with AI Pass SDK — Complete Tutorial
Color season analysis is viral. The demand for a good AI-powered version is real and growing. This tutorial builds one using the AI Pass SDK's multimodal capabilities.
What You'll Build
Users upload a selfie → AI analyzes skin undertone, hair, and eyes → Returns season type (Spring/Summer/Autumn/Winter) + personalized hex color palette.
Step 1: Get Your Client ID
- Sign up at aipass.one, verify email
- Developer Dashboard → OAuth2 Clients → Create client
- Copy Client ID
Step 2: The App
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AI Color Season Analyzer</title>
<link href="https://aipass.one/aipass-ui.css" rel="stylesheet">
<style>
body { font-family: sans-serif; background: #faf8f5; color: #2a2a2a; max-width: 680px; margin: 0 auto; padding: 40px 20px; }
.upload-zone { border: 2px dashed #ddd; border-radius: 14px; padding: 36px; text-align: center; cursor: pointer; background: white; margin-bottom: 20px; }
.upload-zone:hover { border-color: #c47ab5; }
.upload-zone img { max-width: 100%; max-height: 240px; border-radius: 8px; margin-top: 12px; }
.tips { background: #fff8f0; border: 1px solid #ffe0b0; border-radius: 8px; padding: 12px 16px; font-size: 0.88rem; color: #885500; margin-bottom: 20px; }
.analyze-btn { width: 100%; padding: 15px; background: linear-gradient(135deg, #c47ab5, #e090c8); border: none; border-radius: 12px; color: white; font-size: 1.05rem; font-weight: 600; cursor: pointer; }
.analyze-btn:disabled { background: #ccc; cursor: not-allowed; }
.loading { display: none; text-align: center; padding: 30px; color: #888; }
.result { display: none; margin-top: 28px; }
.season-badge { text-align: center; padding: 28px; border-radius: 14px; margin-bottom: 20px; }
.spring { background: linear-gradient(135deg, #fff0e8, #ffe0d0); }
.summer { background: linear-gradient(135deg, #e8f0ff, #d8e8f8); }
.autumn { background: linear-gradient(135deg, #fff4e0, #ffe8c0); }
.winter { background: linear-gradient(135deg, #f0f0f8, #e0e0f0); }
.swatches { display: flex; gap: 10px; flex-wrap: wrap; margin: 16px 0; }
.swatch { width: 48px; height: 48px; border-radius: 8px; border: 1px solid rgba(0,0,0,0.1); }
.analysis-card { background: white; border-radius: 12px; padding: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.06); line-height: 1.7; white-space: pre-wrap; }
</style>
</head>
<body>
<h1>🎨 Color Season Analyzer</h1>
<p style="color:#888; margin-bottom:24px;">Discover your personal color palette with AI</p>
<div class="upload-zone" id="zone" onclick="document.getElementById('fi').click()">
<div id="prompt">🤳<br><strong>Upload your photo</strong><br><span style="color:#aaa; font-size:0.9rem">Natural light selfie works best</span></div>
<img id="preview" style="display:none" />
</div>
<input type="file" id="fi" accept="image/*" style="display:none" onchange="handleFile(this)">
<div class="tips">💡 <strong>Best results:</strong> Natural daylight • No heavy filters • Minimal makeup • Face clearly visible</div>
<button class="analyze-btn" id="btn" onclick="analyze()" disabled>✨ Analyze My Color Season</button>
<div class="loading" id="loading">Analyzing your coloring...</div>
<div class="result" id="result">
<div class="season-badge" id="badge">
<h2 id="seasonTitle" style="font-size:2rem; margin-bottom:6px;"></h2>
<p id="tagline" style="color:#666;"></p>
</div>
<p style="font-weight:600; margin-bottom:8px;">✨ Your Color Palette</p>
<div class="swatches" id="swatches"></div>
<div class="analysis-card" id="analysisText"></div>
</div>
<script src="https://aipass.one/aipass-sdk.js"></script>
<script>
AiPass.initialize({ clientId: 'YOUR_CLIENT_ID', requireLogin: true, darkMode: false });
let b64 = null, mime = 'image/jpeg';
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('prompt').style.display = 'none';
const p = document.getElementById('preview'); p.src = e.target.result; p.style.display = 'block';
document.getElementById('btn').disabled = false;
};
reader.readAsDataURL(file);
}
const seasonLabels = { spring:'🌸 Spring', summer:'☀️ Summer', autumn:'🍂 Autumn', winter:'❄️ Winter' };
const fallbackColors = {
spring: ['#FFB347','#FF8C69','#FFD700','#90EE90','#87CEEB','#DDA0DD','#FFDAB9','#98FF98'],
summer: ['#B0C4DE','#DDA0DD','#BC8F8F','#8FBC8F','#87CEEB','#E6E6FA','#FFDAB9','#F08080'],
autumn: ['#8B4513','#D2691E','#CD853F','#556B2F','#B8860B','#A0522D','#6B8E23','#DAA520'],
winter: ['#000080','#8B0000','#006400','#FF1493','#4B0082','#2F4F4F','#DC143C','#4169E1']
};
async function analyze() {
if (!b64) return;
document.getElementById('btn').disabled = true;
document.getElementById('loading').style.display = 'block';
document.getElementById('result').style.display = 'none';
try {
const r = await AiPass.generateCompletion({
model: 'gpt-5-mini',
temperature: 1,
max_tokens: 16000,
messages: [{
role: 'user',
content: [
{ type: 'text', text: `Analyze this person's color season. Check skin undertone, hair, eyes, overall contrast.
Seasons: SPRING (warm+bright), SUMMER (cool+muted), AUTUMN (warm+earthy), WINTER (cool+high-contrast)
Respond EXACTLY:
SEASON: [Spring/Summer/Autumn/Winter]
TAGLINE: [one sentence about their coloring]
ANALYSIS:
[2-3 paragraphs: what you observe, why this season, colors that enhance them]
PALETTE: [8 perfect hex codes, comma-separated]` },
{ type: 'image_url', image_url: { url: `data:${mime};base64,${b64}` } }
]
}]
});
const text = r.choices[0].message.content;
const season = (text.match(/SEASON:\s*(\w+)/i)?.[1] || 'Spring').toLowerCase();
const tagline = text.match(/TAGLINE:\s*([^\n]+)/i)?.[1] || '';
const analysis = text.match(/ANALYSIS:\s*([\s\S]*?)(?=PALETTE:|$)/i)?.[1]?.trim() || text;
const paletteStr = text.match(/PALETTE:\s*([^\n]+)/i)?.[1] || '';
const hexes = paletteStr.split(',').map(h => h.trim()).filter(h => /^#[0-9a-f]{6}$/i.test(h));
document.getElementById('badge').className = 'season-badge ' + season;
document.getElementById('seasonTitle').textContent = seasonLabels[season] || season;
document.getElementById('tagline').textContent = tagline;
const colors = hexes.length >= 4 ? hexes : fallbackColors[season] || [];
document.getElementById('swatches').innerHTML = colors.map(hex =>
`<div class="swatch" style="background:${hex}" title="${hex}"></div>`
).join('');
document.getElementById('analysisText').textContent = analysis;
document.getElementById('result').style.display = 'block';
} catch(e) { console.error(e); alert('Analysis failed — try with a clearer photo.'); }
finally { document.getElementById('loading').style.display = 'none'; document.getElementById('btn').disabled = false; }
}
</script>
</body>
</html>
Multimodal SDK Pattern
// Sending image + text together (multimodal)
const r = await AiPass.generateCompletion({
model: 'gpt-5-mini',
temperature: 1, // Required
max_tokens: 16000, // Required
messages: [{
role: 'user',
content: [
{ type: 'text', text: 'Your analysis prompt...' },
{ type: 'image_url', image_url: { url: `data:image/jpeg;base64,${base64}` } }
]
}]
});
const text = r.choices[0].message.content;
This multimodal pattern unlocks a huge range of apps: color analysis, food recognition, style advice, plant identification, and more.
Deploy & Earn
This app goes viral easily — color seasons are inherently shareable. High organic share rate = high traffic = consistent commission.
50% commission on every analysis via your Client ID.
Live demo: aipass.one/apps/color-season-analyzer Developer Dashboard: aipass.one/panel/developer.html