# Etsy Scraper — Listings, Prices, Shops & Badges (`tortuga/etsy-scraper`) Actor

Scrape Etsy search results, shop pages and listings: title, price, sale price, shop, rating, review count, Bestseller and Star Seller badges, images and details. Any keyword, shop or listing URL.

- **URL**: https://apify.com/tortuga/etsy-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 listing scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Etsy Scraper

Scrape Etsy search results, category pages, shop pages and listing pages into a clean dataset: title, price, sale price and discount, shop, rating, review count, badges (Bestseller, Popular now, Etsy's Pick, Star Seller, Free shipping), stock and "in carts" signals, color options, image, sponsored flag and rank on the page. Turn on **Include listing details** to add the description, materials, every variation with its price, stock, favorites, shipping and returns, estimated delivery, all images, category path, listed-on date and the shop profile (location, sales, rating, review count, years on Etsy).

No login and no browser of your own: the Actor reads the page data Etsy embeds in its own pages through Apify's Unblocker proxy, so one request returns a full result page of about 60 listings. Download the results as JSON, CSV or Excel, or pull them through the API into your own app, Google Sheets or an LLM pipeline. You pay per listing you get.

### What data does Etsy Scraper extract?

Every listing from a search, category, market or shop page (the `result` event):

| Field | Description |
|---|---|
| `listingId` | Etsy listing id (the number in `/listing/4296141840/...`) |
| `title`, `url` | Listing title and canonical URL (`https://www.etsy.com/listing/<id>/<slug>`, tracking parameters removed) |
| `price`, `originalPrice`, `currency` | Current price, strike-through price when on sale, `USD` |
| `discountPercent`, `isOnSale` | Discount as shown (`50` for "50% off") and the sale flag |
| `shopName`, `shopId`, `shopUrl` | Shop (business) name, id and URL. Sponsored cards on category pages show "Ad by Etsy seller" without a name |
| `rating`, `reviewCount`, `reviewCountText` | Shop rating (0-5) and review count as shown on the card: exact on category pages (`12,103`), rounded on search pages (`3.5k` = 3500). The listing page gives the exact item figures |
| `badges` | Card labels: `Bestseller`, `Popular now`, `Etsy’s Pick`, `Star Seller`, `Free shipping`, `Limited stock`, `7 people have this in their cart`, ... |
| `isBestseller`, `isPopularNow`, `isEtsysPick`, `isStarSeller`, `isFreeShipping` | The same as booleans (`isStarSeller` is `null` on shop and market cards, which carry no Star Seller mark) |
| `isAd` | `true` for sponsored listings. A listing shown as an ad and again as an organic result is saved once, at its first position |
| `stockText`, `inCartCount`, `inCartText` | `Limited stock` / `Only 3 left`; "7 people have this in their cart" as a number and as shown |
| `colorOptions`, `moreColorOptions` | Color swatches shown on the card (`["Tan", "Blue", ...]`) and the "+6" counter |
| `hasVideo`, `imageUrl` | Whether the card plays a video; main image, full size |
| `shopSales`, `shopSalesText`, `shopTenure`, `shipsFrom`, `acceptsCustomOrders` | From the "Preview seller" button some search cards carry (`20800`, `"20.8k sales"`, `"13 years on Etsy"`, `"Spokane, Washington"`); `null` when the card has none |
| `position`, `page` | Rank among the cards of the page (ads included, in display order) and page number |
| `searchTerm`, `sourceUrl`, `scrapedAt` | Provenance |
| `changeType`, `previousValues` | Only with **Only new or changed items** on: `new` or `changed`, and for changed listings the old values of the fields that changed |

With **Include listing details** on, or for listing URLs (the extra `detail` event), each listing also gets:

| Field | Description |
|---|---|
| `description` | Full description as plain text |
| `highlights`, `materials` | The "Item details" lines (`Made by KJPottery`, `Materials: Ceramic`, `Capacity: 12 fluid ounces`) and the materials list |
| `variations`, `hasVariations` | Every option dimension with its options: `[{name: "Glaze Color", options: [{id, name, price, isAvailable}]}]` (option prices are shown only when they differ) |
| `quantityAvailable`, `availability` | Units in stock (Etsy's `eligibleQuantity`) and `InStock` / `OutOfStock` |
| `favoritesCount`, `listedOn` | Number of favorites and the "Listed on" date (ISO) |
| `rating`, `reviewCount` | Exact rating and number of reviews **of this item** when it has reviews; otherwise the card's shop figures stay and the shop's own are in `shop` |
| `ratingBreakdown`, `reviewHighlights` | `{itemQuality, shipping, customerService, recommendPercent}` and Etsy's review summary tags (`Looks great`, `Fast shipping`, ...) |
| `shipping` | `{isFree, cost, costText, shipsFrom, shipsFromCountry, shipsToCountry, estimatedDelivery, returnsAccepted, returnsText}`, e.g. `"Oct 10-22"`, `"Returns & exchanges accepted within 7 days"` |
| `shop` | `{name, id, url, location, rating, reviewCount, salesCount, tenure, isStarSeller, badges}` with the exact review count and badges such as `Smooth shipping`, `Speedy replies`, `Rave reviews` |
| `images`, `imageCount` | All listing images, full size |
| `categoryPath`, `categoryId` | Etsy's category breadcrumb (`["Home & Living", "Kitchen & Dining", ...]`) and category id |
| `saleEndsAt`, `personalization`, `tags` | End of a running sale (ISO timestamp); personalization instructions when present; `tags` stay `null` on English pages (Etsy loads them after the page) |
| `detailError` | Set when the listing page could not be loaded; the listing keeps its card data and no `detail` event is charged |

Seller and shop owner names, avatars, shop member names and reviewer names are deliberately not collected.

### How to use Etsy Scraper

1. Type one or more **Search terms** (one per line) and/or paste **Start URLs**: search pages, category pages (`/c/...`), market pages (`/market/...`), shop pages (`/shop/<name>`) or listing pages (`/listing/<id>/...`).
2. Pick **Sort by** and, if you want, a **Min / Max price**.
3. Set **Max items** to cap the run (and the cost) and **Max pages per search** to limit how deep each search goes.
4. Turn on **Include listing details** only if you need the listing-page fields: it costs one extra request and one extra event per listing (see below).
5. Click **Start**. Results appear in the **Dataset** tab; export from there or use the API.

### Input example

```json
{
  "searchTerms": ["ceramic mug", "handmade candle"],
  "startUrls": [
    { "url": "https://www.etsy.com/shop/CeramicArtisanMan" },
    { "url": "https://www.etsy.com/listing/4296141840/coffee-mug-kj-pottery" }
  ],
  "maxItems": 200,
  "maxPagesPerSearch": 3,
  "sortBy": "highest_reviews",
  "minPrice": 10,
  "maxPrice": 60,
  "includeDetails": false,
  "country": "US",
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["UNBLOCKER"], "apifyProxyCountry": "US" }
}
```

### Output example

A listing from a search page:

```json
{
  "listingId": "4544291854",
  "title": "Handmade Ceramic Travel Mug with Sip Lid, Stoneware Coffee Tumbler, Pottery Gift",
  "url": "https://www.etsy.com/listing/4544291854/handmade-ceramic-travel-mug-with-sip-lid",
  "price": 35.55,
  "originalPrice": 71.1,
  "currency": "USD",
  "discountPercent": 50,
  "isOnSale": true,
  "shopName": "EmbermadeBoutique",
  "shopId": "60869717",
  "shopUrl": "https://www.etsy.com/shop/EmbermadeBoutique",
  "rating": 4.6,
  "reviewCount": 15,
  "reviewCountText": "15",
  "badges": ["Popular now", "Free shipping", "Limited stock"],
  "isBestseller": false,
  "isPopularNow": true,
  "isEtsysPick": false,
  "isStarSeller": false,
  "isFreeShipping": true,
  "isAd": false,
  "stockText": "Limited stock",
  "inCartCount": null,
  "inCartText": null,
  "colorOptions": ["Tan", "Dark green", "Blue", "Purple", "Rose gold", "Dark yellow"],
  "moreColorOptions": null,
  "hasVideo": false,
  "imageUrl": "https://i.etsystatic.com/60869717/r/il/4c4956/8299421456/il_fullxfull.8299421456_6lb6.jpg",
  "shopSales": 151,
  "shopSalesText": "151 sales",
  "shopTenure": "1 year on Etsy",
  "shipsFrom": "Israel",
  "acceptsCustomOrders": false,
  "position": 18,
  "page": 1,
  "searchTerm": "ceramic mug",
  "sourceUrl": null,
  "scrapedAt": "2026-10-02T22:57:36+00:00"
}
```

With `includeDetails: true` the same listing additionally carries, for example:

```json
{
  "description": "✨ Say goodbye to plastic lids and taste your coffee the way it was meant to be. ✨\nUpgrade your daily commute ...",
  "highlights": ["Designed by EmbermadeBoutique", "Materials: Ceramic", "Capacity: 17 fluid ounces"],
  "materials": ["Ceramic"],
  "variations": [
    { "name": "Primary color", "options": [
      { "id": "6896475982", "name": "Autumn Terracotta", "price": null, "isAvailable": true },
      { "id": "6896475980", "name": "Deep Ocean Blue", "price": null, "isAvailable": true }
    ] }
  ],
  "hasVariations": true,
  "quantityAvailable": 3,
  "availability": "InStock",
  "inCartCount": 20,
  "inCartText": "In 20+ carts",
  "saleEndsAt": "2026-10-03T20:59:59+00:00",
  "favoritesCount": 117,
  "listedOn": "2026-10-02",
  "rating": null,
  "reviewCount": null,
  "shipping": {
    "isFree": true, "cost": 0, "costText": "Free shipping", "shipsFrom": "China", "shipsFromCountry": "CN",
    "shipsToCountry": "US", "estimatedDelivery": "Oct 13-19", "returnsAccepted": true,
    "returnsText": "Returns & exchanges accepted within 30 days"
  },
  "shop": {
    "name": "EmbermadeBoutique", "id": "60869717", "url": "https://www.etsy.com/shop/EmbermadeBoutique",
    "location": "China", "rating": 4.6, "reviewCount": 15, "salesCount": 151, "tenure": "1 year on Etsy",
    "isStarSeller": false, "badges": ["Smooth shipping", "Speedy replies"]
  },
  "images": ["https://i.etsystatic.com/60869717/r/il/4c4956/8299421456/il_fullxfull.8299421456_6lb6.jpg", "..."],
  "imageCount": 14,
  "categoryPath": ["Home & Living", "Kitchen & Dining", "Drink & Barware", "Drinkware", "Mugs"],
  "categoryId": "68887416"
}
```

### Proxy note

Etsy answers datacenter and residential proxy traffic with an error page, so this Actor uses **Apify's Unblocker proxy** (group `UNBLOCKER`), pinned to the United States, by default. Unblocker is billed to your Apify account per request it answers: 10 Unblocker units, about **$0.0015 on the free plan** and less on paid plans. A quick error Etsy returns (HTTP 502 within a few seconds) is billed as well, a request the proxy gives up on is not. One request returns either a result page (48 listings plus up to 24 sponsored ones on a search page, 64 on a category page, 36 on a shop page) or one listing page.

The Actor is built around that price: it requests a further result page only when **Max items** still needs it, opens listing pages only when you ask for them, and never makes discovery requests. The `SUMMARY` record in the run's key-value store reports `successfulRequests`, so you can check the proxy cost of every run.

### How much does it cost?

Pay per event, no subscription: **$0.003 per listing**, **+ $0.004 per listing page opened** (details), plus the proxy requests above and a few cents of platform usage per thousand items. Worked example for 100 listings from one search, on the free plan:

| Run | Requests (proxy cost) | Events | Total |
|---|---|---|---|
| 100 listings, search data only | 2 search pages ($0.003) | 100 x $0.003 = $0.30 | about $0.31 |
| + listing details | + 100 listing pages ($0.15) | + 100 x $0.004 = $0.40 | about $0.86 |

Search data alone is by far the cheapest per listing: one $0.0015 request brings about 60 listings. Turn details on only for the listings you need them for, for example by running a second pass on listing URLs you selected from the first dataset.

### How fast is it?

Slower than a typical scraper, because every page is rendered through the Unblocker proxy. A search page takes 30 to 60 seconds (category and shop pages 1 to 50 seconds), a listing page 10 to 60 seconds, and about two requests in five fail and are retried, so a page can take two or three minutes in the worst case. Result pages of one search are fetched up to five at a time, listing pages five at a time. In live tests one search page with 40 listings took about a minute, a shop's two item pages (40 listings) 50 seconds, and 5 listings with details (one search page, one of them requested twice, plus five listing pages) about 4 minutes. Plan for roughly 50-150 listings per minute without details and 5-15 listings per minute with details.

### How to scrape Etsy search results by keyword

Put the keywords into **Search terms**. Each term is searched on etsy.com and paginated automatically: 48 listings per page plus the sponsored listings Etsy mixes in (`isAd`), deduplicated across pages. Etsy serves 20 pages of a relevance-sorted search and up to 250 pages of a search sorted by price, newest or top reviews, so one term yields roughly 1,000 to 12,000 listings; `position` and `page` give the rank of every listing, which makes the output usable for rank tracking and competitor research. All five sort orders of Etsy's "Sort by" menu are supported, and **Min / Max price** is sent to Etsy as its own price filter.

Etsy loads the second half of a search page a moment after the first; occasionally the proxy captures a page before that happened (12 cards instead of 60). The Actor recognises those pages, requests them again and keeps the best copy; `incompletePages` in the run summary counts them.

### How to scrape all listings of an Etsy shop

Paste the shop URL (`https://www.etsy.com/shop/CeramicArtisanMan`) into **Start URLs**. The Actor reads the shop's item pages (36 listings each) and adds the shop's name and Star Seller status to every listing. With **Sort by** set to a price order or newest the shop is read in that order. Shop-level facts such as the shop's location, sales count, rating and years on Etsy come with **Include listing details** (in the `shop` object of every listing).

### How to track Etsy prices, sales and stock

Schedule the Actor (daily for fast-moving items) with the same search terms, shop URLs or listing URLs and compare `price`, `originalPrice`, `discountPercent`, `badges`, `stockText` and, with details, `quantityAvailable`, `favoritesCount` and `inCartCount` between runs, joining on `listingId`, or let the Actor do the comparison with **Only new or changed items** (next section). Listing URLs can be passed in bulk in **Start URLs**; each returns one fully detailed item.

### Monitor changes on a schedule

Turn on **Only new or changed items** and the Actor remembers what earlier runs of the same input returned: each run outputs only listings that are new or whose price, original price (a sale starting or ending) or stock hint ("Only 1 left") changed. Unchanged listings are dropped before anything is saved and before any listing page is opened, so they cost neither events nor Unblocker requests; **Max items** becomes the watched window (for example the newest 40 listings of a search sorted by **Newest**, one proxy request per run). Sponsored listings are skipped while monitoring, because Etsy rotates them on every visit, and price moves within 2% count as unchanged (prices of shops outside the US are converted to USD and move by a few cents with the exchange rate). Save the input as a task and add a Schedule to it in Apify Console (Schedules → Create new, daily). Every output listing carries `changeType` (`new` or `changed`), and changed ones carry `previousValues`, e.g. `{"price": 28.0, "originalPrice": null}` for a listing that went on sale at $22.40. **Monitoring key** keeps several schedules on the same search separate.

### Does it work without login or a browser?

Yes. Everything comes from public pages as an anonymous visitor in the United States sees them (`USD`, English). No account and no cookies are involved; the rendering happens inside Apify's Unblocker proxy. Listing tags are the one thing Etsy loads only after the page is shown, so they are not available; `materials`, `categoryPath` and the review highlight tags are.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets.

### Is it legal to scrape Etsy?

This Actor collects only publicly available data: listings, prices, badges and shop (business) profiles. It does not log in, and it does not collect seller or shop owner names, avatars, shop member names or reviewer names and texts. You are responsible for how you use the data and for complying with Etsy's terms and applicable law.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search on Etsy, one per line (e.g. "ceramic mug", "personalized necklace"). Each term is searched separately and paginated automatically: one request returns a result page with 48 listings plus up to 24 sponsored listings.

## `startUrls` (type: `array`):

Etsy URLs to scrape instead of (or in addition to) search terms: search pages (https://www.etsy.com/search?q=ceramic+mug), category pages (https://www.etsy.com/c/home-and-living/…/drinkware/mugs), market pages (https://www.etsy.com/market/ceramic_mug, run as the search "ceramic mug"), shop pages (https://www.etsy.com/shop/CeramicArtisanMan, all items of the shop) or listing pages (https://www.etsy.com/listing/4296141840/…, returned with full details). Filters in a search URL are kept.

## `maxItems` (type: `integer`):

Stop after this many listings in total (across all search terms and URLs). Keeps cost predictable.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to open per search term or URL (48 listings each plus sponsored ones, one proxy request per page; shop pages list 36 items). Etsy itself serves at most 20 pages of a relevance-sorted search and 250 pages of a sorted one.

## `sortBy` (type: `string`):

Result order for search terms and search URLs, as on Etsy's own "Sort by" menu. Shop pages support the price orders and newest; category pages are read in Etsy's order.

## `minPrice` (type: `integer`):

Only listings at or above this price. Sent to Etsy as its own price filter for searches; listings outside the range on any page are dropped before saving and never charged.

## `maxPrice` (type: `integer`):

Only listings at or below this price (Etsy's own price filter for searches; applied to every page before saving).

## `includeDetails` (type: `boolean`):

Also open every listing page to get the description, materials, variations with their prices, stock, favorites count, shipping and returns, estimated delivery, all images, category path, listed-on date, exact item rating and review count, review highlights and the shop profile (location, sales, rating, review count, years on Etsy, Star Seller). One extra proxy request and one extra `detail` charge per listing (see pricing).

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this search returned and output only new items or items whose price/status changed. Use with a Schedule; unchanged items are not charged. With this on, Max items is the number of listings checked each run (the watched window, e.g. the newest 40), so a run never digs deeper than the first one. Price, original price (sales) and the stock hint ("Only 1 left") are compared; price moves within 2% count as unchanged (non-US shops' prices are converted to USD and move with the exchange rate). Sponsored listings are skipped while monitoring: Etsy rotates them on every visit.

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input.

## `country` (type: `string`):

Etsy storefront to scrape. Prices come in that country's currency and the proxy is pinned to it. Only the United States (USD, English) is supported so far: other exit countries did not get through the proxy.

## `proxyConfiguration` (type: `object`):

Etsy answers datacenter and residential proxies with an error, so the default is Apify's Unblocker proxy (group UNBLOCKER), pinned to the selected country. It is billed to your Apify account per successful request: 10 Unblocker units, about $0.0015 on the free plan and less on paid plans. One request returns a result page with about 60 listings (36 on shop pages), or one listing page. Requests take 10-60 seconds each.

## Actor input object example

```json
{
  "searchTerms": [
    "ceramic mug"
  ],
  "startUrls": [],
  "maxItems": 100,
  "maxPagesPerSearch": 5,
  "sortBy": "most_relevant",
  "includeDetails": false,
  "onlyNewOrChanged": false,
  "country": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "ceramic mug"
    ],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/etsy-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["ceramic mug"],
    "startUrls": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/etsy-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "ceramic mug"
  ],
  "startUrls": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call tortuga/etsy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tortuga/etsy-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/qhjXLXeuae7ojFAv0/builds/WbeNFsYdJq07n3Dhg/openapi.json
