---
title: "Retrieve a product"
description: "GET /products/{sku_uuid}: Returns one product's photos, price, specification and shipping options."
url: https://docs.tryflume.ai/api/get-product
updated: 2026-11-11
---

# Retrieve a product

> GET /products/{sku_uuid}: Returns one product's photos, price, specification and shipping options.

Returns one product's photos, price, specification and shipping options.

```http
GET https://sandbox-api.tryflume.ai/partner/v1/products/{sku_uuid}
```

## Request

### Headers

| Header | Required | Description |
|---|---|---|
| `X-Flume-Partner-Key` | Yes | Your partner key. |
| `X-Flume-User-Token` | Yes | The access token of the user you call for. |

### Path parameters

| Parameter | Type | Description |
|---|---|---|
| `sku_uuid` | string | The product's id, from a search result. |

### Sample

**curl**

```sh
curl -X GET "https://sandbox-api.tryflume.ai/partner/v1/products/7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30" \
  -H "X-Flume-Partner-Key: $FLUME_PARTNER_KEY" \
  -H "X-Flume-User-Token: $FLUME_USER_TOKEN"
```

**Python**

```python
import os

import requests

headers = {
    "X-Flume-Partner-Key": os.environ["FLUME_PARTNER_KEY"],
    "X-Flume-User-Token": os.environ["FLUME_USER_TOKEN"],
}

response = requests.get(
    "https://sandbox-api.tryflume.ai/partner/v1/products/7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30",
    headers=headers,
    timeout=30,
)
response.raise_for_status()
print(response.json())
```

**Node.js**

```js
const response = await fetch("https://sandbox-api.tryflume.ai/partner/v1/products/7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30", {
  method: "GET",
  headers: {
    "X-Flume-Partner-Key": process.env.FLUME_PARTNER_KEY,
    "X-Flume-User-Token": process.env.FLUME_USER_TOKEN,
  },
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
console.log(await response.json());
```

## Returns (200)

Every field is always present. A field with no value is `null`.

| Field | Type | Description |
|---|---|---|
| `sku_uuid` | string (UUID) | The product's id. |
| `category` | enum | What the product is: `TILE` or `FLOORING`. |
| `name` | string | The product's name, written by Flume from its specification. |
| `as_low_as_per_sqft` | string or null | The lowest delivered price per square foot, before tax. An instant quote for a real quantity and ZIP code can be higher. `null` when `price_on_request` is `true`. |
| `price_on_request` | boolean | `true`: Flume's sales team prices this product, and there is no instant quote. |
| `image_urls` | array of strings | Product photos, the main one first. |
| `at_a_glance` | array of objects | The key facts, in display order. Tile only. Empty for flooring. |
| `at_a_glance[].label` | string | The fact's name. |
| `at_a_glance[].value` | string | The fact's value. |
| `specification` | array of objects | The full specification, in groups. A property the product does not state is left out. |
| `specification[].group` | string | The group's heading. |
| `specification[].rows` | array of objects | The lines in the group. |
| `specification[].rows[].label` | string | The property's name. |
| `specification[].rows[].value` | string | The property's value. |
| `specification[].rows[].test_method` | string or null | The test standard, when one is stated. |
| `shipping_options` | array of objects | The ways the product ships. |
| `shipping_options[].source` | enum | `US_WAREHOUSE` (stocked in the US) or `OVERSEAS_DIRECT` (shipped from the factory abroad). |
| `shipping_options[].ships_from_country` | string or null | The 2-letter code of the country the option ships from, or `null`. |
| `shipping_options[].minimum_order_sqft` | integer or null | The smallest order this option ships, in square feet. |
| `shipping_options[].lead_time_min_days` | integer | The shortest delivery time, in days. |
| `shipping_options[].lead_time_max_days` | integer | The longest delivery time, in days. |
| `suitable_application_areas` | array of objects | Every area where the product can be used: floors first, then walls, then the rest. Empty for vinyl flooring, or when Flume knows none. |
| `suitable_application_areas[].code` | string | The area's code, as `GET /filters` lists it. |
| `suitable_application_areas[].label` | string | The area's name, to show. |

**Response (200)**

```json
{
  "sku_uuid": "7f3c2a91-4b0e-4c8d-9a21-1f6b2d5e7c30",
  "category": "TILE",
  "name": "Porcelain 24×48″ Matte",
  "as_low_as_per_sqft": "6.40",
  "price_on_request": false,
  "image_urls": [
    "https://sandbox-api.tryflume.ai/partner/v1/images/example-image-main",
    "https://sandbox-api.tryflume.ai/partner/v1/images/example-image-2"
  ],
  "at_a_glance": [
    {
      "label": "Size",
      "value": "24×48″"
    },
    {
      "label": "Thickness",
      "value": "9 mm"
    },
    {
      "label": "Finish",
      "value": "Matte"
    }
  ],
  "specification": [
    {
      "group": "Slip resistance",
      "rows": [
        {
          "label": "DCOF",
          "value": "> 0.42",
          "test_method": "ANSI A326.3"
        }
      ]
    }
  ],
  "shipping_options": [
    {
      "source": "US_WAREHOUSE",
      "lead_time_min_days": 14,
      "lead_time_max_days": 30,
      "ships_from_country": "US",
      "minimum_order_sqft": 1000
    },
    {
      "source": "OVERSEAS_DIRECT",
      "lead_time_min_days": 90,
      "lead_time_max_days": 120,
      "ships_from_country": "ES",
      "minimum_order_sqft": 5000
    }
  ],
  "suitable_application_areas": [
    {
      "code": "INTERIOR_DRY_FLOOR",
      "label": "Interior Dry Floor"
    }
  ]
}
```

## Errors

| Status | Code | Meaning |
|---|---|---|
| 401 | `EMBED_TOKEN_INVALID` | You sent an `Authorization` header and no `X-Flume-Partner-Key`. Flume read the call as one from its own iframe. |
| 401 | `PARTNER_KEY_INVALID` | The partner key is missing, unknown, revoked, expired, or from the other environment. On live, also a platform Flume has not enabled yet. |
| 401 | `USER_TOKEN_INVALID` | The user access token is unknown, revoked, another partner's, or replaced by a later verification. A verification in the iframe replaces it too. |
| 403 | `USER_ACCOUNT_CLOSED` | The user's email belongs to a Flume account that Flume has closed. |
| 403 | `USER_NOT_CONNECTED` | No `X-Flume-User-Token` header was sent. |
| 404 | `NOT_FOUND` | The thing does not exist, or is not this user's. A search id that is not a UUID also returns this code. |
| 422 | `VALIDATION_FAILED` | A field is missing, unknown or has an unusable value. `field` names it as a dotted path. Some refusals carry the detail in `details` and leave `field` empty. |
| 500 | `INTERNAL` | Something failed on Flume's side. |

Every code, with its fix: [API error codes](https://docs.tryflume.ai/api/errors.md).

Guide: [Find products by photo](https://docs.tryflume.ai/guides/find-products-by-photo.md).
