REST API onboarding
Release status. API 1.0.0-rc.1 is a release candidate: request and response shapes may still change before the stable release. SDK 0.2.2 is published as a Developer Preview (@morphiaone/sdk on npm and morphiaone on PyPI).
Every step here is plain HTTP and works without an SDK. If you can use one, the TypeScript and Python SDKs do these steps for you.
Set the two values every call needs
The key goes in an X-API-Key header on every call, and it is a server-side
secret. If the value above ends up in a browser bundle, a mobile binary or a
committed file, it is a leaked credential — see
Serving a browser or mobile client.
1. Upload the image
The image bytes are the whole request body. No multipart, no JSON wrapper.
2. Submit the analysis
Three things in that response are load-bearing:
202, not200. The job was accepted. Nothing has been analysed yet.Retry-Afteris how many seconds to wait before the first poll. It is advice from the server, and honouring it is cheaper for you than a tight loop that gets rate limited.- The
Locationheader holds the polling URL, so you do not have to build it:
The Idempotency-Key is required, and it is what makes retrying this call safe.
Re-running the exact same submission answers 200 with Idempotency-Replayed: true
and the same job, rather than starting a second one and charging you twice. Reusing
the key with a different body answers 409 IDEMPOTENCY_KEY_REUSED on purpose — see
Idempotency.
3. Poll until the job is terminal
Repeat while status is queued or running, waiting the Retry-After each answer
gives you between polls. The terminal states are succeeded and failed, and there
are only four states in total — the set is closed, so a switch over it will not
encounter a fifth.
A failed analysis is a 200. This is the detail worth reading twice:
Your HTTP client will not raise on that. Code that treats 2xx as success and
moves on will silently carry a failed job forward as if it had results.
4. Read the output and fetch the images
A succeeded job carries a typed output. Result images are assets, referenced by id
and href, not bytes:
Result assets expire with their job, at the expires_at each one carries. After
that the job answers 404 JOB_NOT_FOUND and the image is gone. Fetch or copy what
you need before then rather than treating the href as durable storage.
Hair color try-on (draft)
Hair color try-on takes a source Asset; the draft endpoint finds the hair and recolors
only those pixels. An optional same-size grayscale hair_mask Asset replaces its own
segmentation. It does not change a haircut. See the Hair color try-on guide
for its REST, Python, and TypeScript calls.
What you have just built, and what is still missing
You have the whole interaction shape. What a production integration adds is not more endpoints — it is four behaviours:
Production checklist is those four in order, with the rest.