{"servers":[{"url":"https://app.piernode.com/api"}],"info":{"title":"PierNode API","version":"1.0.0","description":"Image and video generation. Authenticate every request with `Authorization: Bearer pn_...`, except the pricing endpoint, which is public."},"openapi":"3.1.1","paths":{"/v1/me":{"get":{"operationId":"v1.me","summary":"Get the authenticated account","description":"Returns the account the presented API key belongs to, along with its current balance.","tags":["v1"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"anyOf":[{},{"not":{}}]}}}}}}},"/v1/pricing":{"get":{"operationId":"v1.pricing","summary":"List pricing","description":"Current rates for every generation type that is available. No authentication required.","tags":["v1"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"product":{"type":"string"},"unit":{"enum":["image","second","unit"],"type":"string"},"tiers":{"type":"array","items":{"type":"object","properties":{"tier":{"type":"string"},"unitPrice":{"type":"string"}},"required":["tier","unitPrice"]}}},"required":["product","unit","tiers"]}}},"required":["currency","products"]}}}}}}},"/v1/effects":{"get":{"operationId":"v1.effects","summary":"List effects","description":"Named presets for the transformation endpoints. Send an id as `effectId` and the instruction is supplied for you. No authentication required.","tags":["v1"],"parameters":[{"name":"surface","in":"query","schema":{"enum":["image","video"],"type":"string"},"allowEmptyValue":true,"allowReserved":true}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"effects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"surface":{"enum":["image","video"],"type":"string"},"defaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"}]}}},"required":["id","name","description","surface","defaults"]}}},"required":["effects"]}}}}}}},"/v1/examples":{"get":{"operationId":"v1.examples","summary":"List gallery examples","description":"Worked examples shown in the documentation, each with the effect that produced it. No authentication required.","tags":["v1"],"parameters":[{"name":"surface","in":"query","schema":{"enum":["image","video"],"type":"string"},"allowEmptyValue":true,"allowReserved":true}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"examples":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"surface":{"enum":["IMAGE","VIDEO"],"type":"string"},"title":{"type":"string"},"caption":{"type":"string"},"parameter":{"const":"effectId"},"request":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"}]}},"category":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"sortOrder":{"type":"number"}},"required":["id","label","sortOrder"]},{"type":"null"}]},"input":{"type":"object","properties":{"assetId":{"type":"string"}},"required":["assetId"]},"poster":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"}},"required":["assetId"]},{"type":"null"}]},"output":{"type":"object","properties":{"assetId":{"type":"string"}},"required":["assetId"]},"blurredPoster":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"}},"required":["assetId"]},{"type":"null"}]},"blurredOutput":{"anyOf":[{"type":"object","properties":{"assetId":{"type":"string"}},"required":["assetId"]},{"type":"null"}]},"width":{"anyOf":[{"type":"number"},{"type":"null"}]},"height":{"anyOf":[{"type":"number"},{"type":"null"}]}},"required":["id","surface","title","caption","parameter","request","category","input","poster","output","blurredPoster","blurredOutput","width","height"]}}},"required":["examples"]}}}}}}},"/v1/images/generations":{"post":{"operationId":"v1.imageGeneration","summary":"Generate an image","description":"Starts an asynchronous text-to-image generation and returns a task to poll. The cost is reserved from your balance when the task is accepted, and refunded if it fails.","tags":["v1"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000},"negativePrompt":{"type":"string","maxLength":1000},"resolution":{"enum":["1k","2k","4k"],"type":"string","default":"1k"},"aspectRatio":{"enum":["1:1","9:16","16:9","4:3","3:4","3:2","2:3","2:1","1:2"],"type":"string","default":"1:1"}},"required":["prompt"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"}},"required":["id","status","createdAt"]}}}},"409":{"description":"The Idempotency-Key was already used with different request parameters. No task was created and nothing was charged."}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A stable client-generated value identifying one logical generation. Retrying with the same key and the same body returns the original task instead of creating and charging for a second one.","schema":{"type":"string","maxLength":128}}]}},"/v1/images/transformations":{"post":{"operationId":"v1.imageTransformation","summary":"Transform an image","description":"Starts an asynchronous image-to-image generation from an image you uploaded, guided by a prompt. Returns a task to poll. The cost is reserved from your balance when the task is accepted, and refunded if it fails.","tags":["v1"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"assetId":{"type":"string","minLength":1,"maxLength":64},"effectId":{"type":"string","minLength":1,"maxLength":64,"description":"A named preset from GET /api/v1/effects, which supplies the instruction and may preset other parameters. Anything you set explicitly wins over it. Required unless `prompt` is given."},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"What the transformation should do. Required unless `effectId` is given; alongside an effect it is added to the effect's own instruction rather than replacing it."},"resolution":{"enum":["hd","fhd"],"type":"string"},"aspectRatio":{"enum":["1:1","9:16","16:9","4:3","3:4","3:2","2:3"],"type":"string"}},"required":["assetId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"}},"required":["id","status","createdAt"]}}}},"409":{"description":"The Idempotency-Key was already used with different request parameters. No task was created and nothing was charged."}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A stable client-generated value identifying one logical generation. Retrying with the same key and the same body returns the original task instead of creating and charging for a second one.","schema":{"type":"string","maxLength":128}}]}},"/v1/videos/generations":{"post":{"operationId":"v1.videoGeneration","summary":"Generate a video","description":"Starts an asynchronous video generation and returns a task to poll. The cost is reserved from your balance when the task is accepted, and refunded if it fails.","tags":["v1"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000},"resolution":{"enum":["480p","512p","720p","1080p"],"type":"string","default":"720p"},"aspectRatio":{"enum":["16:9","9:16","1:1","4:3","3:4","21:9"],"type":"string","default":"16:9"},"durationSeconds":{"type":"integer","minimum":4,"maximum":15,"default":5}},"required":["prompt"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"}},"required":["id","status","createdAt"]}}}},"409":{"description":"The Idempotency-Key was already used with different request parameters. No task was created and nothing was charged."}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A stable client-generated value identifying one logical generation. Retrying with the same key and the same body returns the original task instead of creating and charging for a second one.","schema":{"type":"string","maxLength":128}}]}},"/v1/videos/transformations":{"post":{"operationId":"v1.videoTransformation","summary":"Animate an image","description":"Starts an asynchronous image-to-video generation from an image you uploaded, using a named effect. Returns a task to poll. The cost is reserved from your balance when the task is accepted, and refunded if it fails.","tags":["v1"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"assetId":{"type":"string","minLength":1,"maxLength":64},"effectId":{"type":"string","minLength":1,"maxLength":64,"description":"A named effect from GET /api/v1/effects. Supplies the motion, and may preset other parameters — anything you set explicitly wins over it."},"prompt":{"type":"string","minLength":1,"maxLength":2000,"description":"Optional. Added to the effect's own instruction to fine-tune the result; it does not replace it."},"resolution":{"enum":["hd","fhd"],"type":"string"},"aspectRatio":{"enum":["16:9","9:16","4:3","3:4","3:2","2:3","1:1"],"type":"string"},"durationSeconds":{"anyOf":[{"const":5},{"const":8}],"description":"Clip length in seconds. Either 5 or 8; this model produces no other length."}},"required":["assetId","effectId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"}},"required":["id","status","createdAt"]}}}},"409":{"description":"The Idempotency-Key was already used with different request parameters. No task was created and nothing was charged."}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"A stable client-generated value identifying one logical generation. Retrying with the same key and the same body returns the original task instead of creating and charging for a second one.","schema":{"type":"string","maxLength":128}}]}},"/v1/tasks/{taskId}":{"get":{"operationId":"v1.task","summary":"Get a task","description":"Returns the current state of one of your tasks. Polling is not billed.","tags":["v1"],"parameters":[{"name":"taskId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"},"startedAt":{"anyOf":[{"type":"string","format":"date-time","x-native-type":"date"},{"type":"null"}]},"completedAt":{"anyOf":[{"type":"string","format":"date-time","x-native-type":"date"},{"type":"null"}]},"output":{"anyOf":[{"type":"object","properties":{"images":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"number"}},"required":["url","contentType"]}},"videos":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"number"}},"required":["url","contentType"]}}}},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["code","message"]},{"type":"null"}]}},"required":["id","type","status","createdAt","startedAt","completedAt","output","error"]}}}}}}},"/v1/tasks/{taskId}/cancel":{"post":{"operationId":"v1.cancelTask","summary":"Cancel a queued task","description":"Cancels a task that has not started running and refunds its reservation. A task that is already processing cannot be cancelled.","tags":["v1"],"parameters":[{"name":"taskId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"anyOf":[{},{"not":{}}]}}}}}}},"/v1/uploads":{"post":{"operationId":"v1.createUpload","summary":"Create an upload","description":"Reserves an upload and returns a short-lived URL to PUT your image to. Send the bytes with the same Content-Type you declared here, then call the complete endpoint. Uploads are not billed.","tags":["v1"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contentType":{"enum":["image/jpeg","image/png","image/webp"],"type":"string"}},"required":["contentType"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"uploadUrl":{"type":"string"},"method":{"const":"PUT"},"expiresAt":{"type":"string","format":"date-time","x-native-type":"date"}},"required":["id","uploadUrl","method","expiresAt"]}}}}}}},"/v1/uploads/{assetId}/complete":{"post":{"operationId":"v1.completeUpload","summary":"Complete an upload","description":"Verifies uploaded bytes and marks the upload ready for use. Safe to call more than once. Not billed.","tags":["v1"],"parameters":[{"name":"assetId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["PENDING","READY","INVALID","EXPIRED"],"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"anyOf":[{"type":"number"},{"type":"null"}]},"width":{"anyOf":[{"type":"number"},{"type":"null"}]},"height":{"anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"},"expiresAt":{"type":"string","format":"date-time","x-native-type":"date"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","x-native-type":"date"},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]},{"type":"null"}]}},"required":["id","status","contentType","sizeBytes","width","height","createdAt","expiresAt","verifiedAt","error"]}}}}}}},"/v1/uploads/{assetId}":{"get":{"operationId":"v1.upload","summary":"Get an upload","description":"Returns the current state of one of your uploads.","tags":["v1"],"parameters":[{"name":"assetId","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["PENDING","READY","INVALID","EXPIRED"],"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"anyOf":[{"type":"number"},{"type":"null"}]},"width":{"anyOf":[{"type":"number"},{"type":"null"}]},"height":{"anyOf":[{"type":"number"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","x-native-type":"date"},"expiresAt":{"type":"string","format":"date-time","x-native-type":"date"},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","x-native-type":"date"},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]},{"type":"null"}]}},"required":["id","status","contentType","sizeBytes","width","height","createdAt","expiresAt","verifiedAt","error"]}}}}}}}}}