Menu
Language
Log in

Virtual Staging ART Developer API

Use the Virtual Staging ART API to upload an image, request staging or decluttering, poll for status, and receive finished render URLs by webhook.

Base URL

Examples on this page use the legacy-compatible /api/... paths:

  • https://www.virtualstaging.art/api/...

Equivalent /v1/... paths are also available if you prefer them.

Authentication

All developer API requests use a Bearer token:

Authorization: Bearer YOUR_API_TOKEN

You can generate an API token from your Virtual Staging ART account settings.

Typical workflow

Most integrations follow this sequence:

  1. Upload an image with /api/image/upload, or provide your own public image URL.
  2. Submit a render request with /api/image/render/request or /api/image/render/declutter.
  3. Poll /api/image/check-status with the returned upload_id, or provide a callback_url and wait for the webhook.
  4. Use the returned render URLs in your app.

1. Upload an image

Endpoint

  • POST /api/image/upload

Response

{
  "url": "https://..."
}

Use the returned url as the image_url in the render request.

Option A: Multipart upload

Send a standard file upload using multipart/form-data.

Form field:

  • file

Example:

curl -X POST "https://www.virtualstaging.art/api/image/upload" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "[email protected]"

Option B: Base64 JSON upload

Send either raw base64 or a data URL in JSON.

Raw base64 example:

{
  "image_base64": "BASE64_HERE",
  "content_type": "image/jpeg"
}

Data URL example:

{
  "data_url": "data:image/png;base64,iVBORw0KGgoAAA..."
}

Upload limits

  • Max upload size: 10 MB
  • Accepted formats:
    • JPEG
    • PNG
    • WebP
    • HEIC / HEIF

2. Use your own image URL instead of uploading

If you already host your images yourself, you can skip /api/image/upload and send your own image_url directly in the render request.

Your image_url should be:

  • a direct image URL
  • publicly reachable
  • https://
  • returning the image file itself with a normal 200 response

Examples that usually fail:

  • expired temporary URLs
  • links that require login or cookies
  • share pages that return HTML instead of the raw image
  • localhost or private-network URLs

3. Submit a staging render

Endpoint

  • POST /api/image/render/request

Request body

{
  "image_url": "https://example.com/source.jpg",
  "room_type": "living",
  "style": "modern",
  "number_of_renders": 1,
  "upload_id": "optional-grouping-id",
  "layout_type": "studio",
  "ai_notes": "Keep the room bright and add a premium contemporary feel.",
  "callback_url": "https://example.com/callback",
  "tier": "premium"
}

Required fields

  • image_url
  • room_type
  • style

tier options

  • classic
    • default if omitted
    • supports up to 20 renders per upload group
  • premium
    • supports up to 8 renders per credit charge on this compatibility endpoint

Supported room_type

  • living
  • bed
  • kitchen
  • office
  • dining
  • studio
  • ldk * premium only
  • bathroom * premium only
  • entrance * premium only

Legacy note: home_office is also accepted as an alias for office.

Supported style

  • modern
  • scandinavian
  • industrial
  • coastal
  • luxury
  • mid-century modern
  • farmhouse
  • standard
  • minimalist * premium only
  • japandi * premium only
  • bohemian * premium only
  • traditional * premium only

Optional fields

  • number_of_renders
    • default: 1
    • max per request: 10
  • upload_id
    • lets you keep repeated requests grouped under the same upload
  • layout_type
    • studio is supported for compatibility
  • callback_url
    • webhook destination for completion notifications
  • ai_notes * premium only
    • optional free-text guidance for the model
    • max length: 500 characters
  • tier
    • classic or premium
    • existing API users default to classic if omitted

Response

{
  "upload_id": "uuid-or-existing-group-id",
  "status": "rendering",
  "tier": "classic"
}

4. Submit a declutter render

Endpoint

  • POST /api/image/render/declutter

tier options

  • classic
    • default if omitted
    • supports up to 20 renders per upload group
  • premium
    • supports up to 8 renders per credit charge on this compatibility endpoint

Request body

{
  "image_url": "https://example.com/source.jpg",
  "number_of_renders": 1,
  "upload_id": "optional-grouping-id",
  "ai_notes": "Remove clutter while preserving the natural lighting.",
  "callback_url": "https://example.com/callback",
  "tier": "premium"
}

ai_notes is available on declutter requests only when tier is premium.

Response

{
  "upload_id": "uuid-or-existing-group-id",
  "status": "rendering",
  "tier": "classic"
}

5. Check render status

Endpoint

  • POST /api/image/check-status

Recommended request

{
  "upload_id": "uuid-or-existing-group-id"
}

Compatibility request

{
  "image_url": "https://example.com/source.jpg"
}

Response

{
  "status": "rendering"
}

Possible values:

  • rendering
  • done
  • error

upload_id is the preferred lookup method.

6. Check how many renders have been used for an upload

Endpoint

  • POST /api/image/check-rendering-amount

Request body

{
  "uploadId": "uuid-or-existing-group-id"
}

You can also use:

{
  "sourceImage": "https://example.com/source.jpg"
}

Compatibility aliases are also accepted:

{
  "upload_id": "uuid-or-existing-group-id",
  "image_url": "https://example.com/source.jpg"
}

Response

{
  "renderCount": 3,
  "limitExceeded": false,
  "maxRenders": 20
}

7. Webhook callbacks

If you provide callback_url in a render request, Virtual Staging ART will POST the result when the job completes.

Success payload

{
  "status": "done",
  "render_urls": [
    "https://assets.example.com/render-1.jpg",
    "https://assets.example.com/render-2.jpg"
  ]
}

Error payload

{
  "status": "error",
  "error": "Internal server error. Please try again later."
}

Compatibility notes for existing Virtual Staging integrations

What still works

  • legacy /api/... image endpoints remain available
  • existing API users still default to classic tier if no tier is provided
  • upload_id grouping is preserved for repeated compatibility requests
  • layout_type="studio" is supported
  • callback payloads still use the familiar status + render_urls shape

What changed

The old Vercel Blob upload handshake is no longer supported.

/api/image/upload now accepts:

  • multipart/form-data
  • JSON with image_base64
  • JSON with data_url

If an old client still tries the legacy Vercel upload method, the endpoint returns a clear error telling you to switch to multipart or base64 upload.

Common errors

  • 400 invalid request body, invalid image format, invalid image URL, unsupported content type, or render cap exceeded
  • 401 missing or invalid API token
  • 402 insufficient credits
  • 403 account blocked or restricted
  • 413 upload too large
  • 503 temporary service or queueing failure