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
| Scenario | Endpoint |
|---|
| Local file upload | POST /v1/files/uploads |
| Base64 image upload | POST /v1/files/uploads/base64 |
| Remote image rehosting | POST /v1/files/uploads/url |
| Presigned direct R2 upload | POST /v1/files/uploads/presign |
Common limits:
| Item | Current rule |
|---|
| Auth | Authorization: Bearer YOUR_API_KEY |
| Supported formats | image/png, image/jpeg, image/webp, image/gif |
| Single file size | 20MB |
| User upload quota | 200MB / rolling 24-hour window |
| Default expiration | 48 hours |
| Returned URL | https://media.crazyrouter.com/task-artifacts/tmp-inputs/... |
Local File Upload
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 -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 -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 -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 -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:
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 -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.