Flux Kontext API Documentation

Flux Kontext API Documentation

Based on KIE AI's Flux Kontext API, providing AI image generation and editing capabilities for the RemoveTextFromImage project.

Overview

The Flux Kontext API is a powerful AI image generation and editing API that supports text-to-image generation, image editing, and text removal functionality. The API uses asynchronous processing mode and supports webhook callback notifications.

Basic Information

  • Base URL: https://api.kie.ai/api/v1/flux/kontext
  • Authentication: Bearer Token
  • Content Type: application/json
  • Image Storage: Generated images stored for 14 days, original image URLs valid for 10 minutes

Authentication

Get API Key

  1. Visit KIE AI API Key Management Page
  2. Create new API key
  3. Use Bearer Token authentication in request headers
Authorization: Bearer YOUR_API_KEY

⚠️ Important:

  • Keep your API key secure and never share it publicly
  • If compromised, reset it immediately in the management page

Core Endpoints

1. Image Generation/Editing

Endpoint: POST /api/v1/flux/kontext/generate

Usage Modes

Text-to-Image Generation

  • Provide prompt and aspectRatio
  • Model generates new image based on text description

Image Editing

  • Provide prompt and inputImage
  • Optionally provide aspectRatio (will crop or pad to specified ratio)
  • Model edits input image according to prompt

Request Parameters

ParameterTypeRequiredDescription
promptstringImage description text or editing instruction (English only)
modelstringModel selection, default flux-kontext-pro
aspectRatiostringImage ratio, default 16:9
inputImagestringInput image URL for editing mode
enableTranslationbooleanEnable automatic translation, default true
promptUpsamplingbooleanEnable prompt enhancement, default false
outputFormatstringOutput format: jpeg (default), png
safetyToleranceintegerSafety tolerance, generation 0-6, editing 0-2, default 2
callBackUrlstringCallback URL for completion
uploadCnbooleanWhether to use China servers for upload
watermarkstringWatermark identifier

Supported Aspect Ratios

RatioFormat TypeCommon Use Cases
21:9Ultra-wideCinematic displays, panoramic views
16:9WidescreenHD video, desktop wallpapers
4:3StandardTraditional displays, presentations
1:1SquareSocial media posts, avatars
3:4PortraitMagazine layouts, portrait photos
9:16Mobile PortraitPhone wallpapers, stories
16:21Ultra-tallMobile app splash screens

Model Selection

ModelDescriptionRecommended Usage
flux-kontext-proStandard model, balanced performanceMost use cases
flux-kontext-maxEnhanced model, advanced capabilitiesComplex scenes, higher quality

Request Examples

Text-to-Image Generation:

{
  "prompt": "A serene mountain landscape at sunset with a lake reflecting the orange sky",
  "model": "flux-kontext-pro",
  "aspectRatio": "16:9",
  "enableTranslation": true,
  "promptUpsampling": false,
  "safetyTolerance": 2
}

Image Editing:

{
  "prompt": "Remove all text from this image while preserving the background",
  "inputImage": "https://example.com/input.jpg",
  "aspectRatio": "16:9",
  "model": "flux-kontext-pro",
  "callBackUrl": "https://your-server.com/callback"
}

Success Response

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task12345"
  }
}

2. Task Status Query

Endpoint: GET /api/v1/flux/kontext/record-info

Query Parameters

ParameterTypeRequiredDescription
taskIdstringUnique identifier of image generation task

Response Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task12345",
    "paramJson": "{\"prompt\":\"A serene mountain landscape\",\"aspectRatio\":\"16:9\"}",
    "completeTime": "2024-03-20T10:30:00Z",
    "response": {
      "originImageUrl": "https://example.com/original.jpg",
      "resultImageUrl": "https://example.com/result.jpg"
    },
    "successFlag": 1,
    "errorCode": null,
    "errorMessage": "",
    "createTime": "2024-03-20T10:25:00Z"
  }
}

Status Codes

Status CodeMeaningDescription
0GENERATINGTask is being processed
1SUCCESSTask completed successfully
2CREATE_TASK_FAILEDFailed to create task
3GENERATE_FAILEDTask creation succeeded but generation failed

Webhook Callback Mechanism

Callback Timing

The system sends callback notifications in the following situations:

  • Image generation or editing task completed successfully
  • Image generation or editing task failed
  • Errors occurred during task processing

Callback Configuration

  • HTTP Method: POST
  • Content Type: application/json
  • Timeout Setting: 15 seconds
  • Retry Mechanism: Retry 3 times after failure, with intervals of 1 minute, 5 minutes, and 15 minutes

Callback Format

Success Callback:

{
  "code": 200,
  "msg": "BFL image generated successfully.",
  "data": {
    "taskId": "task12345",
    "info": {
      "originImageUrl": "https://example.com/original.jpg",
      "resultImageUrl": "https://example.com/result.jpg"
    }
  }
}

Failure Callback:

{
  "code": 400,
  "msg": "Your prompt was flagged by Website as violating content policies",
  "data": {
    "taskId": "task12345"
  }
}

Callback Status Codes

Status CodeDescription
200Success - Image generation completed
400Failed - Prompt violated content policies
500Failed - Internal error, please try again later
501Failed - Image generation task failed

Error Handling

HTTP Status Codes

Status CodeMeaningDescription
200SuccessRequest processed successfully
401UnauthorizedAuthentication credentials missing or invalid
402Insufficient CreditsAccount lacks sufficient credits
404Not FoundRequested resource does not exist
422Validation ErrorRequest parameters failed validation
429Rate LimitedRequest limit exceeded
455Service UnavailableSystem under maintenance
500Server ErrorUnexpected error during processing
501Generation FailedImage generation task failed
505Feature DisabledRequested feature currently disabled

Error Response Format

{
  "code": 400,
  "msg": "Your prompt was flagged by Website as violating content policies",
  "data": null
}

Code Examples

JavaScript/Node.js

class FluxKontextAPI {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.kie.ai/api/v1/flux/kontext';
    this.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };
  }

  // Text removal functionality
  async removeTextFromImage(inputImage, prompt = "Remove all text from this image while preserving the background") {
    try {
      const response = await fetch(`${this.baseUrl}/generate`, {
        method: 'POST',
        headers: this.headers,
        body: JSON.stringify({
          prompt,
          inputImage,
          model: 'flux-kontext-pro',
          aspectRatio: '16:9',
          enableTranslation: true,
          safetyTolerance: 2
        })
      });

      const result = await response.json();
      
      if (result.code !== 200) {
        throw new Error(`Generation failed: ${result.msg}`);
      }

      return result.data.taskId;
    } catch (error) {
      console.error('Error:', error);
      throw error;
    }
  }

  // Query task status
  async getTaskStatus(taskId) {
    try {
      const response = await fetch(
        `${this.baseUrl}/record-info?taskId=${taskId}`,
        { headers: this.headers }
      );

      const result = await response.json();
      
      if (result.code !== 200) {
        throw new Error(`Status query failed: ${result.msg}`);
      }

      return result.data;
    } catch (error) {
      console.error('Error querying status:', error);
      throw error;
    }
  }

  // Wait for task completion
  async waitForCompletion(taskId, maxWaitTime = 300000) { // 5 minutes
    const startTime = Date.now();
    
    while (Date.now() - startTime < maxWaitTime) {
      const status = await this.getTaskStatus(taskId);
      
      console.log(`Task ${taskId} status: ${status.successFlag}`);
      
      if (status.successFlag === 1) {
        console.log('Task completed successfully');
        return status.response;
      } else if (status.successFlag === 2 || status.successFlag === 3) {
        throw new Error(`Task failed: ${status.errorMessage || 'Unknown error'}`);
      }
      
      // Wait 3 seconds before retry
      await new Promise(resolve => setTimeout(resolve, 3000));
    }
    
    throw new Error('Task timeout');
  }

  // Complete text removal workflow
  async processImageTextRemoval(inputImage, options = {}) {
    try {
      console.log('Starting text removal...');
      
      const taskId = await this.removeTextFromImage(
        inputImage, 
        options.prompt || "Remove all text from this image while preserving the background"
      );
      
      console.log(`Task created: ${taskId}`);
      
      const result = await this.waitForCompletion(taskId);
      
      console.log('Text removal completed!');
      console.log('Result Image URL:', result.resultImageUrl);
      console.log('Original Image URL (valid 10 min):', result.originImageUrl);
      
      return result;
    } catch (error) {
      console.error('Text removal failed:', error.message);
      throw error;
    }
  }
}

// Usage example
const api = new FluxKontextAPI('your_api_key_here');

// Remove text from image
api.processImageTextRemoval('https://example.com/image-with-text.jpg')
  .then(result => {
    console.log('Success! Image URL:', result.resultImageUrl);
  })
  .catch(error => {
    console.error('Failed:', error.message);
  });

Python

import requests
import time
from typing import Optional, Dict, Any

class FluxKontextAPI:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.kie.ai/api/v1/flux/kontext"
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
    
    def remove_text_from_image(
        self, 
        input_image: str, 
        prompt: str = "Remove all text from this image while preserving the background"
    ) -> str:
        """Create text removal task"""
        payload = {
            "prompt": prompt,
            "inputImage": input_image,
            "model": "flux-kontext-pro",
            "aspectRatio": "16:9",
            "enableTranslation": True,
            "safetyTolerance": 2
        }
        
        try:
            response = requests.post(
                f"{self.base_url}/generate",
                json=payload,
                headers=self.headers
            )
            response.raise_for_status()
            
            result = response.json()
            
            if result["code"] != 200:
                raise Exception(f"Generation failed: {result['msg']}")
                
            return result["data"]["taskId"]
            
        except requests.exceptions.RequestException as e:
            print(f"API request error: {e}")
            raise
    
    def get_task_status(self, task_id: str) -> Dict[str, Any]:
        """Query task status"""
        try:
            response = requests.get(
                f"{self.base_url}/record-info",
                params={"taskId": task_id},
                headers=self.headers
            )
            response.raise_for_status()
            
            result = response.json()
            
            if result["code"] != 200:
                raise Exception(f"Status query failed: {result['msg']}")
                
            return result["data"]
            
        except requests.exceptions.RequestException as e:
            print(f"Status query error: {e}")
            raise
    
    def wait_for_completion(self, task_id: str, max_wait_time: int = 300) -> Dict[str, Any]:
        """Wait for task completion"""
        start_time = time.time()
        
        while time.time() - start_time < max_wait_time:
            try:
                status = self.get_task_status(task_id)
                
                print(f"Task {task_id} status: {status['successFlag']}")
                
                if status["successFlag"] == 1:  # Success
                    print("Task completed successfully!")
                    return status["response"]
                elif status["successFlag"] in [2, 3]:  # Failed
                    raise Exception(f"Task failed: {status.get('errorMessage', 'Unknown error')}")
                
                # Wait 3 seconds before retry
                time.sleep(3)
                
            except Exception as e:
                if "Status query failed" in str(e):
                    raise
                print(f"Status query error: {e}")
                time.sleep(3)
        
        raise Exception("Task timeout")
    
    def process_image_text_removal(
        self, 
        input_image: str, 
        prompt: Optional[str] = None
    ) -> Dict[str, Any]:
        """Complete text removal workflow"""
        try:
            print("Starting text removal...")
            
            if prompt is None:
                prompt = "Remove all text from this image while preserving the background"
            
            task_id = self.remove_text_from_image(input_image, prompt)
            print(f"Task created: {task_id}")
            
            result = self.wait_for_completion(task_id)
            
            print("Text removal completed!")
            print(f"Result image URL: {result['resultImageUrl']}")
            print(f"Original image URL (10 min valid): {result['originImageUrl']}")
            
            return result
            
        except Exception as e:
            print(f"Text removal failed: {e}")
            raise

# Usage example
if __name__ == "__main__":
    api = FluxKontextAPI("your_api_key_here")
    
    try:
        result = api.process_image_text_removal(
            "https://example.com/image-with-text.jpg"
        )
        print("Success! Result image URL:", result["resultImageUrl"])
        
    except Exception as e:
        print(f"Processing failed: {e}")

cURL Examples

# Create text removal task
curl --request POST \
  --url https://api.kie.ai/api/v1/flux/kontext/generate \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "prompt": "Remove all text from this image while preserving the background",
    "inputImage": "https://example.com/image-with-text.jpg",
    "model": "flux-kontext-pro",
    "aspectRatio": "16:9",
    "enableTranslation": true,
    "safetyTolerance": 2
  }'

# Query task status
curl --request GET \
  --url "https://api.kie.ai/api/v1/flux/kontext/record-info?taskId=task12345" \
  --header 'Authorization: Bearer YOUR_API_KEY'

Webhook Callback Handling Examples

Node.js/Express

const express = require('express');
const fs = require('fs');
const https = require('https');
const app = express();

app.use(express.json());

app.post('/flux-callback', (req, res) => {
  const { code, msg, data } = req.body;
  
  console.log('Received Flux image processing callback:', {
    taskId: data.taskId,
    status: code,
    message: msg
  });
  
  if (code === 200) {
    // Task completed successfully
    console.log('Image processing completed successfully');
    const { taskId, info } = data;
    const { originImageUrl, resultImageUrl } = info;
    
    console.log(`Original image URL: ${originImageUrl}`);
    console.log(`Result image URL: ${resultImageUrl}`);
    console.log('Note: Original image URL valid for 10 minutes only');
    
    // Download result image
    if (resultImageUrl) {
      downloadFile(resultImageUrl, `result_${taskId}.jpg`)
        .then(() => console.log('Result image downloaded successfully'))
        .catch(err => console.error('Result image download failed:', err));
    }
    
    // Download original image (if needed)
    if (originImageUrl) {
      downloadFile(originImageUrl, `original_${taskId}.jpg`)
        .then(() => console.log('Original image downloaded successfully'))
        .catch(err => console.error('Original image download failed:', err));
    }
    
  } else {
    // Task failed
    console.log('Image processing failed:', msg);
    
    // Handle specific error types
    if (code === 400) {
      console.log('Content policy violation - please adjust prompt');
    } else if (code === 500) {
      console.log('Internal error - please try again later');
    } else if (code === 501) {
      console.log('Generation task failed - may need to adjust parameters');
    }
  }
  
  // Return 200 status code to confirm callback received
  res.status(200).json({ status: 'received' });
});

// Helper function: download files
function downloadFile(url, filename) {
  return new Promise((resolve, reject) => {
    const file = fs.createWriteStream(filename);
    https.get(url, (response) => {
      if (response.statusCode === 200) {
        response.pipe(file);
        file.on('finish', () => {
          file.close();
          resolve();
        });
      } else {
        reject(new Error(`HTTP ${response.statusCode}`));
      }
    }).on('error', reject);
  });
}

app.listen(3000, () => {
  console.log('Callback server running on port 3000');
});

Best Practices

Performance Optimization

  1. Use Callback Mechanism: Set up webhook callbacks instead of polling for better performance
  2. Choose Appropriate Model: Use flux-kontext-pro for standard tasks, flux-kontext-max for complex scenes
  3. Prompt Engineering: Use detailed, specific prompts for better results
  4. Image Preprocessing: Ensure input images are accessible and optimized
  5. Timely Download: Images expire after 14 days, original image links valid for 10 minutes, download promptly
  6. Translation Settings: If prompts are already in English, set enableTranslation: false

Error Handling Strategy

async function handleTextRemoval(imageUrl, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const result = await api.processImageTextRemoval(imageUrl);
      return result;
    } catch (error) {
      if (error.message.includes('429')) {
        // Rate limit, exponential backoff retry
        await new Promise(resolve => 
          setTimeout(resolve, Math.pow(2, i) * 1000)
        );
        continue;
      } else if (error.message.includes('400')) {
        // Content policy violation, don't retry
        console.error('Content violation, please modify input:', error.message);
        throw error;
      } else if (error.message.includes('500')) {
        // Server error, can retry
        if (i === maxRetries - 1) throw error;
        continue;
      } else {
        // Other errors, throw directly
        throw error;
      }
    }
  }
}

Batch Processing

async function batchProcessImages(imageUrls, maxConcurrency = 3) {
  const results = [];
  
  for (let i = 0; i < imageUrls.length; i += maxConcurrency) {
    const batch = imageUrls.slice(i, i + maxConcurrency);
    const batchPromises = batch.map(url => 
      handleTextRemoval(url).catch(err => ({ error: err.message, url }))
    );
    const batchResults = await Promise.all(batchPromises);
    results.push(...batchResults);
  }
  
  return results;
}

Important Limitations and Considerations

Language Support

  • Prompts support English only (use enableTranslation: true for automatic translation)

Image Storage

  • Generated images: Stored for 14 days then automatically expire
  • Original image URLs: Valid for 10 minutes only, need immediate download

Safety Tolerance

  • Generation mode: 0-6 (higher values are more permissive)
  • Editing mode: 0-2 (editing mode has stricter limits)

Input Image Requirements

  • Must be publicly accessible URLs
  • Support common image formats (JPEG, PNG, etc.)

Callback Requirements

  • Callback URL must be publicly accessible address
  • Server must respond within 15 seconds, otherwise considered timeout
  • After 3 consecutive retry failures, system stops sending callbacks

Troubleshooting

Common Problem Solutions

  1. Callbacks Not Received

    • Check if callback URL is publicly accessible
    • Confirm server returns 200 status code within 15 seconds
    • Check firewall settings
  2. Image Download Failed

    • Confirm image URL is accessible
    • Note original image URL 10-minute validity
    • Check network connection and download permissions
  3. Content Policy Violation

    • Check if prompt contains sensitive content
    • Adjust prompt to comply with platform content guidelines
    • Ensure image content is compliant
  4. Generation Failed

    • Check if generation parameters are reasonable
    • Verify input image format and quality
    • Consider adjusting safety tolerance and retrying

Support & Contact


Based on KIE AI Flux Kontext API v1 - Last updated: 2024-01-15