Virtual Try-On — Tattoo
Preview how a tattoo design would look as real ink on a person's skin.
Ink a design onto skin. Submit a close-up photo of bare skin (body_image) and
the tattoo design on its own (design_image); the API returns a job id you poll
on the Job Status endpoint until the result is
ready.
POST
https://tryiton.now/api/v1/tryon/tattoo
All image fields accept either a public URL or a base64 data URL
(data:image/png;base64,...).
Request
Use an official SDK (recommended) or call the endpoint directly.
import { TryItOn } from "tryiton";
const client = new TryItOn({ apiKey: process.env.TRYITON_API_KEY });
const jobId = await client.tryOnTattoo({
bodyImage: "https://example.com/forearm.jpg",
designImage: "https://example.com/design.png",
placement: "on the right forearm, small",
// Or pin the exact spot instead — see "Positioning the tattoo" below:
// region: { x: 0.32, y: 0.18, w: 0.28, h: 0.34 },
});
const [resultUrl] = await client.waitForResult(jobId);import os
from tryiton import TryItOn
client = TryItOn(api_key=os.environ["TRYITON_API_KEY"])
job_id = client.try_on_tattoo(
body_image="https://example.com/forearm.jpg",
design_image="https://example.com/design.png",
placement="on the right forearm, small",
# Or pin the exact spot instead — see "Positioning the tattoo" below:
# region={"x": 0.32, "y": 0.18, "w": 0.28, "h": 0.34},
)
urls = client.wait_for_result(job_id)curl -X POST https://tryiton.now/api/v1/tryon/tattoo \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"body_image": "https://example.com/forearm.jpg",
"design_image": "https://example.com/design.png",
"placement": "on the right forearm, small"
}'Body Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
body_image | string | — | Required. URL or base64 data URL — a close-up of bare skin (arm, leg, shoulder, back). |
design_image | string | — | Required. URL or base64 data URL of the tattoo design on its own. |
placement | string | (auto) | Optional free-text placement/size, e.g. "on the right forearm, small". Max 140 characters. Omitted: placed naturally on the most visible skin, palm-sized. |
region | object | — | Optional exact spot for the ink: { "x": 0.32, "y": 0.18, "w": 0.28, "h": 0.34 }. See Positioning the tattoo. |
num_samples | integer | 1 | Number of output images to generate (1–4). Charged per output image. |
output_format | string | png | Output image format: png or jpeg. |
Positioning the tattoo
There are two ways to say where the ink goes, and they compose.
placement is free text — the simplest option, and enough when the body photo
shows one obvious area:
{ "placement": "on the right forearm, small" }region pins the exact spot. It's a rectangle on body_image, normalized
0–1 from the image's top-left corner:
| Field | Description |
|---|---|
x | Left edge, 0–1 |
y | Top edge, 0–1 |
w | Width, 0–1 |
h | Height, 0–1 |
{
"region": { "x": 0.32, "y": 0.18, "w": 0.28, "h": 0.34 },
"placement": "fine-line, black ink"
}The design is centred in the rectangle and scaled to fill it, so with a region
set, placement no longer decides where — use it for size and style notes only.
Each side must be at least 0.06 of the image, and the rectangle is clamped into
frame. A malformed region is rejected with 400 InvalidRegion rather than
silently ignored — inking the wrong spot is worse than a clear error.
For the most faithful result, use a design on a plain background and a body photo
where the target skin area is clearly visible and evenly lit. Use region when
your UI lets people point at a spot (a drag box on the photo); use placement
text when it doesn't.
Response
A successful submission returns a jobId. Poll
/api/v1/status/{jobId} until status is
completed.
201 Created
{
"ok": true,
"jobId": "64b7f1a9d9a3b8e5c7f9a123"
}Credits: 1 credit per output image. With num_samples: 3 you are charged 3
credits. Failed jobs are never charged.