Special Offer: 35% OFF with code linkoffer Expires 19/04/2026

Get the discount

Replica Link API

PUBLIC BETA — The Replica Link API is currently in public beta. Endpoints and behavior may change in future updates.

Replica Link embeds an HTTP server inside the Replica Pro macOS app, exposing a REST API on the local network. All endpoints return JSON unless otherwise noted.

  • Base URL: http://<local-ip>:8247
  • Protocol: HTTP (TLS available but disabled by default)
  • Authentication: PIN-based, with Bearer token for subsequent requests

Quick Start

# 1. Authenticate
TOKEN=$(curl -s -X POST http://192.168.1.10:8247/api/auth \
  -H "Content-Type: application/json" \
  -d '{"pin":"482193"}' | jq -r '.token')

# 2. List projects
curl -s http://192.168.1.10:8247/api/projects \
  -H "Authorization: Bearer $TOKEN" | jq

# 3. Upload a new project
curl -s -X POST http://192.168.1.10:8247/api/projects \
  -H "Authorization: Bearer $TOKEN" \
  -F "name=TestProject" \
  -F "images=@photo1.jpg" \
  -F "images=@photo2.jpg" | jq

# 4. Start computation
curl -s -X POST http://192.168.1.10:8247/api/projects/<project-id>/compute \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"detail":"medium"}' | jq

# 5. Poll status
curl -s http://192.168.1.10:8247/api/status \
  -H "Authorization: Bearer $TOKEN" | jq

# 6. Download model
curl -s -o model.glb \
  http://192.168.1.10:8247/api/projects/<project-id>/download?format=glb \
  -H "Authorization: Bearer $TOKEN"

Authentication

All endpoints except POST /api/auth and GET /api/health require authentication via:

  • Header: Authorization: Bearer <token>
  • Query parameter: ?token=<token> (for contexts where headers can't be set, e.g. <model-viewer>)

Tokens expire after 24 hours.

Health Check

GET /api/health

Health check endpoint. No authentication required.

Response 200

{
  "status": "ok",
  "version": "1.0"
}

Authenticate

POST /api/auth

Authenticate with the 6-digit PIN displayed in the Replica desktop app.

Request Body

{
  "pin": "482193"
}

Response 200

{
  "token": "550e8400-e29b-41d4-a716-446655440000"
}

Errors

Status Body Cause
400 {"error": "Invalid request body"} Malformed JSON
401 {"error": "Invalid PIN"} Wrong PIN

Projects

List Projects

GET /api/projects

Returns all projects.

Response 200

{
  "projects": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "MyProject",
      "imageCount": 42,
      "status": "completed",
      "progress": 1.0,
      "processingStage": "",
      "hasModel": true,
      "hasGlb": true,
      "modelDetail": "medium",
      "errorMessage": ""
    }
  ]
}

Get Project

GET /api/projects/:id

Get a single project's details.

Path Parameters

Parameter Type Description
id UUID string Project persistent ID

Response 200 — Same structure as a single item in the project list.

Errors

Status Cause
404 Project not found

Create Project

POST /api/projects

Create a new project by uploading images.

Content-Type: multipart/form-data

Form Fields

Field Type Required Description
name string No Project name. Defaults to LinkUpload_<timestamp>
images file[] Yes One or more image files

Supported image formats: jpg, jpeg, png, heif, heifs, raw, tif, tiff

Response 201

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "MyProject",
  "imageCount": 42,
  "status": "ready"
}

Errors

Status Cause
400 No images provided, unsupported format, or invalid content type
412 Upload directory not configured in the desktop app
500 Failed to create project folder

Rename Project

PUT /api/projects/:id

Rename a project. Renames both the project and its folder on disk.

Request Body

{
  "name": "NewProjectName"
}

Validation rules:

  • Name cannot be empty
  • Name cannot contain / or \
  • Cannot rename a project that is currently processing or queued
  • Destination folder must not already exist

Response 200

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "NewProjectName"
}

Errors

Status Cause
400 Empty name, path separators, already processing, or folder conflict
404 Project not found

Delete Project

DELETE /api/projects/:id

Delete a project. Optionally removes files from disk.

Query Parameters

Parameter Type Default Description
deleteFiles string "false" Set to "true" to also delete the project folder from disk

Response 200

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "deleted": true
}

Errors

Status Cause
404 Project not found

Images

Add Images

POST /api/projects/:id/images

Add images to an existing project.

Content-Type: multipart/form-data

Form Fields

Field Type Required Description
images file[] Yes One or more image files

Response 200

{
  "imageCount": 58,
  "addedCount": 16
}
Field Description
imageCount Total image count after adding
addedCount Number of images successfully added

Errors

Status Cause
400 No images provided or invalid content type
404 Project not found

Get Image Thumbnail

GET /api/projects/:id/images/:filename

Serve a single image as a JPEG thumbnail.

  • Max size: 400px (longest side)
  • Format: JPEG, quality 0.7
  • Content-Type: image/jpeg

Errors

Status Cause
404 Project or image not found
500 Failed to generate thumbnail

Download All Images

GET /api/projects/:id/images/download

Download all project images as a ZIP archive.

  • Content-Type: application/zip
  • Content-Disposition: attachment; filename="<project-name>_images.zip"

Errors

Status Cause
400 Project has no images
404 Project not found
500 Failed to create ZIP archive

Computation

Start Computation

POST /api/projects/:id/compute

Start photogrammetry computation on a project.

Preconditions:

  • Project status must be ready or completed
  • Project must have at least one image

Request Body (all fields optional — defaults to medium detail)

{
  "detail": "medium",
  "sampleOrdering": "unordered",
  "featureSensitivity": "normal",
  "meshPrimitive": "triangle",
  "isObjectMaskingEnabled": false
}

Standard Parameters

Field Values Default Description
detail preview, reduced, medium, full, raw, custom medium Reconstruction detail level
sampleOrdering unordered, sequential unordered Photo capture ordering hint
featureSensitivity normal, high normal Feature detection sensitivity
meshPrimitive triangle, quad triangle Output mesh primitive type
isObjectMaskingEnabled true, false false Automatic object masking

Custom Detail Parameters (only when detail is "custom")

Field Type Description
maximumPolygonCount int Max polygon count
maximumTextureDimension string oneK, twoK, fourK, eightK, sixteenK
textureFormat string png, jpeg
jpegCompressionQuality float 0.0 – 1.0 (only with jpeg format)
outputTextureMaps string[] ["all"] or subset: ambientOcclusion, diffuseColor, displacement, normal, roughness

Response 202

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "queued"
}

Errors

Status Cause
404 Project not found
409 Project is already processing or queued

Cancel Computation

POST /api/projects/:id/cancel

Cancel an ongoing or queued computation.

Preconditions: Project status must be processing or queued.

Response 200

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "ready"
}

Errors

Status Cause
404 Project not found or not currently processing

3D Models

Serve Model

GET /api/projects/:id/model

Serve the GLB model for use with <model-viewer> or similar 3D viewers.

  • Content-Type: model/gltf-binary

Errors

Status Cause
404 GLB model not available

Serve Model (Viewer)

GET /api/viewer/projects/:id/model

Same as above, but accepts authentication via query parameter instead of header. Designed for <model-viewer> which cannot send custom headers.

Query Parameters

Parameter Required Description
token Yes Session token

Note: This endpoint does NOT go through the auth middleware — it validates the token inline.

Download Model

GET /api/projects/:id/download

Download the 3D model in the requested format. Conversion is performed on-demand and cached.

Query Parameters

Parameter Values Default Description
format glb, usdz, obj, fbx glb Output format

Content Types

Format Content-Type
glb model/gltf-binary
usdz model/vnd.usdz+zip
obj text/plain
fbx application/octet-stream

Behavior:

  • USDZ is the native output format — served directly, no conversion needed
  • GLB is auto-generated during Link workflows and cached in link-exports/
  • OBJ and FBX are generated on-demand via Blender and cached for subsequent requests

Errors

Status Cause
400 Invalid format
404 Project or model not found
500 Conversion failed

Status & Polling

Poll Status

GET /api/status

Lightweight polling endpoint. Returns minimal status for all projects plus an adaptive poll interval.

Response 200

{
  "projects": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "status": "processing",
      "progress": 0.63,
      "processingStage": "Mesh Generation",
      "hasGlb": false,
      "errorMessage": ""
    }
  ],
  "pollInterval": 2
}
Field Description
pollInterval Suggested polling interval in seconds: 2 if any project is processing/queued, 10 otherwise

Data Models

Project Status

Value Description
ready Images loaded, ready for computation
queued Waiting in computation queue
processing Photogrammetry in progress
completed Model successfully generated
failed Computation failed (see errorMessage)

LinkProjectDTO (Full)

id              string    UUID
name            string    Project folder name
imageCount      int       Number of images
status          string    Project status
progress        double    0.0 – 1.0
processingStage string    Current stage (e.g. "Mesh Generation")
hasModel        bool      USDZ model exists
hasGlb          bool      GLB export exists
modelDetail     string    Detail level used
errorMessage    string    Error description (empty if none)

LinkStatusProjectDTO (Lightweight)

id              string    UUID
status          string    Project status
progress        double    0.0 – 1.0
processingStage string    Current stage
hasGlb          bool      GLB export exists
errorMessage    string    Error description

Error Handling

All errors return a JSON body:

{
  "error": "Descriptive error message"
}

HTTP Status Codes

Code Usage
200 Success
201 Resource created (project upload)
202 Accepted (computation queued)
400 Bad request (validation, malformed body)
401 Unauthorized (invalid/missing token or PIN)
404 Resource not found
409 Conflict (project already processing)
412 Precondition failed (upload directory not configured)
500 Internal server error (file I/O, conversion failure)

Server Configuration

Parameter Default Notes
Port 8247 Falls back to 8248+ if in use
Protocol HTTP TLS available but disabled by default
Session expiry 24 hours Automatic
PIN length 6 digits Regenerable from desktop UI