Turn videos into 3D scenes with 2 API calls
POST a walkthrough video, poll the job, download a Gaussian-splat scene (.ply). Metered credits, automatic refunds on failed reconstructions.
Get API KeyNot a developer? Use the web app instead — no code required.
Easy to integrate
An async job API with a deliberately small surface:
- Source video
- Direct multipart upload (
video_file): MP4 or MOV, up to 1080p, up to 3 minutes, up to 500 MB. - Job status
queued → processing → succeeded | failed | expired, with a coarseprogressvalue for UIs.- Result
- A 3D Gaussian-splat scene: raw
.ply(streams straight into viewers like Spark or SuperSplat) or the provider archive. Splats are view-dependent reconstructions — not editable polygon meshes.
Get started
Create an API key in your dashboard, top up credits, then start your first job. One reconstruction costs 20 credits, charged at creation and automatically refunded if the provider fails. Authenticate with X-Api-Key: v3_live_… (or Authorization: Bearer v3_live_…).
Sample code
The whole lifecycle:
curl -X POST https://usely.tools/api/v1/video-to-3d/jobs \
-H "X-Api-Key: v3_live_..." \
-H "Idempotency-Key: tour-42" \
-F "video_file=@room-tour.mp4"Output format
Finished jobs expose two downloads. Both URLs are same-origin paths authorized by the (unguessable, signed) job id itself.
| Field | Contents | Notes |
|---|---|---|
output.ply_url | Raw 3D Gaussian splat (.ply) | Streams into web viewers; also opens in Blender (splat add-ons), SuperSplat, Polycam viewer |
output.archive_url | Provider archive (zip) | Contains the .ply; provider links expire after ~60 min — re-poll to mint fresh ones |
Honest labeling: output.kind is always gaussian_splat_ply — a view-dependent reconstruction, not a polygon mesh. We do not convert splats into "game-ready" geometry.
The job lifecycle
Reconstructions run minutes to ~an hour. Create the job, then poll every few seconds; the job id stays valid across restarts, so you can persist it and resume polling later.
{
"data": {
"job_id": "job_…",
"status": "succeeded",
"progress": 100,
"output": {
"ply_url": "/api/app/jobs/…/download?extract=ply",
"archive_url": "/api/app/jobs/…/download",
"kind": "gaussian_splat_ply"
},
"error": null
}
}queued/processing- Keep polling.
progressis coarse (stage-based), not a percentage promise. succeededoutputis set; download the scene.failederror.messageexplains what to fix (usually filming technique). The 20 credits are refunded automatically.expired- The provider purged the result; start a new job.
API Reference
POST /api/v1/video-to-3d/jobs
Starts a reconstruction. Requires an API key in the X-Api-Key header (or a Bearer token in Authorization). Returns 202 with the job id.
Request body — multipart/form-data
| Parameter | Type | Description |
|---|---|---|
video_file | binary | The walkthrough video. MP4 or MOV (ISO-BMFF), ≤1080p, ≤3 minutes, ≤500 MB. One continuous take without cuts reconstructs best. |
Request headers
| Header | Description |
|---|---|
X-Api-Key | Your API key (v3_live_…). Also accepted as Authorization: Bearer …. |
Idempotency-Key | Recommended. Retries with the same key return the original response and are never double-charged. |
GET /api/v1/video-to-3d/jobs/{job_id}
Polls a job you created (keys can only see their own jobs). Returns the envelope shown above.
Responses
| Code | Description |
|---|---|
202 | Job created. Body: { "data": { "job_id", "status" }, "credits_charged", "credits_remaining" } plus X-Credits-Charged / X-Credits-Remaining headers. |
200 | Poll result (GET). |
400 / 413 / 422 | Invalid, oversized or non-MP4/MOV input (no credits charged). Envelope: { "error": { "code", "message" } }. |
401 | Missing or invalid API key. |
402 | Insufficient credits (no credits charged). |
429 | Rate limit exceeded (no credits charged). Includes Retry-After. |
Account endpoint
GET /api/v1/account
Fetch the current credit balance for the authenticated key. To track locally, read this once and adjust using the X-Credits-Charged header returned when you create jobs.
{
"data": {
"credits": { "balance": 200 }
}
}