# Puma API Scraper (`rl1987/puma-api-scraper`) Actor

Scrapes PUMA.com product listing (category) and product detail data via the official mobile app GraphQL API.

- **URL**: https://apify.com/rl1987/puma-api-scraper.md
- **Developed by:** [R.L.](https://apify.com/rl1987) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 6 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.69 / 1,000 listing rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### What does Puma API Scraper do?

**Puma API Scraper** extracts product data directly from [PUMA.com](https://us.puma.com)'s
official GraphQL API — the same API the PUMA mobile app uses — giving you clean, structured
**category listing (PLP)**, **keyword search**, and **product detail (PDP)** data without
rendering a single web page. Because it talks to the API instead of scraping HTML, it's fast,
reliable, and returns fields (pricing, stock per size, badges, images, materials) that aren't
always visible in the page markup.

Run it on the [Apify platform](https://apify.com) to get API access, scheduling, webhooks, and
integrations with Zapier, Make, Google Sheets, and 30+ other tools — no infrastructure to manage.

### Why use Puma API Scraper?

- **Price and availability monitoring** — track PUMA prices, sale prices, and per-size stock
  status over time for competitor or assortment monitoring.
- **Catalog enrichment** — pull structured product attributes (materials, care instructions,
  size charts, badges) to enrich your own product database.
- **Market research** — analyze PUMA's category assortment, search rankings, new arrivals, and
  pricing strategy across countries and locales.

### How to use Puma API Scraper

The Actor supports three scraping modes. **Select which one(s) to run in the `Scrape modes`
field** — a mode's input list (e.g. `categoryUrls`) is only read if that mode is selected, even
if it's filled in, so leftover values from a saved input never trigger an unwanted mode.

1. Tick **Category** in `Scrape modes`, then add one or more **Category URLs** — paste the full
   PUMA category page URL (e.g. `https://us.puma.com/us/en/men/shoes`) or just the path
   (`/men/shoes`); the locale segment is stripped automatically.
2. Tick **Search**, then add one or more **Search queries** (e.g. `"running shoes"`), same as the
   in-app search bar.
3. Tick **Product IDs**, then add specific **Product IDs** to fetch individual products directly.
4. Choose whether to fetch full **PDP** data for every product found via category/search (on by
   default).
5. Click **Start** and download your results from the **Dataset** tab in JSON, CSV, Excel, or
   other formats.

### Input

| Field | Type | Description |
|---|---|---|
| `scrapeModes` | array of strings | Which mode(s) to run: `category`, `search`, `productIds` (default `["category"]`) |
| `categoryUrls` | array of strings | Used when `category` is selected. PLP category pages to crawl — full URL or bare path, e.g. `["https://us.puma.com/us/en/men/shoes"]` |
| `searchQueries` | array of strings | Used when `search` is selected. Keyword searches to run, e.g. `["running shoes"]` |
| `productIds` | array of strings | Used when `productIds` is selected. Specific master product IDs to fetch directly |
| `locale` | string | Storefront locale, e.g. `en-US`, `en-GB`, `de-DE`, `ja-JP` (default `en-US`) |
| `fetchProductDetails` | boolean | Also fetch full PDP data for every PLP/search result (default `true`) |
| `maxProductsPerCategory` | integer | Cap products per category; `0` = unlimited |
| `maxProductsPerSearch` | integer | Cap products per search query; `0` = unlimited |

See the full input schema on the **Input** tab.

### Output

Each dataset item is either a lightweight `plp` listing record or a full `pdp` product record.

```json
{
  "type": "pdp",
  "id": "398846",
  "name": "Speedcat OG Sneakers",
  "price": 100,
  "brand": "Speedcat",
  "category": { "id": "mens-shoes", "name": "Men's Shoes and Sneakers", "url": "/men/shoes" },
  "variations": [
    {
      "id": "398846_01",
      "colorName": "PUMA Black-PUMA White",
      "orderable": true,
      "productPrice": { "price": 100, "salePrice": 100 },
      "sizeGroups": [ { "label": "Mens", "sizes": [ { "label": "9", "orderable": true } ] } ]
    }
  ]
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

#### Data table

| Field | Description |
|---|---|
| `id` / `masterId` | PUMA master product ID |
| `name` | Product name |
| `price` | Base price |
| `variations` | Array of color variants, each with pricing, images, materials, and per-size stock (`sizeGroups`) |
| `category` | Category ID, name, and URL |
| `productStory` | Long description and care instructions |

### Pricing

The current rates for each event are on the Actor's **Pricing** tab, which is generated from
the live configuration — this page deliberately does not repeat them, so there is no second
copy to fall out of date.

What you are charged *for*:

- **Listing row** — one row per product **colourway**. A style sold in three colours returns
  three rows, so a catalogue of 100 styles is more than 100 rows. Repeated rows are
  de-duplicated and not charged: Puma's own index sometimes returns the same colourway twice
  under different internal hit ids, and those repeats are dropped before billing.
- **Product detail row** — one row per **distinct product**, fetched once no matter how many
  of its colourways appeared in the listing, and only when `fetchProductDetails` is on.

So the cheapest way to run this is with `fetchProductDetails` off, which skips the per-product
detail fetch entirely (see Tips below).

### Tips or Advanced options

- Leave `fetchProductDetails` off if you only need the PLP summary (variant colors, prices,
  ratings) — this roughly halves the number of API calls.
- Use `maxProductsPerCategory` while testing to keep runs small before scaling up.

### Sneaker & streetwear resale toolkit

Part of the **Sneaker & streetwear resale toolkit** — resale-market pricing and product data across the major sneaker/streetwear marketplaces and brands:

- [StockX API Scraper](https://apify.com/rl1987/stockx-api-scraper) — Product listings, market data, and pricing from StockX.
- [GOAT API Scraper](https://apify.com/rl1987/goat-api-scraper) — Scrapes GOAT.com product listings by search query or category.
- [Supreme API Scraper](https://apify.com/rl1987/supreme-api-scraper) — Supreme catalogue: categories, full product detail, every colour/size variant.
- [Nike API Scraper](https://apify.com/rl1987/nike-api-scraper) — Scrape Nike.com listings and full product detail from api.nike.com.

### Did you find this useful?

Rate this actor on Apify! Your feedback helps other users find it and helps us keep improving it.

### FAQ, disclaimers, and support

This Actor is an independent tool and is not affiliated with or endorsed by PUMA. It's built for
legitimate research, monitoring, and catalog-enrichment purposes — always ensure your use
complies with PUMA's Terms of Service. Data availability and fields may change if PUMA updates
its API. Found an issue or need custom fields? Use the Issues tab, or reach out for a custom
scraping solution.

# Actor input Schema

## `scrapeModes` (type: `array`):

Which scraping mode(s) to run. Only the selected mode(s) are executed, even if the corresponding input field below is filled in.

## `categoryUrls` (type: `array`):

Used only when "category" is selected in Scrape modes. PUMA category pages to crawl. Accepts a full URL (e.g. "https://us.puma.com/us/en/men/shoes") or a bare path (e.g. "/men/shoes") - the locale segment is stripped automatically.

## `searchQueries` (type: `array`):

Used only when "search" is selected in Scrape modes. Keyword searches to run, same as the in-app search bar, e.g. "running shoes".

## `productIds` (type: `array`):

Used only when "productIds" is selected in Scrape modes. Specific PUMA master product IDs to scrape directly. Master IDs are numeric, e.g. "398846".

## `locale` (type: `string`):

Storefront locale sent as the GraphQL `locale` header, e.g. en-US, en-GB, de-DE, ja-JP.

## `fetchProductDetails` (type: `boolean`):

When true, in addition to the lightweight PLP/search listing, fetch the full product-detail (PDP) record for every unique product found.

## `maxProductsPerCategory` (type: `integer`):

Maximum number of PLP items to fetch per category URL (0 = unlimited, fetches all pages).

## `maxProductsPerSearch` (type: `integer`):

Maximum number of results to fetch per search query (0 = unlimited, fetches all pages).

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

Optional proxy settings.

## Actor input object example

```json
{
  "scrapeModes": [
    "category"
  ],
  "categoryUrls": [
    "https://us.puma.com/us/en/men/shoes"
  ],
  "searchQueries": [],
  "productIds": [],
  "locale": "en-US",
  "fetchProductDetails": true,
  "maxProductsPerCategory": 5,
  "maxProductsPerSearch": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `products` (type: `string`):

PLP/search listing rows and full PDP product rows, in the order they were scraped. Filter by the `type` field to separate them.

# 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 = {
    "scrapeModes": [
        "category"
    ],
    "categoryUrls": [
        "https://us.puma.com/us/en/men/shoes"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("rl1987/puma-api-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 = {
    "scrapeModes": ["category"],
    "categoryUrls": ["https://us.puma.com/us/en/men/shoes"],
}

# Run the Actor and wait for it to finish
run = client.actor("rl1987/puma-api-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 '{
  "scrapeModes": [
    "category"
  ],
  "categoryUrls": [
    "https://us.puma.com/us/en/men/shoes"
  ]
}' |
apify call rl1987/puma-api-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rl1987/puma-api-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/k7lHUOnDmgzu83Jzl/builds/giW0fRTK4NmfARB63/openapi.json
