Web data feeds are account-owned, recurring collections from public or authenticated web pages. Create and manage them in **Dashboard → [Web Data Feeds](/WebDataFeeds)**. The REST API can only read their state and retained verified results; it cannot create, run, pause, resume, delete, or configure one.

Both endpoints require the API key belonging to the same Pro account. A feed identifier owned by another account is reported as `404`, exactly like one that does not exist. Reading stored data never contacts the source website, and a failed newer collection does not erase the last good result. Existing clients may continue using the compatibility alias `/v1/custom-data-sets`.

## GET /v1/web-data-feeds

Lists the account's web data feeds, including their schedule, public or authenticated access mode, and latest run state.

**Parameters:** none.

```bash
curl "https://api.equibles.com/v1/web-data-feeds" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
import requests
r = requests.get(
    "https://api.equibles.com/v1/web-data-feeds",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
```

```javascript
const res = await fetch("https://api.equibles.com/v1/web-data-feeds", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
```

An account with no web data feeds returns:

```json
{
  "data": []
}
```

## GET /v1/custom-data-sets

Compatibility alias for `GET /v1/web-data-feeds`. It returns the same account-owned feed list and remains available to existing v1 clients.

**Parameters:** none.

## GET /v1/web-data-feeds/{id}

Returns the latest successful stored result for one account-owned web data feed. Pass `at` to retrieve the newest verified capture completed at or before a past instant. `sources` contains the exact pages captured for that result. `normalizedData` is the recommended consumption shape: repeated non-identity values appear once under `shared`, each item under `rows` contains only row-varying fields, and declared numbers and booleans use native JSON types. Field names differ by feed. The original verified extraction envelope remains under `data` for v1 compatibility and evidence auditing. A legacy result that cannot satisfy the stricter normalized type contract returns `normalizedData: null` without suppressing `data`.

History is retained for at most 12 months and is also bounded to the newest 4,000 collection observations and 20 MB per feed. When a bound is reached, the oldest observations are removed first. Deleting a feed in the Portal permanently deletes all of its retained history.

Example result shape:

```json
{
  "normalizedData": {
    "nothingStated": false,
    "shared": {
      "price": 4929.00,
      "price_currency": "€",
      "total_reviews": 79
    },
    "rows": [
      {
        "star_bucket": 5,
        "bucket_percentage": 70,
        "bucket_count": 55
      }
    ]
  }
}
```

**Parameters:** `id` (required in the path; web data feed identifier from `GET /v1/web-data-feeds`); `at` (optional ISO-8601 timestamp, for example `2026-08-31T18:00:00Z`; returns the latest retained verified capture completed at or before that instant).

```bash
curl "https://api.equibles.com/v1/web-data-feeds/00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
import requests
r = requests.get(
    "https://api.equibles.com/v1/web-data-feeds/00000000-0000-0000-0000-000000000000",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
```

```javascript
const res = await fetch(
  "https://api.equibles.com/v1/web-data-feeds/00000000-0000-0000-0000-000000000000",
  { headers: { Authorization: "Bearer eq_your_api_key" } },
);
console.log(await res.json());
```

To read historical data, add the optional cutoff:

```bash
curl "https://api.equibles.com/v1/web-data-feeds/00000000-0000-0000-0000-000000000000?at=2026-08-31T18%3A00%3A00Z" \
  -H "Authorization: Bearer eq_your_api_key"
```

The empty-account example above returns the normal ownership-safe not-found envelope:

```json
{
  "error": {
    "code": "not_found",
    "message": "No web data feed 00000000-0000-0000-0000-000000000000 on this account. List yours at GET /v1/web-data-feeds.",
    "status": 404
  }
}
```

## GET /v1/custom-data-sets/{id}

Compatibility alias for `GET /v1/web-data-feeds/{id}`. It returns the same ownership-safe current or historical verified result and accepts the same optional `at` parameter.

**Parameters:** `id` (required in the path; web data feed identifier); `at` (optional ISO-8601 historical cutoff).