For developers

Call the models from your own code

Every model is on Replicate, so Replicate’s API is the API. You use your own Replicate token, and there is nothing of ours to sign up for.
  • Your own Replicate token
  • No PropLabs key to provision
curl -s -X POST \
  https://api.replicate.com/v1/models/proplabs/virtual-staging/predictions \
  -H "Authorization: Bearer $REPLICATE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait" \
  -d '{
    "input": {
      "image": "https://example.com/empty-living-room.jpg",
      "replicate_api_key": "'"$REPLICATE_API_TOKEN"'",
      "room": "Living Room",
      "furniture_style": "Scandinavian"
    }
  }'
Prefer: wait returns the result on the same request; drop it to poll instead.

The endpoint

One path per model

Each model is addressed by its account and name. Swap the name and everything else stays the same.

POST https://api.replicate.com/v1/models/proplabs/<model>/predictions
  • proplabs/virtual-staging
  • proplabs/virtual-renovation
  • proplabs/furniture-removal
  • proplabs/object-removal
  • proplabs/sky-replacement
  • proplabs/lawn-enhancement
  • proplabs/photo-enhancement

Inputs differ per model. Each model page lists its fields, and Replicate’s API reference for that model is the authority.

Clean output

One extra field removes the watermark

Every model takes an optional watermark_remove_token. Without it, output is watermarked. Tokens are $100 a month for 1,000 images.

import os
import replicate

# Without this field the output comes back watermarked.
output = replicate.run(
    "proplabs/virtual-staging",
    input={
        "image": open("empty-living-room.jpg", "rb"),
        "replicate_api_key": os.environ["REPLICATE_API_TOKEN"],
        "room": "Living Room",
        "furniture_style": "Scandinavian",
        "watermark_remove_token": os.environ["PROPLABS_TOKEN"],
    },
)

Worth knowing

  • The field is optional on every model
  • One token works across all seven
  • Keep it server-side, like any other secret
  • Replicate still bills the compute separately

At volume

A whole shoot, and models chained together

Furniture removal then virtual staging is the common pair: clear an occupied room, then furnish it in the style you want.

import asyncio
import os
import replicate

# A shoot is just concurrent predictions. How many run at once is governed by
# your Replicate account, not by PropLabs.
KEY = os.environ["REPLICATE_API_TOKEN"]

async def clear_then_stage(path: str) -> str:
    empty = await replicate.async_run(
        "proplabs/furniture-removal",
        input={"image": open(path, "rb"), "replicate_api_key": KEY,
               "scope": "Furniture and decor"},
    )
    staged = await replicate.async_run(
        "proplabs/virtual-staging",
        input={"image": empty, "replicate_api_key": KEY,
               "room": "Living Room", "furniture_style": "Coastal"},
    )
    return staged

async def main(paths: list[str]) -> list[str]:
    return await asyncio.gather(*(clear_then_stage(p) for p in paths))
Concurrency limits come from your Replicate account.

Off Replicate

Need it behind your own endpoint?

That is something we arrange case by case rather than offer self-serve. If Replicate is not where this can live for you — because of volume, latency or where the data has to sit — tell us the constraints and we will work out what is possible.

  • Direct API access, arranged per account
  • Volume pricing quoted against real numbers
  • Deployment under your own infrastructure
  • Custom pipelines that chain several models

FAQ

Developer questions

  • Yes — Replicate's. Every model is callable over Replicate's HTTP API or their Python, JavaScript and other client libraries, with the same inputs you see in the playground. There is no separate PropLabs API to sign up for.