> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e-cubee.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List products

> Search and filter products available to your API key.

Returns a paginated product list. Your API key needs the `products:list` scope.

## Headers

<ParamField header="X-Api-Key" type="string" required>
  Your API key. You can use `Authorization: Api-Key your_key` instead.
</ParamField>

## Query parameters

<ParamField query="query" type="string">
  Search text.
</ParamField>

<ParamField query="page" type="integer" default="1">
  One-based page number. Values below `1` are treated as `1`.
</ParamField>

<ParamField query="isAvailable" type="boolean">
  Filter by availability.
</ParamField>

<ParamField query="categoryIds" type="string">
  Comma-separated category GUIDs. Invalid GUIDs are ignored.
</ParamField>

<ParamField query="brandIds" type="string">
  Comma-separated brand GUIDs. Invalid GUIDs are ignored.
</ParamField>

<ParamField query="barcode" type="string">
  Filter by barcode.
</ParamField>

<ParamField query="sku" type="string">
  Filter by SKU.
</ParamField>

Each page contains up to 25 products.

## Request example

```bash theme={null}
curl --get "$MORABAA_API_URL/external/v1/products" \
  --header "X-Api-Key: $MORABAA_API_KEY" \
  --data-urlencode "query=coffee" \
  --data-urlencode "isAvailable=true" \
  --data-urlencode "page=1"
```

## Response

`price` is the list price. `sellPrice` is the effective price after an active discount, when one applies.

<ResponseField name="items" type="object[]" required>
  Products on the current page.

  <Expandable title="Product fields">
    <ResponseField name="id" type="UUID" required>Product ID.</ResponseField>
    <ResponseField name="name" type="string" required>Product name.</ResponseField>
    <ResponseField name="sku" type="string | null">Product SKU.</ResponseField>
    <ResponseField name="quantity" type="number | null">Available quantity.</ResponseField>
    <ResponseField name="price" type="number" required>List price.</ResponseField>
    <ResponseField name="sellPrice" type="number" required>Effective selling price.</ResponseField>
    <ResponseField name="isAvailable" type="boolean" required>Whether the product is available.</ResponseField>
    <ResponseField name="productImageUrl" type="string | null">Product image URL.</ResponseField>
    <ResponseField name="variants" type="object[]" required>Product variants and their options.</ResponseField>
    <ResponseField name="combinations" type="object[]" required>Available option combinations, including IDs, option IDs, SKU, barcode, quantity, prices, availability, and image URL.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="page" type="integer" required>Current page.</ResponseField>
<ResponseField name="pageSize" type="integer" required>Maximum items per page. Always `25`.</ResponseField>
<ResponseField name="total" type="integer" required>Total matching products.</ResponseField>

```json theme={null}
{
  "items": [
    {
      "id": "11111111-1111-1111-1111-111111111111",
      "name": "Arabic coffee",
      "sku": "COFFEE-250",
      "quantity": 18,
      "price": 12000,
      "sellPrice": 10000,
      "isAvailable": true,
      "productImageUrl": "https://cdn.example.com/products/coffee.jpg",
      "variants": [],
      "combinations": []
    }
  ],
  "page": 1,
  "pageSize": 25,
  "total": 1
}
```

## Errors

| Status | Cause                                    |
| ------ | ---------------------------------------- |
| `401`  | The API key is missing or invalid.       |
| `403`  | The key lacks the `products:list` scope. |
| `429`  | The rate limit was exceeded.             |
| `500`  | An unexpected error occurred.            |
