API Documentation

Integrate Elirian's AI design engine into your products. Generate photorealistic room redesigns, virtual staging, and style transfers programmatically.

Introduction

The Elirian API is a REST API that returns JSON. All requests must be made over HTTPS. The base URL for all endpoints is:

https://app.elirian.com/api/v1

API access is available on Pro and higher plans. Each API call consumes the same credits as using the studio directly.

Authentication

Authenticate requests by passing your API key in the Authorization header:

Authorization: Bearer ek_YOUR_API_KEY

API keys are generated in your account dashboard. Keep your key secret - never expose it in client-side code.

Generating a key

Go to Dashboard → API Keys → Create New Key. Choose the scopes your key needs and give it a descriptive name.

Rate Limits

PlanRequests / minuteConcurrent jobs
Pro303
Studio606
Agency12012

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Generate Design

POST /api/v1/generate

Submits a design job. Returns immediately with a token you can use to poll for results.

Request body

ParameterTypeRequiredDescription
modestringrequiredGeneration mode. See Modes Reference for all 22 available modes.
image_urlstring*mode-dependentURL of the source room image (JPEG or PNG, max 10 MB). Required for all modes except freestyle.
stylestringoptionalStyle name (e.g. Japandi, Modern Luxury)
room_typestringoptionalRoom type (e.g. Living Room, Bedroom)
qualitystringoptionalstandard (1 cr), high (2 cr), ultra (5 cr). Default: high
promptstringoptionalAdditional text instructions (max 500 chars)
make_publicbooleanoptionalPublish to public gallery on completion. Default: false

Example

curl -X POST https://app.elirian.com/api/v1/generate \
  -H "Authorization: Bearer ek_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/room.jpg",
    "mode": "redesign",
    "style": "Japandi",
    "room_type": "Living Room"
  }'

Response

{
  "token": "dsn_abc123xyz",
  "status": "queued",
  "estimated_seconds": 15,
  "credits_charged": 1
}

Generation Modes

Pass one of the following values as the mode parameter. Modes marked img required need an image_url; freestyle generates from a prompt alone.

ModeDescriptionImageCredits
redesignFull AI redesign of an existing room in a new stylerequired1-5
style_transferApply a style reference image to your roomrequired1-5
virtual_stagingFurnish and stage an empty or bare roomrequired1-5
sketch2imageConvert a hand-drawn or 2D floor-plan sketch to a renderrequired2-5
sketchupRender from a SketchUp / CAD model screenshotrequired2-5
empty_spaceRemove all furniture and render a clean empty roomrequired2
outdoorTransform or redesign outdoor spaces and gardensrequired1-5
freestyleGenerate a room purely from text description - no image needednot needed1-5
upscaleUpscale and enhance an existing image (2× or 4×)required1-2
wall_painterChange wall colour(s) without altering furnishingsrequired1-2
lighting_changerAlter the lighting mood (warm, cool, natural, dramatic)required1-2
color_paletteExtract a colour palette from a room and apply variationsrequired1
furniture_placementDrop specific furniture pieces into a room photorequired1-5
layout_optimizerAI-suggest optimised furniture arrangements for a floor planrequired1-2
room_planner2D room planning and layout drawing tooloptional1
add_peopleAdd lifelike people to room renders for lifestyle photographyrequired1-2
product_placementInsert specific products into a room scenerequired1-5
lens_lookupIdentify products and materials visible in a room photorequired1
compareGenerate a side-by-side or slider before/after comparisonrequired1
3d_flythroughGenerate a short 3D flythrough video of a roomrequired5-10
vr_walkthroughCreate an interactive 360° VR walkthroughrequired5-10
batchApply the same transformation to multiple images at oncerequiredper-image

Check Job Status

GET /api/v1/session/{token}

Poll this endpoint until status is completed or failed. We recommend polling every 2 seconds.

Response (completed)

{
  "token": "dsn_abc123xyz",
  "status": "completed",
  "output_url": "https://cdn.elirian.com/outputs/...",
  "thumbnail_url": "https://cdn.elirian.com/thumbs/...",
  "gallery_id": 42,
  "created_at": "2026-05-20T14:23:01Z",
  "completed_at": "2026-05-20T14:23:18Z"
}

Scopes Reference

API keys can be restricted to specific scopes. Grant only the permissions your integration needs.

ScopeAccess granted
generateSubmit design jobs and consume credits
gallery:readList and read your design gallery
gallery:writeUpdate visibility / metadata of your designs
session:readPoll job status

Errors

All errors return a JSON body with message and optional errors array.

StatusMeaning
400Bad request - validation failed
401Unauthorized - missing or invalid API key
402Payment required - insufficient credits
403Forbidden - key lacks required scope
404Resource not found
429Too many requests - rate limit exceeded
500Internal server error

SDKs & Examples

Official SDKs are in development. Use the REST API directly with any HTTP client. The examples below show a full generate + poll cycle.

# 1. Submit a job
curl -X POST https://app.elirian.com/api/v1/generate \
  -H "Authorization: Bearer ek_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "redesign",
    "image_url": "https://example.com/room.jpg",
    "style": "Japandi",
    "room_type": "Living Room",
    "quality": "high"
  }'

# 2. Poll for result (repeat until status = completed)
curl https://app.elirian.com/api/v1/session/dsn_abc123xyz \
  -H "Authorization: Bearer ek_YOUR_API_KEY"
const API_KEY = 'ek_YOUR_API_KEY';
const BASE    = 'https://app.elirian.com/api/v1';

// 1. Submit job
const job = await fetch(`${BASE}/generate`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    mode: 'redesign',
    image_url: 'https://example.com/room.jpg',
    style: 'Japandi',
    room_type: 'Living Room',
    quality: 'high',
  }),
}).then(r => r.json());

// 2. Poll until done
async function pollResult(token) {
  while (true) {
    const res = await fetch(`${BASE}/session/${token}`, {
      headers: { 'Authorization': `Bearer ${API_KEY}` },
    }).then(r => r.json());

    if (res.status === 'completed') return res.output_url;
    if (res.status === 'failed')    throw new Error(res.failure_reason);

    await new Promise(r => setTimeout(r, 2000)); // wait 2s
  }
}

const outputUrl = await pollResult(job.token);
console.log('Done:', outputUrl);
<?php

$apiKey = 'ek_YOUR_API_KEY';
$base   = 'https://app.elirian.com/api/v1';

// 1. Submit job
$ch = curl_init("{$base}/generate");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        "Authorization: Bearer {$apiKey}",
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'mode'       => 'redesign',
        'image_url'  => 'https://example.com/room.jpg',
        'style'      => 'Japandi',
        'room_type'  => 'Living Room',
        'quality'    => 'high',
    ]),
]);
$job = json_decode(curl_exec($ch), true);
curl_close($ch);

// 2. Poll until done
$token = $job['token'];
do {
    sleep(2);
    $ch = curl_init("{$base}/session/{$token}");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ["Authorization: Bearer {$apiKey}"],
    ]);
    $result = json_decode(curl_exec($ch), true);
    curl_close($ch);
} while ($result['status'] === 'pending' || $result['status'] === 'processing');

if ($result['status'] === 'completed') {
    echo "Output: " . $result['output_url'] . PHP_EOL;
} else {
    echo "Failed: " . $result['failure_reason'] . PHP_EOL;
}
import time
import httpx

API_KEY = "ek_YOUR_API_KEY"
BASE    = "https://app.elirian.com/api/v1"

client = httpx.Client(headers={"Authorization": f"Bearer {API_KEY}"})

# 1. Submit job
job = client.post(f"{BASE}/generate", json={
    "mode":      "redesign",
    "image_url": "https://example.com/room.jpg",
    "style":     "Japandi",
    "room_type": "Living Room",
    "quality":   "high",
}).json()

# 2. Poll until done
token = job["token"]
while True:
    result = client.get(f"{BASE}/session/{token}").json()
    if result["status"] == "completed":
        print("Output:", result["output_url"])
        break
    elif result["status"] == "failed":
        raise RuntimeError(result["failure_reason"])
    time.sleep(2)