PierNode
Images

Image to image

Transform an image you uploaded, guided by a prompt.

Give PierNode an image you have uploaded and an instruction, and get back a new image. The prompt describes the change you want — "make the sky look like dusk", "remove the car on the left", "turn this into a pencil sketch".

This is a general image transformation, not an upscaler: you choose the output size, and it is not derived from the input.

Like every PierNode generation, this is asynchronous: you start a task and poll it until it reaches a terminal state.

Before you start

You need an upload in the READY state. See Uploading an image:

POST /api/v1/uploads          → { id, uploadUrl }
PUT  <uploadUrl>              → your image bytes
POST /api/v1/uploads/{id}/complete  → { status: "READY" }

Keep that id. It is the assetId below, and it stays valid for as long as the upload exists, so one upload can feed as many transformations as you like.

POST /api/v1/images/transformations

curl -X POST https://your-piernode-host/api/v1/images/transformations \
  -H "Authorization: Bearer $PIERNODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "assetId": "c8f2a1d4e5b64c9a8f3d2e1b0a9c8d7e",
    "prompt": "make the sky look like dusk"
  }'

Request

FieldTypeRequiredDefaultNotes
assetIdstringyesA READY upload of yours.
promptstringyes1–2000 characters. Describes the change you want.
qualitystringnohdhd (1024 px long edge) or fhd (1280 px long edge).
aspectRatiostringnothe input's shape1:1, 9:16, 16:9, 4:3, 3:4, 3:2, 2:3.

By default the output keeps roughly the shape of the image you uploaded, so a landscape photo stays landscape. Set aspectRatio when you want to change it.

Request bodies are limited to 64 KB. Any field not listed above is ignored — in particular there is no way to pass an image URL, an object key or a bucket. An input image is always one of your own uploads, named by assetId.

Response

{
	"id": "01JD8Z9K2M4N6P8Q0R2S4T6V8W",
	"status": "QUEUED",
	"createdAt": "2026-01-01T12:00:00.000Z"
}

Poll GET /api/v1/tasks/\{taskId\} until status is SUCCEEDED or FAILED.

Result

{
	"id": "01JD8Z9K2M4N6P8Q0R2S4T6V8W",
	"status": "SUCCEEDED",
	"output": {
		"images": [
			{
				"url": "https://...",
				"contentType": "image/png",
				"sizeBytes": 1048576
			}
		]
	},
	"error": null
}

Result links are valid for one hour. Re-poll the task for a fresh one, or copy the file somewhere of your own.

The result is a generation output, not a new upload — it does not get an assetId, and it does not appear under /v1/uploads. Your input upload is unchanged and still usable.

Errors

StatusMeaning
400No usable upload for that assetId — it is not yours, does not exist, or is not READY.
402Your balance is too low to start this generation.
429Too many generation requests. The limit is 60 per minute per account.
503This tier is not currently available.

Nothing is reserved from your balance unless the task is accepted, and a failed generation is refunded in full.

Pricing

Charged per generated image, one image per request. The fhd tier is priced separately from hd. Current rates are shown on your dashboard.

Cancelling

POST /api/v1/tasks/\{taskId\}/cancel refunds a task that has not started yet. Once processing has begun it returns 409, because the work upstream cannot be recalled.

On this page