# Poly Haven Scraper — Free CC0 3D Assets, HDRIs & Textures (`crawlerbros/polyhaven-scraper`) Actor

Scrape Poly Haven's free CC0 library of HDRIs, PBR textures, and 3D models. Browse by category, search by keyword, or look up assets by ID. Returns full metadata plus direct download links for every resolution/format. No API key or login required.

- **URL**: https://apify.com/crawlerbros/polyhaven-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Developer tools, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Poly Haven Scraper

Extract 3D assets from [Poly Haven](https://polyhaven.com) — a free, public-domain (CC0) library of HDRIs, PBR textures, and 3D models widely used by 3D artists, game developers, and VFX/archviz studios. Browse by asset type and category, search by keyword, or look up specific assets by ID. Every record includes full metadata plus direct, no-login download links for every available resolution and file format.

### Features

- **4 scraping modes** — browse, keyword search, ID lookup, category discovery
- **3 asset catalogs** — HDRIs (environment lighting), textures (PBR materials), models (3D objects)
- **Direct CC0 download links** — every resolution (1k–24k) and format (EXR/HDR/JPG/PNG/blend/FBX/glTF/USD) with file sizes
- **Rich metadata** — tags, categories, authors, resolution, polycount, real-world dimensions, and more
- **19–48 categories per asset type** — selectable dropdowns, e.g. "outdoor", "furniture", "night", "wood"
- **No authentication required** — uses the free public [Poly Haven API](https://api.polyhaven.com) (no key, no login, no proxy)

### Input

| Field | Type | Description | Default |
|-------|------|-------------|---------|
| `mode` | Select | Scraping mode | `browse` |
| `assetType` | Select | `hdris`, `textures`, `models`, or `all` | `hdris` |
| `hdriCategory` | Select | Category filter (mode=browse/search, assetType=hdris/all) | — |
| `textureCategory` | Select | Category filter (mode=browse/search, assetType=textures/all) | — |
| `modelCategory` | Select | Category filter (mode=browse/search, assetType=models/all) | — |
| `searchQuery` | String | Keyword to match against name/tags/categories/description (mode=search) | `wood` |
| `assetIds` | Array | Poly Haven asset IDs to look up directly (mode=byId) | `[]` |
| `includeDownloadLinks` | Boolean | Fetch direct download URLs for every resolution/format | `true` |
| `maxItems` | Integer | Maximum number of records to return | `30` |

#### Modes

| Mode | Description |
|------|-------------|
| `browse` | List assets of the chosen type, optionally filtered by category |
| `search` | Keyword search across name, tags, categories, and description |
| `byId` | Look up specific assets directly by their Poly Haven ID (the slug from a `polyhaven.com/a/{id}` URL) |
| `listCategories` | List every category for the chosen asset type along with its asset count — useful for discovering valid category filter values |

#### Example Input

```json
{
  "mode": "search",
  "assetType": "textures",
  "searchQuery": "wood",
  "maxItems": 20,
  "includeDownloadLinks": true
}
```

### Output

| Field | Type | Description |
|-------|------|-------------|
| `assetId` | String | Poly Haven's unique asset slug |
| `name` | String | Asset name |
| `assetType` | String | `hdri`, `texture`, or `model` |
| `category` | String | Full category path (e.g. `Wood/Bark/Furrowed Bark`) |
| `categories` | Array | Top-level category tags |
| `tags` | Array | Search tags |
| `description` | String | Asset description |
| `authors` | Array | Author name(s) |
| `thumbnailUrl` | String | Preview image URL |
| `downloadCount` | Integer | Total downloads on Poly Haven |
| `datePublished` | String | ISO 8601 publish date |
| `maxResolution` | Array | `[width, height]` in pixels (HDRIs/textures) |
| `coordinates` | Array | `[lat, lon]` where the HDRI was captured (HDRIs only) |
| `whitebalanceKelvin` | Integer | White balance in Kelvin (HDRIs only) |
| `evsCap` | Integer | Exposure value cap (HDRIs only) |
| `hasBackplates` | Boolean | Whether matching backplate photos are available (HDRIs only) |
| `realWorldDimensionsCm` | Array | Real-world texture tile size in cm (textures only) |
| `polycount` | Integer | Polygon count (models only) |
| `texelDensity` | Number | Texel density (models only) |
| `dimensionsMm` | Array | `[x, y, z]` bounding box in mm (models only) |
| `attributes` | Object | Extra type-specific attributes (surface use, material, condition, etc.) |
| `sourceUrl` | String | Link to the asset's Poly Haven page |
| `downloadFiles` | Object | Direct CC0 download URLs, organized by map/resolution/format, each with `url` and `sizeBytes` |
| `availableFormats` | Array | Unique file formats available for this asset |
| `scrapedAt` | String | ISO timestamp |

#### Example Output

```json
{
  "assetId": "aarfontein_dirt_road",
  "name": "Aarfontein Dirt Road",
  "assetType": "hdri",
  "category": "Desert & Arid/Karoo & Scrubland/Dirt Roads & Tracks",
  "categories": ["outdoor", "nature", "natural light", "high contrast", "clear", "morning-afternoon"],
  "tags": ["sun", "arid", "gravel", "dirt road", "scrubland", "tracks"],
  "authors": ["Dario Barresi", "Jarod Guest"],
  "thumbnailUrl": "https://cdn.polyhaven.com/asset_img/thumbs/aarfontein_dirt_road.png?width=256&height=256",
  "downloadCount": 975,
  "maxResolution": [24576, 12288],
  "sourceUrl": "https://polyhaven.com/a/aarfontein_dirt_road",
  "downloadFiles": {
    "hdri": {
      "1k": {"exr": {"url": "https://dl.polyhaven.org/.../aarfontein_dirt_road_1k.exr", "sizeBytes": 5779773}}
    }
  },
  "availableFormats": ["exr", "hdr", "tonemapped"],
  "scrapedAt": "2026-07-03T12:00:00+00:00"
}
```

### FAQ

**Do I need an API key or Poly Haven account?**
No. Poly Haven's API (`api.polyhaven.com`) is fully public and keyless — this actor requires no login, cookies, or proxy.

**Are the assets really free to use?**
Yes. Every asset on Poly Haven is released under the CC0 public-domain license — free for personal and commercial use, no attribution required (though appreciated).

**How many assets are available?**
Roughly 2,300+ assets: ~980 HDRIs, ~780 textures, and ~520 models, growing regularly.

**What resolutions/formats can I download?**
Depends on the asset — HDRIs go up to 24K in EXR/HDR; textures up to 8K in JPG/PNG/EXR; models include multiple texture map resolutions plus blend/FBX/glTF/USD mesh files. Every record's `downloadFiles` field lists exactly what's available for that specific asset.

**Can I search across all three catalogs at once?**
Yes — set `assetType` to `all` in `browse` or `search` mode.

**Can I disable the download-link enrichment for faster runs?**
Yes — set `includeDownloadLinks` to `false` to return metadata-only records with one API call per asset type instead of one extra call per asset.

**What categories are available?**
HDRIs: natural light, outdoor, nature, urban, skies, night, studio, and more (19 total). Textures: wood, brick, fabric, metal, concrete, and more (48 total). Models: furniture, props, plants, electronics, vehicles-adjacent categories like weapons/ships, and more (36 total). Use `mode=listCategories` to fetch the full live list with asset counts for any type.

# Actor input Schema

## `mode` (type: `string`):

How to find assets.

## `assetType` (type: `string`):

Which Poly Haven catalog to browse/search/list categories for. Ignored in mode=byId (the type is detected automatically from each asset).

## `hdriCategory` (type: `string`):

Optional category filter used when browsing/searching HDRIs. Leave blank for no filter.

## `textureCategory` (type: `string`):

Optional category filter used when browsing/searching textures. Leave blank for no filter.

## `modelCategory` (type: `string`):

Optional category filter used when browsing/searching models. Leave blank for no filter.

## `searchQuery` (type: `string`):

Keyword matched against each asset's name, tags, categories, and description.

## `assetIds` (type: `array`):

Poly Haven asset IDs to look up directly (the slug from a polyhaven.com/a/{id} URL), e.g. "aarfontein\_dirt\_road" or "ArmChair\_01".

## `includeDownloadLinks` (type: `boolean`):

Fetch and include direct CC0 download URLs (all resolutions/formats) for each asset. Adds one extra request per asset.

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

Maximum number of records to return.

## Actor input object example

```json
{
  "mode": "browse",
  "assetType": "hdris",
  "searchQuery": "wood",
  "assetIds": [],
  "includeDownloadLinks": true,
  "maxItems": 30
}
```

# Actor output Schema

## `assets` (type: `string`):

Dataset containing all scraped assets.

# 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 = {
    "mode": "browse",
    "assetType": "hdris",
    "searchQuery": "wood",
    "assetIds": [],
    "includeDownloadLinks": true,
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/polyhaven-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 = {
    "mode": "browse",
    "assetType": "hdris",
    "searchQuery": "wood",
    "assetIds": [],
    "includeDownloadLinks": True,
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/polyhaven-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 '{
  "mode": "browse",
  "assetType": "hdris",
  "searchQuery": "wood",
  "assetIds": [],
  "includeDownloadLinks": true,
  "maxItems": 30
}' |
apify call crawlerbros/polyhaven-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/polyhaven-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/GwpRdTZXUMUPhgP8P/builds/rflTCvPpSqFvrzGsx/openapi.json
