Skip to main content

Getting Started

Get up and running with MOD Platform in 5 minutes — first in the UI, then with the API.

1. Sign up

  1. Go to your MOD Platform URL.
  2. Click Register and create an account.
  3. Fill in your profile (username, company, name).
  4. Choose a plan — or start on the Free plan, which is the no-cost way to try MOD.

2. Upload your first file

  1. Click Data in the sidebar.
  2. Click Upload, or drag files into the browser.
  3. Supported formats include images (PNG, JPG, TIFF, EXR), 3D meshes (OBJ, FBX, GLB, PLY), video (MP4, MOV), audio (MP3, WAV), and more.

3. Create a workflow

  1. Click Workflow Builder in the sidebar.
  2. Drag an Input node onto the canvas.
  3. Drag a Processing node (e.g. Resize, Albedo Texture, Background Extraction).
  4. Connect the input to the processing node.
  5. Click Save and name your workflow.

4. Run it

  1. Click the Input node and select your uploaded file.
  2. Click Run in the toolbar.
  3. Watch progress in real time.
  4. Download your results when complete.

Quickstart with the API

Everything above is also available over the REST API. Here's the full loop — upload → run → poll → download — in three languages.

First, create an API key in Settings → API Keys (it starts with sk_ and is shown once). API requests use a short-lived Bearer token that you get by exchanging that key — see Authentication.

curl

BASE=https://dev-api.modtechlabs.com

# 0. Exchange your sk_ key for a ~1h Bearer token
TOKEN=$(curl -s -X POST "$BASE/api-keys/token" -H "Content-Type: application/json" \
-d '{"api_key": "sk_your_key_here"}' | jq -r .access_token)
AUTH="Authorization: Bearer $TOKEN"

# 1. Upload a file -> returns the new cog (note its "id")
COG=$(curl -s -X POST "$BASE/cogs/upload-file" -H "$AUTH" \
-F "file=@./input.png" | jq -r .id)

# 2. Run a saved workflow version against that file (202 Accepted)
RUN=$(curl -s -X POST "$BASE/workflows/workflow-versions/42/run" -H "$AUTH" \
-H "Content-Type: application/json" \
-d "{\"cog_ids\": [$COG]}" | jq -r .workflow_run_id)

# 3. Poll until the run reaches a terminal status
curl -s "$BASE/workflows/workflow-runs/$RUN" -H "$AUTH" | jq '{status, run_files}'

# 4. Output files are listed in run_files; download one by its cog id
curl -s "$BASE/cogs/<output_id>/download" -H "$AUTH" -o result.png

Python

import time
import requests

BASE = "https://dev-api.modtechlabs.com"

# 0. Exchange your sk_ key for a Bearer token
token = requests.post(f"{BASE}/api-keys/token",
json={"api_key": "sk_your_key_here"}).json()["access_token"]
HEADERS = {"Authorization": f"Bearer {token}"}

# 1. Upload
with open("input.png", "rb") as f:
cog = requests.post(f"{BASE}/cogs/upload-file", headers=HEADERS,
files={"file": f}).json()
print("uploaded cog", cog["id"])

# 2. Run workflow version 42 against it
run = requests.post(f"{BASE}/workflows/workflow-versions/42/run", headers=HEADERS,
json={"cog_ids": [cog["id"]]}).json()
run_id = run["workflow_run_id"]

# 3. Poll until the run reaches a terminal status
TERMINAL = ("success", "partial_success", "failure", "cancelled")
while True:
r = requests.get(f"{BASE}/workflows/workflow-runs/{run_id}", headers=HEADERS).json()
print(r["status"])
if r["status"] in TERMINAL:
break
time.sleep(3)

# 4. Output files are listed in run_files
for rf in r.get("run_files", []):
print("output:", rf["title"], rf["id"])

JavaScript (Node 18+ / browser)

const BASE = "https://dev-api.modtechlabs.com";

// 0. Exchange your sk_ key for a Bearer token
const { access_token } = await fetch(`${BASE}/api-keys/token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ api_key: "sk_your_key_here" }),
}).then(r => r.json());
const headers = { Authorization: `Bearer ${access_token}` };

// 1. Upload
const form = new FormData();
form.append("file", fileBlob, "input.png");
const cog = await fetch(`${BASE}/cogs/upload-file`, { method: "POST", headers, body: form })
.then(r => r.json());

// 2. Run workflow version 42
const { workflow_run_id } = await fetch(`${BASE}/workflows/workflow-versions/42/run`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ cog_ids: [cog.id] }),
}).then(r => r.json());

// 3. Poll until terminal
const TERMINAL = ["success", "partial_success", "failure", "cancelled"];
let run;
do {
await new Promise(r => setTimeout(r, 3000));
run = await fetch(`${BASE}/workflows/workflow-runs/${workflow_run_id}`, { headers })
.then(r => r.json());
console.log(run.status);
} while (!TERMINAL.includes(run.status));

console.log("outputs:", run.run_files);

Get the workflow version id (42 above) from the Workflow Builder URL or GET /workflows/. The token inherits your permissions, and you can run any endpoint interactively in the Swagger explorer.

Next steps