Goodtake AI

Seedream - Image Generation

Generate high-quality AI images using ByteDance's Seedream model

Overview

The Seedream endpoint allows you to generate high-quality AI images from text descriptions using ByteDance's advanced image generation models. Seedream produces stunning, realistic images for a wide variety of use cases. This endpoint also supports image blending/editing when source images are provided.

Endpoint: POST /api/v1/bytedance/generate-image

Authentication

This endpoint requires authentication. Include your API key in the request headers:

Authorization: Bearer gt_your_api_key_here

See the Authentication guide for more details.

Model Variants

GoodTake AI offers two versions of the Seedream model:

The latest version released on November 28, 2025. This model offers:

  • Improved Quality: Enhanced image fidelity and detail
  • Better Prompt Understanding: More accurate interpretation of complex prompts
  • Enhanced Consistency: Better handling of style and composition
  • Faster Generation: Optimized inference speed

Use this model for: Production applications, highest quality output, and best prompt adherence.

seedream-4-0-250828 (Legacy)

The previous version released on August 28, 2025. This model provides:

  • Stable Performance: Well-tested and reliable
  • Consistent Results: Predictable output for known prompts
  • Lower Cost: May consume fewer credits per generation

Use this model for: Backward compatibility, cost optimization, or when you need consistent results with existing prompts.

Recommendation: Use seedream-4-5-251128 for new projects. The legacy model is maintained for backward compatibility.

Request

Endpoint

POST https://api.goodtake.ai/api/v1/bytedance/generate-image

Headers

HeaderValueRequired
AuthorizationBearer gt_your_api_keyYes
Content-Typeapplication/jsonYes

Request Body

{
  "prompt": "A beautiful sunset over mountains",
  "model": "seedream-4-5-251128",
  "number_of_images": 1,
  "size": "2K",
  "optimize_prompt_mode": "standard",
  "include_base64_encoding": false,
  "image_urls": []
}

Parameters

ParameterTypeRequiredDefaultDescription
promptstringYes-Text description of the image to generate or edit
modelstringNoseedream-4-5-251128Model variant to use. Options: seedream-4-5-251128 (latest), seedream-4-0-250828 (legacy)
number_of_imagesintegerNo1Number of images to generate (1-4)
sizestringNo2KImage dimensions. See Supported Image Sizes below for allowed values per model
optimize_prompt_modestringNostandardPrompt optimization mode. Options: standard, creative, precise
include_base64_encodingbooleanNofalseIf true, response includes base64-encoded image data in addition to URLs
image_urlsarrayNo[]Array of HTTP URLs or base64 data URIs for image blending/editing. If provided, routes to blend-images mode

Supported Image Sizes

Important: Each model supports different image sizes. Using an unsupported size will result in a 400 Bad Request error. Always verify the size is supported for your chosen model.

Seedream 4.5 (seedream-4-5-251128)

The latest Seedream 4.5 model supports the following sizes:

SizeDescription
1KAutomatic 1K resolution (optimized aspect ratio)
2KAutomatic 2K resolution (optimized aspect ratio)
4KAutomatic 4K resolution (optimized aspect ratio)

Exact Dimensions

SizeAspect RatioOrientationResolution
2048x20481:1Square4.2 MP
2304x17284:3Landscape4.0 MP
1728x23043:4Portrait4.0 MP
2560x144016:9Widescreen Landscape3.7 MP
1440x25609:16Mobile Portrait3.7 MP
2496x16643:2Standard Photo4.2 MP
1664x24962:3Portrait Photo4.2 MP
3024x129621:9Ultra-wide Cinematic3.9 MP

Recommendation: Use auto-size modes (2K, 4K) for best results. The model automatically optimizes the aspect ratio based on your prompt.

Seedream 4.0 (seedream-4-0-250828)

The legacy Seedream 4.0 model supports these sizes:

SizeAspect RatioResolution
512x5121:10.26 MP
768x7681:10.59 MP
1024x10241:11.0 MP
1024x7684:30.79 MP
768x10243:40.79 MP
1920x108016:92.1 MP
1080x19209:162.1 MP

Common Error: The size 1024x1024 is only supported by Seedream 4.0, not by Seedream 4.5. If you're using the latest model and receive a 400 Bad Request error, switch to 2K, 2048x2048, or another supported size.

Base64 Encoding

The include_base64_encoding parameter controls whether the API returns base64-encoded image data in the response:

When to Use Base64 Encoding

Set include_base64_encoding: true when:

  • You need immediate inline image data without additional HTTP requests
  • Building applications that process images locally before storage
  • Working in environments with limited external HTTP access
  • Implementing real-time image processing pipelines

Set include_base64_encoding: false (default) when:

  • You only need CDN URLs for display
  • Optimizing response payload size
  • Images will be loaded directly in web browsers
  • Reducing bandwidth and API response times

Performance Impact: Base64 encoding increases response size by ~33% and adds processing time. Only enable when you need the raw image data.

Base64 Response Format

When include_base64_encoding: true, each image object includes a base64 field:

{
  "url": "https://cdn.goodtake.ai/images/abc123.png",
  "base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}

You can use this data URI directly in HTML:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="Generated image" />

Image Blending Mode

When image_urls array is provided with HTTP URLs or base64 data URIs, the endpoint automatically routes to blend-images mode for image editing and composition.

Blending Use Cases

  • Style Transfer: Apply the style of one image to another
  • Image Editing: Modify existing images based on text prompts
  • Composition: Combine multiple images into a cohesive result
  • Variations: Generate variations of an existing image

Blending Example

{
  "prompt": "Transform this landscape into a cyberpunk scene with neon lights",
  "model": "seedream-4-5-251128",
  "image_urls": [
    "https://example.com/landscape.jpg"
  ],
  "number_of_images": 1
}

You can also use base64 data URIs directly:

{
  "prompt": "Add dramatic lighting and enhance colors",
  "image_urls": [
    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  ]
}

Response

Success Response (200 OK)

Standard Response (without base64):

{
  "status": "success",
  "data": {
    "images": [
      {
        "url": "https://cdn.goodtake.ai/images/abc123.png",
        "width": 1024,
        "height": 1024
      }
    ],
    "generation_time_ms": 3420,
    "model": "seedream-4-5-251128",
    "prompt": "A beautiful sunset over mountains"
  }
}

Response with Base64 Encoding:

{
  "status": "success",
  "data": {
    "images": [
      {
        "url": "https://cdn.goodtake.ai/images/abc123.png",
        "base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
        "width": 1024,
        "height": 1024
      }
    ],
    "generation_time_ms": 3420,
    "model": "seedream-4-5-251128",
    "prompt": "A beautiful sunset over mountains"
  }
}

Response Fields

FieldTypeDescription
statusstringResponse status ("success" or "error")
data.imagesarrayArray of generated image objects
data.images[].urlstringCDN URL of the generated image (always present)
data.images[].base64stringBase64 data URI (only if include_base64_encoding: true)
data.images[].widthintegerActual width of the generated image
data.images[].heightintegerActual height of the generated image
data.generation_time_msintegerTime taken to generate in milliseconds
data.modelstringModel variant used for generation
data.promptstringThe prompt used for generation

Error Responses

400 Bad Request

{
  "error": {
    "code": "invalid_parameters",
    "message": "Width must be between 128 and 2048 pixels"
  }
}

401 Unauthorized

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key"
  }
}

403 Forbidden

{
  "error": {
    "code": "insufficient_credits",
    "message": "Insufficient credits to complete this request"
  }
}

429 Too Many Requests

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please try again in 60 seconds.",
    "retry_after": 60
  }
}

Examples

Basic Image Generation

curl -X POST https://api.goodtake.ai/api/v1/bytedance/generate-image \
  -H "Authorization: Bearer gt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A beautiful sunset over mountains"
  }'

Using Latest Model with Custom Size

curl -X POST https://api.goodtake.ai/api/v1/bytedance/generate-image \
  -H "Authorization: Bearer $GOODTAKE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A cyberpunk cityscape with neon lights and flying cars",
    "model": "seedream-4-5-251128",
    "size": "2560x1440",
    "number_of_images": 2,
    "optimize_prompt_mode": "creative"
  }'

Using Legacy Model

curl -X POST https://api.goodtake.ai/api/v1/bytedance/generate-image \
  -H "Authorization: Bearer $GOODTAKE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A serene forest path with morning mist",
    "model": "seedream-4-0-250828",
    "size": "1024x1024"
  }'

With Base64 Encoding

curl -X POST https://api.goodtake.ai/api/v1/bytedance/generate-image \
  -H "Authorization: Bearer $GOODTAKE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A futuristic robot in a laboratory",
    "model": "seedream-4-5-251128",
    "include_base64_encoding": true
  }'

Image Blending/Editing

curl -X POST https://api.goodtake.ai/api/v1/bytedance/generate-image \
  -H "Authorization: Bearer $GOODTAKE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Transform into a dramatic noir style with high contrast",
    "model": "seedream-4-5-251128",
    "image_urls": ["https://example.com/photo.jpg"]
  }'

Python Example

import requests
import os
import base64

API_KEY = os.environ.get("GOODTAKE_API_KEY")
BASE_URL = "https://api.goodtake.ai"

def generate_image(prompt, model="seedream-4-5-251128", size="2K", 
                   include_base64=False):
    """Generate an image using GoodTake AI"""
    response = requests.post(
        f"{BASE_URL}/api/v1/bytedance/generate-image",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "prompt": prompt,
            "model": model,
            "size": size,
            "number_of_images": 1,
            "optimize_prompt_mode": "standard",
            "include_base64_encoding": include_base64
        }
    )
    
    response.raise_for_status()
    data = response.json()
    return data["data"]["images"][0]

def blend_image(prompt, image_url, model="seedream-4-5-251128"):
    """Blend/edit an existing image"""
    response = requests.post(
        f"{BASE_URL}/api/v1/bytedance/generate-image",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "prompt": prompt,
            "model": model,
            "image_urls": [image_url],
            "number_of_images": 1
        }
    )
    
    response.raise_for_status()
    data = response.json()
    return data["data"]["images"][0]

# Example 1: Basic generation
image = generate_image("A beautiful sunset over mountains")
print(f"Generated image URL: {image['url']}")

# Example 2: Using legacy model
image = generate_image(
    "A serene forest path",
    model="seedream-4-0-250828"
)
print(f"Generated with legacy model: {image['url']}")

# Example 3: With base64 encoding
image = generate_image(
    "A futuristic cityscape",
    include_base64=True
)
print(f"URL: {image['url']}")
print(f"Has base64: {'base64' in image}")

# Example 4: Image blending
edited = blend_image(
    "Add dramatic sunset lighting",
    "https://example.com/landscape.jpg"
)
print(f"Edited image: {edited['url']}")

JavaScript/Node.js Example

const GOODTAKE_API_KEY = process.env.GOODTAKE_API_KEY;
const BASE_URL = "https://api.goodtake.ai";

async function generateImage(prompt, options = {}) {
  const payload = {
    prompt,
    model: options.model || "seedream-4-5-251128",
    size: options.size || "2K",
    number_of_images: options.numberOfImages || 1,
    optimize_prompt_mode: options.optimizeMode || "standard",
    include_base64_encoding: options.includeBase64 || false,
    image_urls: options.imageUrls || []
  };

  const response = await fetch(`${BASE_URL}/api/v1/bytedance/generate-image`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${GOODTAKE_API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(payload)
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Error: ${error.error.message}`);
  }

  const data = await response.json();
  return data.data.images[0];
}

async function blendImage(prompt, imageUrl, model = "seedream-4-5-251128") {
  return generateImage(prompt, {
    model,
    imageUrls: [imageUrl]
  });
}

// Example 1: Basic generation
generateImage("A beautiful sunset over mountains")
  .then(image => console.log(`Generated: ${image.url}`))
  .catch(error => console.error(error));

// Example 2: Using latest model with widescreen size
generateImage("A cyberpunk street scene", {
  model: "seedream-4-5-251128",
  size: "2560x1440",
  optimizeMode: "creative"
})
  .then(image => console.log(`Generated: ${image.url}`))
  .catch(error => console.error(error));

// Example 3: With base64 encoding
generateImage("A futuristic robot", {
  includeBase64: true
})
  .then(image => {
    console.log(`URL: ${image.url}`);
    console.log(`Has base64: ${!!image.base64}`);
  })
  .catch(error => console.error(error));

// Example 4: Image blending
blendImage(
  "Add dramatic noir lighting",
  "https://example.com/photo.jpg"
)
  .then(image => console.log(`Edited: ${image.url}`))
  .catch(error => console.error(error));

Go Example

package main

import (
    "bytes"
    "context"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
)

const BaseURL = "https://api.goodtake.ai"

// SeedreamRequest represents the image generation request
type SeedreamRequest struct {
    Prompt               string   `json:"prompt"`
    Model                string   `json:"model,omitempty"`
    NumberOfImages       int      `json:"number_of_images,omitempty"`
    Size                 string   `json:"size,omitempty"`
    OptimizePromptMode   string   `json:"optimize_prompt_mode,omitempty"`
    IncludeBase64Encoding bool    `json:"include_base64_encoding,omitempty"`
    ImageURLs            []string `json:"image_urls,omitempty"`
}

// Image represents a generated image
type Image struct {
    URL    string `json:"url"`
    Base64 string `json:"base64,omitempty"`
    Width  int    `json:"width"`
    Height int    `json:"height"`
}

// SeedreamResponse represents the API response
type SeedreamResponse struct {
    Status string `json:"status"`
    Data   struct {
        Images           []Image `json:"images"`
        GenerationTimeMs int     `json:"generation_time_ms"`
        Model            string  `json:"model"`
        Prompt           string  `json:"prompt"`
    } `json:"data"`
}

// GenerateImageOptions configures image generation
type GenerateImageOptions struct {
    Model                string
    Size                 string
    NumberOfImages       int
    OptimizePromptMode   string
    IncludeBase64        bool
    ImageURLs            []string
}

// DefaultOptions returns default generation options
func DefaultOptions() GenerateImageOptions {
    return GenerateImageOptions{
        Model:              "seedream-4-5-251128",
        Size:               "2K",
        NumberOfImages:     1,
        OptimizePromptMode: "standard",
        IncludeBase64:      false,
        ImageURLs:          []string{},
    }
}

// GenerateImage generates an image using the GoodTake AI API
func GenerateImage(ctx context.Context, prompt string, opts GenerateImageOptions) (*Image, error) {
    apiKey := os.Getenv("GOODTAKE_API_KEY")
    if apiKey == "" {
        return nil, fmt.Errorf("GOODTAKE_API_KEY environment variable not set")
    }

    reqBody := SeedreamRequest{
        Prompt:               prompt,
        Model:                opts.Model,
        NumberOfImages:       opts.NumberOfImages,
        Size:                 opts.Size,
        OptimizePromptMode:   opts.OptimizePromptMode,
        IncludeBase64Encoding: opts.IncludeBase64,
        ImageURLs:            opts.ImageURLs,
    }

    jsonData, err := json.Marshal(reqBody)
    if err != nil {
        return nil, fmt.Errorf("failed to marshal request: %w", err)
    }

    req, err := http.NewRequestWithContext(
        ctx,
        "POST",
        BaseURL+"/api/v1/bytedance/generate-image",
        bytes.NewBuffer(jsonData),
    )
    if err != nil {
        return nil, fmt.Errorf("failed to create request: %w", err)
    }

    req.Header.Set("Authorization", "Bearer "+apiKey)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, fmt.Errorf("request failed: %w", err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("failed to read response: %w", err)
    }

    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
    }

    var result SeedreamResponse
    if err := json.Unmarshal(body, &result); err != nil {
        return nil, fmt.Errorf("failed to parse response: %w", err)
    }

    if len(result.Data.Images) == 0 {
        return nil, fmt.Errorf("no images generated")
    }

    return &result.Data.Images[0], nil
}

// BlendImage edits an existing image based on a prompt
func BlendImage(ctx context.Context, prompt, imageURL string, model string) (*Image, error) {
    opts := DefaultOptions()
    opts.Model = model
    opts.ImageURLs = []string{imageURL}
    return GenerateImage(ctx, prompt, opts)
}

func main() {
    ctx := context.Background()

    // Example 1: Basic generation with latest model
    image, err := GenerateImage(ctx, "A beautiful sunset over mountains", DefaultOptions())
    if err != nil {
        panic(err)
    }
    fmt.Printf("Generated image: %s\n", image.URL)

    // Example 2: Using widescreen size
    opts := DefaultOptions()
    opts.Size = "2560x1440"
    image, err = GenerateImage(ctx, "A cyberpunk cityscape", opts)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Generated with widescreen: %s\n", image.URL)

    // Example 3: With base64 encoding
    opts = DefaultOptions()
    opts.IncludeBase64 = true
    image, err = GenerateImage(ctx, "A futuristic robot", opts)
    if err != nil {
        panic(err)
    }
    fmt.Printf("URL: %s\n", image.URL)
    fmt.Printf("Has base64: %t\n", image.Base64 != "")

    // Example 4: Image blending
    edited, err := BlendImage(
        ctx,
        "Add dramatic noir lighting",
        "https://example.com/photo.jpg",
        "seedream-4-5-251128",
    )
    if err != nil {
        panic(err)
    }
    fmt.Printf("Edited image: %s\n", edited.URL)
}

Best Practices

Prompt Engineering

For best results, follow these prompt guidelines:

  • Be specific: Instead of "a cat", use "a fluffy orange tabby cat sitting on a windowsill"
  • Include style: Add style keywords like "photorealistic", "oil painting", "digital art"
  • Describe lighting: Specify lighting conditions like "golden hour", "dramatic lighting", "soft diffused light"
  • Add details: Include textures, colors, mood, and composition details

Performance Optimization

  • Start with lower steps: Use 30-50 inference steps for testing, increase to 75-100 for final images
  • Use seeds for consistency: When you like a result, save the seed to generate similar images
  • Batch generation: Generate multiple images in one request to save on API calls

Error Handling

Always implement proper error handling:

try:
    image_url = generate_image(prompt)
    print(f"Success: {image_url}")
except requests.exceptions.HTTPError as e:
    if e.response.status_code == 429:
        print("Rate limited. Waiting before retry...")
        time.sleep(60)
    elif e.response.status_code == 403:
        print("Insufficient credits. Please add credits to your account.")
    else:
        print(f"Error: {e}")

Rate Limits

See the Rate Limits documentation for details on usage quotas and limits.

Next Steps

On this page