Text to video
Start with a text prompt when no source media is needed. Select seedance-2.0 or seedance-2.5 and check the model-specific output settings.
Video APIs
Compare Seedance video APIs for text-to-video and reference-driven workflows. Review supported inputs, pricing, job polling and completed-video retrieval.
Current Seedance models are billed by completion tokens. Duration affects estimated usage; it is not the settlement unit. Keep the job ID to retrieve the result or report a failure.
Built for a specific job
Start with a text prompt when no source media is needed. Select seedance-2.0 or seedance-2.5 and check the model-specific output settings.
Animate a starting image with a motion prompt. Use the image-to-video guide for the selected model rather than mixing fields from other input modes.
Provide a first frame and, when needed, a last frame to guide the shot endpoints. Check the frame roles and media requirements in the model guide.
Combine references using their documented image, video and audio roles. At least one image or video reference is required; an audio reference alone is not sufficient.
Billing unit
USD per million completion tokens. The applicable rate depends on the model, output resolution, and video-reference conditions.
Operational limits
Integration guides
Current catalog coverage
Compare API IDs, operations, providers, and prices. Check the catalog date and each operation's billing unit before estimating usage costs.
Generate videos with Seedance 2.0.
POST /v1/video/seedance Video task submission reference GET /v1/jobs/{id} Job polling reference 480p · With video reference
Official price
API Hop price Save 5%
480p · Without video reference
Official price
API Hop price Save 5%
720p · With video reference
Official price
API Hop price Save 5%
720p · Without video reference
Official price
API Hop price Save 5%
1080p · With video reference
Official price
API Hop price Save 5%
1080p · Without video reference
Official price
API Hop price Save 5%
4k · With video reference
Official price
API Hop price Save 5%
4k · Without video reference
Official price
API Hop price Save 5%
Reference price - not independently verified. Check the publisher's current rates, billing units and applicable terms before comparing costs.
Generate videos with Seedance 2.5.
POST /v1/video/seedance Video task submission reference GET /v1/jobs/{id} Job polling reference 480p · With video reference
Official price
API Hop price Save 2%
480p · Without video reference
Official price
API Hop price Save 2%
720p · With video reference
Official price
API Hop price Save 2%
720p · Without video reference
Official price
API Hop price Save 2%
1080p · With video reference
Official price
API Hop price Save 2%
1080p · Without video reference
Official price
API Hop price Save 2%
Reference price - not independently verified. Check the publisher's current rates, billing units and applicable terms before comparing costs.
Request example
These video generation request examples submit one Seedance 2.5 text-to-video task, retain jobId and poll GET /v1/jobs/{jobId} with a time limit. Retrieve outputResult only after COMPLETED; handle FAILED and CANCELLED separately. They are integration examples, not generated-video demonstrations.
# Requires bash, curl and jq. A polling timeout does not cancel the job.
set -euo pipefail
BASE_URL="https://api.apihop.ai"
API_KEY='YOUR_API_KEY'
created=$(curl --fail-with-body --silent --show-error --max-time 30 \
"$BASE_URL/v1/video/seedance" \
-H "Authorization: Bearer $API_KEY" -H 'Content-Type: application/json' \
--data '{"model":"seedance-2.5","prompt":"A calm city street at dawn","duration":5,"resolution":"720p"}')
job_id=$(printf '%s' "$created" | jq -er '.data.jobId | select(. != null) | tostring')
deadline=$((SECONDS + 600))
while (( SECONDS < deadline )); do
job=$(curl --fail-with-body --silent --show-error --max-time 30 \
"$BASE_URL/v1/jobs/$job_id" -H "Authorization: Bearer $API_KEY")
status=$(printf '%s' "$job" | jq -er '.data.status')
case "$status" in
COMPLETED) printf '%s' "$job" | jq -e '.data.outputResult'; exit 0 ;;
FAILED|CANCELLED) printf 'Job %s: %s\n' "$job_id" "$status" >&2; exit 1 ;;
esac
sleep 5
done
printf 'Polling timed out; retain jobId for a later status check: %s\n' "$job_id" >&2
exit 1const baseUrl = "https://api.apihop.ai";
const headers = { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' };
async function request(path, options = {}) {
const response = await fetch(baseUrl + path, { ...options, headers, signal: AbortSignal.timeout(30000) });
if (!response.ok) throw new Error('HTTP ' + response.status);
const result = await response.json();
if (result.success === false) throw new Error(JSON.stringify(result.error));
return result.data;
}
const created = await request('/v1/video/seedance', { method: 'POST', body: JSON.stringify({"model":"seedance-2.5","prompt":"A calm city street at dawn","duration":5,"resolution":"720p"}) });
if (!created?.jobId) throw new Error('Missing data.jobId');
const deadline = Date.now() + 10 * 60 * 1000;
let completed = false;
while (Date.now() < deadline) {
const job = await request('/v1/jobs/' + encodeURIComponent(created.jobId));
if (job.status === 'COMPLETED') {
if (job.outputResult == null) throw new Error('Completed job has no outputResult');
console.log(job.outputResult);
completed = true;
break;
}
if (['FAILED', 'CANCELLED'].includes(job.status)) throw new Error('Job ' + job.status);
await new Promise(resolve => setTimeout(resolve, 5000));
}
if (!completed) throw new Error('Polling timed out; retain jobId for a later status check: ' + created.jobId);import json
import time
import urllib.request
base_url = "https://api.apihop.ai"
headers = {'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json'}
def request(path, body=None):
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(base_url + path, data=data, headers=headers)
with urllib.request.urlopen(req, timeout=30) as response:
result = json.load(response)
if result.get('success') is False:
raise RuntimeError(result.get('error'))
return result['data']
created = request('/v1/video/seedance', json.loads("{\"model\":\"seedance-2.5\",\"prompt\":\"A calm city street at dawn\",\"duration\":5,\"resolution\":\"720p\"}"))
job_id = str(created['jobId'])
deadline = time.monotonic() + 600
while time.monotonic() < deadline:
job = request('/v1/jobs/' + job_id)
if job['status'] == 'COMPLETED':
if job.get('outputResult') is None:
raise RuntimeError('Completed job has no outputResult')
print(job['outputResult'])
break
if job['status'] in ('FAILED', 'CANCELLED'):
raise RuntimeError('Job ' + job['status'])
time.sleep(5)
else:
raise TimeoutError('Polling timed out; retain jobId for a later status check: ' + job_id) Use the API base URL from your account documentation and replace the example placeholders. Send your API key in the Authorization header; never include it in a URL or committed file.