AITuberKit × AICU API Integration Guide
How to wire AICU TTS into AITuberKit
Overview
AITuberKit is a web application for conversing with AI characters. Point it at AICU API's TTS endpoint and you get high-quality Japanese speech.
Environment variables
Add the following to .env.local:
# AICU API Settings
AICU_API_KEY=aicu_live_xxxxxxxxxxxxxxxx
AICU_API_URL=https://api.aicu.ai/v1
# Character Settings (use either slug or char_id)
AICU_SLUG=luc4 # Character slug
# AICU_CHAR_ID=0 # or the numeric ID
TypeScript examples
TTS client
// lib/aicu-tts.ts
interface TTSOptions {
text: string;
slug?: string; // Character slug (recommended)
char_id?: number; // or the numeric ID
voice?: string;
seed?: number;
instruct?: string;
force?: boolean; // Bypass the cache
}
export async function generateSpeech(options: TTSOptions): Promise<ArrayBuffer> {
const response = await fetch(`${process.env.AICU_API_URL}/tts/generate`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AICU_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: options.text,
slug: options.slug || process.env.AICU_SLUG,
char_id: options.char_id,
voice: options.voice,
seed: options.seed,
instruct: options.instruct,
force: options.force,
format: 'mp3',
}),
});
if (!response.ok) {
throw new Error(`TTS Error: ${response.status}`);
}
// Log the response headers
const cacheHit = response.headers.get('X-Cache-Hit');
const creditsUsed = response.headers.get('X-Credits-Used');
console.log(`Cache: ${cacheHit}, Credits: ${creditsUsed}`);
return response.arrayBuffer();
}
React hook
// hooks/useAicuTTS.ts
import { useState, useCallback } from 'react';
export function useAicuTTS() {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const speak = useCallback(async (text: string) => {
setIsLoading(true);
setError(null);
try {
const res = await fetch('/api/tts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text }),
});
if (!res.ok) throw new Error('TTS failed');
const audioBlob = await res.blob();
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
await audio.play();
// Cleanup
audio.onended = () => URL.revokeObjectURL(audioUrl);
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
} finally {
setIsLoading(false);
}
}, []);
return { speak, isLoading, error };
}
API route (Next.js)
// app/api/tts/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const { text, slug, char_id, force } = await request.json();
const response = await fetch('https://api.aicu.ai/v1/tts/generate', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AICU_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text,
slug: slug || process.env.AICU_SLUG || 'luc4',
char_id,
force,
format: 'mp3',
}),
});
if (!response.ok) {
return NextResponse.json(
{ error: 'TTS generation failed' },
{ status: response.status }
);
}
const audioBuffer = await response.arrayBuffer();
return new NextResponse(audioBuffer, {
headers: {
'Content-Type': 'audio/mpeg',
'X-Cache-Hit': response.headers.get('X-Cache-Hit') || 'false',
'X-Slug': response.headers.get('X-Slug') || '',
'X-Credits-Used': response.headers.get('X-Credits-Used') || '0',
},
});
}
Character settings (CharID)
| char_id | slug | Name | Voice | Seed | Status |
|---|---|---|---|---|---|
| 0 | luc4 | LuC4 | aiden | 608 | public |
| 1 | elena | Elena Bloom | ono_anna | 330 | private |
| 2 | mei | Mei Soleil | ono_anna | 721 | private |
| 3 | mina | Mina Azure | ono_anna | 101 | private |
| 4 | nao | Nao Verde | aiden | 505 | private |
| 5 | saki | Saki Noir | ono_anna | 1031 | private |
Usage:
// Select by slug (recommended)
await generateSpeech({ text: 'こんにちは', slug: 'luc4' });
// Select by char_id
await generateSpeech({ text: 'こんにちは', char_id: 0 });
Voice style direction (instruct)
Use the instruct parameter to steer delivery and intonation:
// An upbeat greeting
await generateSpeech({
text: 'おはようございます!',
voice: 'ono_anna',
instruct: 'Speak with energy and excitement',
});
// A calm explanation
await generateSpeech({
text: '本日の予定を説明します。',
voice: 'serena',
instruct: 'Speak calmly and clearly like a professional narrator',
});
// A whisper
await generateSpeech({
text: '秘密だよ...',
voice: 'vivian',
instruct: 'Whisper softly',
});
Troubleshooting
401 Unauthorized
→ The API key is invalid. Reissue it from the dashboard.
402 Payment Required
→ You are out of credits. Buy an add-on or upgrade your plan.
429 Too Many Requests
→ You hit the rate limit. Check the limits that apply to your plan.
Support
- AICU API dashboard: https://api.aicu.ai/dashboard
- AITuberKit GitHub: https://github.com/kaitas/aituber-kit
- Contact: https://aicu.ai/contact
© 2026 AICU Inc.