POST /api/v1/storage/lora/upload
API version: v1.2.4
Upload custom LoRA model files for video generation with custom styles.
Endpoint
Plain text
POST /api/v1/storage/lora/uploadAuthentication
Required. Include your API key in the request header:
Plain text
X-API-Key: your-api-key-hereRequest
Content Type
Plain text
multipart/form-dataForm Fields
| Field | Type | Required | Description |
|---|---|---|---|
high_noise_file | file | Yes | High noise .safetensors file |
low_noise_file | file | Yes | Low noise .safetensors file |
name | string | No | Display name for the LoRA model |
description | string | No | Description of the LoRA model |
tags | string | No | JSON array string of tags (e.g., ["anime", "style"]) |
default_scale | float | No | Default LoRA strength (0.0-1.0, default: 1.0) |
File Requirements
- Format:
.safetensorsonly - Files: Both high_noise and low_noise files are required
- Size: Maximum file size depends on server configuration
Response
Success (200 OK)
JSON
{
"lora_id": "550e8400-e29b-41d4-a716-446655440000",
"file_id": "lora-550e8400-e29b-41d4-a716-446655440000",
"name": "My Custom Style",
"status": "pending",
"file_size": 524288000,
"message": "LoRA upload started. Use GET /api/v1/loras/{lora_id}/status to check progress."
}Response Fields
| Field | Type | Description |
|---|---|---|
lora_id | string | Unique UUID identifier for the LoRA model |
file_id | string | File identifier (format: lora-{uuid}) |
name | string | Display name of the LoRA model |
status | string | Upload status: pending, downloading, ready, failed |
file_size | integer | Total file size in bytes |
message | string | Instructions for checking upload progress |
Note: Uploaded LoRAs expire after 24 hours. Check
expires_atin the status response.
Examples
Upload (cURL)
cURL
curl -X POST https://phosor.ai/api/v1/storage/lora/upload \
-H "X-API-Key: your-api-key" \
-F "high_noise_file=@high_noise.safetensors" \
-F "low_noise_file=@low_noise.safetensors" \
-F "name=My Custom Style" \
-F "description=A custom trained LoRA for anime style"Upload with Tags (Python)
Python
import requests
# Prepare files and metadata
files = {
"high_noise_file": ("high_noise.safetensors", open("high_noise.safetensors", "rb")),
"low_noise_file": ("low_noise.safetensors", open("low_noise.safetensors", "rb"))
}
data = {
"name": "Anime Style LoRA",
"description": "Custom trained for anime-style character generation",
"tags": '["anime", "character", "style"]',
"default_scale": 0.8
}
response = requests.post(
"https://phosor.ai/api/v1/storage/lora/upload",
headers={"X-API-Key": "your-api-key"},
files=files,
data=data
)
result = response.json()
lora_id = result["lora_id"]
print(f"LoRA upload started: {lora_id}")
print(f"Status: {result['status']}")Complete Upload Flow
Python
import requests
import time
def upload_lora_and_wait(high_noise_path, low_noise_path, name, api_key):
"""Upload LoRA files and wait for processing to complete"""
# Step 1: Upload files
print("Uploading LoRA files...")
with open(high_noise_path, "rb") as high_f, open(low_noise_path, "rb") as low_f:
response = requests.post(
"https://phosor.ai/api/v1/storage/lora/upload",
headers={"X-API-Key": api_key},
files={
"high_noise_file": ("high_noise.safetensors", high_f),
"low_noise_file": ("low_noise.safetensors", low_f)
},
data={"name": name}
)
if response.status_code != 200:
print(f"Upload failed: {response.text}")
return None
lora_id = response.json()["lora_id"]
print(f"Upload started. LoRA ID: {lora_id}")
# Step 2: Poll for completion
while True:
status_response = requests.get(
f"https://phosor.ai/api/v1/loras/{lora_id}/status",
headers={"X-API-Key": api_key}
)
status_data = status_response.json()
status = status_data["status"]
print(f"Status: {status}")
if status == "ready":
print("LoRA model is ready to use!")
return lora_id
elif status == "failed":
print(f"Upload failed: {status_data.get('error_message')}")
return None
time.sleep(5)
# Usage
lora_id = upload_lora_and_wait(
"high_noise.safetensors",
"low_noise.safetensors",
"My Custom Style",
"your-api-key"
)
if lora_id:
print(f"Use this lora_id in /api/v1/inference/submit: {lora_id}")JavaScript/Node.js Example
JavaScript
const fetch = require('node-fetch');
const FormData = require('form-data');
const fs = require('fs');
async function uploadLora(highNoisePath, lowNoisePath, name, apiKey) {
const formData = new FormData();
formData.append('high_noise_file', fs.createReadStream(highNoisePath));
formData.append('low_noise_file', fs.createReadStream(lowNoisePath));
formData.append('name', name);
const response = await fetch('https://phosor.ai/api/v1/storage/lora/upload', {
method: 'POST',
headers: {
'X-API-Key': apiKey
},
body: formData
});
if (response.ok) {
const result = await response.json();
console.log('LoRA upload started:', result.lora_id);
return result;
} else {
console.error('Upload failed:', await response.text());
return null;
}
}
// Usage
uploadLora(
'./high_noise.safetensors',
'./low_noise.safetensors',
'My Custom Style',
'your-api-key'
).then(result => {
if (result) {
console.log('Check status at: /api/v1/loras/' + result.lora_id + '/status');
}
});Status Transitions
The upload process is non-blocking. Status transitions are:
Plain text
pending → downloading → ready
↘ failed- pending: Upload request received, processing queued
- downloading: Files being processed and stored in Phosor Storage
- ready: LoRA model ready for use in video generation
- failed: Upload failed (check
error_messagefor details)
Error Responses
Invalid File Format (400 Bad Request)
JSON
{
"error": "Invalid file format",
"message": "Only .safetensors files are supported"
}Missing Required Files (400 Bad Request)
JSON
{
"error": "Missing required files",
"message": "Both high_noise_file and low_noise_file are required"
}Unauthorized (401 Unauthorized)
JSON
{
"error": "API key required",
"message": "X-API-Key header is required"
}