Skip to main content

Kie.ai Image Generation Service

Client-side TypeScript service for Kie.ai image generation. Provides functions for creating and polling image generation tasks. Location: src/services/kieai.ts

Overview

The Kie.ai service provides:
  • Task Creation - Initiate image generation jobs
  • Status Polling - Check task completion status
  • Wait Utilities - Automated polling until completion
  • Image Transformation - Modify existing images
All requests proxy through /api/images/* endpoints, which handle API keys and authentication.

createTask()

Create a new image generation task.
function createTask(
  params: KieAiCreateTaskParams
): Promise<KieAiTaskResponse>

Parameters

interface KieAiCreateTaskParams {
  prompt: string
  aspectRatio?: '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '4:5' | '5:4' | '9:16' | '16:9' | '21:9' | 'auto'
  resolution?: '1K' | '2K' | '4K'
  outputFormat?: 'png' | 'jpg'
  imageInput?: string[]  // Input images for transformation (max 8)
}
prompt
string
required
Image generation prompt
aspectRatio
string
default:"16:9"
Image aspect ratio
resolution
string
default:"2K"
Image resolution: 1K, 2K, or 4K
outputFormat
string
default:"png"
Output format: png or jpg
imageInput
string[]
default:"[]"
Input image URLs for transformation (max 8 images)

Returns

interface KieAiTaskResponse {
  taskId: string  // Unique task ID for polling
}

Example

import { createTask } from '@/services/kieai'

const { taskId } = await createTask({
  prompt: 'Create a professional isometric 3D infographic showing the three pillars of IT leadership...',
  aspectRatio: '16:9',
  resolution: '2K'
})

console.log('Task created:', taskId)

queryTask()

Check the status of a generation task.
function queryTask(taskId: string): Promise<KieAiTaskResult>

Parameters

taskId
string
required
Task ID from createTask()

Returns

interface KieAiTaskResult {
  taskId: string
  state: 'pending' | 'processing' | 'success' | 'fail'
  imageUrl?: string | null       // Available when state = 'success'
  failMsg?: string               // Available when state = 'fail'
  costTime?: number              // Generation time in milliseconds
}

Example

import { queryTask } from '@/services/kieai'

const result = await queryTask(taskId)

if (result.state === 'success') {
  console.log('Image ready:', result.imageUrl)
} else if (result.state === 'fail') {
  console.error('Generation failed:', result.failMsg)
} else {
  console.log('Still processing...', result.state)
}

waitForTask()

Poll for task completion with automatic retries.
function waitForTask(
  taskId: string,
  maxAttempts?: number,
  intervalMs?: number,
  onProgress?: (attempt: number, maxAttempts: number, state: string) => void
): Promise<KieAiTaskResult>

Parameters

taskId
string
required
Task ID to poll
maxAttempts
number
default:"90"
Maximum polling attempts
intervalMs
number
default:"3000"
Polling interval in milliseconds
onProgress
function
Progress callback: (attempt, maxAttempts, state) => void

Returns

KieAiTaskResult  // Final result when state = 'success' or 'fail'

Example

import { createTask, waitForTask } from '@/services/kieai'

try {
  // Create task
  const { taskId } = await createTask({
    prompt: spec.prompt,
    aspectRatio: spec.aspectRatio,
    resolution: '2K'
  })
  
  // Wait for completion with progress
  const result = await waitForTask(
    taskId,
    90,
    3000,
    (attempt, maxAttempts, state) => {
      const progress = (attempt / maxAttempts) * 100
      console.log(`[${progress.toFixed(0)}%] State: ${state}`)
    }
  )
  
  console.log('Image URL:', result.imageUrl)
  console.log('Generated in:', result.costTime, 'ms')
  
} catch (error) {
  console.error('Generation failed:', error.message)
}

Default Timeouts

  • Max attempts: 90
  • Interval: 3 seconds
  • Total timeout: 4.5 minutes (90 × 3 seconds)
Generation Time: Most images complete in 30-90 seconds. Complex infographics may take 2-3 minutes.

Image Transformation

Modify existing images by providing them as imageInput.

Example: Recolor

import { createTask, waitForTask } from '@/services/kieai'

// Recolor existing infographic
const { taskId } = await createTask({
  prompt: 'Convert this infographic to YBH brand colors (yellow #F7B500, orange #F17529, red #EF4136) on dark background #1A1A2E',
  imageInput: [
    'https://kie.ai/cdn/images/original-infographic.png'
  ],
  aspectRatio: '16:9',
  resolution: '2K'
})

const result = await waitForTask(taskId)
console.log('Recolored image:', result.imageUrl)

Example: Add Elements

// Add episode number to existing image
const { taskId } = await createTask({
  prompt: 'Add "EP 385" in the top-left corner in white Fonseca Bold font, and YBH logo in bottom-right',
  imageInput: [
    'https://kie.ai/cdn/images/base-infographic.png'
  ],
  aspectRatio: '16:9'
})

Example: Merge Images

// Combine multiple images
const { taskId } = await createTask({
  prompt: 'Arrange these three infographics in a horizontal triptych layout with subtle dividers',
  imageInput: [
    'https://kie.ai/cdn/images/infographic-1.png',
    'https://kie.ai/cdn/images/infographic-2.png',
    'https://kie.ai/cdn/images/infographic-3.png'
  ],
  aspectRatio: '21:9',
  resolution: '4K'
})
imageInput
string[]
Limit: Max 8 imagesUse cases:
  • Recolor/restyle existing images
  • Add text or branding elements
  • Merge multiple images
  • Change layout or composition

Task States

StateDescriptionAction
pendingTask queued, not startedContinue polling
processingImage being generatedContinue polling
successGeneration completeRetrieve imageUrl
failGeneration failedCheck failMsg

State Mapping

Kie.ai uses different state names internally, which are mapped to standard states:
const stateMap = {
  'waiting': 'pending',
  'queuing': 'pending',
  'generating': 'processing',
  'success': 'success',
  'fail': 'fail'
}

Error Handling

All functions throw errors that should be caught:
try {
  const result = await waitForTask(taskId)
  console.log('Image URL:', result.imageUrl)
  
} catch (error) {
  if (error.message.includes('Task timed out')) {
    // Exceeded 4.5 minutes
    console.error('Generation took too long')
    console.log('Check Kie.ai dashboard for task status')
    
  } else if (error.message.includes('Image generation failed')) {
    // Task failed
    console.error('Generation failed:', error.message)
    
  } else {
    // Network or API error
    console.error('API error:', error.message)
  }
}

Common Errors

ErrorCauseSolution
Task timed outExceeded 4.5 minutesCheck Kie.ai dashboard, increase maxAttempts
Image generation failedKie.ai rejected requestSimplify prompt, check content policy
API error: 401Not authenticatedLogin again
API error: 500Kie.ai service errorRetry later, contact Kie.ai support

Response Parsing

parseResultUrls()

Parse result URLs from Kie.ai’s resultJson (legacy compatibility).
function parseResultUrls(resultJson: string): string[]

Example

import { parseResultUrls } from '@/services/kieai'

const resultJson = '{"resultUrls": ["https://kie.ai/cdn/images/abc123.png"]}'
const urls = parseResultUrls(resultJson)

console.log('URLs:', urls)  // ["https://kie.ai/cdn/images/abc123.png"]
Automatic Parsing: The queryTask() function automatically parses imageUrl from the response. You don’t need to use parseResultUrls() unless working with raw API responses.

Integration with AI Service

Common workflow: Generate spec → Create image:
import { generateInfographicSpec } from '@/services/ai'
import { createTask, waitForTask } from '@/services/kieai'

// 1. Generate infographic spec
const spec = await generateInfographicSpec(
  selectedText,
  transcript,
  prf,
  episodeNumber,
  guestName,
  history
)

// 2. Create image generation task
const { taskId } = await createTask({
  prompt: spec.prompt,
  aspectRatio: spec.aspectRatio,
  resolution: '2K'
})

// 3. Wait for completion
const result = await waitForTask(taskId)

// 4. Save to episode
await updateEpisode(episodeId, {
  assets: [
    ...episode.assets,
    {
      _key: crypto.randomUUID(),
      type: spec.layout,
      status: 'generated',
      imageUrl: result.imageUrl,
      spec,
      createdAt: new Date().toISOString()
    }
  ]
})

Logging

The service uses debug logging (dev only):
import { logger } from '@/utils/logger'

logger.debug('[kieai] Task succeeded')
logger.debug('[kieai] waitForTask complete')
logger.warn('[kieai] Task succeeded but imageUrl is missing')
logger.warn(`[kieai] Poll attempt ${i + 1} failed, retrying`)
Logs only appear in development mode.

Performance

OperationTimeNotes
createTask()~500msReturns immediately with taskId
queryTask()~200msQuick status check
waitForTask()30-180sDepends on image complexity

Generation Times

  • Simple quote cards: 30-60 seconds
  • Standard infographics: 60-120 seconds
  • Complex 4K infographics: 120-180 seconds
  • Image transformations: 45-90 seconds

Cost Estimates

Kie.ai Pricing: Image generation incurs costs:
  • 2K resolution: ~$0.10-0.15 per image
  • 4K resolution: ~$0.20-0.30 per image
  • Transformations: Same cost as generation
Monitor usage via Kie.ai dashboard.

TypeScript Types

All types are exported:
import type { 
  KieAiCreateTaskParams, 
  KieAiTaskResponse, 
  KieAiTaskResult 
} from '@/services/kieai'

function MyComponent() {
  const [result, setResult] = useState<KieAiTaskResult | null>(null)
  // ...
}

Build docs developers (and LLMs) love