Developer Guide
Kie AI Integration Guide
Hướng dẫn chi tiết tích hợp provider Kie AI vào OpenStory
Hướng Dẫn Tích Hợp Provider Kie AI (Async Media Gateway)
Tài liệu hướng dẫn chi tiết dành cho kỹ sư phần mềm / team phát triển để triển khai tích hợp dịch vụ Kie AI vào bất kỳ source code / hệ thống nào (Node.js, TypeScript, Python, Go, NestJS, Express, v.v.).
1. Tổng Quan Về Kie AI
Kie AI là một nền tảng Aggregator Gateway cung cấp một API Key duy nhất để truy cập đa dạng các mô hình sinh nội dung đa phương tiện (Generative Media):
- Image: xAI Grok Imagine, OpenAI GPT Image 2 (Text-to-Image, Image-to-Image).
- Video: xAI Grok Video 1.5, Video Extend, Google Veo 3.1 (Text-to-Video, Image-to-Video).
- Music & Audio: Suno V5, Suno V5.5, Suno Extend, Suno Cover/Remix, Suno Lyrics.
- Text-to-Speech (TTS): ElevenLabs TTS, Google Gemini 3.1 Flash TTS (hỗ trợ đối thoại nhiều nhân vật multi-speaker trong cùng một lượt gọi).
Vòng Đời Tác Vụ Bất Đồng Bộ (Async Task Lifecycle)
Toàn bộ các tác vụ media trên Kie AI đều vận hành theo cơ chế bất đồng bộ:
2. Thông Số Kỹ Thuật Cơ Bản
- Base URL chính:
https://api.kie.ai - File Upload Base URL:
https://kieai.redpandaai.co(hoặchttps://api.kie.ai) - Authentication: Bearer Token
Authorization: Bearer <YOUR_KIE_API_KEY> Content-Type: application/json - Lấy API Key: Truy cập kie.ai/api-key.
- Biến môi trường khuyến nghị:
KIE_API_KEY=your_kie_api_key_here KIE_BASE_URL=https://api.kie.ai KIE_MAX_POLL_MS=600000 # Timeout tối đa 10 phút (mili-giây) KIE_POLL_INTERVAL_MS=3000 # Chu kỳ thăm dò 3 giây KIE_CALLBACK_URL=https://... # URL Webhook (nếu không dùng polling thuần)
3. Danh Mục Mô Hình (Model Catalog) & Wire Names
Nên định nghĩa một bảng ánh xạ nội bộ giữa Model ID của hệ thống bạn và tên Wire Model thực tế của Kie AI:
3.1. Image Models
| Internal Model ID | Wire Model Name (model) | Surface / Endpoint | Mô Tả |
|---|---|---|---|
kie-grok-imagine-text | grok-imagine/text-to-image | /api/v1/jobs/createTask | xAI Grok Text-to-Image |
kie-grok-imagine-image | grok-imagine/image-to-image | /api/v1/jobs/createTask | xAI Grok Image-to-Image |
kie-gpt-image-text | gpt-image-2-text-to-image | /api/v1/jobs/createTask | OpenAI GPT Image 2 Text-to-Image |
kie-gpt-image-image | gpt-image-2-5-flare-image-to-image | /api/v1/jobs/createTask | OpenAI GPT Image 2 Image-to-Image |
3.2. Video Models
| Internal Model ID | Wire Model Name (model) | Surface / Endpoint | Mô Tả |
|---|---|---|---|
kie-grok-video-text | grok-imagine-video-1-5-preview | /api/v1/jobs/createTask | xAI Grok Video 1.5 Text/Image-to-Video |
kie-grok-video-extend | grok-imagine/extend | /api/v1/jobs/createTask | Kéo dài video cũ thông qua taskId |
kie-veo-video | veo3_fast | /api/v1/veo/generate | Google Veo 3 Video Generator |
kie-gemini-omni-video | google/gemini-omni-flash-1-1 | /api/v1/jobs/createTask | Google Gemini Omni Flash 1.1 Video Gen |
3.3. Audio & Music Models (Suno)
| Internal Model ID | Wire Model Name (model) | Endpoint Chuyên Biệt | Mô Tả |
|---|---|---|---|
kie-suno-v5 | V5 | POST /api/v1/generate | Tạo nhạc Suno V5 hoàn chỉnh (tối đa 8 phút) |
kie-suno-v5-5 | V5_5 | POST /api/v1/generate | Tạo nhạc Suno V5.5 chất lượng cao |
kie-suno-extend | extend | POST /api/v1/generate/extend | Nối dài bản nhạc trước đó |
kie-suno-cover | cover | POST /api/v1/suno/cover/generate | Tạo bản remix/cover phong cách mới |
kie-suno-lyrics | lyrics | POST /api/v1/lyrics | Sinh lời bài hát theo chủ đề |
3.4. Text-To-Speech (TTS)
| Internal Model ID | Wire Model Name (model) | Surface / Endpoint | Mô Tả |
|---|---|---|---|
kie-elevenlabs-tts | elevenlabs/tts | /api/v1/jobs/createTask | Giọng đọc ElevenLabs chuẩn quốc tế |
kie-gemini-3-1-flash-tts | google/gemini-3-1-flash-tts | /api/v1/jobs/createTask | Gemini 3.1 Flash TTS đa giọng, hỗ trợ đối thoại nhiều nhân vật |
4. Chi Tiết API Endpoints & Request Payloads
4.1. File Base64 Upload API
Dùng để tải ảnh nguồn dạng base64 lên lấy URL công khai trước khi gọi Image-to-Image hoặc Video.
- Endpoint:
POST https://kieai.redpandaai.co/api/file-base64-upload - Headers: Bearer Auth + JSON
- Body:
{ "base64Data": "data:image/png;base64,iVBORw0KGgo...", "uploadPath": "images/base64", "fileName": "reference.png" } - Response:
{ "code": 200, "success": true, "data": { "downloadUrl": "https://cdn.redpandaai.co/files/.../reference.png" } }
4.2. Image Generation
- Endpoint:
POST https://api.kie.ai/api/v1/jobs/createTask - Aspect Ratios được chấp nhận:
1:1,16:9,9:16,3:2,2:3,auto.
Text-to-Image:
{
"model": "grok-imagine/text-to-image",
"input": {
"prompt": "A futuristic city in mist at sunrise, highly detailed, architectural rendering",
"aspect_ratio": "16:9"
}
}Image-to-Image:
{
"model": "gpt-image-2-5-flare-image-to-image",
"input": {
"prompt": "Transform into anime watercolor style, soft pastel palette",
"aspect_ratio": "1:1",
"input_urls": ["https://cdn.redpandaai.co/files/.../reference.png"]
}
}4.3. Video Generation
- Endpoint:
POST https://api.kie.ai/api/v1/jobs/createTask - Thời lượng: 6 đến 30 giây (mặc định khuyến nghị: 8s).
- Độ phân giải:
480p,720p,1080p.
Text / Image to Video (Grok Video):
{
"model": "grok-imagine-video-1-5-preview",
"callBackUrl": "https://api.kie.ai/callback",
"input": {
"prompt": "Cinematic camera orbiting an astronaut floating over Earth",
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 8,
"mode": "normal",
"image_urls": ["https://cdn.redpandaai.co/files/.../start_frame.png"]
}
}Video Extend (Nối dài video cũ):
{
"model": "grok-imagine/extend",
"input": {
"task_id": "tsk_original_video_task_id",
"extend_at": 2,
"extend_times": "6",
"prompt": "Continue the slow pan upwards into the starfield"
}
}4.4. Audio & Music Generation (Suno)
Tạo nhạc mới (/api/v1/generate):
Lưu ý: Endpoint này bắt buộc phải có
customMode: true,instrumental: boolean, vàcallBackUrl.
{
"model": "V5",
"prompt": "An upbeat 80s synthwave pop track with energetic drums and retro synths",
"customMode": true,
"instrumental": true,
"callBackUrl": "https://api.kie.ai/callback"
}Nối dài bài nhạc (/api/v1/generate/extend):
{
"model": "V5",
"audioId": "suno_audio_id_from_previous_task",
"defaultParamFlag": true,
"prompt": "Add an epic electric guitar solo"
}4.5. Text-To-Speech (TTS)
ElevenLabs TTS:
{
"model": "elevenlabs/tts",
"input": {
"prompt": "Welcome to our latest technology podcast episode.",
"voice": "Rachel"
}
}Gemini 3.1 Flash TTS (Đối thoại đa nhân vật Multi-turn Dialogue):
Hỗ trợ kịch bản đối thoại nhiều nhân vật với các thẻ phong cách/cảm xúc (style, accent, pace):
{
"model": "google/gemini-3-1-flash-tts",
"callBackUrl": "https://api.kie.ai/callback",
"input": {
"temperature": 1,
"speakers": [
{
"speaker_id": "Speaker 1",
"voice_name": "Kore",
"accent": "Neutral",
"style": "Natural",
"pace": "Natural"
},
{
"speaker_id": "Speaker 2",
"voice_name": "Fenrir",
"accent": "Neutral",
"style": "Thoughtful",
"pace": "Natural"
}
],
"dialogue_turns": [
{
"speaker_id": "Speaker 1",
"text": "[warm] Chào buổi sáng mọi người, hôm nay chúng ta sẽ bàn về AI."
},
{
"speaker_id": "Speaker 2",
"text": "[thoughtful] Đúng vậy, một chủ đề rất đáng suy ngẫm trong năm nay."
}
]
}
}5. Cơ Chế Polling & Bóc Tách Kết Quả (Result Extraction)
Sau khi gửi request thành công, bạn nhận được:
{
"code": 200,
"data": {
"taskId": "tsk_01jk47abc99xyz123"
}
}5.1. Thăm dò trạng thái
Gửi request GET:
GET https://api.kie.ai/api/v1/jobs/recordInfo?taskId={taskId}
Authorization: Bearer <YOUR_KIE_API_KEY>5.2. Các trạng thái của Task (state)
pending: Đang xếp hàng chờ tài nguyên.processing: Đang trong tiến trình tính toán / sinh media.success: Hoàn thành thành công.fail/failed/error/cancelled: Thất bại (Lấy thông báo lỗi tạifailMsg,failCodehoặcmsg).
5.3. Bóc tách kết quả (3 biến thể quan trọng)
Kie AI trả về URL kết quả ở các dạng khác nhau tùy theo endpoint:
- Unified Tasks (Image, Video, TTS):
- Dữ liệu nằm trong chuỗi JSON string:
task.resultJson. - Cần parse:
const parsed = JSON.parse(task.resultJson); const resultUrl = parsed.resultUrls?.[0] || parsed.data?.[0]?.audio_url;
- Dữ liệu nằm trong chuỗi JSON string:
- Direct Suno Endpoints (Music):
- Dữ liệu nằm trong object:
const resultUrl = task.response?.sunoData?.[0]?.audioUrl || task.response?.sunoData?.[0]?.streamAudioUrl;
- Dữ liệu nằm trong object:
- Lyrics Endpoint:
- Dữ liệu văn bản thuần:
const lyrics = task.response?.text;
- Dữ liệu văn bản thuần:
6. Code Triển Khai Mẫu Hoàn Chỉnh (TypeScript / Node.js)
Dưới đây là một module triển khai độc lập, có thể copy trực tiếp vào dự án mới:
// kie-service.ts
import fs from 'node:fs';
import path from 'node:path';
export interface KieConfig {
apiKey: string;
baseUrl?: string;
maxPollMs?: number;
pollIntervalMs?: number;
}
export class KieAIService {
private apiKey: string;
private baseUrl: string;
private maxPollMs: number;
private pollIntervalMs: number;
constructor(config: KieConfig) {
this.apiKey = config.apiKey;
this.baseUrl = (config.baseUrl || 'https://api.kie.ai').replace(/\/$/, '');
this.maxPollMs = config.maxPollMs || 10 * 60 * 1000; // 10 phút
this.pollIntervalMs = config.pollIntervalMs || 3000; // 3 giây
}
private headers(): Record<string, string> {
return {
Authorization: `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
};
}
/**
* Upload ảnh local dạng base64 lên CDN Kie AI
*/
async uploadImageBase64(
base64DataUrl: string,
fileName = 'input.png'
): Promise<string> {
const uploadUrl = 'https://kieai.redpandaai.co/api/file-base64-upload';
const res = await fetch(uploadUrl, {
method: 'POST',
headers: this.headers(),
body: JSON.stringify({
base64Data: base64DataUrl,
uploadPath: 'images/base64',
fileName,
}),
});
if (!res.ok) {
throw new Error(`Kie upload failed with status ${res.status}`);
}
const data = await res.json();
const url =
data?.data?.downloadUrl ||
data?.data?.fileUrl ||
data?.downloadUrl ||
data?.url;
if (!url) {
throw new Error('Kie upload response did not return a valid downloadUrl');
}
return url;
}
/**
* Tạo Image (Grok Imagine / GPT Image 2)
*/
async generateImage(params: {
prompt: string;
model?: string; // 'grok-imagine/text-to-image' | 'gpt-image-2-text-to-image' | ...
aspectRatio?: '1:1' | '16:9' | '9:16' | '3:2' | '2:3';
inputUrls?: string[];
}): Promise<Buffer> {
const body = {
model: params.model || 'grok-imagine/text-to-image',
input: {
prompt: params.prompt,
aspect_ratio: params.aspectRatio || '1:1',
...(params.inputUrls ? { input_urls: params.inputUrls } : {}),
},
};
const taskId = await this.submitTask('/api/v1/jobs/createTask', body);
return this.pollTask(taskId);
}
/**
* Tạo Video (Grok Video 1.5)
*/
async generateVideo(params: {
prompt: string;
duration?: number; // 6 - 30
aspectRatio?: '16:9' | '9:16' | '1:1';
resolution?: '480p' | '720p' | '1080p';
imageUrl?: string;
}): Promise<Buffer> {
const body = {
model: 'grok-imagine-video-1-5-preview',
callBackUrl: 'https://api.kie.ai/callback',
input: {
prompt: params.prompt,
aspect_ratio: params.aspectRatio || '16:9',
resolution: params.resolution || '720p',
duration: Math.min(Math.max(params.duration || 8, 6), 30),
mode: 'normal',
...(params.imageUrl ? { image_urls: [params.imageUrl] } : {}),
},
};
const taskId = await this.submitTask('/api/v1/jobs/createTask', body);
return this.pollTask(taskId);
}
/**
* Tạo Nhạc Suno V5
*/
async generateMusic(params: {
prompt: string;
instrumental?: boolean;
}): Promise<Buffer> {
const body = {
model: 'V5',
prompt: params.prompt,
customMode: true,
instrumental: params.instrumental !== false,
callBackUrl: 'https://api.kie.ai/callback',
};
const taskId = await this.submitTask('/api/v1/generate', body);
return this.pollTask(taskId);
}
/**
* Gửi lệnh submit task và lấy về taskId
*/
private async submitTask(
endpoint: string,
payload: unknown
): Promise<string> {
const url = `${this.baseUrl}${endpoint}`;
const res = await fetch(url, {
method: 'POST',
headers: this.headers(),
body: JSON.stringify(payload),
});
const text = await res.text();
if (!res.ok) {
throw new Error(`Kie submit failed (${res.status}): ${text}`);
}
const data = JSON.parse(text);
const taskId = data?.data?.taskId || data?.taskId;
if (!taskId) {
throw new Error(`Kie response missing taskId: ${text}`);
}
return taskId;
}
/**
* Vòng lặp Polling kiểm tra trạng thái và download bytes
*/
private async pollTask(taskId: string): Promise<Buffer> {
const start = Date.now();
const pollUrl = `${this.baseUrl}/api/v1/jobs/recordInfo?taskId=${encodeURIComponent(taskId)}`;
while (Date.now() - start < this.maxPollMs) {
await new Promise((resolve) => setTimeout(resolve, this.pollIntervalMs));
const res = await fetch(pollUrl, {
method: 'GET',
headers: { Authorization: `Bearer ${this.apiKey}` },
});
if (!res.ok) {
throw new Error(`Polling request failed with status ${res.status}`);
}
const pollData = await res.json();
const task = pollData.data || pollData;
const state = task.state;
if (state === 'success') {
let resultUrl: string | null = null;
// 1. Kiểm tra Suno Data format
if (task.response?.sunoData?.length > 0) {
resultUrl =
task.response.sunoData[0].audioUrl ||
task.response.sunoData[0].streamAudioUrl;
}
// 2. Kiểm tra Unified Task format (resultJson)
if (!resultUrl && typeof task.resultJson === 'string') {
try {
const parsed = JSON.parse(task.resultJson);
resultUrl =
parsed.resultUrls?.[0] || parsed.data?.[0]?.audio_url || null;
} catch {
// bỏ qua lỗi parse json
}
}
// 3. Kiểm tra Lyrics format
if (!resultUrl && typeof task.response?.text === 'string') {
return Buffer.from(task.response.text, 'utf-8');
}
if (!resultUrl) {
throw new Error(
`Task completed successfully but no result URL found: ${JSON.stringify(pollData)}`
);
}
// Tải media bytes từ CDN URL
const downloadRes = await fetch(resultUrl);
if (!downloadRes.ok) {
throw new Error(
`Failed to download result file: ${downloadRes.status}`
);
}
return Buffer.from(await downloadRes.arrayBuffer());
}
if (['fail', 'failed', 'error', 'cancelled'].includes(state)) {
const errorMsg =
task.failMsg || task.failCode || pollData.msg || 'Unknown error';
throw new Error(
`Kie task failed (${state}): ${JSON.stringify(errorMsg)}`
);
}
}
throw new Error(
`Kie task ${taskId} timed out after ${this.maxPollMs / 1000}s`
);
}
}7. Các Lưu Ý Vận Hành Thực Tế (Production Best Practices)
- Idempotency & Lưu trữ State:
- Luôn lưu
taskId,status, và thời gian tạo vào Database của bạn. - Khi nhận callback webhook hoặc người dùng reload trang, kiểm tra theo
taskIdđể tránh submit trùng lặp tốn credit.
- Luôn lưu
- Exponential Backoff:
- Đối với các tác vụ tạo video (thường mất 30s – 120s), có thể tăng thời gian thăm dò từ 3s ban đầu lên 5s hoặc 10s để giảm tải network request.
- Bảo mật CDN URL:
- URL do Kie CDN trả về có thể có hạn sử dụng. Hãy tải binary về và lưu trực tiếp lên Cloud Storage nội bộ (S3, Cloudflare R2, Google Cloud Storage, v.v.).
- Giới hạn tham số (Clamping):
- Video duration luôn phải nằm trong khoảng
6 – 30s. - Audio duration tối đa
480s(8 phút).
- Video duration luôn phải nằm trong khoảng