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

# Fetching Feeds

> Retrieve product feeds for Google Shopping, Meta Commerce, and OpenAI Commerce.

## Endpoint

```
GET /api/v1/feeds/{platform}
```

**Path parameters:**

| Parameter  | Values                     |
| ---------- | -------------------------- |
| `platform` | `google`, `meta`, `openai` |

## Basic Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://app.alana.shopping/api/v1/feeds/google" \
    -H "X-API-Key: sk_live_your_api_key"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://app.alana.shopping/api/v1/feeds/google",
    { headers: { "X-API-Key": "sk_live_your_api_key" } }
  );
  const xml = await res.text(); // Google returns XML
  ```

  ```python Python theme={null}
  import requests

  res = requests.get(
      "https://app.alana.shopping/api/v1/feeds/google",
      headers={"X-API-Key": "sk_live_your_api_key"},
  )
  print(res.text)  # XML content
  ```
</CodeGroup>

## Format Options

| Platform | Default Format     | Accept Header Override |
| -------- | ------------------ | ---------------------- |
| `google` | `application/xml`  | `application/x-ndjson` |
| `meta`   | `text/csv`         | `application/x-ndjson` |
| `openai` | `application/json` | `application/x-ndjson` |

## NDJSON Streaming

For large catalogs, request NDJSON to process products one at a time:

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://app.alana.shopping/api/v1/feeds/google" \
    -H "X-API-Key: sk_live_your_api_key" \
    -H "Accept: application/x-ndjson"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://app.alana.shopping/api/v1/feeds/google",
    {
      headers: {
        "X-API-Key": "sk_live_your_api_key",
        Accept: "application/x-ndjson",
      },
    }
  );

  const reader = res.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    const lines = decoder.decode(value).split("\n").filter(Boolean);
    for (const line of lines) {
      const product = JSON.parse(line);
      console.log(product.id, product.title);
    }
  }
  ```

  ```python Python theme={null}
  import requests, json

  with requests.get(
      "https://app.alana.shopping/api/v1/feeds/google",
      headers={
          "X-API-Key": "sk_live_your_api_key",
          "Accept": "application/x-ndjson",
      },
      stream=True,
  ) as res:
      for line in res.iter_lines():
          if line:
              product = json.loads(line)
              print(product["id"], product["title"])
  ```
</CodeGroup>

## ETag and Delta Feeds

Use `ETag` for efficient polling — only download a new feed when content has changed:

<CodeGroup>
  ```bash cURL theme={null}
  # First request — save the ETag
  curl -I "https://app.alana.shopping/api/v1/feeds/google" \
    -H "X-API-Key: sk_live_your_api_key"
  # ETag: "abc123def456"

  # Subsequent requests — skip download if unchanged
  curl "https://app.alana.shopping/api/v1/feeds/google" \
    -H "X-API-Key: sk_live_your_api_key" \
    -H "If-None-Match: \"abc123def456\""
  # Returns 304 Not Modified if feed hasn't changed
  ```

  ```javascript JavaScript theme={null}
  let etag = null;

  async function pollFeed() {
    const headers = { "X-API-Key": "sk_live_your_api_key" };
    if (etag) headers["If-None-Match"] = etag;

    const res = await fetch(
      "https://app.alana.shopping/api/v1/feeds/google",
      { headers }
    );

    if (res.status === 304) {
      console.log("Feed unchanged");
      return null;
    }

    etag = res.headers.get("ETag");
    return await res.text();
  }
  ```

  ```python Python theme={null}
  import requests

  etag = None

  def poll_feed():
      global etag
      headers = {"X-API-Key": "sk_live_your_api_key"}
      if etag:
          headers["If-None-Match"] = etag

      res = requests.get(
          "https://app.alana.shopping/api/v1/feeds/google",
          headers=headers,
      )

      if res.status_code == 304:
          print("Feed unchanged")
          return None

      etag = res.headers.get("ETag")
      return res.text
  ```
</CodeGroup>

## Response Headers

| Header                 | Description                                |
| ---------------------- | ------------------------------------------ |
| `ETag`                 | Feed content hash for conditional requests |
| `Last-Modified`        | Timestamp of last feed generation          |
| `X-Feed-Product-Count` | Number of products in the feed             |
| `Cache-Control`        | `max-age=900` (15-minute cache)            |

## Query Parameters

| Parameter    | Type    | Description                             |
| ------------ | ------- | --------------------------------------- |
| `catalog_id` | string  | Filter to a specific catalog (optional) |
| `limit`      | integer | Max products per page (default: all)    |
| `offset`     | integer | Pagination offset                       |
