RoomStack integrations

API documentation

Use the API to generate staged room photos, edit existing images, check credits, download generated assets, and receive webhooks when work is completed. Create API keys and webhook endpoints from the API Access page.

Base URL and authentication

All API requests are authenticated with an API key in the x-api-key header. API keys are scoped to the account that created them. Generated image download URLs also require the same header.

curl https://roomstack.io/api/v1/credits \
  -H "x-api-key: aptd_YOUR_KEY"

Endpoints

POST/api/v1/generate

Generate furnished room images from one uploaded room photo.

POST/api/v1/edit

Edit an existing image with a prompt, selected furniture, or an optional mask.

GET/api/v1/images/{imageId}

Download a generated image returned in API responses or webhook payloads.

GET/api/v1/credits

Return remaining credits and current subscription state.

GET/api/v1/usage

Return API usage counters for the authenticated API key.

Generate room images

Send multipart form-data with one required room image. Furniture reference images are optional. Credits are charged per variant and can cost more for wider scale or larger output sizes. By default the response is synchronous and includes base64 images plus a persisted generationId when storage succeeds. Send async=true to queue the job and receive a generationId immediately.

curl -X POST https://roomstack.io/api/v1/generate \
  -H "x-api-key: aptd_YOUR_KEY" \
  -F image=@/path/to/empty-room.jpg \
  -F style=modern \
  -F roomType=living_room \
  -F budget=mid \
  -F variants=4 \
  -F scale=wide \
  -F imageSize=1K \
  -F roomFidelity=strict \
  -F roomSize=small \
  -F furnitureImages=@/path/to/sofa.png
curl -X POST "https://roomstack.io/api/v1/generate?async=true" \
  -H "x-api-key: aptd_YOUR_KEY" \
  -F image=@/path/to/empty-room.jpg \
  -F style=modern \
  -F roomType=living_room \
  -F budget=mid \
  -F variants=4
Supported fields

image, style, roomType, budget, variants, scale, imageSize, roomFidelity, roomSize, promptOverride, async, and repeated furnitureImages.

roomFidelity can be strict, balanced, or creative. Use strict when the room itself must not change. roomSize can be small, medium, or large to guide furniture scale.

Edit an image

Use edit when you already have a generated image or a customer-facing photo and want to adjust styling, furniture, light, or layout. Edits cost 1 credit.

curl -X POST https://roomstack.io/api/v1/edit \
  -H "x-api-key: aptd_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "originalImage": "data:image/png;base64,...",
    "editPrompt": "Make the room warmer and add modern Nordic furniture",
    "selectedFurniture": ["oak dining table", "linen sofa"]
  }'

Response format

Generation and edit endpoints return the provider request id, persisted generation id, image results, and metadata. Images are returned as data URLs/base64 for immediate use. When webhooks fire, they include authenticated download URLs for the same stored images. Async generation returns HTTP 202 with status queued; poll /api/generations?id=... in the app or rely on webhooks for completion.

{
  "requestId": "provider_request_id",
  "generationId": "persisted_generation_id",
  "images": [
    {
      "base64": "data:image/png;base64,..."
    }
  ],
  "meta": {
    "status": "COMPLETED",
    "durationMs": 8400
  }
}

Download generated images

Webhook payloads include downloadUrl for each generated image. Download URLs are not public; call them with your API key. This keeps webhook payloads small while still letting you copy images to your own CDN, DAM, CRM, or listing platform.

curl https://roomstack.io/api/v1/images/IMAGE_ID \
  -H "x-api-key: aptd_YOUR_KEY" \
  --output staged-room.png

Webhooks

Webhooks can be configured under API Access. RoomStack sends a POST request when a generation or edit completes. A webhook endpoint can subscribe to generation.completed, edit.completed, or both.

{
  "id": "delivery_id",
  "event": "generation.completed",
  "createdAt": "2026-05-01T12:00:00.000Z",
  "data": {
    "generationId": "generation_id",
    "kind": "generation",
    "source": "api",
    "status": "completed",
    "creditsCharged": 1,
    "settings": {
      "style": "modern",
      "roomType": "living_room",
      "variants": 4
    },
    "images": [
      {
        "id": "image_id",
        "index": 0,
        "mimeType": "image/png",
        "sizeBytes": 123456,
        "downloadUrl": "https://roomstack.io/api/v1/images/image_id"
      }
    ]
  }
}

Webhook signatures

Each delivery is signed with your endpoint secret. Verify signatures before trusting the payload. The signature base string is timestamp + "." + rawBody, signed with HMAC SHA-256.

Headers
  • RoomStack-Event
  • RoomStack-Delivery
  • RoomStack-Timestamp
  • RoomStack-Signature
Signature format

RoomStack-Signature: v1=hex_hmac_sha256

import crypto from "crypto";

function verifyRoomStackWebhook({ rawBody, timestamp, signature, secret }) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature.replace("v1=", ""), "hex"),
    Buffer.from(expected, "hex")
  );
}

Errors and rate limits

Common status codes
  • 400: invalid input or unsupported file
  • 401: missing or invalid API key
  • 402: not enough credits
  • 403: subscription or permission issue
  • 429: rate limit exceeded
  • 500: provider or server error
Error body
{
  "error": "Not enough credits.",
  "creditsRequired": 2,
  "availableCredits": 0
}