curl --request POST \
--url https://mvp.tryunsora.com/api/v1/catalog/quote \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "seedance-2.5",
"mode": "omni",
"inputs": {
"prompt": "A red fox running through fresh snow at sunrise",
"aspect_ratio": "9:16",
"resolution": "720p",
"duration": 8,
"generate_audio": true
}
}
'import requests
url = "https://mvp.tryunsora.com/api/v1/catalog/quote"
payload = {
"model": "seedance-2.5",
"mode": "omni",
"inputs": {
"prompt": "A red fox running through fresh snow at sunrise",
"aspect_ratio": "9:16",
"resolution": "720p",
"duration": 8,
"generate_audio": True
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'seedance-2.5',
mode: 'omni',
inputs: {
prompt: 'A red fox running through fresh snow at sunrise',
aspect_ratio: '9:16',
resolution: '720p',
duration: 8,
generate_audio: true
}
})
};
fetch('https://mvp.tryunsora.com/api/v1/catalog/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://mvp.tryunsora.com/api/v1/catalog/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'seedance-2.5',
'mode' => 'omni',
'inputs' => [
'prompt' => 'A red fox running through fresh snow at sunrise',
'aspect_ratio' => '9:16',
'resolution' => '720p',
'duration' => 8,
'generate_audio' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://mvp.tryunsora.com/api/v1/catalog/quote"
payload := strings.NewReader("{\n \"model\": \"seedance-2.5\",\n \"mode\": \"omni\",\n \"inputs\": {\n \"prompt\": \"A red fox running through fresh snow at sunrise\",\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\",\n \"duration\": 8,\n \"generate_audio\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://mvp.tryunsora.com/api/v1/catalog/quote")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"seedance-2.5\",\n \"mode\": \"omni\",\n \"inputs\": {\n \"prompt\": \"A red fox running through fresh snow at sunrise\",\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\",\n \"duration\": 8,\n \"generate_audio\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://mvp.tryunsora.com/api/v1/catalog/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"seedance-2.5\",\n \"mode\": \"omni\",\n \"inputs\": {\n \"prompt\": \"A red fox running through fresh snow at sunrise\",\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\",\n \"duration\": 8,\n \"generate_audio\": true\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"credits": 123,
"estimate": true,
"mode": "<string>",
"modelId": "<string>"
}{
"error": "<string>",
"success": true,
"code": "<string>",
"message": "<string>"
}Quote a generation
Get the live credit price of one generation with your exact inputs before you run it. Free; nothing is charged.
curl --request POST \
--url https://mvp.tryunsora.com/api/v1/catalog/quote \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "seedance-2.5",
"mode": "omni",
"inputs": {
"prompt": "A red fox running through fresh snow at sunrise",
"aspect_ratio": "9:16",
"resolution": "720p",
"duration": 8,
"generate_audio": true
}
}
'import requests
url = "https://mvp.tryunsora.com/api/v1/catalog/quote"
payload = {
"model": "seedance-2.5",
"mode": "omni",
"inputs": {
"prompt": "A red fox running through fresh snow at sunrise",
"aspect_ratio": "9:16",
"resolution": "720p",
"duration": 8,
"generate_audio": True
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'seedance-2.5',
mode: 'omni',
inputs: {
prompt: 'A red fox running through fresh snow at sunrise',
aspect_ratio: '9:16',
resolution: '720p',
duration: 8,
generate_audio: true
}
})
};
fetch('https://mvp.tryunsora.com/api/v1/catalog/quote', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://mvp.tryunsora.com/api/v1/catalog/quote",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'seedance-2.5',
'mode' => 'omni',
'inputs' => [
'prompt' => 'A red fox running through fresh snow at sunrise',
'aspect_ratio' => '9:16',
'resolution' => '720p',
'duration' => 8,
'generate_audio' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://mvp.tryunsora.com/api/v1/catalog/quote"
payload := strings.NewReader("{\n \"model\": \"seedance-2.5\",\n \"mode\": \"omni\",\n \"inputs\": {\n \"prompt\": \"A red fox running through fresh snow at sunrise\",\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\",\n \"duration\": 8,\n \"generate_audio\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://mvp.tryunsora.com/api/v1/catalog/quote")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"seedance-2.5\",\n \"mode\": \"omni\",\n \"inputs\": {\n \"prompt\": \"A red fox running through fresh snow at sunrise\",\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\",\n \"duration\": 8,\n \"generate_audio\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://mvp.tryunsora.com/api/v1/catalog/quote")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"seedance-2.5\",\n \"mode\": \"omni\",\n \"inputs\": {\n \"prompt\": \"A red fox running through fresh snow at sunrise\",\n \"aspect_ratio\": \"9:16\",\n \"resolution\": \"720p\",\n \"duration\": 8,\n \"generate_audio\": true\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"credits": 123,
"estimate": true,
"mode": "<string>",
"modelId": "<string>"
}{
"error": "<string>",
"success": true,
"code": "<string>",
"message": "<string>"
}estimate is true while required files are still missing, so the final price may differ; credits can be null for models that can’t be priced until their files are attached.
curl -X POST "https://mvp.tryunsora.com/api/v1/catalog/quote" \
-H "Authorization: Bearer uns_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"inputs": { "prompt": "A red fox running through fresh snow", "duration": 8, "resolution": "720p" }
}'
credits as expectedCredits to Generate to be sure you’re never charged more.Authorizations
An Unsora API key (uns_…). A Clerk session token also works.
Body
Model key from GET /catalog. Older names listed in the model's legacyDbModels (e.g. veo, kling-pro, seedance_2.0) also work. Retired names such as wan, wan_2.6, gpt-image-1.5 and seedream-v5-lite are rejected here; only POST /videos/create and POST /image-generations/create translate them.
"seedance-2.5"
Optional guard: reject the request if the model is from another category.
video, image, motion-control Mode key from GET /catalog. Omit to pick it from the attached media.
"omni"
Inputs in the provider's field names, as listed by GET /catalog. Media fields take URLs; files hosted outside Unsora are imported into your library first. Omitted fields use the model's defaults.
{
"prompt": "A red fox running through fresh snow at sunrise",
"aspect_ratio": "9:16",
"resolution": "720p",
"duration": 8,
"generate_audio": true
}
Response
Quote
Credits one run costs. Null when the model can't be priced until its required files are attached.
True while required files are missing, so the final price may differ.
Provider endpoint the request routes to.

