Lumely
Lumely
HomeFeaturesExamplesPricing
Lumely

AI-Powered architectural visualization for professionals. Enhance renders, stage rooms, and explore design options in minutes.

Product

  • Features
  • Pricing
  • Showcase
  • Render Enhancement
  • Virtual Staging
  • Design Options
  • 3D Floor Plans
  • Image Upscaler

Resources

  • Help Center
  • Documentation
  • API Documentation

Company

  • Privacy Policy
  • Terms of Service

© 2026 Lumely AI. All rights reserved.

All systems operational
Back to Documentation

API Reference

Integrate Lumely AI into your workflow programmatically.

v1Base URL: https://lumely.ai/api/v1

Authentication

All API requests require authentication. There are three supported methods, evaluated in this priority order:

1. API Key (Recommended)

Pass your API key in the Authorization header. Keys are prefixed with lum_live_.

curl -H "Authorization: Bearer lum_live_abc123..." \
  https://lumely.ai/api/v1/credits

2. Bearer Token (Supabase JWT)

Use a Supabase session JWT for browser-based integrations.

curl -H "Authorization: Bearer eyJhbGci..." \
  https://lumely.ai/api/v1/credits

3. Session Cookie

Automatically used when calling from the Lumely dashboard. No additional setup needed.

Rate Limiting: Standard accounts are limited to 30 requests per minute. Enterprise accounts receive custom RPM limits. Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are included in every response.

Credits

Check your current credit balance and subscription status.

GET/api/v1/credits
Example response
{
  "credits_remaining": 58,
  "credits_total": 60,
  "plan_id": "basic",
  "subscription_status": "active",
  // Enterprise accounts also receive:
  "enterprise": {
    "company_name": "Acme Architecture",
    "credit_price_cents": 25,
    "currency": "EUR",
    "auto_topup_enabled": true,
    "monthly_credit_limit": 1000,
    "credits_used_this_month": 142,
    "rate_limit_rpm": 120,
    "allowed_services": ["render-enhancement", "virtual-staging"]
  }
}

Services

List available services and their configuration options.

GET/api/v1/services
Example response
{
  "services": [
    {
      "id": "render-enhancement",
      "name": "Render Enhancement",
      "description": "Enhance architectural renders with photorealistic lighting, materials, and detail.",
      "credits_2k": 2,
      "credits_4k": 3,
      "config_ids": [
        "exterior-modern", "exterior-traditional", 
        "interior-modern", "interior-traditional", 
        "interior-minimalist", "landscape", "aerial"
      ],
      "supports_mask": true,
      "supports_reference_image": false,
      "supports_prompt": true
    },
    {
      "id": "virtual-staging",
      "name": "Virtual Staging",
      "config_ids": ["living-room", "bedroom", "kitchen", "dining-room", "office", "bathroom"],
      "supports_mask": true,
      "supports_reference_image": true,
      "supports_prompt": true
    }
    // ... more services
  ],
  "resolutions": ["2K", "4K"],
  "note": "4K resolution requires a paid subscription."
}

Available Services

ServiceConfig IDsCredits (2K / 4K)Features
render-enhancementexterior-modern, exterior-traditional, interior-modern, interior-traditional, interior-minimalist, landscape, aerial2 / 3Mask, Prompt
virtual-stagingliving-room, bedroom, kitchen, dining-room, office, bathroom2 / 3Mask, Reference Image, Prompt
design-optionsexterior-modern, exterior-traditional, interior-modern, interior-traditional, landscape2 / 3Mask, Reference Image, Prompt
3d-plansresidential, commercial, office2 / 3Prompt

Upload

Upload an image to receive a storage_path for use when creating jobs.

POST/api/v1/upload
ParameterTypeRequiredDescription
imagestringRequiredBase64-encoded image data, with or without the data:image/... prefix. Supports JPEG, PNG, WebP, and GIF. Max 10 MB body size.
cURL
curl -X POST https://lumely.ai/api/v1/upload \
  -H "Authorization: Bearer lum_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "image": "data:image/jpeg;base64,/9j/4AAQ..."
  }'

Jobs

Create, list, cancel, and retry image processing jobs. Jobs are processed asynchronously — poll the job status or use webhooks for notifications.

Create a Job

POST/api/v1/jobs
ParameterTypeRequiredDescription
service_typestringRequiredService to run. One of: render-enhancement, virtual-staging, design-options, 3d-plans.
config_idstringRequiredConfiguration preset. Valid IDs depend on the service — see the Services table.
storage_pathstringRequiredPath returned from POST /api/v1/upload.
resolutionstringOptionalOutput resolution. "2K" (default) or "4K" (paid plans only, costs 3 credits).
promptstringOptionalOptional text prompt to guide the AI generation.
mask_base64stringOptionalBase64-encoded mask image for targeted edits (services that support masking).
reference_image_base64stringOptionalBase64-encoded style reference image (services that support reference images).
reference_image_storage_pathstringOptionalStorage path for a previously uploaded reference image (alternative to base64).
reference_idstringOptionalYour own identifier to link this job to your system (max 255 chars).
idempotency_keystringOptionalUnique key to prevent duplicate job creation on retries (max 255 chars).
optionsobjectOptionalScene settings object: { lighting, weather, season, crowd, camera, style, flooring, landscaping }.
locationobjectOptionalGeographic location to match local architectural styles. Object: { description, city, region, country, latitude, longitude }.
cURL
curl -X POST https://lumely.ai/api/v1/jobs \
  -H "Authorization: Bearer lum_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "service_type": "virtual-staging",
    "config_id": "living-room",
    "storage_path": "user-uuid/api_1709654321_a1b2c3d4e5f6.jpg",
    "resolution": "2K",
    "prompt": "Modern Scandinavian style with warm lighting",
    "reference_id": "project-42-room-3",
    "options": {
      "lighting": "warm",
      "style": "modern"
    },
    "location": {
      "description": "Grafton Street, Dublin, Ireland",
      "city": "Dublin",
      "region": "County Dublin",
      "country": "Ireland",
      "latitude": 53.3411,
      "longitude": -6.2603
    }
  }'
Pay-on-Success: Credits are validated at job creation but only deducted when processing completes successfully. Failed or cancelled jobs are never charged.

Get Job Status

GET/api/v1/jobs/{job_id}

Job Statuses

StatusDescription
pendingJob is queued and waiting to be processed.
compressingInput image is being optimised for processing.
processingAI generation is in progress (typically 30–90 seconds).
completedJob finished successfully. Output URL is available.
failedProcessing encountered an error. Check error_message. Can be retried.
cancelledJob was cancelled by the user. Can be retried.

List Jobs

GET/api/v1/jobs
ParameterTypeRequiredDescription
statusstringOptionalFilter by job status (e.g. completed, failed).
service_typestringOptionalFilter by service type.
limitintegerOptionalNumber of results (default: 50, max: 100).
offsetintegerOptionalPagination offset (default: 0).

Cancel / Retry a Job

POST/api/v1/jobs/{job_id}
ParameterTypeRequiredDescription
actionstringRequired"cancel" (pending/processing jobs) or "retry" (failed/cancelled jobs). Credits are re-validated on retry.

API Keys

Create and manage API keys. You can have up to 10 active keys.

List API Keys

GET/api/v1/api-keys

Create API Key

POST/api/v1/api-keys
ParameterTypeRequiredDescription
namestringOptionalLabel for the key (default: "Default", max 100 chars).
Important: The full key value is only returned once at creation time. Store it securely — it cannot be retrieved later.

Update / Revoke a Key

PATCH/api/v1/api-keys/{key_id}
DELETE/api/v1/api-keys/{key_id}
ParameterTypeRequiredDescription
namestringOptionalPATCH only. Update the key label.
is_activebooleanOptionalPATCH only. Set false to revoke, true to re-activate.

Webhooks

Receive real-time notifications when jobs complete, fail, or are cancelled. You can register up to 5 active webhook endpoints.

Create Webhook Endpoint

POST/api/v1/webhooks
ParameterTypeRequiredDescription
urlstringRequiredHTTPS URL to receive webhook POST requests. Localhost allowed for testing.
eventsstring[]OptionalEvents to subscribe to. Default: ["job.completed", "job.failed"]. Available: job.completed, job.failed, job.cancelled.

Update / Delete Webhook

PATCH/api/v1/webhooks/{webhook_id}
DELETE/api/v1/webhooks/{webhook_id}
ParameterTypeRequiredDescription
urlstringOptionalPATCH only. New HTTPS URL.
eventsstring[]OptionalPATCH only. Updated event subscriptions.
is_activebooleanOptionalPATCH only. Set false to deactivate, true to re-enable (resets failure count).

List Webhooks

GET/api/v1/webhooks

Verifying Webhook Signatures

Each webhook delivery includes a signature in the X-Lumely-Signature header. Verify it using your webhook secret to ensure the request came from Lumely.

Node.js
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler:
app.post('/webhooks/lumely', (req, res) => {
  const signature = req.headers['x-lumely-signature'];
  if (!verifyWebhookSignature(req.body, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const { event, data } = req.body;
  if (event === 'job.completed') {
    console.log('Output:', data.output_image_url);
  }
  res.status(200).send('OK');
});

Error Handling

All errors return a JSON object with an error field and usually a message field with actionable guidance.

Error response format
{
  "error": "Insufficient credits",
  "message": "You need 2 credits but only have 1 remaining.",
  "credits_required": 2,
  "credits_remaining": 1
}

HTTP Status Codes

CodeMeaningCommon Causes
200OKSuccessful read, update, cancel, or retry.
201CreatedSuccessfully created a resource (job, API key, webhook, upload).
400Bad RequestMissing required fields, invalid service_type, invalid config_id, malformed image data.
401UnauthorisedInvalid or revoked API key, expired Bearer token, no auth provided.
403ForbiddenInsufficient credits, 4K without paid plan, storage path access denied, monthly limit reached.
404Not FoundJob/key/webhook ID not found or belongs to another account, no subscription.
405Method Not AllowedHTTP method not supported for this endpoint. Check the "allowed" array in the response.
409ConflictDuplicate job detected (when using idempotency_key — existing job returned with 200 instead).
429Rate LimitedToo many requests. Check Retry-After header and X-RateLimit-* headers.
500Server ErrorInternal error. The response message will suggest whether to retry.

Rate Limit Headers

Every response includes these headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute.
X-RateLimit-RemainingRequests remaining in the current window.
X-RateLimit-ResetISO 8601 timestamp when the limit resets.
Retry-AfterSeconds to wait before retrying (only present on 429 responses).

Complete Workflow Example

Here's the full flow to enhance an image via the API:

Step 1: Upload your image

cURL
curl -X POST https://lumely.ai/api/v1/upload \
  -H "Authorization: Bearer lum_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{ "image": "data:image/jpeg;base64,/9j/4AAQ..." }'

# Response: { "storage_path": "user-uuid/api_123_abc.jpg", ... }

Step 2: Create a job

cURL
curl -X POST https://lumely.ai/api/v1/jobs \
  -H "Authorization: Bearer lum_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "service_type": "render-enhancement",
    "config_id": "exterior-modern",
    "storage_path": "user-uuid/api_123_abc.jpg"
  }'

# Response: { "id": "JOB_ID", "status": "pending", "poll_url": "/api/v1/jobs/JOB_ID" }

Step 3: Poll for completion (or use webhooks)

cURL
curl https://lumely.ai/api/v1/jobs/JOB_ID \
  -H "Authorization: Bearer lum_live_abc123..."

# When status is "completed":
# { "status": "completed", "output_image_url": "https://..." }

Step 4: Download the result

cURL
# The output_image_url is a public URL — download directly:
curl -o result.jpg "https://your-supabase-url.../output-image.jpg"

Need help with your integration?

Contact Support Manage API Keys