> For the complete documentation index, see [llms.txt](https://docs.projectsim.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.projectsim.ai/creating-assets/assets-measured.md).

# Measured asset

`POST /v1/assets/measured`

Same pipeline as the [standard asset](/creating-assets/assets-standard.md) **plus a metric-scale stage**, so the result is **up to mm accurate**. This route **requires** a ChArUco capture video as the measurement reference.

<figure><img src="https://70818391-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWnQtI3aVPkZHPVyrjjFG%2Fuploads%2Fgit-blob-cb3c717c7728b343917365a9094235228bccc824%2Fmeasured-examples.png?alt=media" alt="Five reconstructed household products in different container and packaging shapes"><figcaption><p>Reconstruct household objects at measured scale for precision grasping and contact-rich manipulation.</p></figcaption></figure>

## Input

| Field                       | Notes                                                                                                                                                                                                                 |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inputs.images` (required)  | Exactly **one** image — the reconstruction input: an HTTPS `url` or inline base64 `data`; ≤ 100 MB, PNG, JPEG or WebP.                                                                                                |
| `inputs.capture` (required) | Exactly **one video clip** (MP4/MOV, ≤ 500 MB) of the object beside a printed ChArUco board — an HTTPS `url` or inline base64 `data`. See [Capturing an asset](/creating-assets/assets-measured/measured-capture.md). |
| `name`                      | Display label (≤ 100 chars).                                                                                                                                                                                          |
| `params`                    | Optional output settings; see [Parameters that apply](#parameters-that-apply).                                                                                                                                        |
| `Idempotency-Key` (header)  | Makes a retry safe.                                                                                                                                                                                                   |

Omit `inputs.capture` and the request is a `422`; `inputs.text` is not accepted on this route, even alongside an image. The scale stage measures the object against the known-size board in the clip.

As on the standard route, an inline image or clip is format-checked at create (`422`), while one given by URL is fetched by the job, so a bad URL fails the job. The request body is capped at 832 MB (`413`), so prefer a URL for a large clip, and any account-specific asset limit applies (`429` `asset-limit-reached`).

## Parameters that apply

`mesh`, `texture`, and `physics` all apply, exactly as for the standard route. See [Parameters](/creating-assets/parameters.md).

## Example

Install the generated Python SDK and set `PROJECTSIM_TOKEN` as shown in the [Quickstart](/getting-started/quickstart.md).

{% tabs %}
{% tab title="Python" %}

```python
import os
import uuid

import httpx
from projectsim import AuthenticatedClient
from projectsim.api.assets import create_asset_measured
from projectsim.models import (
    MeasuredAssetInputs,
    CaptureInput,
    CreateMeasuredAssetRequest,
    ImageInput,
    Params,
    PhysicsParams,
)

client = AuthenticatedClient(
    base_url="https://api.projectsim.ai",
    token=os.environ["PROJECTSIM_TOKEN"],
    timeout=httpx.Timeout(30.0),
    raise_on_unexpected_status=True,
)

body = CreateMeasuredAssetRequest(
    name='piston conn rod',
    inputs=MeasuredAssetInputs(
        images=[ImageInput(
            url='https://example.com/piston_front.png',
        )],
        capture=[CaptureInput(
            url='https://example.com/piston_charuco.mp4',
        )],
    ),
    params=Params(
        physics=PhysicsParams(
            simulator='mujoco',
        ),
    ),
)

with client:
    response = create_asset_measured.sync_detailed(
        client=client,
        body=body,
        idempotency_key=str(uuid.uuid4()),
    )
if response.status_code != 202:
    raise RuntimeError(response.content.decode("utf-8"))
created = response.parsed
if created is None:
    raise RuntimeError("The API returned an empty response")
print(created.job_id)
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -X POST "https://api.projectsim.ai/v1/assets/measured" \
  -H "Authorization: Bearer $PROJECTSIM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name": "piston conn rod",
    "inputs": {
      "images": [{ "url": "https://example.com/piston_front.png" }],
      "capture": [{ "url": "https://example.com/piston_charuco.mp4" }]
    },
    "params": { "physics": { "simulator": "mujoco" } }
  }'
```

{% endtab %}
{% endtabs %}

Returns `202` with a `job_id`; poll and download as for any asset. The scale stage adds `scale` to the job's `current_stage` sequence — see [Jobs & assets](/guides/jobs-and-assets.md).

Next: [Capturing an asset](/creating-assets/assets-measured/measured-capture.md) for how to film the clip.
