Skip to content

2D to 3D Generator — API Reference

Base URL: https://api.wearfits.com

Interactive documentation: - OpenAPI Spec: api.wearfits.com/doc - Swagger UI: api.wearfits.com/reference - Shoe AR Integration Guide: tryon.wearfits.com/docs/integration-shoes


Authentication

All /api/* routes require the X-API-Key header. API keys are created and managed at dash.wearfits.com.

X-API-Key: your_api_key

Requests without a valid key return HTTP 401.


Image Input Formats

All images fields across the API accept two formats:

  1. URLs (HTTP/HTTPS) — standard web URLs pointing to publicly accessible hosted images.
  2. Base64 Data URLs — inline base64-encoded images embedded directly in the request body.
  3. Format: data:image/<format>;base64,<data>
  4. Supported image formats: png, jpeg, jpg, gif, webp, svg+xml

Endpoints

POST /api/v1/shoe-3d

Generate a high-quality 3D shoe model from one or more 2D product photos. The request is accepted immediately and processed asynchronously. Use GET /api/v1/jobs/{jobId} to poll for results.

Returns: 202 Accepted with a jobId.

Request body

Field Type Required Description
images string[] Yes List of shoe photo URLs or base64 data URLs. Provide multiple angles for best results.
glbInput string No URL to an existing GLB file to use as the base for transformation or texture enhancement instead of generating from scratch.
options object No Processing options (see below).
options.uploadToWearFits boolean No After generation, automatically upload the model to the AR platform at dev.wearfits.com.
options.enhanceTexture boolean No Run an AI texture enhancement pass after 3D generation. Renders multiple views, enhances them with Gemini, then projects the result back onto the model.
options.correctImage boolean No Apply professional packshot correction to the input photos before 3D generation.
options.productType string No Hint for the generation model. One of: shoe, other, or auto (default).
options.refineLogo boolean No Run a second AI pass focused specifically on fixing logos and brand text on the generated model. Non-fatal: if the logo pass fails, the pipeline continues with first-pass results.
options.genaiQuality string No Controls texture enhancement quality and render count. "default" uses 4 views (3-minute timeout). "high" uses 6 views (5-minute timeout). Defaults to "high" when enhanceTexture is enabled.

Example request

curl -X POST https://api.wearfits.com/api/v1/shoe-3d \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      "https://example.com/shoe-side.jpg",
      "https://example.com/shoe-front.jpg",
      "https://example.com/shoe-back.jpg"
    ],
    "options": {
      "uploadToWearFits": true,
      "enhanceTexture": true,
      "correctImage": true,
      "productType": "shoe",
      "refineLogo": false,
      "genaiQuality": "high"
    }
  }'

Example request with base64 image

curl -X POST https://api.wearfits.com/api/v1/shoe-3d \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      "data:image/jpeg;base64,/9j/4AAQSkZJRgAB..."
    ],
    "options": {
      "productType": "shoe"
    }
  }'

Example request with existing GLB

curl -X POST https://api.wearfits.com/api/v1/shoe-3d \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
      "https://example.com/shoe-packshot.jpg"
    ],
    "glbInput": "https://example.com/base-model.glb",
    "options": {
      "enhanceTexture": true,
      "uploadToWearFits": true
    }
  }'

Response — 202 Accepted

{
  "jobId": "job_01HX3Z7K2MFVBN9Q4RPTDY6WCE"
}

POST /api/v1/files/upload

Upload a large binary file (such as a source .glb model) to Cloudflare R2 storage before triggering the shoe-3d pipeline. Use this endpoint when your GLB exceeds the inline payload size limit for the shoe-3d request body.

The endpoint returns a hosted URL that can be passed as glbInput in a subsequent POST /api/v1/shoe-3d call.

Request

Content-Type: multipart/form-data

Field Type Required Description
file file Yes The binary file to upload (e.g., .glb).

Example request

curl -X POST https://api.wearfits.com/api/v1/files/upload \
  -H "X-API-Key: your_api_key" \
  -F "file=@base-model.glb"

Response — 200 OK

{
  "url": "https://storage.example.com/uploads/base-model.glb"
}

Use the returned url as the glbInput value when calling POST /api/v1/shoe-3d.


GET /api/v1/jobs/{jobId}

Poll the status and retrieve the final results of an asynchronous job submitted via POST /api/v1/shoe-3d or any other job-producing endpoint.

Path parameters

Parameter Type Description
jobId string Job identifier returned by the submission endpoint.

Example request

curl https://api.wearfits.com/api/v1/jobs/job_01HX3Z7K2MFVBN9Q4RPTDY6WCE \
  -H "X-API-Key: your_api_key"

Response — 200 OK (in progress)

{
  "jobId": "job_01HX3Z7K2MFVBN9Q4RPTDY6WCE",
  "status": "processing",
  "progress": 42
}

Response — 200 OK (completed)

{
  "jobId": "job_01HX3Z7K2MFVBN9Q4RPTDY6WCE",
  "status": "completed",
  "progress": 100,
  "result": {
    "glbUrl": "https://storage.example.com/models/shoe.glb",
    "viewerUrl": "https://app.wearfits.com/viewer?object=abc123",
    "previewGrid": "https://storage.example.com/previews/shoe-grid.png"
  }
}

Response — 200 OK (failed)

{
  "jobId": "job_01HX3Z7K2MFVBN9Q4RPTDY6WCE",
  "status": "failed",
  "error": "Generation failed: no valid shoe silhouette detected in input images."
}

Job status values

Status Description
queued Job has been accepted and is waiting for a processing slot.
validating Input images and parameters are being validated.
processing 3D generation and optional AI passes are running.
uploading Generated model is being uploaded to storage and, if requested, to the AR platform.
completed Processing is complete. The result object contains output URLs.
failed An unrecoverable error occurred. See the error field for details.

Result fields (on completion)

Field Description
glbUrl Direct URL to the generated GLB 3D model file.
viewerUrl URL to preview the model in the WEARFITS 3D viewer.
previewGrid URL to a composite preview image showing the model from multiple angles.

Poll every 5–10 seconds. Typical processing times are 2–5 minutes depending on enabled options and queue depth. Do not poll more frequently than every 2 seconds to stay within rate limits.


DELETE /api/v1/jobs/{jobId}

Cancel a running job. The job is terminated immediately. Jobs that have already reached completed or failed status cannot be cancelled.

Path parameters

Parameter Type Description
jobId string Job identifier to cancel.

Example request

curl -X DELETE https://api.wearfits.com/api/v1/jobs/job_01HX3Z7K2MFVBN9Q4RPTDY6WCE \
  -H "X-API-Key: your_api_key"

Response — 200 OK

{
  "cancelled": true
}

POST /api/v1/digitization/batches

Submit multiple shoes for bulk 3D digitization processing. This is a secondary endpoint intended for high-volume batch workflows. Jobs submitted via this endpoint are placed in a lower-priority queue (DIGITIZATION_QUEUE) separate from the real-time JOB_QUEUE used by POST /api/v1/shoe-3d.

Example request

curl -X POST https://api.wearfits.com/api/v1/digitization/batches \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "images": ["https://example.com/shoe-a-side.jpg"],
        "options": { "productType": "shoe", "uploadToWearFits": true }
      },
      {
        "images": ["https://example.com/shoe-b-side.jpg"],
        "options": { "productType": "shoe", "uploadToWearFits": true }
      }
    ]
  }'

Use GET /api/v1/jobs/{jobId} to track each item's progress individually.


Webhook Signatures

If your integration is configured to receive webhook notifications, each webhook payload is signed with HMAC-SHA256 using a secret derived from your API key.

Signing secret: SHA-256(your_api_key) (hex-encoded string).

Verification steps

  1. Compute the signing secret:

    import hashlib
    signing_secret = hashlib.sha256(api_key.encode()).hexdigest()
    

  2. Sort the webhook JSON body keys alphabetically and serialize to a canonical string:

    import json
    canonical = json.dumps(payload, sort_keys=True, separators=(',', ':'))
    

  3. Compute the HMAC-SHA256 of the canonical string using the signing secret:

    import hmac
    signature = hmac.new(
        signing_secret.encode(),
        canonical.encode(),
        hashlib.sha256
    ).hexdigest()
    

  4. Compare the computed signature with the value in the X-Webhook-Signature request header. Use a constant-time comparison to avoid timing attacks:

    import hmac
    is_valid = hmac.compare_digest(signature, request.headers['X-Webhook-Signature'])
    


Rate Limits

Limits apply per API key per minute.

Endpoint category Limit
Job submission (POST) 50 requests/min
Job status (GET) 500 requests/min
File downloads 300 requests/min
Health check 5000 requests/min

Requests that exceed the limit return HTTP 429 Too Many Requests.

Note: Rate limits are 10x higher when using localhost or the development API key (DEV_API_KEY). This elevated limit applies to local development environments only and is not active in production.


Full Integration Example

The following example demonstrates a complete shoe-3d workflow: uploading a large GLB base file, submitting the generation job, polling until completion, and handling the result.

# Step 1: Upload a large base GLB (if applicable)
UPLOAD_RESPONSE=$(curl -s -X POST https://api.wearfits.com/api/v1/files/upload \
  -H "X-API-Key: your_api_key" \
  -F "file=@base-model.glb")

GLB_URL=$(echo $UPLOAD_RESPONSE | jq -r '.url')

# Step 2: Submit the shoe-3d generation job
JOB_RESPONSE=$(curl -s -X POST https://api.wearfits.com/api/v1/shoe-3d \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d "{
    \"images\": [\"https://example.com/shoe-side.jpg\"],
    \"glbInput\": \"$GLB_URL\",
    \"options\": {
      \"uploadToWearFits\": true,
      \"enhanceTexture\": true,
      \"genaiQuality\": \"high\"
    }
  }")

JOB_ID=$(echo $JOB_RESPONSE | jq -r '.jobId')
echo "Job submitted: $JOB_ID"

# Step 3: Poll for job completion
while true; do
  STATUS_RESPONSE=$(curl -s "https://api.wearfits.com/api/v1/jobs/$JOB_ID" \
    -H "X-API-Key: your_api_key")

  STATUS=$(echo $STATUS_RESPONSE | jq -r '.status')
  PROGRESS=$(echo $STATUS_RESPONSE | jq -r '.progress')
  echo "Status: $STATUS ($PROGRESS%)"

  if [ "$STATUS" = "completed" ]; then
    GLB_URL=$(echo $STATUS_RESPONSE | jq -r '.result.glbUrl')
    VIEWER_URL=$(echo $STATUS_RESPONSE | jq -r '.result.viewerUrl')
    echo "Done! GLB: $GLB_URL"
    echo "Viewer: $VIEWER_URL"
    break
  elif [ "$STATUS" = "failed" ]; then
    ERROR=$(echo $STATUS_RESPONSE | jq -r '.error')
    echo "Job failed: $ERROR"
    break
  fi

  sleep 10
done