---
title: Shoes & Bags AR Try-On — API Reference
product: ar-tryon
last_updated: '2026-10-26'
description: "Base URL: https://dev.wearfits.com"
---

# Shoes & Bags AR Try-On — API Reference

Base URL: `https://dev.wearfits.com`

---

## Authentication

All authenticated endpoints accept credentials via one of the following methods, checked in priority order:

### 1. Bearer Token (Recommended)

Include an API key or session token in the `Authorization` header:

```http
Authorization: Bearer your_api_key_here
```

API keys are created and managed at [dash.wearfits.com](https://dash.wearfits.com). This is the recommended method for server-to-server integrations.

### 2. Dashboard session

If the caller is logged into the WEARFITS dashboard in the same browser, the session is sent automatically. No additional headers are required. Server-to-server integrations should use an API key.

### 3. Query Parameter (Legacy, Discouraged)

```
GET /some/endpoint?token=your_token_here
```

This method may leak tokens in server logs and referrer headers. Avoid it in new integrations.

---

### API Key Validation

When a Bearer token is an API key created at `dash.wearfits.com`, it is validated against the following rules:

| Condition | Rejection reason |
|-----------|-----------------|
| Key not found in database | `not_found` |
| Key has `isActive = false` | `inactive` |
| `expiresAt` is set and in the past | `expired` |
| `maxUsage > 0` and `usageCount >= maxUsage` | `over_limit` |

All validation failures return HTTP **401** with error code `invalid_api_key`. Usage is incremented only on successful requests.

---

## Model Upload API

### `POST /tryon/api/upload_shoe`

Upload a binary GLB shoe model. On success the system automatically creates a new object and queues it for the Autofit processing pipeline.

**Authentication required:** API key from dash.wearfits.com, or a dashboard session in the same browser.

**Content-Type:** `multipart/form-data`

#### Request fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `file` | file | Yes | Binary `.glb` file, maximum **30 MB** |
| `token` | string | No | Alternative authentication token (query/body parameter) |

#### Example request

```bash
curl -X POST https://dev.wearfits.com/tryon/api/upload_shoe \
  -H "Authorization: Bearer your_api_key_here" \
  -F "file=@shoe_model.glb"
```

#### Response — 200 OK

```json
{
    "id": "e84bc8b8afb5e6973556e376f0b942ab",
    "color_id": "default",
    "viewer_url": "https://app.wearfits.com/viewer?object=e84bc8b8afb5e6973556e376f0b942ab"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique object identifier (hex string) |
| `color_id` | string | Color/material variant identifier |
| `viewer_url` | string | Direct URL to preview the uploaded model in the 3D viewer |

#### Error responses

| HTTP Status | Error Code | Description |
|-------------|------------|-------------|
| 400 | `no_file` | No `.glb` file was included in the request |
| 400 | `file_too_large` | File exceeds the 30 MB limit |
| 401 | `unauthorized` | Missing or invalid authentication |
| 401 | `invalid_api_key` | API key is inactive, expired, or over quota |

---

### `POST /tryon/api/upload_bag`

Upload a bag (accessory) GLB. This endpoint uses the same authentication, attribution options, and 30 MB limit as `POST /tryon/api/upload_shoe`; it does not queue an Autofit run. The object is stored as an accessory, is try-on ready immediately, and the response is `{id, color_id, viewer_url}`.

For customer attribution, use `token` or `user_id`. When using an attribution-enabled Bearer key, provide `user_id` to identify the customer account. `user_id` is accepted only with that Bearer key and must not be combined with `token`.

Optional field `size` is the bag's real length in centimetres measured along its longest **horizontal** side: the larger of its width and depth, never its vertical height. Values from **5 to 150 cm** are accepted, using a dot or comma as the decimal separator, and are rounded to 0.1 cm. The value must be a scalar number or numeric string; arrays, objects, malformed values, and values outside the range are invalid. A valid value is stored as `tryonAssetLongestSideCm`, and pose-mode try-on scales the model so the longer horizontal bounding-box dimension (X/Z, with Y as up) matches it.

If `size` is omitted or empty, no size is stored. Pose-mode try-on then measures the GLB's horizontal length automatically: a value strictly greater than 10 cm and less than 100 cm is treated as real-scale and rendered as-is. At 10 cm or less, or 100 cm or more, the model is scaled to the default **40 cm**. This fallback is not stored. Invalid values are rejected with HTTP **400** and error `invalid_size` before anything is written.

### `POST /tryon/api/set_bag_size`

Set or clear the real size of an existing bag without re-uploading it. Send multipart fields `id`, `size`, and optional `user_id`. The `size` rules are the same as for `upload_bag`; send an empty value to remove the stored size and return to the automatic GLB-size check. The response is `{id, size}`, with `size: null` after clearing. Only objects with `tryonAssetType: "accessory"` are accepted, and existing AR export files are retained.

`id` must be a plain 1–64 character identifier containing only letters, numbers, `_`, or `-`. Repeated, nested, path-like, or otherwise invalid ID values are rejected rather than normalized.

The endpoint uses the same authentication as `upload_bag`. Access is checked for the account acting on the request. An attribution-enabled Bearer key does **not** bypass ownership or protected-object checks; it must use `user_id` to identify the customer account, under the same rules as `upload_bag`. Do not combine `user_id` with `token`.

| HTTP Status | Error Code | Description |
|-------------|------------|-------------|
| 400 | `no_id` | Missing or invalid bag identifier |
| 400 | `invalid_size` | Size is malformed, non-scalar, or outside the 5–150 cm range |
| 400 | `unsupported_object_type` | The object is not a bag/accessory |
| 400 | `attribution_conflict` | `user_id` was combined with `token` |
| 400 | `attribution_not_permitted` | `user_id` was supplied without an attribution-enabled Bearer key |
| 400 | `invalid_user_id` | The supplied customer account could not be identified |
| 401 | `unauthorized` | Missing or invalid authentication |
| 403 | `forbidden` | The acting account lacks modify access |
| 403 | `protected` | The object is protected |
| 404 | `not_found` | No matching object exists |
| 503 | `catalog_unavailable` | The property write failed; retry the request |
### `POST /tryon/api/replace_shoe`

Replace the GLB for an existing shoe in place and start a new Autofit run. The object ID, owner, display name, properties, and existing viewer or try-on links remain unchanged. The mesh, selected color/material set, and its textures are fully overwritten from the new GLB.

**Authentication required:** Same authentication as `POST /tryon/api/upload_shoe`. The caller must have modify access to the object, such as being its owner or an administrator. An allowlisted Bearer key may bypass only the ownership check; protected objects cannot be replaced by any caller.

**Content-Type:** `multipart/form-data`

#### Request fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `file` | file | Yes | New binary `.glb` file, maximum **30 MB** |
| `id` | string | Yes | Existing shoe object ID. Characters outside `[a-zA-Z0-9 _-]` are removed before lookup. |
| `color_id` | string | No | Existing color/material preset to replace. Defaults to `default`. The color must already exist on the object. |

#### Example request

```bash
curl -X POST https://dev.wearfits.com/tryon/api/replace_shoe \
  -H "Authorization: Bearer your_api_key_here" \
  -F "file=@new_shoe_model.glb" \
  -F "id=e84bc8b8afb5e6973556e376f0b942ab" \
  -F "color_id=default"
```

The replacement is a full overwrite. If the replaced color had a derived `<color_id>_mirror` material preset, that preset is removed and must be recreated if needed.

#### Readiness and Autofit status

The endpoint returns after the replacement has been queued. The object is persisted as **not try-on ready** before Autofit starts, so the status endpoint does not continue to report a stale `finished` result from the previous model. While the new fit is running, the try-on link shows the object as not ready.

Poll `GET /tryon/api/autofit_status?id=<id>&color_id=<color_id>` for the new run. Its normal progression is `in_queue` → `in_progress` → `exporting` → `finished`; a failed run reports `failed`. When Autofit finishes, the object becomes try-on ready again.
## Autofit Status API

After a successful upload, the model enters the Autofit queue where it is automatically aligned and optimized for the try-on engine. Use this endpoint to poll processing progress.

### `GET /tryon/api/autofit_status`

**Authentication required:** No (public endpoint)

#### Query parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `id` | Yes | Object ID returned by `upload_shoe` |
| `color_id` | No | Color/material variant ID (defaults to `default`) |

#### Example request

```bash
curl "https://dev.wearfits.com/tryon/api/autofit_status?id=e84bc8b8afb5e6973556e376f0b942ab"
```

#### Response — 200 OK

```json
{
    "status": "finished",
    "progress": 100,
    "glb_url": "https://storage.googleapis.com/.../object.glb"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `status` | string | Current processing state (see values below) |
| `progress` | number | Completion percentage, 0–100 |
| `glb_url` | string | URL of the processed GLB file (present only when `status` is `finished`) |

When processing finishes, the response can also include `object_properties`. Public autofit metadata omits `created`, `createdBy`, `modifiedBy`, `owner`, `modified`, `model_url`, `custom`, and `materialsData`.
#### Status values

| Value | Description |
|-------|-------------|
| `in_queue` | Waiting for an available processing slot |
| `in_progress` | Actively being processed |
| `exporting` | Generating the final optimized GLB |
| `finished` | Model is ready for use in the viewer |
| `failed` | Processing encountered an unrecoverable error |

---
## Object & Asset API

These endpoints manage 3D objects, materials, and asset files. Most are public unless noted.

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/get_models` | List all available models (filtered by ownership when authenticated) |
| GET | `/api/get_object_properties/:name` | Retrieve properties for a named object |
| GET | `/api/get_materials/:name` | Retrieve materials for a named object |
| POST | `/api/set_object_properties` | Update object properties |
| POST | `/api/set_materials` | Update materials for an object |
| POST | `/api/upload_textures` | Upload texture files for an object |
| POST | `/api/upload_mesh` | Upload a mesh file for an object |
| POST | `/api/replace_mesh` | Replace the existing mesh of an object |
| POST | `/api/claim_object` | Claim ownership of an object |
| GET | `/api/get_gltf/:name` | Download the GLTF file for a named object |
| GET | `/api/get_usdz/:name` | Download the USDZ file for a named object |

The legacy baking endpoints `POST /api/bake` and `POST /api/upload_bake` are no longer supported.

For public metadata, `created`, `createdBy`, `modifiedBy`, and `owner` are returned by `/api/get_object_properties/:name` only to the owner, a member of the same group, or an admin/low admin; `modified` is preserved in responses and `protected` does not hide it. `/api/get_materials/:name` includes `created`, `createdBy`, `modifiedBy`, and `owner` only for admins; `modified` is preserved for all responses. The hosted viewer provides public fallback endpoints (no authentication required): `GET /tryonapi/get_object_properties/:name` and `GET /tryonapi/get_materials/:name`. Their responses omit `created`, `createdBy`, `modifiedBy`, and `owner`, but preserve `modified`. The materials fallback accepts an optional `color_id` query parameter, uses `default` when it is omitted, and returns the requested preset plus the corresponding `<color_id>_mirror` preset when that mirror preset exists.
---
## Try-On API

Server-side endpoints for programmatic try-on operations.

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/tryon/api/garment_fit_on` | Apply a garment to a provided image |
| POST | `/tryon/api/shoes_fit_on` | Apply shoes to a provided image |
| POST | `/tryon/api/report_bug` | Submit a bug report from a try-on session |

---

## Try-On Viewer Endpoints

These are browser-facing HTML routes that load the client-side try-on experience.

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/tryon` | Main try-on experience |
| GET | `/tryon/app` | Try-on application (full UI) |
| GET | `/tryon/editor` | Try-on editor for content management |
| GET | `/tryon/accessory-editor` | Accessory (bags, jewelry) try-on editor |

Viewer endpoints support a rich set of URL parameters for runtime configuration. Key parameters include:

| Parameter | Values | Description |
|-----------|--------|-------------|
| `pose_quality` | `1` / `2` / `3` | ML pose model quality: lite / full / heavy |
| `native_ml_size` | `160` / `192` / `256` | Input resolution for the ML model |
| `mirror_mode` / `mm` | `1`–`5` | Mirror display mode |
| `turbo` | `0` / `1` | Enable alternating ML/optical-flow pipeline |
| `no_logs` | `0` / `1` | Disable worker logging (15–30% performance gain) |
| `settings` | `0` / `1` | Show advanced settings panel |
| `async_mode` | `0` / `1` | Enable asynchronous processing mode |
| `debug` | `0` / `1` | Enable debug overlay |

---

## T4L Payload Behavior

T4L payloads may assign materials to named mesh parts. A visible structural part with `material: null` keeps the material embedded in the GLB. Parts sent with `visible: false` or an empty material object are dropped.

Optional overlays whose names start with `perforado_`, `grabado_`, `bordado_`, `picado_`, `ghost_`, or `reflejo_ghost_`, and floor meshes whose names start with `suelo`, are included only when the payload supplies a visible part with a non-empty material object. They are dropped when their material is null or empty, when `visible` is `false`, or when they are omitted from the parts map.

---
## Rate Limits & Constraints

| Constraint | Value |
|------------|-------|
| Maximum file size | 30 MB per upload |
| Accepted upload format | Binary `.glb` only |
| Batch uploads | Queued; track progress via `/tryon/api/autofit_status` |
| API key usage tracking | Incremented per successful request only |
| API key quota enforcement | Enforced when `maxUsage > 0` |
