Skip to main content
The Souldi REST API lets you build a fully custom virtual try-on experience: you control the UI, the flow, and the look, while Souldi handles authentication, secure photo storage, and AI generation behind the scenes. This page gives you the big picture — how requests are authenticated and the end-to-end flow — before you dive into the per-endpoint pages.
Most teams should start with the widget — it’s a drop-in script that ships the entire end-user flow out of the box. Reach for the REST API when you want full control over the UI and the user journey. Both paths hit the exact same Souldi backend, so you can mix and match.

Base URL & content type

All requests go to the Souldi API base URL:
Requests and responses are JSON (Content-Type: application/json), with two exceptions:
  • The binary photo upload is a PUT directly to a signed storage URL (raw image bytes, not JSON).
  • The job stream is a Server-Sent Events (SSE) stream of text events.

Authentication model

Souldi uses two layers of authentication. The tenant key identifies your store; the user session identifies the end-user shopping on it.

Tenant key

Your publishable API key, sent as the x-api-key header on every request. It identifies your store and is validated against your whitelisted origins.

User session

A JWT obtained after the end-user completes email OTP login, sent as Authorization: Bearer <access_token> on all user-scoped endpoints (profile, image upload, generation).
Your x-api-key is a publishable key — it’s safe to ship in client code, but it only works from origins you’ve whitelisted. A request from a non-whitelisted origin is rejected with 403. Never send a user’s access_token to any party other than the Souldi API.

Required headers by endpoint group

End-to-end flow

Here’s the full integration, start to finish. It’s the same sequence the official widget performs internally.
1

Authenticate the user

Send a one-time code to the user’s email, then verify it to receive an access_token and a refresh_token. See Authentication.
2

Ensure a base image

Read the user’s profile. If has_base_image is false, upload a photo and wait until base_image_status is ready before generating. See User & Image.
3

Generate a try-on

POST the garment URL(s) to start a job. You’ll get back a job_id with a 202 Accepted. See Generation.
4

Track the job

Stream the job over SSE or poll it until status is completed, then read the generated_image_url.
5

Display the result

Show the generated_image_url to the user — that’s your finished try-on.
Access tokens are short-lived. When one nears expiry, call /auth/refresh with the refresh_token to get a fresh access_token without making the user log in again.

Job & image statuses

Two status fields drive the flow. Poll or stream until they reach a terminal state.

Try-on job status

Base image status

HTTP status & error codes

These are the responses you’ll encounter as an integrator.
/try-on/generate is rate-limited to 5 requests per 60 seconds per user. Exceeding it returns 429 — back off before retrying.

Next steps

Authentication

Email OTP login, token verification, and refresh.

User & Image

Read the profile and upload a base photo.

Generation

Start a try-on job and track it to completion.