Glossi Docs
Glossi API

Simplified Workflow: Jobs Endpoint

Beta: The Glossi API is currently in beta. Endpoints, request/response formats, and behavior may change as we iterate. If you run into issues or have feedback, reach out at support@glossi.io.

The Jobs endpoint combines the entire workflow into fewer steps. Instead of managing each step individually, you create a single job that orchestrates everything.

Why Use Jobs?

Traditional Flow (8+ steps)Jobs Flow (4 steps)
Create model → Upload → Confirm → Poll status → Create project → Render → Poll renderCreate job → Upload → Confirm → Poll until done

Step 1: Create a Job

Endpoint:

POST https://api.glossi.app/api/v1/jobs

Headers:

HeaderValue
X-API-KeyYour API key
Content-Typeapplication/json

Body (without rendering):

{
  "models": [
    { "fileName": "chair.glb", "fileType": "glb" },
    { "fileName": "table.glb", "fileType": "glb" }
  ],
  "templateId": "your-template-uuid",
  "createProjects": true
}

Body (with rendering):

{
  "models": [
    { "fileName": "chair.glb", "fileType": "glb" }
  ],
  "templateId": "your-template-uuid",
  "renderSettings": {
    "renderBookmarks": true,
    "imageQuality": 1
  }
}

Response:

{
  "jobId": "job-uuid",
  "status": "AWAITING_UPLOADS",
  "models": [
    {
      "id": "model-1-uuid",
      "fileName": "chair.glb",
      "uploadUrl": "https://s3.../signed-url-1",
      "uploadKey": "workspaces/.../model.glb"
    },
    {
      "id": "model-2-uuid",
      "fileName": "table.glb",
      "uploadUrl": "https://s3.../signed-url-2",
      "uploadKey": "workspaces/.../model.glb"
    }
  ]
}

Step 2: Upload Files to S3

Upload each file directly to its signed URL. This request goes directly to S3, not to Glossi's API.

Endpoint:

PUT <uploadUrl from Step 1 response>

Headers:

HeaderValue
Content-Typemodel/gltf-binary (for GLB files)

Body: Your binary file data

Note: Don't include your API key for this request - the signed URL already contains authentication.

A successful upload returns an empty response with status 200 OK.

Repeat this for each model in your job.


Step 3: Confirm Uploads

After uploading all files, tell the job that uploads are complete. This sets the file paths and advances the job to processing.

Endpoint:

POST https://api.glossi.app/api/v1/jobs/{jobId}/confirm-uploads

Headers:

HeaderValue
X-API-KeyYour API key

Body: None required

Response:

{
  "jobId": "job-uuid",
  "status": "PROCESSING",
  "modelsConfirmed": 2
}

Step 4: Poll for Completion

The job automatically progresses through each phase. Poll this endpoint to check status.

Endpoint:

GET https://api.glossi.app/api/v1/jobs/{jobId}

Headers:

HeaderValue
X-API-KeyYour API key

Response (in progress):

{
  "jobId": "job-uuid",
  "status": "PROCESSING",
  "progress": {
    "modelsUploaded": 2,
    "modelsReady": 1,
    "modelsTotal": 2,
    "projectsCreated": 0,
    "projectsTotal": 2,
    "rendersComplete": 0,
    "rendersTotal": 0
  }
}

Response (complete):

{
  "jobId": "job-uuid",
  "status": "COMPLETE",
  "batchProject": {
    "id": "batch-uuid",
    "title": "API Job - 2025-02-10"
  },
  "progress": {
    "modelsUploaded": 2,
    "modelsReady": 2,
    "modelsTotal": 2,
    "projectsCreated": 2,
    "projectsTotal": 2,
    "rendersComplete": 0,
    "rendersTotal": 0
  },
  "results": [
    {
      "model": { "id": "model-1-uuid", "name": "chair.glb" },
      "project": { "id": "project-1-uuid", "name": "Chair Project" }
    },
    {
      "model": { "id": "model-2-uuid", "name": "table.glb" },
      "project": { "id": "project-2-uuid", "name": "Table Project" }
    }
  ]
}

Job Status Flow

AWAITING_UPLOADS → PROCESSING → CREATING_PROJECTS → RENDERING → COMPLETE
                       ↓              ↓                 ↓
                    FAILED         FAILED            FAILED
StatusDescription
AWAITING_UPLOADSWaiting for files to be uploaded and confirmed
PROCESSINGModels are being processed
CREATING_PROJECTSProjects are being created
RENDERINGRenders in progress (if rendering requested)
COMPLETEAll done
FAILEDSomething went wrong (check error field)

Job Options

FieldTypeDefaultDescription
modelsarrayRequiredModels to upload (fileName + fileType)
templateIdstring-Template to use for projects (required if rendering)
createProjectsbooleantrueCreate projects after models are ready
renderSettingsobject-Render settings. Include renderBookmarks: true or renderShots: true to trigger rendering
webhookUrlstring-URL to receive completion notification

Tip: To render images, include "renderSettings": { "renderBookmarks": true }. To skip rendering, omit renderSettings entirely.


BatchProject

When you upload multiple models, they're automatically grouped into a BatchProject. The batchProject field in the response contains the ID you can use to manage them together.


Complete Example with cURL

# 1. Create job
JOB_RESPONSE=$(curl -s -X POST https://api.glossi.app/api/v1/jobs \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "models": [
      { "fileName": "chair.glb", "fileType": "glb" }
    ],
    "templateId": "your-template-uuid",
    "createProjects": true
  }')

JOB_ID=$(echo $JOB_RESPONSE | jq -r '.jobId')
UPLOAD_URL=$(echo $JOB_RESPONSE | jq -r '.models[0].uploadUrl')

# 2. Upload file to S3
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: model/gltf-binary" \
  --data-binary @chair.glb

# 3. Confirm uploads
curl -X POST "https://api.glossi.app/api/v1/jobs/$JOB_ID/confirm-uploads" \
  -H "X-API-Key: $API_KEY"

# 4. Poll for completion
while true; do
  STATUS_RESPONSE=$(curl -s "https://api.glossi.app/api/v1/jobs/$JOB_ID" \
    -H "X-API-Key: $API_KEY")

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

  if [ "$STATUS" = "COMPLETE" ] || [ "$STATUS" = "FAILED" ]; then
    echo "Final response:"
    echo $STATUS_RESPONSE | jq
    break
  fi

  sleep 5
done

Using Webhooks with Jobs

Instead of polling, you can provide a webhookUrl when creating the job to receive notifications:

{
  "models": [
    { "fileName": "chair.glb", "fileType": "glb" }
  ],
  "templateId": "your-template-uuid",
  "webhookUrl": "https://your-app.com/webhooks/glossi"
}

When the job completes (or fails), Glossi will POST to your webhook URL. See Webhooks for details on payload formats and signature verification.

On this page