Spacevo Interior Design API Reference

Authentication, endpoints, parameters, error codes and rate limits for the Spacevo interior design and virtual staging API (v1).

The Spacevo API runs the same render pipeline as the web product, without the browser. One POST submits a room photo, one GET returns the finished image at full resolution with no watermark.

Looking for prices and use cases first? Start on the API overview page.

Base URL

https://spacevo.io/api/v1

All endpoints accept and return application/json. Everything is served over HTTPS; plain HTTP requests are refused.

Authentication

Every request carries a bearer key:

Authorization: Bearer sk-your_key
  • Create and revoke keys in Settings → API Keys once your account is on the API Plan. Keys look like sk- followed by 32 characters and are shown once at creation time — store them in your secret manager, not in source control.
  • Keys are issued to API Plan subscribers only. There is no free API tier; evaluate output quality on the web product first.
  • A missing, malformed, revoked or unknown key returns 401. Every failure mode collapses to the same 401, so the endpoint cannot be used to probe which keys exist.
  • Authentication and quota are separate gates: a valid key on an account with no API quota authenticates fine and then gets 402 on the render itself.

The key is a full account credential. Never ship it to a browser, a mobile app, or any client you do not control — call the API from your own server.

Quota and metering

  • 1 render = 1 credit. A credit is consumed when a render is accepted, not when it finishes.
  • The API Plan grants 1,000 renders per calendar month. Quota resets at the start of each billing month and does not roll over.
  • The API quota is a separate pool from web credits. Subscription credits, credit packs and the 5 sign-up credits belong to the browser product and are never spent by the API — and vice versa.
  • A render that fails on our side is refunded to the API pool automatically.
  • Both endpoints report credits_remaining, so you can alert on your own threshold rather than waiting for a 402.

Rate limit

60 requests per minute, per key. The submit endpoint and the poll endpoint each get their own 60/minute window, so polling in-flight renders never eats the budget you need for submitting new ones.

Over the limit the API returns 429 with a Retry-After header (in seconds). Back off and retry; a queue of a few hundred renders is best submitted at a steady pace rather than in one burst.

POST /api/v1/render

Submits a room photo and starts a render. The call returns immediately — it does not wait for the image.

Request body

FieldTypeRequiredDescription
image_urlstringYesPublicly reachable HTTPS URL of the source photo, at most 2,048 characters. The URL must resolve without authentication for as long as the render is running. Hosts that resolve to a private or loopback address are refused.
stylestringYesEither a style id from the Spacevo style library — scandinavian, modern, japandi, industrial, minimalist, bohemian, midcentury, luxury, newchinese, cream, french, mediterranean — or a free-text style direction of 3–500 characters, which is run through content moderation.
room_typestringNoliving-room (default), bedroom, kitchen, dining-room, bathroom, home-office, kids-room, villa.
modestringNorestyle (default) restyles a furnished room. staging furnishes an empty room. No other value is accepted in v1.

Example

curl -X POST https://spacevo.io/api/v1/render \
  -H "Authorization: Bearer sk-your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://cdn.example.com/listings/8412/living-room.jpg",
    "style": "scandinavian",
    "room_type": "living-room",
    "mode": "staging"
  }'

Response — 202

{
  "id": "8f4c1d6e-2b7a-4f19-9c3d-5a10e7b64f28",
  "status": "processing",
  "credits_remaining": 962
}

Store id — a UUID, and the only handle on the render.

GET /api/v1/render/{id}

Returns the current state of a render. Poll it until status is terminal.

curl https://spacevo.io/api/v1/render/8f4c1d6e-2b7a-4f19-9c3d-5a10e7b64f28 \
  -H "Authorization: Bearer sk-your_key"

Response — 200

{
  "id": "8f4c1d6e-2b7a-4f19-9c3d-5a10e7b64f28",
  "status": "succeeded",
  "image_url": "https://cdn.spacevo.io/interior/api/8f4c1d6e.jpg",
  "credits_remaining": 962,
  "created_at": "2026-08-06T09:14:22.481Z"
}
statusMeaning
processingAccepted and rendering. This is also the state a render is in the moment it is created.
succeededDone. image_url is populated.
failedRender failed; the credit has been refunded. error explains why.

image_url is present only on succeeded, and error only on failed; id, status, credits_remaining and created_at are always returned. An id that does not exist — or belongs to another account, or to a render made in the browser rather than through the API — returns 404.

image_url is the full-resolution image with no watermark. Download and store it on your own storage — the URL is not a permanent asset host.

Renders normally complete in tens of seconds. Poll every 2–3 seconds; polling faster only burns your rate limit.

Error codes

Errors return a JSON body:

{
  "error": {
    "code": "insufficient_quota",
    "message": "Your API quota for this period is exhausted. Upgrade or wait for the next billing period."
  }
}
HTTPCodeWhat happenedWhat to do
401unauthorizedKey missing, malformed, unknown or revoked.Check the Authorization header and the key's status in Settings → API Keys.
402insufficient_quotaThe period's render quota is spent.Wait for the monthly reset, or contact us to size up. Quota does not roll over.
404not_foundUnknown render id — also returned for another account's id, and for renders made in the browser.Check the id you stored from the POST.
422invalid_requestThe body is not JSON, a parameter is missing or not one of the accepted values, or image_url is not a reachable public HTTPS URL.Fix the field named in message and resubmit. Not billed.
429rate_limitedMore than 60 requests in a minute on this key, on this endpoint.Back off for the seconds given in Retry-After and retry. Not billed.
451content_rejectedA free-text style was blocked by content moderation. Built-in style ids are never moderated.Do not retry the same text. Not billed — moderation runs before the charge.
503moderation_unavailableContent moderation was unreachable, so the request failed closed.Retry in a moment. Not billed.
500internal_errorSomething broke on our side.Retry with backoff. Not billed.

5xx responses mean the failure is on our side: retry with backoff, and no credit is consumed.

End-to-end example

import os
import time

import requests

API = "https://spacevo.io/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SPACEVO_API_KEY']}"}

created = requests.post(
    f"{API}/render",
    headers=HEADERS,
    json={
        "image_url": "https://cdn.example.com/listings/8412/living-room.jpg",
        "style": "scandinavian",
        "room_type": "living-room",
    },
    timeout=30,
).json()

while True:
    render = requests.get(
        f"{API}/render/{created['id']}", headers=HEADERS, timeout=30
    ).json()
    if render["status"] in ("succeeded", "failed"):
        break
    time.sleep(2)

print(render["image_url"])
const API = 'https://spacevo.io/api/v1';
const headers = {
  Authorization: `Bearer ${process.env.SPACEVO_API_KEY}`,
  'Content-Type': 'application/json',
};

const created = await fetch(`${API}/render`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    image_url: 'https://cdn.example.com/listings/8412/living-room.jpg',
    style: 'scandinavian',
    room_type: 'living-room',
  }),
}).then((res) => res.json());

let render;
do {
  await new Promise((resolve) => setTimeout(resolve, 2000));
  render = await fetch(`${API}/render/${created.id}`, { headers }).then((res) =>
    res.json()
  );
} while (render.status === 'processing');

console.log(render.image_url);

Using the output

The API Plan includes a commercial licence: rendered images can go on listing portals, in brochures and inside client-facing products. Most property portals and industry codes require a virtually staged photo to be labelled as virtually staged — keep the disclosure your market expects.

Video rendering is not part of v1. Need it, or need volume beyond the plan? Talk to us.