Skip to main content
Last updated: 2026-06-06
Crazyrouter provides temporary public image upload endpoints for converting local reference images into model-readable public URLs. They are suitable for Kling, Veo, Seedance, Runway, Luma, MiniMax, Nano Banana Pro, Doubao Seedream, and other APIs that accept image_url, image_urls, image_list, images, or image_input.
Temporary images are kept for 48 hours by default and then cleaned up automatically. Storage during that period is not billed separately; current anti-abuse controls use per-user upload quota and rate limits.

Endpoint Overview

ScenarioEndpoint
Local file uploadPOST /v1/files/uploads
Base64 image uploadPOST /v1/files/uploads/base64
Remote image rehostingPOST /v1/files/uploads/url
Presigned direct R2 uploadPOST /v1/files/uploads/presign
Common limits:
ItemCurrent rule
AuthAuthorization: Bearer YOUR_API_KEY
Supported formatsimage/png, image/jpeg, image/webp, image/gif
Single file size20MB
User upload quota200MB / rolling 24-hour window
Default expiration48 hours
Returned URLhttps://media.crazyrouter.com/task-artifacts/tmp-inputs/...

Local File Upload

cURL
curl -X POST https://api.crazyrouter.com/v1/files/uploads \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@./reference.png" \
  -F "purpose=model_input"
Example response:
{
  "id": "file_e5bbce820b5941409682a9c5e9ba79f1",
  "url": "https://media.crazyrouter.com/task-artifacts/tmp-inputs/2026/06/07/user-1/file_e5bbce820b5941409682a9c5e9ba79f1.png",
  "mime_type": "image/png",
  "size": 2025,
  "expires_at": "2026-06-09T04:41:35Z"
}

Base64 Upload

cURL
curl -X POST https://api.crazyrouter.com/v1/files/uploads/base64 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "data": "data:image/png;base64,iVBORw0KGgoAAA...",
    "filename": "reference.png",
    "purpose": "model_input"
  }'

Remote URL Rehosting

cURL
curl -X POST https://api.crazyrouter.com/v1/files/uploads/url \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "url": "https://example.com/reference.png",
    "filename": "reference.png",
    "purpose": "model_input"
  }'
The remote URL must be an http or https image URL reachable by Crazyrouter servers. The system checks file size, MIME type, and SSRF protection rules.

Presigned Direct R2 Upload

For high-upload-volume workflows, request a presigned upload URL first, then upload the image directly from your client to the storage endpoint with PUT. The image bytes do not pass through the Crazyrouter application server. First, request a direct upload URL:
cURL
curl -X POST https://api.crazyrouter.com/v1/files/uploads/presign \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "filename": "reference.jpg",
    "content_type": "image/jpeg",
    "size": 12345,
    "purpose": "model_input"
  }'
Example response:
{
  "id": "file_e5bbce820b5941409682a9c5e9ba79f1",
  "upload_url": "https://...r2.cloudflarestorage.com/...?...",
  "url": "https://media.crazyrouter.com/task-artifacts/tmp-inputs/2026/06/21/user-1/file_e5bbce820b5941409682a9c5e9ba79f1.jpg",
  "method": "PUT",
  "headers": {
    "Content-Type": "image/jpeg",
    "Content-Length": "12345"
  },
  "mime_type": "image/jpeg",
  "size": 12345,
  "expires_at": "2026-06-22T04:41:35Z",
  "upload_expires_at": "2026-06-21T04:56:35Z"
}
Then upload the file directly to upload_url:
cURL
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  -H "Content-Length: 12345" \
  --data-binary @./reference.jpg
After the upload succeeds, use the returned url as the image URL in the model request.
The upload_url is a short-lived write URL, valid for about 15 minutes by default. Content-Type and Content-Length must match the presign request. Do not pass upload_url to the model; use the returned url instead.

Example: Use a Local Reference Image for Kling Image-to-Video

First, upload the local reference image:
cURL
UPLOAD_RESPONSE=$(curl -sS -X POST https://api.crazyrouter.com/v1/files/uploads \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@./portrait.png" \
  -F "purpose=model_input")

IMAGE_URL=$(python -c "import json,sys; print(json.load(sys.stdin)['url'])" <<< "$UPLOAD_RESPONSE")
echo "$IMAGE_URL"
Then pass the returned IMAGE_URL to Kling image-to-video:
cURL
curl -X POST https://api.crazyrouter.com/kling/v1/videos/image2video \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model_name": "kling-v3",
    "prompt": "The person in the image slowly turns their head and smiles, cinematic lighting",
    "image_urls": ["'"$IMAGE_URL"'"],
    "duration": "5",
    "mode": "std"
  }'
The submit request returns a task ID. Use the Kling task query endpoint to get the final video result.
Temporary URLs are not a permanent asset library. Make sure the URL has not expired before submitting a generation task, and do not store it as a long-term business image URL.