Quickstart
From API key to downloadable .ply in four HTTP calls. Any language, any stack — if it can speak HTTPS, it can make splats.
1 · Get an API key
Sign up, open the dashboard, and create a key. It looks like sk_live_... — store it like a password, it's shown only once. Send it on every request:
Authorization: Bearer sk_live_your_key_here2 · Reserve a scan
This returns a job_id and a presigned upload_url (valid 1 hour). Nothing is charged yet.
curl -X POST https://api.makesplat.com/v1/scans \
-H "Authorization: Bearer sk_live_..."
# → { "job_id": "...", "upload_url": "https://...", "expires_in_seconds": 3600 }3 · Upload your video
PUT the file straight to the upload URL — no auth header needed, the URL is signed. MP4/MOV up to 500 MB. Orbit the object slowly with good lighting for best results.
curl -X PUT --upload-file dish.mp4 "<upload_url>"4 · Start processing
Credits are charged here (1.0 for defaults). Pass parameters to trade cost for quality — or call /v1/scans/estimate first to see the price of any combination.
curl -X POST https://api.makesplat.com/v1/scans/<job_id>/start \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"params": {"steps": 15000, "downscale": 2, "matching": "sequential"}}'
# → { "job_id": "...", "status": "queued" }
# 402 = not enough credits. Failed jobs refund automatically.5 · Poll until done, download
Processing takes ~10-40 minutes depending on queue and quality. Poll every 15-30 s; when status isdone, the response carries a signed ply_url (valid 24 h).
curl https://api.makesplat.com/v1/scans/<job_id> \
-H "Authorization: Bearer sk_live_..."
# → { "status": "done", "ply_url": "https://...", "ply_size_mb": 64.2,
# "elapsed_sec": 1240, "credits_charged": "1.0", ... }
curl -o dish.ply "<ply_url>"Parameters
| Param | Range | Default | Effect |
|---|---|---|---|
| steps | 1,000-30,000 | 15,000 | Training iterations — detail vs cost |
| downscale | 1, 2, 4 | 2 | 1 = full resolution (pricier), 4 = quarter |
| num_frames | 30-300 | 120 | Frames extracted from your video |
| matching | sequential · vocab_tree · exhaustive | sequential | Camera-pose matching strategy |
Batch processing
There's no special batch endpoint — just loop. Reserve and start N jobs, then poll them together. Jobs run in parallel on our GPU fleet.
import requests
API = "https://api.makesplat.com"
H = {"Authorization": "Bearer sk_live_..."}
jobs = []
for video in ["a.mp4", "b.mp4", "c.mp4"]:
r = requests.post(f"{API}/v1/scans", headers=H).json()
requests.put(r["upload_url"], data=open(video, "rb"))
requests.post(f"{API}/v1/scans/{r['job_id']}/start", headers=H, json={})
jobs.append(r["job_id"])
# poll until all done, then download each ply_urlRate limits & rules
- 10 starts/min, 30 reserves/min, 120 reads/min per account
- Videos up to 500 MB; upload URLs expire after 1 hour
- Download URLs expire after 24 h — re-poll the job to get a fresh one
- Failed or cancelled scans are refunded automatically