Skin analysis
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).
Calls need a key with the skin.analyze scope, in an environment your account is provisioned
for; see product availability.
POST /v1/skin/analyses submits an uploaded face image for cosmetic skin analysis.
Upload the image as an Asset first. Product requests run as
asynchronous Jobs.
TypeScript SDK
Assume client is configured as shown in the SDK guide:
Python SDK
Assume client is configured as shown in the SDK guide:
jobs.wait returns only after success and raises ProcessingError for a failed job.
Pass a stable idempotency key for retries across processes; both SDKs generate a key
when omitted, but that protects only retries inside one call. See
Idempotency.
REST
Upload the image as raw bytes with POST /v1/assets, then submit its asset_id. The
request below returns a Job; persist its id, poll GET /v1/jobs/{job_id} until
succeeded or failed, and download any result Asset before it expires. See
Assets and Jobs for those steps.
inputs must name exactly one Asset with role: "source". concerns is required and
is a set: order does not matter, and a duplicate is a 400 INVALID_REQUEST.
visualizations is optional; each (concern, kind) pair must refer to a requested
concern, and kind is mask or visual.
Only requested concerns are analysed, and only requested images are rendered. Asking for all twelve concerns and every visualization when you display two of them adds work you wait for and discard.
The draft currently lists these twelve concerns:
The launch set is still an open decision; none of these draft concern semantics is release-ready.
Reading the output
A succeeded job’s output.type is skin.analysis:
concernshas one entry per requested concern.- A
measuredconcern carries ascoreand a nullunavailable_reason. - An
unavailableconcern carries a nullscoreand a reason:not_measured(the engine produced no value) ornot_measurable(the value was outside its documented range). It is never a score of0. analysis_versionnames the scoring semantics. Compare scores only within one version.
Scores: higher means less visible
Scores are from 0 to 10, rounded to one decimal, and higher means the concern is
less visible—an 8.7 for acne is a good reading, not severe acne. The meaning is
per concern, not universal, and every concern’s semantics are draft and not
release-ready. pore and hyper_pigmentation bottom out at 1 in practice,
tear_trough is scaled by face size and is not comparable across faces, and
firmness has no proven upper bound. The contract’s SkinConcern schema carries the
note for each value.
This is cosmetic appearance analysis, not a clinical diagnosis.
No demographic inferences
The V1 output schema carries no inferred skin tone, gender, age or race, and no request field asks for them. It returns the concerns you named and the images you requested.
The input is still a photograph of an identifiable face, so your privacy notice and retention rules have to cover it: Privacy and retention.
Result images
Each entry in visualizations is a result Asset. Its role is mask.<concern> or
visual.<concern>, and its href is /v1/assets/{id}/content relative to the API base
URL. Download it with your API key before expires_at; it expires with the job.
Assets
Determinism
The internal Skin result contract specifies byte-identical results for the same image
and configuration, apart from expiry and job-scoped Asset paths. The V1 analysis
version remains draft, so store analysis_version alongside any score you keep.