For AI agents: this page is also available as Markdown at https://docs.refabric.com/task-api-reference/ghost_photoshoot.create.md, and the index of every page is https://docs.refabric.com/llms.txt.

Photoshoots

Create a ghost photoshoot

Shoot your products with nobody in them: on an invisible mannequin, laid flat or in close-up, one image per view. Delivered as one record whose items are the images.

Endpoint: POST https://api.refabric.com/v1/tasks/ghost_photoshoot.createTask: ghost_photoshoot.createScope: tasks:runCategory: Photoshoots

Quick start

import os
import time
import requests

headers = {"Authorization": f"Key {os.environ['REFABRIC_API_KEY']}"}

job = requests.post(
    "https://api.refabric.com/v1/tasks/ghost_photoshoot.create",
    headers=headers,
    json={
        "products": [
            {
                "image": "file:77",
            },
        ],
    },
).json()
print(job["job_id"])

while True:
    status = requests.get(job["status_url"], headers=headers).json()
    if status["lifecycle"] == "terminal":
        break
    time.sleep(5)

print(requests.get(job["result_url"], headers=headers).json())

cURL waits for the result with Prefer: wait; when the job outlives the wait, it answers 202 with the job's URLs.

Input schema

  • array<object>required

    The products to shoot, one entry each, at least one. Every product gets every view: products × views images, at most 500.

    at least 1 items

    Example: [{"image":"file:77"},{"image":"https://files.example.com/ghost_photoshoot.create/1.jpg","photo_type":"on_model","prompt":"the striped shirt"}]

  • stringoptionalDefault: 1:1

    The shape of every image. 1:1 is a square frame, the usual shape for a product shown on its own in a store or catalogue grid. Send another ratio to match your own layout.

    Values

    • 1:1 — Square. For square places: product grids and social posts.
    • 3:4 — Portrait, slightly taller than wide. For portrait product pages.
    • 4:3 — Landscape, slightly wider than tall. For landscape layouts and slides.
    • 9:16 — Tall portrait, as for phone screens and stories. For phone screens: stories and reels.
    • 16:9 — Wide landscape, as for banners and video. For banners, headers and video frames.
    • 2:3 — Portrait, as for a classic photo print. For a portrait print or a lookbook page.
    • 3:2 — Landscape, as for a classic photo print. For a landscape print.
    • 4:5 — Portrait, as for social feeds. For portrait posts in social feeds.

    Example: 1:1

  • stringoptional

    The shoot's name, as it appears in your library and as the record's data.name (at most 255 characters). Omitted: the kind of shoot and the day it was started, in UTC — "Photoshoot 2026-10-01".

    max length 255

  • objectoptionalDefault: {"type":"auto"}

    The backdrop of every image. The backdrop is chosen for you, so a shoot needs no colour from you. Send colour when every image must share one exact colour, such as your store's.

    Example: {"type":"colour","colour":{"hex":"#F5F2ED"}}

  • array<object>optional

    The views to make of every product, one {type, view} each — ghost (on an invisible mannequin) or flat (laid flat) with its side, front, back or side, or {"type": "close_up"} for one close-up. Every listed side is made in every listed type, so list each pair (front and back, ghost and flat: four entries). Omitted, the front on an invisible mannequin.

    Example: [{"type":"ghost","view":"front"},{"type":"flat","view":"front"},{"type":"ghost","view":"back"},{"type":"flat","view":"back"},{"type":"close_up"}]

  • stringoptionalDefault: 2K

    The size of every image. 2K is sharp enough for screens and review; ask for 4K when the result will be printed or zoomed into.

    Values

    • 2K — Standard size, for screens and review.
    • 4K — Large size, for print and zoom. When the image will be printed or zoomed into.

    Example: 4K

Output schema

  • array<object>optional

    ONE file: the shoot, photoshoot:<id> (application/json). Its data.items are the shoot's images — ghost or flat with its view (front · back · side) for a product view, close_up — each with its url and named by its product: the product's own name, else Product <n> by its place in products, and its external_id (SKU) when it has one. An image that failed carries status: failed and no url. Read it again with GET /v1/files/photoshoot:<id>; pass any items[].url into an edit (image.polish, …).

  • objectoptional

    How many images the shoot holds, how many came out with an image, and a warning for any that did not.

Required-fields example

{
  "products": [
    {
      "image": "file:77"
    }
  ]
}

Full example

{
  "products": [
    {
      "image": "file:77"
    },
    {
      "image": "https://files.example.com/ghost_photoshoot.create/1.jpg",
      "photo_type": "on_model",
      "prompt": "the striped shirt"
    }
  ],
  "background": {
    "type": "colour",
    "colour": {
      "hex": "#F5F2ED"
    }
  },
  "views": [
    {
      "type": "ghost",
      "view": "front"
    },
    {
      "type": "flat",
      "view": "front"
    },
    {
      "type": "ghost",
      "view": "back"
    },
    {
      "type": "flat",
      "view": "back"
    },
    {
      "type": "close_up"
    }
  ],
  "aspect_ratio": "1:1",
  "resolution": "4K"
}

Response example

{
  "job_id": "1123456789abcdef0123456789abcdef",
  "lifecycle": "queued",
  "status_url": "http://v3-api.refabric.com/v1/jobs/1123456789abcdef0123456789abcdef",
  "result_url": "http://v3-api.refabric.com/v1/jobs/1123456789abcdef0123456789abcdef/result",
  "cancel_url": "http://v3-api.refabric.com/v1/jobs/1123456789abcdef0123456789abcdef/cancel"
}

Result example

{
  "job_id": "1123456789abcdef0123456789abcdef",
  "files": [
    {
      "file": "photoshoot:1123456789abcdef0123456789abcdef",
      "url": "https://files.example.com/ghost_photoshoot.create/2.png",
      "media_type": "application/json",
      "task": "ghost_photoshoot.create",
      "job_id": "1123456789abcdef0123456789abcdef",
      "created_at": "2026-10-01T10:14:02Z",
      "data": {
        "name": "Ghost photoshoot 2026-10-01",
        "status": "ready",
        "items": [
          {
            "type": "ghost",
            "view": "front",
            "name": "Blazer",
            "external_id": "SKU-77",
            "url": "https://files.example.com/ghost_photoshoot.create/2.png"
          },
          {
            "type": "ghost",
            "view": "back",
            "name": "Blazer",
            "external_id": "SKU-77",
            "url": "https://files.example.com/ghost_photoshoot.create/3.png"
          },
          {
            "type": "flat",
            "view": "front",
            "name": "Blazer",
            "external_id": "SKU-77",
            "url": "https://files.example.com/ghost_photoshoot.create/4.png"
          },
          {
            "type": "flat",
            "view": "back",
            "name": "Blazer",
            "external_id": "SKU-77",
            "url": "https://files.example.com/ghost_photoshoot.create/5.png"
          },
          {
            "type": "close_up",
            "name": "Blazer",
            "external_id": "SKU-77",
            "url": "https://files.example.com/ghost_photoshoot.create/6.png"
          },
          {
            "type": "ghost",
            "view": "front",
            "name": "Product 2",
            "url": "https://files.example.com/ghost_photoshoot.create/7.png"
          },
          {
            "type": "ghost",
            "view": "back",
            "name": "Product 2",
            "url": "https://files.example.com/ghost_photoshoot.create/8.png"
          },
          {
            "type": "flat",
            "view": "front",
            "name": "Product 2",
            "url": "https://files.example.com/ghost_photoshoot.create/9.png"
          },
          {
            "type": "flat",
            "view": "back",
            "name": "Product 2",
            "status": "failed"
          },
          {
            "type": "close_up",
            "name": "Product 2",
            "url": "https://files.example.com/ghost_photoshoot.create/10.png"
          }
        ]
      }
    }
  ],
  "has_more": false,
  "summary": {
    "requested": 10,
    "delivered": 9,
    "warnings": [
      {
        "code": "output_not_produced",
        "field": "items",
        "message": "1 of the shoot's 10 images were not produced; they are in the record without a url."
      }
    ]
  }
}

Every product gets every listed view — each side in each type, plus one close-up: 2 × (2 × 2 + 1) = 10 images; a shoot over the schema's limit is refused (too_many_outputs). prompt is taken only with photo_type: on_model; a product without photo_type is garment_only. No name was sent, so the shoot is named after its task and the UTC day. The product sent by url has no name of its own, so it is Product 2 on every one of its images.

Send product photos — the garment on its own, or worn by a person — and get catalogue images with nobody in them: on an invisible mannequin, laid flat, or in close-up. Every product gets every view you list, in one shape and on one backdrop.

Built for

  • Product pages of an online store
  • Ghost-mannequin and flat-lay catalogue images
  • Product images taken from photos of a person wearing them

What you get

  • One photoshoot: record — the shoot's name, its status and its images in data.items.
  • Each image's url, its type (ghost, flat or close_up) and side, and the product it shows, by name and SKU.
  • A summary that counts the images asked for and made, and warns when some were not made.

Specs

Input formatsImages, each one string: a URL, an upload (file:…) or a file from an earlier result (art:…). Upload types and sizes: GET /v1/meta limits.upload.
Input countproducts: at least 1, each with its image
Output formatOne photoshoot: record: its data is JSON in the record vocabulary, its url a preview image.
Output resolution2K, 4K
Aspect ratios1:1, 3:4, 4:3, 9:16, 16:9, 2:3, 3:2, 4:5
Outputs per jobOne record file, however large the shoot. Its data.items hold one image per product and view.

Choosing a task

Errors

Good to know

  • name is at most 255 characters.
  • products holds at least 1 items.

Pricing: Estimate a request before you run it, or see the price of each option.

For agents and code generation

Schema changes follow Versioning.