For developers

API documentation

Make 3D models from your own apps, scripts and services: send photos, words or drawings, follow the model while it is made, and download its files.

How it works

The API makes the same models as the app. You send what a model is made from, and the API answers at once with a job: the model is then made on a GPU over the next minutes. Ask for the job until it is done, or have the API tell your server, then download its files.

Address
https://api.zynmesh.ai
Requests
Forms for uploads (multipart), JSON otherwise
Answers
JSON, times in UTC (ISO 8601)
Keys
Made in the app, under Account, API keys

Every endpoint can also be tried in the browser, with your key, at api.zynmesh.ai/docs.

API keys and scopes

Make a key in the app: open Account, API keys and choose New key. Name it after where you’ll use it, choose how far it reaches, and copy it: it is shown once. Send it with every request:

HTTP header
Authorization: Bearer nvk_...

Or on its own, as X-API-Key: nvk_.... A key acts as you, within your account’s limits, and only as far as you let it.

Keep keys on your server. Anyone who can read a key, in a web page or an app you ship, can use it. The API answers browsers only on ZynMesh’s own sites, so calls from other web pages fail anyway.

What a key can do

Each key has one or more scopes. A request the key’s scopes don’t cover is refused with 403 and the code key_scope.

ScopeIt lets the keyEndpoints
models:read See models, follow them while they are made, and download their files.
models:create Make models, and change, texture or remake them (each a new model).
models:update Stop models while they are made, and set where they were taken and their picture.
models:delete Delete models and their files.

How far it reaches

  • Modes. A key that makes models can be kept to some modes, such as objects only. Others are refused with key_mode.
  • Models it sees. Only the models made with it, or all of yours (made in the app or with any key). A key that sees only its own gets 404 for any other model, as if it weren’t there.
  • Models per day. A cap of its own, on top of your account’s limits: 429 with key_limit_day once reached, until midnight (Zurich time).
  • Expiry. After 30 days, 90 days, a year, or never. An expired key gets 401 with key_expired.

To check a key, ask who it is. The answer says how far it reaches, how many models it made today, your account’s limits and usage, and the key’s webhook secret:

curl
curl https://api.zynmesh.ai/v1/me -H "Authorization: Bearer $ZYNMESH_KEY"

{
  "key": {
    "name": "Shop website",
    "hint": "uuHo",
    "scopes": ["models:read", "models:create"],
    "modes": ["object"],
    "access": "own",
    "per_day": 100,
    "made_today": 3,
    "expires_at": null,
    "webhook_secret": "whsec_..."
  },
  "limits": { "at_once": 3, "per_day": 50, "per_month": null, ... },
  "usage": { "active_jobs": 1, "today": 7, "this_month": 41, ... },
  ...
}

Revoke a key in the app, under Account, API keys: it stops at once, with 401 and key_revoked. The models made with it stay. To change what a key can do, make a new one and revoke the old.

Your first model

An object from one photo, in three steps: send the photo, ask for the job until it is done, download the model. Put your key in the ZYNMESH_KEY environment variable first.

curl
curl https://api.zynmesh.ai/v1/image-to-3d \
  -H "Authorization: Bearer $ZYNMESH_KEY" \
  -F image=@chair.jpg \
  -F quality=standard

The answer, at once, with status 202:

JSON
{
  "id": "job_8f2c41d0a9b3e7c65d10",
  "status": "queued",
  "stage": "queued",
  "progress": 0,
  "message": "Queued",
  ...
}

Ask for the job every 5 to 10 seconds:

curl
curl https://api.zynmesh.ai/v1/jobs/job_8f2c41d0a9b3e7c65d10 \
  -H "Authorization: Bearer $ZYNMESH_KEY"

Once it is done, the answer carries the model and every file it came with:

JSON
{
  "id": "job_8f2c41d0a9b3e7c65d10",
  "status": "succeeded",
  "progress": 1,
  "model_url": "https://.../model.glb?expires=...&sig=...",
  "view_url": "https://.../view.glb?expires=...&sig=...",
  "outputs": [
    { "name": "model.glb", "content_type": "model/gltf-binary", "size": 14640768, "url": "https://..." },
    { "name": "model_obj.zip", "content_type": "application/zip", "size": 13341148, "url": "https://..." }
  ],
  "links_expire_at": "2026-10-23T00:00:00Z",
  ...
}

The same in JavaScript and in Python:

JavaScript
// Node 18 or later: fetch, FormData and Blob are built in.
import { readFile, writeFile } from 'node:fs/promises';

const API = 'https://api.zynmesh.ai';
const headers = { Authorization: `Bearer ${process.env.ZYNMESH_KEY}` };

async function call(path, init = {}) {
  const response = await fetch(API + path, { ...init, headers });
  const body = await response.json();
  if (!response.ok) throw new Error(`${response.status} ${body.code ?? ''}: ${JSON.stringify(body.detail)}`);
  return body;
}

const form = new FormData();
form.append('image', new Blob([await readFile('chair.jpg')], { type: 'image/jpeg' }), 'chair.jpg');
form.append('quality', 'standard');
let job = await call('/v1/image-to-3d', { method: 'POST', body: form });

while (job.status === 'queued' || job.status === 'running') {
  await new Promise((resolve) => setTimeout(resolve, 10_000));
  job = await call(`/v1/jobs/${job.id}`);
  console.log(job.status, Math.round(job.progress * 100) + '%', job.message ?? '');
}
if (job.status !== 'succeeded') throw new Error(job.error ?? job.status);

const model = await fetch(job.model_url); // a signed link: no key needed
await writeFile('chair.glb', Buffer.from(await model.arrayBuffer()));
Python
# pip install requests
import os
import time

import requests

API = "https://api.zynmesh.ai"
headers = {"Authorization": f"Bearer {os.environ['ZYNMESH_KEY']}"}

with open("chair.jpg", "rb") as photo:
    response = requests.post(f"{API}/v1/image-to-3d", headers=headers,
                             files={"image": photo}, data={"quality": "standard"})
response.raise_for_status()
job = response.json()

while job["status"] in ("queued", "running"):
    time.sleep(10)
    job = requests.get(f"{API}/v1/jobs/{job['id']}", headers=headers).json()
    print(job["status"], f"{job['progress']:.0%}", job["message"] or "")

if job["status"] != "succeeded":
    raise RuntimeError(job["error"] or job["status"])

model = requests.get(job["model_url"])  # a signed link: no key needed
with open("chair.glb", "wb") as out:
    out.write(model.content)

Up to four photos of the object, in any order, make a better model: send each as images. Every mode works the same way; the endpoints are under Every endpoint.

Following a model

A job goes from queued to running, and ends succeeded, failed or canceled. While it runs, stage names the step, progress goes from 0 to 1, and message says in words what is happening. A failed job says why in error.

An object takes about 7 to 11 minutes, a place from photos a few minutes. The first model after a quiet spell waits a few minutes more for a GPU to start; POST /v1/warmup starts one early, for instance when someone picks a photo.

GET /v1/jobs lists models, newest first, up to 100 at a time; next_before in the answer asks for the next page.

Its files

  • model_url is the model to use (GLB), view_url a lighter copy for showing it in a browser, thumbnail_url a small picture for lists.
  • outputs lists every file with its name, type, size and link.
  • The links work without a key until links_expire_at, a week later, so you can hand them straight to your users. Ask for the job again for fresh links.
  • A model and what it was made from stay until you delete them. Only the largest extras (splat PLY files and point clouds) go after 30 days, on large_files_deleted_after.
ModeFiles
Object, from photos or wordsmodel.glb (PBR textures and a normal map), model_obj.zip (OBJ with its textures), subject.png (the photo cut out), sides.png (the four sides drawn first), picture.png (from words: the picture it was made from)
Place, from photos or a videoscene.spz and preview.spz (Gaussian splats), scene.ply, mesh.glb, points.ply, cameras.json
HomeThe outside as an object (model.glb, model_obj.zip), and per room room-1.spz with its cameras
Building, from floor plansbuilding.glb, building_obj.zip, plan.json and an overlay per drawing
Part, from a drawingpart.step, part.stl, model.glb, part.py (the CadQuery script)
Map areamodel.glb, area.json, preview.png

Webhooks

Instead of asking again and again, send webhook_url (a public https address) with the model. When the job ends, the API posts its JSON there, the same answer as GET /v1/jobs/{id}. It tries three times, at once, after 10 seconds and after a minute, until your server answers with a 2xx.

X-NoView-Event
job.succeeded, job.failed or job.canceled
X-NoView-Timestamp
When it was sent, in seconds since 1970
X-NoView-Signature
sha256= and the HMAC-SHA256 of the timestamp, a dot and the raw body

Check the signature with your key’s webhook secret, from GET /v1/me with the key (key.webhook_secret). Each key made since scopes has its own; keys from before share the server’s, which your admin has. Turn away webhooks whose timestamp is more than five minutes off.

JavaScript
import { createHmac, timingSafeEqual } from 'node:crypto';

// rawBody: the request's body exactly as it arrived (a Buffer), before parsing it.
function verified(rawBody, headers, secret) {
  const timestamp = headers['x-noview-timestamp'] ?? '';
  const expected = 'sha256=' + createHmac('sha256', secret)
    .update(`${timestamp}.`).update(rawBody).digest('hex');
  const given = String(headers['x-noview-signature'] ?? '');
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
  return fresh && given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}
Python
import hashlib
import hmac
import time

def verified(raw_body: bytes, timestamp: str, signature: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body,
                                    hashlib.sha256).hexdigest()
    fresh = abs(time.time() - int(timestamp or 0)) < 300
    return fresh and hmac.compare_digest(expected, signature)

Errors

An answer that isn’t 2xx says what went wrong in detail, in words for people, and most say it in code too, for your code to act on:

HTTP
HTTP/1.1 403 Forbidden

{
  "detail": "This API key can’t make Text models. It can make: Object.",
  "code": "key_mode"
}

A field that is missing or wrong answers 422, with detail listing each problem and where it is.

StatusWhenCodes
401No key, or one that doesn’t workinvalid_key, key_revoked, key_expired
403The key or the account may not do thiskey_scope, key_mode, mode_not_allowed, mode_off, ultra_not_allowed, account_off
404No such model, or one the key doesn’t see
409The model isn’t ready for this, such as stopping one that has finished
413A file is larger than allowed
422A field is missing or wrong, or a file can’t be read
429A limit is reached: wait as the message sayslimit_at_once, limit_day, limit_month, key_limit_day
503The GPUs can’t be reached just now: try again in a minute

Limits

  • Your account’s. How many models at once, a day and a month, for the app and all your keys together. GET /v1/me shows them, what is used, and when the counts start again. Your admin sets them.
  • A key’s own. The models it may make a day, if you gave it a cap.
  • Uploads. Photos and drawings up to 20 MB each; a place up to 32 photos and 200 MB in all, or a video of up to 3 minutes and 200 MB; up to 8 floor plans; a home up to 4 outside and 24 inside photos; a map area up to 3 km on a side and 4 km² in all.

Every endpoint

Made from the API itself, so it always matches it. Paths start at https://api.zynmesh.ai. An endpoint with a scope needs a key that has it; the rest need none.

Make a model

An object, from photos

POST /v1/image-to-3d models:create

Turns one photo of an object, or up to four of it in any order, into a textured, PBR-material 3D model (GLB and OBJ).

Form (multipart): files and fields

image file
PNG, JPEG or WebP photo of one object
images files
or up to 4 photos of it, in any order: the engine works out which side each shows
quality fast | standard | high | ultra · default standard
fast | standard | high | ultra (default standard). Every quality builds the shape with Microsoft TRELLIS.2 at full detail and paints it with Hunyuan3D's PBR painter; the qualities differ in the faces delivered (30,000, 40,000, 80,000, 300,000) and in the texture's size (2K for fast, else 4K) and painted views, not in the shape's detail.
texture true | false · default true
true | false (default true). false makes the shape only, faster and cheaper, and keeps it (shape.npz) so that POST /v1/jobs/{id}/texture can paint it later: a model in two steps, the shape chosen first.
face_count integer · 2,000 to 300,000
2000-300000 (default from quality)
texture_size integer
1024 | 2048 | 4096 (default from quality)
seed integer · 0 to 2,147,483,647
0-2147483647 (default random). Same seed + image + settings gives the same shape.
remove_background auto | always | never · default auto
auto | always | never (default auto: keep an existing transparent cut-out)
normal_map true | false
true | false (default true): bake the full-detail shape's fine surface into a normal map
project_photos true | false
true | false (default true): put the photos' own pixels on the surfaces they show, so lettering and fine patterns stay sharp. false keeps the generated, evenly lit texture.
description text · up to 600 characters
What the photos don't show, or what to change: OpenAI draws the object's sides from the photos and these words first
draw_sides true | false · default true
Have OpenAI redraw the object from all four sides first (the default); false builds from the photos alone
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional WGS 84 degrees: where the input was captured. Without them the location is read from the photo's EXIF GPS or the video's metadata, when present.
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

An object, from words

POST /v1/text-to-3d models:create

Turns a description of an object into a textured, PBR-material 3D model (GLB and OBJ). OpenAI's GPT Image model pictures the object and redraws it from all four sides, Microsoft TRELLIS.2 builds the shape from those views and Hunyuan3D's painter textures it. The picture comes with the model.

Form (multipart): files and fields

prompt required text · up to 600 characters
The object, in any language: what it is, its shape and parts, materials and colours
quality fast | standard | high | ultra · default standard
fast | standard | high | ultra (default standard), as for image-to-3d: the same shape and detail, more faces and a larger texture up the scale.
texture true | false · default true
true | false (default true). false returns untextured geometry.
face_count integer · 2,000 to 300,000
2000-300000 (default from quality)
texture_size integer
1024 | 2048 | 4096 (default from quality)
seed integer · 0 to 2,147,483,647
0-2147483647 (default random): the 3D model's seed; the picture differs each time
images files
optional: up to 4 reference photos of the object or of how it should look
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional: where the object belongs on the map
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

A part or object, from a drawing

POST /v1/drawing-to-3d models:create

Turns a technical drawing into an exact 3D part (STEP, STL and GLB, with its CadQuery code), or a sketch of anything into a textured 3D model.

Form (multipart): files and fields

drawing required file
PNG, JPEG, WebP or PDF: a technical drawing or a sketch
kind auto | part | object · default auto
part: exact CAD from views and dimensions; object: a 3D model of the drawn thing; auto: decide
notes text · up to 600 characters
What the drawing does not say, e.g. 'dimensions in inches'
page integer · 1 to 500 · default 1
The PDF page to read
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional: where the part or object belongs on the map; never read from the file
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

A place, from photos

POST /v1/images-to-environment models:create

Turns overlapping photos of a place (a room, a street, a garden) into a 3D environment: Gaussian splats (SPZ and PLY), a vertex-coloured mesh (GLB), a point cloud and camera poses.

Form (multipart): files and fields

images required files
1-32 overlapping photos of one place
quality fast | standard | high · default standard
fast | standard | high (default standard)
mesh true | false · default true
true | false (default true): also fuse a vertex-coloured mesh
remove_sky true | false · default true
true | false (default true): leave the sky out of the reconstruction
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional WGS 84 degrees: where the input was captured. Without them the location is read from the photo's EXIF GPS or the video's metadata, when present.
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

A place, from a video

POST /v1/video-to-environment models:create

Turns a short video walking through or around a place into a 3D environment. The sharpest frames are picked where the camera has moved, then reconstructed like photos.

Form (multipart): files and fields

video required file
One short MP4, MOV or WebM (H.264, HEVC or VP9) clip of one place
quality fast | standard | high · default standard
fast | standard | high (default standard). fast picks up to 16 frames, the others 32.
mesh true | false · default true
true | false (default true): also fuse a vertex-coloured mesh
remove_sky true | false · default true
true | false (default true): leave the sky out of the reconstruction
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional WGS 84 degrees: where the input was captured. Without them the location is read from the photo's EXIF GPS or the video's metadata, when present.
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

A home, from photos

POST /v1/property-to-3d models:create

Turns photos of a home or apartment, outside and in, into a textured 3D model of the outside (GLB and OBJ) and a 3D scene of each room (Gaussian splats, SPZ). Gemini sorts the inside photos into rooms; Microsoft TRELLIS.2 builds and textures the outside from its photos, and each room is reconstructed like an environment (WorldMirror 2.0). With a location, the building's outline in Overture Maps places the model on the map at its real size, facing its street.

Form (multipart): files and fields

exterior required files
1-4 photos of the outside, in any order: the front, and its sides and back
interior files
up to 24 photos of the inside, any rooms, in any order
quality fast | standard | high | ultra · default standard
fast | standard | high | ultra (default standard): the outside's, as for image-to-3d
texture true | false · default true
true | false (default true). false returns the outside untextured.
face_count integer · 2,000 to 300,000
2000-300000 (default from quality)
texture_size integer
1024 | 2048 | 4096 (default from quality)
seed integer · 0 to 2,147,483,647
0-2147483647 (default random)
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional WGS 84 degrees: where the input was captured. Without them the location is read from the photo's EXIF GPS or the video's metadata, when present.
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

A building, from floor plans

POST /v1/plans-to-environment models:create

Turns floor plan drawings into a true-scale 3D building: walls, doors, windows (with glass) and floor slabs, one storey per drawing, as GLB and OBJ, plus the recognised plan as JSON and an overlay per drawing showing what was recognised.

Form (multipart): files and fields

images required files
1-8 floor plan drawings, one per storey, ground floor first
storey_height number · 2 to 8 · default 2.8
Metres from floor to floor
building_width number · 2 to 2,000
The ground floor's overall outside width in metres, left to right on the drawing; fixes the scale
webhook_url text
optional https URL; receives the finished job, including download links
latitude number · -90 to 90
Where the photos or video were taken (WGS 84 degrees). Send it with longitude; it takes precedence over the files' metadata.
longitude number · -180 to 180
optional WGS 84 degrees: where the building stands. Drawings carry no position, so it is never read from the files.
heading number · 0 to 360
Compass direction the (first) photo faced, in degrees from north
location_source photo | video | device | manual · default manual
Where latitude and longitude came from, for display
detect_location true | false · default true
Without latitude and longitude, read the location from the photo's EXIF GPS or the video's metadata

A map area

POST /v1/area-to-3d models:create

Turns a rectangle of the map into a 3D model of its ground and buildings, in metres, laid out so it can be laid back over the map: terrain from open elevation data, buildings from OpenStreetMap and Overture Maps (heights, floors, roof shapes), coloured by free government aerial photos where they exist and as a plain map elsewhere. GLB, plus area.json saying where it lies and a picture of it from above.

Form fields

west required number · -180 to 180
The area's western edge, WGS 84 degrees
south required number · -85 to 85
Its southern edge
east required number · -180 to 180
Its eastern edge
north required number · -85 to 85
Its northern edge
webhook_url text
optional https URL; receives the finished job, including download links

Follow and manage models

List models

GET /v1/jobs models:read

Your models, newest first: every one you made in the app or with any key, or for a key that sees only its own, those made with it. next_before asks for the next page.

limit integer · 1 to 100 · default 20
How many models to list, newest first.
before number
For the next page: next_before from the page before.

Get a model

GET /v1/jobs/{job_id} models:read

A model: its status and progress while it is made, then its files (signed links), stats and location. Each answer carries fresh links.

job_id required text
The model's id, from the answer that made it (job_...).

Stop a model

POST /v1/jobs/{job_id}/cancel models:update

Stops a model that is waiting or being made. 409 once it has finished.

job_id required text
The model's id, from the answer that made it (job_...).

Delete a model

DELETE /v1/jobs/{job_id} models:delete

Deletes a model and all its files (stopping it first if it is still being made). This can't be undone.

job_id required text
The model's id, from the answer that made it (job_...).

Change a model

Change it by description

POST /v1/jobs/{job_id}/edit models:create

Change a finished object or part by description: a new job, made from the model and the words.

Form (multipart): files and fields

job_id required text
The model's id, from the answer that made it (job_...).
instruction required text · up to 600 characters
The change, in any language: 'make the roof dark grey', 'make the bore 12 mm'
images files
Objects: 4 pictures of the model from its front, left side (the side on the right in the front view), back and right side, in that order. Without them, the pictures it was built from
quality fast | standard | high | ultra
Objects: the edited model's quality (default: the original's)
webhook_url text
A public https URL. The finished job's JSON is sent there, signed (see Webhooks).

Add textures to a shape

POST /v1/jobs/{job_id}/texture models:create

The second step of a model made shape first (texture=false): paint the kept shape with the photos it was made from. A new job; the shape stays as it is.

Form fields

job_id required text
The model's id, from the answer that made it (job_...).
quality fast | standard | high | ultra
The texture's quality: fast, standard or high (default: the shape's own). Ultra is for shapes: the painter's settings stop at high.
project_photos true | false
Put the photos' own pixels on the surfaces they show (default: as the shape was asked for, true)
webhook_url text
A public https URL. The finished job's JSON is sent there, signed (see Webhooks).

Make it again

POST /v1/jobs/{job_id}/again models:create

The same model again from the same photos and settings, with another seed: another shape to choose from when the first is not right. A new job; the first stays.

Form fields

job_id required text
The model's id, from the answer that made it (job_...).
seed integer · 0 to 2,147,483,647
default: a new random seed
webhook_url text
A public https URL. The finished job's JSON is sent there, signed (see Webhooks).

Set where it was taken

PUT /v1/jobs/{job_id}/location models:update

Set or correct where a job's input was captured, and how to lay the result over a map.

JSON body

job_id required text
The model's id, from the answer that made it (job_...).
latitude required number · -90 to 90
Where it was captured: WGS 84 degrees north
longitude required number · -180 to 180
WGS 84 degrees east
heading number · 0 to 360
Compass direction the first camera faced, in degrees from north
scale number · at most 1000000
Environments: metres per scene unit, to lay them over a map at size
source device | manual · default manual
Used when the position changes

Remove where it was taken

DELETE /v1/jobs/{job_id}/location models:update

Removes where a model was captured.

job_id required text
The model's id, from the answer that made it (job_...).

Set its picture

PUT /v1/jobs/{job_id}/poster models:update

The picture lists show for a finished model, rendered from the model by the app's viewer (the server has no GPU to render with). Kept as a 640 px WebP.

Form (multipart): files and fields

job_id required text
The model's id, from the answer that made it (job_...).
image required file
PNG, JPEG or WebP picture of the finished model

Your key, and the rest

Your key, limits and usage

GET /v1/me no scope

Who is asking: the account, its limits and today's usage, and with an API key, the key itself: how far it reaches, how many models it made today and its webhook secret.

What the API makes

GET /v1/capabilities no scope

Every kind of model the API makes: its endpoint, its options in words and its quality presets.

Start a GPU early

POST /v1/warmup models:create

Start a GPU worker for capability early, e.g. when a photo is chosen, so the job that follows starts sooner. Throttled server-side; it makes nothing.

capability text · default image-to-3d
The kind of model to start a GPU for, such as image-to-3d.
quality text
The quality the job will ask for: image-to-3d's ultra runs on its own worker

Download a file

GET /v1/files/{job_id}/{name} no scope

A file of a model, by the signed link in the job's answer: no key needed, until the link expires (links_expire_at). Ask for the job again for fresh links.

job_id required text
The model's id, from the answer that made it (job_...).
name required text
The file's name, from the job's outputs.
expires required integer
Part of the signed link: copy links from the job as they are.
sig required text · up to 64 characters
Part of the signed link: copy links from the job as they are.

Status

GET /healthz no scope

Whether the API is up, which workers it can reach, and how many jobs wait and run.