Homux

Homux for developers

The visualizer on your website

Let shoppers see your products in their own room — right from your website. Add the button with two lines of HTML, share try links with no code, and sync your catalog with the REST API.

  1. 1The shopper clicks “Try in your room”
  2. 2The visualizer opens in a window on your page
  3. 3They upload a room photo or pick a sample
  4. 4Your product goes straight onto the room

The window shows only your products, and every open shows up in your Analytics.

Two lines — that’s it
<!-- 1. Once, on every page (before </body>) -->
<script src="https://homux.ge/embed/homux.js" data-company="your-handle" async></script>

<!-- 2. Where the button should appear -->
<div data-homux-try data-sku="WP-1042"></div>

Ready-made code for your products

In your dashboard: Settings → “Website & API” — your handle is already filled in, open →

Live demo

How it looks on your site

Below is a demo online store with the Homux script added. Switch between the product page and the catalog, check the mobile version, or click a button to see what your shopper would see.

kvamo.ge/en/product/calacattaFull screen
  1. 1Product page — a large button under "Add to cart"<div data-homux-try data-size="lg" data-full-width …>
  2. 2Catalog — a small button on every card<div data-homux-try data-size="sm" data-theme="light" …>
  3. 3Footer — the badge (optional)<div data-homux-badge>

"Kvamo" is a made-up store. Everything in the frame is the store’s own code except the highlighted elements, which the Homux script draws. The buttons are real: click one and the visualizer opens in a window right on the store’s page. Product photos: FancyWalls, from the Homux catalog.

Website widget

Quick start

  1. 1

    Make sure the products are on Homux

    Add them in the dashboard or through the API. If your website gives products a code (SKU), enter the same code in Homux — then one template works for every product.

  2. 2

    Add the script once

    On every page, before </body> — or in your site’s “Custom code / Footer scripts” setting. data-company is your Homux handle.

  3. 3

    Place the button

    Where it should appear — e.g. under “Add to cart”.

The button only appears when the product exists on Homux and is public, so it is safe to put in the template for every product.
Every page
<script src="https://homux.ge/embed/homux.js" data-company="your-handle" async></script>
Product page
<div data-homux-try data-sku="WP-1042"></div>

Playground

Fill in a product, pick a style and copy the code — the preview is the real widget.

Once, on every page
<script src="https://homux.ge/embed/homux.js" async></script>
Where the button goes
<div data-homux-try data-product="0BA43UGxzzDhHDkv8wpJ" data-lang="en"></div>

Button options

Every option is an attribute on the element. data-company, data-lang, data-theme, data-size, data-open also work on the script tag, where they become the default for every button.

Attributes

  • data-homux-try
    Marks the element where the button appears.
  • data-skustring
    Your own product code. Needs data-company (on the element or the script tag). Not case-sensitive.
  • data-productstring
    Homux product ID — the alternative to data-sku.
  • data-companystring
    Your Homux handle without the @ (homux.ge/@your-handle). Usually set once, on the script tag.
  • data-openwindow | tab
    window (default) opens the visualizer in a window right on your page. tab opens it in a new tab on homux.ge.
  • data-langka | en
    Language of the button and the visualizer. Defaults to the page’s <html lang>, otherwise ka.
  • data-themebrand | dark | light
    Colours. Default: brand (orange).
  • data-sizesm | md | lg
    Size. Default: md.
  • data-labelstring
    Custom button text.
  • data-full-widthboolean
    Stretches the button to the width of its container.

Your own styling

The button lives in a Shadow DOM, so your site’s CSS can’t break it. Change colours, corner radius and font with CSS variables.

  • A real link (<a>): works with the keyboard and screen readers; Ctrl/⌘-click opens a new tab.
  • The script loads async, sets no cookies, and checks many buttons with a single request.
With every option
<div
  data-homux-try
  data-sku="WP-1042"
  data-theme="dark"
  data-size="lg"
  data-lang="en"
  data-label="See it in your room"
  data-full-width
></div>
Your own styling
/* Match your site's buttons */
[data-homux-try] {
  --homux-bg: #0b5d3b;
  --homux-bg-hover: #0a4f32;
  --homux-color: #ffffff;
  --homux-border: transparent;
  --homux-radius: 6px;
  --homux-font: "Inter", sans-serif;
}

Platform guides

Pick your platform in the code panel.

  • Shopify — Online Store → Themes → Edit code. Script in theme.liquid, button in the product section. When the variant changes, update data-sku and the button follows.
  • WooCommerce — your (child) theme’s functions.php, or a Code Snippets plugin.
  • Wix · Tilda · Webflow — one “Embed HTML” block with both lines together — some builders run each block in its own iframe.
  • React · Next.js · Vue — load the script once, render the element anywhere. New elements are picked up automatically.
<!-- layout/theme.liquid, right before </body> -->
<script src="https://homux.ge/embed/homux.js" data-company="your-handle" async></script>

<!-- sections/main-product.liquid, near the Add to cart button -->
<div data-homux-try data-sku="{{ product.selected_or_first_available_variant.sku | escape }}"></div>

JavaScript & events

The script exposes window.Homux. Events bubble up from the element, so one listener is enough.

Methods

  • Homux.lookup(opts)Promise<product | null>
    Checks whether a product is on Homux. opts: { sku } or { product }.
  • Homux.open(opts)Promise<boolean>
    Opens the visualizer window from your own button; { mode: "tab" } opens a new tab.
  • Homux.close()void
    Closes the window.
  • Homux.scan(root?)void
    Looks for elements again (rarely needed).

Events

  • homux:loadeddocument
    The script is ready.
  • homux:readyelement
    A button appeared. event.detail.product is the product.
  • homux:unavailableelement
    The product is not on Homux — no button is shown.
  • homux:openelement · cancelable
    The shopper clicked. event.preventDefault() stops the visualizer from opening.
  • homux:closeelement
    The visualizer window was closed.
window.Homux
// The script loads async — wait for it once:
function withHomux(fn) {
  if (window.Homux) fn(window.Homux);
  else document.addEventListener('homux:loaded', () => fn(window.Homux), { once: true });
}

withHomux(async (Homux) => {
  // Is this product on Homux? → product object, or null
  const product = await Homux.lookup({ sku: 'WP-1042' });

  // Open the visualizer window from your own button
  document.querySelector('#see-in-room').addEventListener('click', () => {
    Homux.open({ sku: 'WP-1042' }); // or { sku, mode: 'tab' }
  });
});
Events
// Google Analytics 4: track clicks on the Homux button
document.addEventListener('homux:open', (event) => {
  const p = event.detail.product;
  gtag('event', 'homux_try_in_room', { item_id: p.sku || p.id, item_name: p.name });
});

// Hide your own "visualize" label when the product is not on Homux
document.addEventListener('homux:unavailable', (event) => {
  event.target.closest('.visualize-box')?.remove();
});

Badge

A small “Visualized by Homux” credit that links to your Homux page. It uses the same script. The older homux-badge.js keeps working too.

<div data-homux-badge></div>
<div data-homux-badge data-theme="dark" data-lang="en"></div>

Product codes (SKU)

  • Where: Dashboard → Catalog → open a product → Edit → “Product code (SKU)”. Through the API — the sku field.
  • Codes are unique within your company, up to 64 characters. Case doesn’t matter: WP-1042 = wp-1042.
  • No SKU? Use the Homux ID — the last part of the product page address: homux.ge/ka/catalog/aBc123

API reference

Introduction

The Homux API is REST with JSON. Reading the public catalog needs no key and works from the browser (CORS). Adding, changing and deleting products uses a secret key, from your server only.

Responses are always { "data": … }; lists add has_more, next_cursor and total. Public responses are cached — a change can take up to 3 minutes to show.

v1 is stable. New fields may be added without notice — just ignore fields you don’t know. Anything breaking would ship as v2.

Authentication

Create keys in your dashboard: Settings → “Website & API” → API keys. Send it as a header: Authorization: Bearer hx_live_…

Keep keys on your server

A key is shown only once, when it’s created. Never put it in website JavaScript — keyed requests from browsers are blocked on purpose. If a key leaks, revoke it and create a new one.
GETSending your key
curl "https://homux.ge/api/v1/me" \
  -H "Authorization: Bearer $HOMUX_API_KEY"

Errors

Errors always carry a machine-readable code and a human message. Every response has an X-Request-Id header — include it when you ask for help.

Codes

  • bad_request400
    Malformed parameter or JSON.
  • unauthorized401
    Key missing, wrong or revoked.
  • subscription_required402
    Your subscription is not active — writes are paused.
  • plan_limit_reached403
    Your plan’s product limit is reached.
  • not_found · company_not_found404
    Product or company not found.
  • sku_taken409
    Another product already has this SKU (details.product_id).
  • validation_failed422
    Invalid fields — each one is explained in details.fields.
  • image_invalid · image_invalid_url · image_too_small · image_too_large422
    Image problem — message says what to fix.
  • image_unreachable424
    image_url could not be downloaded.
  • rate_limited429
    Too many requests — wait Retry-After seconds.
422 example
{
  "error": {
    "code": "validation_failed",
    "message": "Some fields are invalid.",
    "details": {
      "fields": {
        "price": "A number from 0 to 1000000 (GEL)."
      }
    },
    "docs": "https://homux.ge/developers"
  }
}

Limits & pagination

  • Public reads: 300 requests/min per IP. With a key: 120 requests/min per key.
  • Over the limit you get 429 with a Retry-After header in seconds.
  • Lists: limit (1–100, default 50) and cursor from the previous response’s next_cursor. has_more: false means the last page.
GETNext page
curl "https://homux.ge/api/v1/companies/your-handle/products?limit=50&cursor=Mg"
Response
{
  "data": [
    "…"
  ],
  "has_more": true,
  "next_cursor": "MTAw",
  "total": 148
}

Object

The product object

Attributes

  • idstring
    Homux product ID.
  • skustring | null
    Your code, when set.
  • namestring
    Product name.
  • categorywalls | floors | doors
    The room surface it goes on.
  • typestring
    Product type — see Product types.
  • subtype, material, stylestring | null
    Filter data.
  • finishstring[]
    Surface finish, e.g. ["Matte"].
  • colorstring | null
    Average colour, hex.
  • sizeobject | null
    Real-world size of what the image shows.
  • size_labelstring | null
    Size as text, e.g. "53 × 53 cm".
  • priceobject | null
    The price exactly as shoppers see it.
  • promo_textstring | null
    Offer line.
  • image_urlstring
    Texture, ≤ 2048 px.
  • thumbnail_urlstring
    480 px thumbnail.
  • companyobject
    Whose product it is.
  • urlsobject
    Ready-made links.
  • created_at, updated_atISO 8601
    Timestamps.
The product object
{
  "id": "aBc123",
  "sku": "WP-1042",
  "name": "Linen Grey",
  "category": "walls",
  "type": "Wallpaper",
  "subtype": null,
  "material": "Vinyl",
  "style": "Modern",
  "finish": [
    "Matte",
    "Textured"
  ],
  "color": "#b3b3ab",
  "size": {
    "width": 53,
    "height": 53,
    "unit": "cm"
  },
  "size_label": "53 × 53 cm",
  "price": {
    "amount": 27.99,
    "compare_at": null,
    "base_amount": 28,
    "currency": "GEL"
  },
  "promo_text": null,
  "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
  "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
  "company": {
    "id": "Xk2pQ8…",
    "handle": "your-handle",
    "name": "Your Store"
  },
  "urls": {
    "page": "https://homux.ge/ka/catalog/aBc123",
    "try_on": "https://homux.ge/api/v1/try?product=aBc123"
  },
  "created_at": "2026-09-30T10:12:00.000Z",
  "updated_at": "2026-10-02T08:40:00.000Z"
}

Retrieve a company

GET/v1/companies/{handle}

A company’s public profile and product count. No key needed.

Path parameters

  • handlestringRequired
    Homux handle, without the @.

Returns

  • dataobject
    The company, or 404 company_not_found.
GETRequest
curl "https://homux.ge/api/v1/companies/your-handle"
Response
{
  "data": {
    "id": "Xk2pQ8…",
    "handle": "your-handle",
    "name": "Your Store",
    "bio": "Wallpaper and tiles in Tbilisi",
    "logo_url": "https://firebasestorage.googleapis.com/…/logo.jpg",
    "website": "https://yourstore.ge",
    "location": "Tbilisi",
    "page_url": "https://homux.ge/ka/@your-handle",
    "product_count": 148
  }
}

List a company’s products

GET/v1/companies/{handle}/products

A company’s public products, newest first. No key needed.

Query parameters

  • categorywalls | floors | doors
    Filter by surface.
  • typestring
    Filter by type, e.g. Laminate.
  • skustring
    Specific SKUs, comma-separated (up to 50).
  • limitinteger
    1–100, default 50.
  • cursorstring
    next_cursor from the previous response.
  • langka | en
    Language of the urls.
GETRequest
curl "https://homux.ge/api/v1/companies/your-handle/products?category=walls&limit=2"
Response
{
  "data": [
    {
      "id": "aBc123",
      "sku": "WP-1042",
      "name": "Linen Grey",
      "category": "walls",
      "type": "Wallpaper",
      "subtype": null,
      "material": "Vinyl",
      "style": "Modern",
      "finish": [
        "Matte",
        "Textured"
      ],
      "color": "#b3b3ab",
      "size": {
        "width": 53,
        "height": 53,
        "unit": "cm"
      },
      "size_label": "53 × 53 cm",
      "price": {
        "amount": 27.99,
        "compare_at": null,
        "base_amount": 28,
        "currency": "GEL"
      },
      "promo_text": null,
      "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
      "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
      "company": {
        "id": "Xk2pQ8…",
        "handle": "your-handle",
        "name": "Your Store"
      },
      "urls": {
        "page": "https://homux.ge/ka/catalog/aBc123",
        "try_on": "https://homux.ge/api/v1/try?product=aBc123"
      },
      "created_at": "2026-09-30T10:12:00.000Z",
      "updated_at": "2026-10-02T08:40:00.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "Mg",
  "total": 61
}

Retrieve a product

GET/v1/products/{id}

One public product by Homux ID.

Path parameters

  • idstringRequired
    Homux product ID.
GETRequest
curl "https://homux.ge/api/v1/products/aBc123"
Response
{
  "data": {
    "id": "aBc123",
    "sku": "WP-1042",
    "name": "Linen Grey",
    "category": "walls",
    "type": "Wallpaper",
    "subtype": null,
    "material": "Vinyl",
    "style": "Modern",
    "finish": [
      "Matte",
      "Textured"
    ],
    "color": "#b3b3ab",
    "size": {
      "width": 53,
      "height": 53,
      "unit": "cm"
    },
    "size_label": "53 × 53 cm",
    "price": {
      "amount": 27.99,
      "compare_at": null,
      "base_amount": 28,
      "currency": "GEL"
    },
    "promo_text": null,
    "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
    "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
    "company": {
      "id": "Xk2pQ8…",
      "handle": "your-handle",
      "name": "Your Store"
    },
    "urls": {
      "page": "https://homux.ge/ka/catalog/aBc123",
      "try_on": "https://homux.ge/api/v1/try?product=aBc123"
    },
    "created_at": "2026-09-30T10:12:00.000Z",
    "updated_at": "2026-10-02T08:40:00.000Z"
  }
}

Retrieve many products

GET/v1/products?ids=…

Several products in one request (up to 50). IDs that aren’t found are simply left out.

Query parameters

  • idsstringRequired
    Comma-separated IDs.
GETRequest
curl "https://homux.ge/api/v1/products?ids=aBc123,dEf456"
Response
{
  "data": [
    {
      "id": "aBc123",
      "sku": "WP-1042",
      "name": "Linen Grey",
      "category": "walls",
      "type": "Wallpaper",
      "subtype": null,
      "material": "Vinyl",
      "style": "Modern",
      "finish": [
        "Matte",
        "Textured"
      ],
      "color": "#b3b3ab",
      "size": {
        "width": 53,
        "height": 53,
        "unit": "cm"
      },
      "size_label": "53 × 53 cm",
      "price": {
        "amount": 27.99,
        "compare_at": null,
        "base_amount": 28,
        "currency": "GEL"
      },
      "promo_text": null,
      "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
      "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
      "company": {
        "id": "Xk2pQ8…",
        "handle": "your-handle",
        "name": "Your Store"
      },
      "urls": {
        "page": "https://homux.ge/ka/catalog/aBc123",
        "try_on": "https://homux.ge/api/v1/try?product=aBc123"
      },
      "created_at": "2026-09-30T10:12:00.000Z",
      "updated_at": "2026-10-02T08:40:00.000Z"
    }
  ]
}

Upsert a product by SKU

PUT/v1/products/by-sku/{sku}

Recommended for syncing

Creates the product with this SKU, or updates it if it exists — safe to run again and again. Responds 201 (created) or 200 (updated) with "created": true/false.

Requires an API key.

Path parameters

  • skustringRequired
    Your product code.

Body parameters

  • namestring ≤ 200Required
    Product name.
  • categorywalls | floors | doorsRequired
    Which room surface it goes on.
  • typestringRequired
    Product type — see Product types. Slugs work too: wood-flooring.
  • image_urlhttps URLRequired on create
    Photo of the surface (JPEG, PNG, WebP, AVIF, GIF; max 20 MB and 40 MP; short side at least 200 px). Sending the same URL again does not re-download it.
  • image_base64string
    The same image as base64 when you have no public URL.
  • pricenumber
    Price in GEL (0 – 1,000,000).
  • compare_at_pricenumber
    The old, struck-through price. Must be greater than price.
  • promo_textstring ≤ 120
    Offer line under the price.
  • sizeobject
    Real-world size of what the image shows (each side ≤ 10 m). Give one tile or one wallpaper pattern repeat, not the roll length.
  • finishstring[]
    Surface finish, e.g. ["Matte", "Textured"] (up to 10).
  • material, style, subtypestring ≤ 60
    Material (Porcelain, Oak), style (Modern), subtype (Mosaic).
PUTRequest
curl -X PUT "https://homux.ge/api/v1/products/by-sku/WP-1042" \
  -H "Authorization: Bearer $HOMUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Linen Grey",
  "category": "walls",
  "type": "Wallpaper",
  "price": 26,
  "compare_at_price": 28,
  "image_url": "https://yourstore.ge/images/wp-1042-swatch.jpg"
}'
200 · Response
{
  "data": {
    "id": "aBc123",
    "sku": "WP-1042",
    "name": "Linen Grey",
    "category": "walls",
    "type": "Wallpaper",
    "subtype": null,
    "material": "Vinyl",
    "style": "Modern",
    "finish": [
      "Matte",
      "Textured"
    ],
    "color": "#b3b3ab",
    "size": {
      "width": 53,
      "height": 53,
      "unit": "cm"
    },
    "size_label": "53 × 53 cm",
    "price": {
      "amount": 25.99,
      "compare_at": 28,
      "base_amount": 26,
      "currency": "GEL"
    },
    "promo_text": null,
    "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
    "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
    "company": {
      "id": "Xk2pQ8…",
      "handle": "your-handle",
      "name": "Your Store"
    },
    "urls": {
      "page": "https://homux.ge/ka/catalog/aBc123",
      "try_on": "https://homux.ge/api/v1/try?product=aBc123"
    },
    "created_at": "2026-09-30T10:12:00.000Z",
    "updated_at": "2026-10-02T08:40:00.000Z"
  },
  "created": false
}

Create a product

POST/v1/products

Requires an API key. Products created through the API behave exactly like ones uploaded in the dashboard: in the catalog, the visualizer, QR labels and Analytics.

Body parameters

  • namestring ≤ 200Required
    Product name.
  • categorywalls | floors | doorsRequired
    Which room surface it goes on.
  • typestringRequired
    Product type — see Product types. Slugs work too: wood-flooring.
  • image_urlhttps URLRequired on create
    Photo of the surface (JPEG, PNG, WebP, AVIF, GIF; max 20 MB and 40 MP; short side at least 200 px). Sending the same URL again does not re-download it.
  • image_base64string
    The same image as base64 when you have no public URL.
  • skustring ≤ 64
    Your product code; unique within your company.
  • pricenumber
    Price in GEL (0 – 1,000,000).
  • compare_at_pricenumber
    The old, struck-through price. Must be greater than price.
  • promo_textstring ≤ 120
    Offer line under the price.
  • sizeobject
    Real-world size of what the image shows (each side ≤ 10 m). Give one tile or one wallpaper pattern repeat, not the roll length.
  • finishstring[]
    Surface finish, e.g. ["Matte", "Textured"] (up to 10).
  • material, style, subtypestring ≤ 60
    Material (Porcelain, Oak), style (Modern), subtype (Mosaic).

Images

  • Tiles, wallpaper, flooring: a flat, straight-on photo of the surface, evenly lit, with no shadows or watermarks. A seamless swatch is ideal.
  • Doors: the door alone, square-on — ideally a PNG with a transparent background.
  • 1500 px or larger is recommended. Homux stores a 2048 px texture, a 480 px thumbnail and the original.

Plan limits

Products added through the API count toward your plan (Starter 150, Growth 600, Scale unlimited). At the limit you get 403 plan_limit_reached; with a paused subscription, 402 subscription_required. Reads and the button keep working either way.
POSTRequest
curl -X POST "https://homux.ge/api/v1/products" \
  -H "Authorization: Bearer $HOMUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Linen Grey",
  "category": "walls",
  "type": "Wallpaper",
  "sku": "WP-1042",
  "price": 28,
  "size": {
    "width": 53,
    "height": 53,
    "unit": "cm"
  },
  "finish": [
    "Matte",
    "Textured"
  ],
  "image_url": "https://yourstore.ge/images/wp-1042-swatch.jpg"
}'
201 · Response
{
  "data": {
    "id": "aBc123",
    "sku": "WP-1042",
    "name": "Linen Grey",
    "category": "walls",
    "type": "Wallpaper",
    "subtype": null,
    "material": "Vinyl",
    "style": "Modern",
    "finish": [
      "Matte",
      "Textured"
    ],
    "color": "#b3b3ab",
    "size": {
      "width": 53,
      "height": 53,
      "unit": "cm"
    },
    "size_label": "53 × 53 cm",
    "price": {
      "amount": 27.99,
      "compare_at": null,
      "base_amount": 28,
      "currency": "GEL"
    },
    "promo_text": null,
    "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
    "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
    "company": {
      "id": "Xk2pQ8…",
      "handle": "your-handle",
      "name": "Your Store"
    },
    "urls": {
      "page": "https://homux.ge/ka/catalog/aBc123",
      "try_on": "https://homux.ge/api/v1/try?product=aBc123"
    },
    "created_at": "2026-09-30T10:12:00.000Z",
    "updated_at": "2026-10-02T08:40:00.000Z"
  }
}

Update a product

PATCH/v1/products/{id}

Requires an API key. Changes only the fields you send; null clears an optional field. Same fields as on create.

Path parameters

  • idstringRequired
    Homux product ID.
PATCHRequest
curl -X PATCH "https://homux.ge/api/v1/products/aBc123" \
  -H "Authorization: Bearer $HOMUX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "price": 24,
  "promo_text": "-15% this week",
  "compare_at_price": null
}'
Response
{
  "data": {
    "id": "aBc123",
    "sku": "WP-1042",
    "name": "Linen Grey",
    "category": "walls",
    "type": "Wallpaper",
    "subtype": null,
    "material": "Vinyl",
    "style": "Modern",
    "finish": [
      "Matte",
      "Textured"
    ],
    "color": "#b3b3ab",
    "size": {
      "width": 53,
      "height": 53,
      "unit": "cm"
    },
    "size_label": "53 × 53 cm",
    "price": {
      "amount": 23.99,
      "compare_at": null,
      "base_amount": 24,
      "currency": "GEL"
    },
    "promo_text": "-15% this week",
    "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
    "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
    "company": {
      "id": "Xk2pQ8…",
      "handle": "your-handle",
      "name": "Your Store"
    },
    "urls": {
      "page": "https://homux.ge/ka/catalog/aBc123",
      "try_on": "https://homux.ge/api/v1/try?product=aBc123"
    },
    "created_at": "2026-09-30T10:12:00.000Z",
    "updated_at": "2026-10-02T08:40:00.000Z"
  }
}

Retrieve a product by SKU

GET/v1/products/by-sku/{sku}

Requires an API key. Your product by SKU — including hidden ones.

GETRequest
curl "https://homux.ge/api/v1/products/by-sku/WP-1042" \
  -H "Authorization: Bearer $HOMUX_API_KEY"
Response
{
  "data": {
    "id": "aBc123",
    "sku": "WP-1042",
    "name": "Linen Grey",
    "category": "walls",
    "type": "Wallpaper",
    "subtype": null,
    "material": "Vinyl",
    "style": "Modern",
    "finish": [
      "Matte",
      "Textured"
    ],
    "color": "#b3b3ab",
    "size": {
      "width": 53,
      "height": 53,
      "unit": "cm"
    },
    "size_label": "53 × 53 cm",
    "price": {
      "amount": 27.99,
      "compare_at": null,
      "base_amount": 28,
      "currency": "GEL"
    },
    "promo_text": null,
    "image_url": "https://firebasestorage.googleapis.com/…/aBc123.jpg",
    "thumbnail_url": "https://firebasestorage.googleapis.com/…/aBc123_thumb.webp",
    "company": {
      "id": "Xk2pQ8…",
      "handle": "your-handle",
      "name": "Your Store"
    },
    "urls": {
      "page": "https://homux.ge/ka/catalog/aBc123",
      "try_on": "https://homux.ge/api/v1/try?product=aBc123"
    },
    "created_at": "2026-09-30T10:12:00.000Z",
    "updated_at": "2026-10-02T08:40:00.000Z"
  }
}

Delete a product

DELETE/v1/products/{id}

Requires an API key. Deletes the product and its images. Printed QR labels for it stop working.

DELRequest
curl -X DELETE "https://homux.ge/api/v1/products/aBc123" \
  -H "Authorization: Bearer $HOMUX_API_KEY"
Response
{
  "data": {
    "id": "aBc123",
    "deleted": true
  }
}

Check your key

GET/v1/me

Requires an API key. Which company the key belongs to, the plan, and how many products you can add.

GETRequest
curl "https://homux.ge/api/v1/me" \
  -H "Authorization: Bearer $HOMUX_API_KEY"
Response
{
  "data": {
    "company": {
      "id": "Xk2pQ8…",
      "handle": "your-handle",
      "name": "Your Store",
      "bio": "Wallpaper and tiles in Tbilisi",
      "logo_url": "https://firebasestorage.googleapis.com/…/logo.jpg",
      "website": "https://yourstore.ge",
      "location": "Tbilisi",
      "page_url": "https://homux.ge/ka/@your-handle"
    },
    "plan": "growth",
    "write_access": true,
    "products": {
      "count": 148,
      "limit": 600
    }
  }
}

Try link redirect

GET/v1/try

A link for browsers: counts the open and redirects to the visualizer. Parameters are in Try links.

302 Location
GET https://homux.ge/api/v1/try?product=aBc123&lang=en

HTTP/2 302
location: https://homux.ge/en/room-redesign?material=aBc123&source=widget

Product types

  • wallscategory
    Wallpaper, Stone, Brick, Tile, Panel, Wood Cladding, Plaster, Paint, Other
  • floorscategory
    Wood Flooring, Laminate, Vinyl, Tile, Stone, Carpet, Concrete, Resin, Rubber, Cork, Decking, Linoleum, Other
  • doorscategory
    Hinged, Sliding, Folding, Pivot, Entry, Glass Door, Garage Door, Other

Resources

Sync example

A script that keeps Homux in step with your online store every night. PUT by-sku is idempotent — running it again is safe.

To remove products you no longer sell, list your Homux products and DELETE those whose SKU is no longer in your feed.

Nightly sync
// sync-homux.mjs — run nightly (Node 18+):  HOMUX_API_KEY=hx_live_… node sync-homux.mjs
const API = 'https://homux.ge/api/v1';
const headers = { Authorization: `Bearer ${process.env.HOMUX_API_KEY}`, 'Content-Type': 'application/json' };

const products = await loadMyProducts(); // ← your shop database or export

for (const p of products) {
  const res = await fetch(`${API}/products/by-sku/${encodeURIComponent(p.sku)}`, {
    method: 'PUT',
    headers,
    body: JSON.stringify({
      name: p.title,
      category: 'walls',            // walls | floors | doors
      type: 'Wallpaper',            // see Product types
      price: p.price,
      image_url: p.swatchImageUrl,  // unchanged URL → not downloaded again
      size: { width: 53, height: 53, unit: 'cm' },
    }),
  });
  if (!res.ok) {
    const { error } = await res.json();
    console.error(p.sku, res.status, error.code, error.message, error.details ?? '');
  }
  if (res.status === 429) await new Promise((r) => setTimeout(r, 30_000));
}

Analytics

Your dashboard Analytics shows “Website clicks” — how many times the visualizer was opened from your button or try links, this month and in total.

  • Bots, link previews (Facebook, WhatsApp…) and repeat clicks by the same visitor within 10 minutes are not counted.
  • QR scans count printed QR labels only; redesigns count each time a shopper applies your product in a room.
  • For your own analytics, use homux:open event.

Help & troubleshooting

Button not showing?

  • Open the browser console (F12): the element’s data-homux-state tells you why — unavailable (no matching product) or error.
  • Check the handle and SKU: https://homux.ge/api/v1/companies/your-handle/products?sku=WP-1042 — an empty data list means there is no such product.
  • If your site sends a Content-Security-Policy, allow https://homux.ge in script-src, connect-src and frame-src.
  • A product you just added or changed can take up to 3 minutes to appear.

Talk to us

Email app.homux@gmail.com with your handle and, for API issues, the X-Request-Id. We’re happy to help with the integration.

Changelog

  • 2026-10-10widget 1.1
    The button opens the visualizer in a window right on your site, with only your products, and puts the product on the room automatically. New: data-open="tab", Homux.close(), homux:close.
  • 2026-10-09v1
    First release: homux.js (button, badge, JavaScript API), try links, public catalog API, catalog management with keys, SKU field, website-click analytics.