File Upload API
Upload local images (or other allowed file types) to Tokensmart cloud storage. The response returns a key that can be passed as image_key to the Image Edits API for image-to-image generation.
When to use: Only needed for image-to-image workflows where you supply an external reference image. Pure text-to-image (
/v1/images/generations) does not require an upload step.
Request
POST /api/v1/upload
Headers
Authorization: Bearer pk_live_xxxxxxxxxxxxxxxx
Content-Type: multipart/form-data
x-api-key (Anthropic SDK style) is also supported.
Body (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
files | File | ✅ | File(s) to upload. Repeat for multiple files (up to 5 per request). |
Response
{
"success": true,
"uploaded": [
{
"key": "files/USER_ID/UUID_anchor.jpg",
"filename": "anchor.jpg",
"mimeType": "image/jpeg",
"size": 184320,
"isImage": true
}
]
}
If any file fails validation, the response includes an errors array explaining why.
Limits
| Item | Limit |
|---|---|
| Per-file size | 10 MB |
| Files per request | 5 |
| Per-user storage quota | 200 MB (cumulative across all uploads; excess rejected) |
| Rate limit | 10 requests/minute (atomic) |
| Allowed MIME | image/jpeg, image/png, image/gif, image/webp, text/plain, text/csv, text/markdown, application/json, application/pdf |
| Rejected extensions | .exe, .bat, .js, .html, .svg, archives, etc. |
Validation: Beyond the MIME whitelist, the server runs magic-byte header validation (to prevent
.exerenamed to.jpgbypasses) plus extension double-check.
Security
- Files are stored in isolated per-account storage — no cross-user access
- File contents are accessible only by your own API calls (e.g.
/v1/images/edits) - With API key auth, your configured IP whitelist is enforced (same policy as
/v1/chat/completions)
cURL Example
curl -X POST https://api.tokensmart.ai/api/v1/upload \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxx" \
-F "files=@/path/to/anchor.jpg"
Multiple files in one request:
curl -X POST https://api.tokensmart.ai/api/v1/upload \
-H "Authorization: Bearer pk_live_xxxxxxxxxxxxxxxx" \
-F "files=@/path/to/a.jpg" \
-F "files=@/path/to/b.png"
Python Example
import requests
API_KEY = "pk_live_xxxxxxxxxxxxxxxx"
BASE = "https://api.tokensmart.ai"
with open("anchor.jpg", "rb") as f:
res = requests.post(
f"{BASE}/api/v1/upload",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"files": f},
).json()
image_key = res["uploaded"][0]["key"]
print("image_key:", image_key)
Node.js Example
import fs from "fs";
const API_KEY = "pk_live_xxxxxxxxxxxxxxxx";
const BASE = "https://api.tokensmart.ai";
const form = new FormData();
form.append("files", new Blob([fs.readFileSync("anchor.jpg")], { type: "image/jpeg" }), "anchor.jpg");
const res = await fetch(`${BASE}/api/v1/upload`, {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
body: form,
});
const { uploaded } = await res.json();
console.log("image_key:", uploaded[0].key);
Error Codes
| HTTP | Description |
|---|---|
| 400 | Invalid file format / blocked extension / magic-byte mismatch |
| 401 | Invalid or missing API key |
| 403 | IP not whitelisted / account suspended |
| 413 | Request too large (>50MB total) |
| 429 | Rate limit exceeded (10/min) |
| 503 | File service temporarily unavailable |
Next Step
Once you have the key, call the Image Edits API to do image-to-image generation.