Back to Blog

Seedance 2.5 Local Images: Fix API Upload and URL Errors

Tutorials and Guides4430
Seedance 2.5 Local Images: Fix API Upload and URL Errors

Your Seedance text-to-video request works. Then you add a product image from your laptop, and the request fails.

The problem may occur before video generation begins. A hosted service cannot read an arbitrary file path on your computer, and a URL that works in your browser may depend on a login session the service does not have.

For developers searching for “Seedance 2.5 local,” this distinction becomes important as soon as a workflow uses reference images.

This tutorial covers preparing a local image, choosing a supported transfer method, and separating asset-access failures from model-generation failures. Your image preparation runs locally; the example integration uses hosted model inference.

If you already have a working task submission and polling script, keep it. The resumable Seedance API workflow covers that lifecycle. Here, the focus is the input asset that enters it.

1. Confirm the image contract for your endpoint

Begin with the documentation for the service receiving your request.

BytePlus documents image URL, Base64, and asset-ID inputs in its Seedance 2.5 guide. A gateway may expose the same structure, translate another structure, or support a narrower set of inputs.

Do not assume that every service uses the same field names.

Before writing an upload helper, record:

For a 4SAPI integration, check the current API documentation and confirm the Seedance route available to your account. A working text endpoint does not establish video-task compatibility.

Keep the endpoint, schema, model identifier, and credential together. Mixing examples from different providers is a common way to create a request that looks plausible but cannot be accepted.

2. Understand why local paths fail

A path identifies a file inside a particular environment.

./assets/product.png is meaningful to your Python process if that file exists relative to its working directory. It does not give a remote inference service access to the same bytes.

The same applies to a browser-created blob: URL. That reference belongs to a browser context and is not a public download address.

Image referenceCan a hosted service normally use it directly?
./assets/product.pngNo; your client must read and transfer the file
C:\images\product.pngNo; it is a local filesystem path
file:///home/user/product.pngNo; it refers to a local file
Browser blob: URLNo; it belongs to the browser context
HTTPS image URLPotentially, if accessible and accepted by the service
Base64 data URIPotentially, if the endpoint supports it
Provider asset IDOnly within the documented asset system and access scope

A local web server does not automatically solve the problem. An address using localhost refers to the machine resolving that address, not necessarily your laptop.

For a hosted workflow, transfer the bytes through a documented request format or supply a retrievable asset reference.

3. Inspect the file before submitting a paid job

A filename extension is not sufficient validation.

An image named reference.png could contain another format, be truncated, or have dimensions inappropriate for the selected route. Check the actual image and its byte size before making a generation request.

The following helper prepares a small JPEG or PNG as a data URI. Its five-megabyte limit is a conservative tutorial policy, not a statement of Seedance's maximum upload allowance.

Install Pillow:

bash
python -m pip install Pillow

Save this as prepare_reference.py:

python
import base64
import io
import json
import sys
from pathlib import Path

from PIL import Image

MAX_LOCAL_BYTES = 5 * 1024 * 1024
SUPPORTED_MIME = {
    "JPEG": "image/jpeg",
    "PNG": "image/png",
}

if len(sys.argv) != 3:
    raise SystemExit(
        "Usage: python prepare_reference.py INPUT_IMAGE OUTPUT_JSON"
    )

source = Path(sys.argv[1])
destination = Path(sys.argv[2])

if not source.is_file():
    raise SystemExit("Input image does not exist.")

if source.stat().st_size > MAX_LOCAL_BYTES:
    raise SystemExit("Image exceeds this tutorial's 5 MiB limit.")

raw = source.read_bytes()

if not raw or len(raw) > MAX_LOCAL_BYTES:
    raise SystemExit("Image is empty or exceeds the local limit.")

with Image.open(io.BytesIO(raw)) as image:
    image_format = image.format
    width, height = image.size

    if image_format not in SUPPORTED_MIME:
        raise SystemExit("Use a JPEG or PNG for this example.")

    image.verify()

mime = SUPPORTED_MIME[image_format]
encoded = base64.b64encode(raw).decode("ascii")

prepared = {
    "mime_type": mime,
    "width": width,
    "height": height,
    "source_bytes": len(raw),
    "data_uri": f"data:{mime};base64,{encoded}",
}

with destination.open("x", encoding="utf-8") as output:
    json.dump(prepared, output)

print(f"Prepared {image_format}: {width} x {height}")
print(f"Source bytes: {len(raw)}")
print("Check the selected route's dimension and body-size limits.")

Run it with an image you are authorized to process:

bash
python prepare_reference.py product.png prepared-reference.json

The helper checks a limited set of local properties. It does not establish that the service accepts the image's dimensions, content, or intended use.

Pillow's Image reference documents the image-inspection methods used here.

The output JSON contains the image itself in encoded form. Keep it in private working storage and exclude it from public repositories and routine application logs.

4. Choose Base64 or a retrievable URL

Base64 is convenient for a small first test because the image travels inside the request. That removes a separate remote download dependency.

It also increases the payload. Base64 encoding adds roughly one-third to the original byte count, before the rest of the JSON structure. A modest image can therefore produce a noticeably larger request.

A retrievable URL is often more suitable for larger assets or repeated use. Your application uploads the file to approved storage, then supplies a download reference accepted by the model service.

The tradeoff is operational: the model service must be able to retrieve the image when needed.

Choose based on the endpoint contract and your application:

Do not send a multipart body to a JSON endpoint merely because both approaches can transport images.

5. Assign the image a clear role

An image can define an opening frame or act as a more general reference. Those uses should be represented through the documented request fields.

The following fragment illustrates BytePlus-style content for a first-frame input:

json
{
  "content": [
    {
      "type": "text",
      "text": "A paper sculpture moves gently in a light breeze. Fixed camera, one continuous shot."
    },
    {
      "type": "image_url",
      "image_url": {
        "url": "REPLACE_WITH_SUPPORTED_IMAGE_REFERENCE"
      },
      "role": "first_frame"
    }
  ]
}

This is a content fragment, not a complete gateway request.

The official task-creation reference describes the relevant schema. When using another service, confirm that it accepts this structure before copying it.

For a route that supports data URIs in this field, load prepared-reference.json and use its data_uri value. For a URL-based route, use the approved retrievable URL instead.

Keep the first test visually simple. A recognizable object, a fixed camera, and restrained motion make it easier to distinguish input failure from an unsatisfactory creative result.

6. Give signed URLs enough retrieval time

A signed URL can grant temporary access to a private object without making the entire storage bucket public.

However, the generation service may retrieve the source after a queue delay or retry. A link that expires almost immediately can work during your manual check and fail when the remote worker tries to use it.

Choose an expiry window that covers the expected queue and retrieval period, with an appropriate margin. Avoid treating a fixed number of minutes as universally sufficient.

AWS explains in its presigned URL documentation that temporary signing credentials can shorten a URL's usable lifetime. The link can become invalid when those credentials expire even if the requested URL expiry is later.

Protect signed URLs as access-bearing secrets. Do not paste complete query strings into public issue reports.

When debugging, record the asset's internal identifier, creation time, intended expiry, and retrieval result. Keep the full access URL only where the application needs it.

7. Test access outside your logged-in browser

Opening an image in your normal browser proves less than it appears to.

Your browser may send cookies, follow an authenticated sharing flow, or display a preview page. The remote service may receive an HTML login screen instead of image bytes.

Test the exact download reference without relying on your browser session. For a signed URL, use the documented HTTP method; a URL signed for GET is not necessarily valid for HEAD.

Check the response type and returned content. An HTTP success status alone does not prove that the body is a usable image.

A successful independent download remains a diagnostic check. The model provider can still have network restrictions or retrieval rules that differ from your test environment.

If the URL works from your environment but the model task reports an asset-fetch error, preserve the task ID and sanitized asset metadata for support.

8. Separate the failure stages

Changing the prompt cannot fix every image-to-video error.

Failure stageUseful evidenceLikely next action
Local preparationFile existence, decoded format, byte sizeRepair or replace the source asset
Request validationRejected field or size categoryMatch the endpoint schema
Asset retrievalDownload status and access expiryCorrect storage access or URL lifetime
Content reviewProvider's documented rejection categoryReview the input requirements
GenerationTask ID and terminal statusInvestigate the model-task error
Creative reviewCompleted video and original briefAdjust composition or motion instructions

A service can accept a task before discovering an asset problem. That is why task creation and successful generation must remain separate states in your application.

Do not automatically create another task whenever the local connection times out. Inspect the original task when its identity is known. Otherwise, you may turn one uncertain submission into several intentional generations.

9. Keep an asset record beside the task record

A useful local record connects the source image to the generated output.

Store the source filename or internal asset ID, its checksum, dimensions, transport method, and the intended image role. Link those details to the model ID and task ID.

A checksum helps distinguish visually similar revisions. Two product images can share a filename while containing different crops, labels, or colors.

Keep signed credentials separate from durable audit metadata. An expired URL is a poor long-term identifier, while a stable internal asset ID remains meaningful.

For a small creative team, this record also prevents accidental reuse of an unapproved image. A colleague should be able to determine which source was used without opening several nearly identical files.

10. Evaluate the gateway with one controlled image

Use the same reference image and brief when evaluating an API relay.

Confirm model access and image-input support first. Then submit one short task and record whether the asset was accepted, the job completed, and the result could be retrieved.

Inspect the whole clip. Successful transfer does not guarantee that text on packaging, object proportions, or small visual details remain accurate.

Separate the integration decision from the creative decision. One concerns whether the workflow functions; the other concerns whether the output meets your production requirements.

Only expand to a folder of images after the single-image workflow behaves predictably.

Frequently asked questions

Can Seedance read a file directly from my computer?

A hosted endpoint needs transferred bytes or an accepted asset reference. A local path alone does not give the remote service access to your filesystem.

Does Base64 keep my image offline?

No. Base64 changes how the image is represented in the request. The image still travels to the service receiving that request.

Why does my image link work in a browser but fail through the API?

Possible causes include browser authentication, a preview-page URL, expired signatures, retrieval restrictions, or unsupported image properties. Inspect the actual download behavior and the task's error details.

Should I use a public storage bucket?

A permanently public bucket is not required for every workflow. Consider a supported temporary-access mechanism or another documented transfer method appropriate to your data.

Start with one verified image-to-video task

Open the 4SAPI login to register or sign in, then confirm the Seedance model route and accepted image format before submitting a task.

Use one prepared reference image and a short, measurable prompt. A completed task with a retrievable result gives you a practical foundation for a larger video workflow.

Tags:seedance 2.5 localseedance 2.5 local image uploadseedance image url errorseedance base64 image inputseedance API gateway

Recommended reading

Explore more frontier insights and industry know-how.