SDKs
Official TypeScript SDK plus language-agnostic OpenAPI access.
We ship a typed TypeScript SDK today. Python is coming next; for any other language, the OpenAPI 3.1 spec at https://garmentverse-api-807711804803.asia-south1.run.app/openapi.json generates a client in seconds.
#TypeScript / JavaScript
Works in Node, Bun, Deno, and the browser. Uses the platform fetch — no extra runtime.
npm i @garmentverse/sdk # or: pnpm add @garmentverse/sdk # or: yarn add @garmentverse/sdk
import { createClient } from "@garmentverse/sdk";
const gv = createClient({
baseUrl: "https://garmentverse-api-807711804803.asia-south1.run.app",
apiKey: process.env.GARMENTVERSE_API_KEY!,
});
// 1. Upload images
const person = await gv.files.upload(personBlob, { kind: "person", filename: "p.jpg" });
const garment = await gv.files.upload(garmentBlob, { kind: "garment", filename: "g.jpg" });
// 2. Submit a try-on
const job = await gv.images.tryon({
mode: "garment_to_person",
person_image: person.id,
garment_image: garment.id,
garment: { category: "saree", subtype: "nivi" },
views: ["front", "back"],
tier: "premium",
consent_token: true,
});
// 3. Poll, then fetch outputs
while ((await gv.jobs.get(job.id)).status === "running") {
await new Promise((r) => setTimeout(r, 2000));
}
const outputs = await gv.images.outputs(job.id);
const blob = await gv.files.contentBlob(outputs[0].file_id);#Python
The official Python SDK is in development. Until then, every endpoint is a single requests call.
import os, time, requests
GV = "https://garmentverse-api-807711804803.asia-south1.run.app"
HEAD = {"Authorization": f"Bearer {os.environ['GARMENTVERSE_API_KEY']}"}
# Upload
with open("person.jpg", "rb") as f:
person = requests.post(
f"{GV}/v1/files", headers=HEAD,
files={"file": ("person.jpg", f, "image/jpeg")},
data={"kind": "person"},
).json()
# Try-on
job = requests.post(
f"{GV}/v1/images/tryon",
headers={**HEAD, "Content-Type": "application/json"},
json={
"mode": "garment_to_person",
"person_image": person["id"],
"garment_image": garment_id,
"garment": {"category": "saree", "subtype": "nivi"},
"tier": "standard",
"consent_token": True,
},
).json()
# Poll
while True:
j = requests.get(f"{GV}/v1/jobs/{job['id']}", headers=HEAD).json()
if j["status"] in ("succeeded", "failed"): break
time.sleep(2)#Other languages
Generate a typed client from our OpenAPI spec:
# Go oapi-codegen -package garmentverse \ https://garmentverse-api-807711804803.asia-south1.run.app/openapi.json > garmentverse.go # Ruby openapi-generator generate -i https://garmentverse-api-807711804803.asia-south1.run.app/openapi.json \ -g ruby -o ./garmentverse-ruby # Java / Kotlin openapi-generator generate -i https://garmentverse-api-807711804803.asia-south1.run.app/openapi.json \ -g kotlin -o ./garmentverse-kotlin
#Authentication
Every request needs a Authorization: Bearer sk_… header. Keys are scoped to a workspace; create separate keys per environment (test / live) and per service.
Authorization: Bearer sk_live_abc123_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Never expose live keys in client-side code. Use a backend proxy or short-lived test keys for browser apps.
#Errors & retries
Errors return a typed JSON envelope: { error: { code, message, detail? } }. Treat 5xx, 429, and provider_unavailable as retryable; treat 4xx as a code bug or invalid input. See the full error reference.