# Printables 3D Model Scraper (`crawlerbros/printables-3d-model-scraper`) Actor

Scrape Printables.com - Prusa's 3D-print model community. Search models, browse categories, fetch trending/popular feeds, list a designer's uploads, or pull full model detail (print settings, files, images, licence). HTTP-only via the public GraphQL API. No auth, no proxy.

- **URL**: https://apify.com/crawlerbros/printables-3d-model-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Developer tools, Integrations
- **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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Printables 3D Model Scraper

Scrape **Printables.com** — Prusa's community platform for free and paid 3D-printable models. Search by keyword, browse any of the 89 official categories, pull the trending/popular feed, list everything a designer has published, list every model in a public collection, or fetch full detail for one model (print settings, files, images, license, remix lineage, related models, and community "make" photos). HTTP-only via Printables' own public API. No auth, no cookies, no proxy.

### What this actor does

- **Six modes:** `search`, `category`, `trending`, `byUser`, `byCollection`, `modelDetail`
- **Rich filters:** category, material, printer, "designed with" modeling app, print technology (FDM/resin via sliced-file type), license, price, AI-generated status, min/max print duration, min/max weight, published-within-N-days freshness, "has makes only"
- **10 sort orders:** relevance, latest, popular, top rated, most downloaded, most liked, most printed, most viewed, trending, random
- **Full model detail on demand:** description, print settings, every file name/size/format, all gallery images, remix parent(s), related models, and a sample of community "make" photos
- **Designer profiles:** follower counts, published-model counts, verification badge
- **Empty fields are omitted**

### Output per model

- `modelId`, `name`, `slug`, `modelUrl`, `sourceUrl`
- `summary` — short blurb (all modes); `description` — full write-up, HTML stripped to plain text (mode=modelDetail only)
- `categoryId`, `categoryName`, `categoryPath[]`
- `licenseId`, `licenseName`, `licenseAbbreviation`
- `tags[]`, `materials[]` — recommended filaments/resins
- `printerName`, `printerCategory` (`FFF` or `SLA`)
- `printDurationHours`, `weightGrams`, `layerHeightsMm[]`, `nozzleDiametersMm[]`, `numPieces`
- `filesType` (`GCODE` / `SLA` / `NONE`), `filesCount`, `imagesCount`
- `likesCount`, `ratingAvg`, `ratingCount`, `downloadCount`, `viewsCount`, `makesCount`, `remixCount`, `commentCount`
- `isPremium`, `priceUsd` (paid models only), `isAiGenerated`, `isNsfw`, `isPoliticalContent`
- `datePublished`, `firstPublished`, `lastModified`, `thingiverseLink` (if migrated from Thingiverse)
- `coverImageUrl`, `coverImageWidth`, `coverImageHeight`
- `imageUrls[]` — full gallery (mode=modelDetail only)
- `files[]` — `{name, fileSizeBytes, fileFormat, printDurationHours, material, printer}` per file; `fileFormats[]` — distinct formats included (mode=modelDetail only)
- `remixOf[]` — `{modelId, name, url}` per parent model this is a remix of (mode=modelDetail only)
- `relatedModels[]` — `{modelId, name, url, categoryName, imageUrl}`, up to 8 similar models (mode=modelDetail only)
- `makes[]` — `{makerHandle, makerUsername, imageUrl, comment, madeAt}`, up to 8 sampled community "make" photos (mode=modelDetail only)
- `designerUserId`, `designerHandle`, `designerUsername`, `designerVerified`, `designerAvatarUrl`, `designerProfileUrl`, `designerFollowersCount`, `designerPublishedModelsCount`
- `recordType: "model"`, `scrapedAt`

**Note on file downloads:** actual STL/G-code/3MF file *download* links on Printables are generated on demand behind the site's own download flow and are not exposed by the public API — including them here would mean shipping broken or expiring URLs. Instead, every file's **name, size, and format** is included so you always know exactly what's in the model before deciding to visit the page.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `category` / `trending` / `byUser` / `byCollection` / `modelDetail` |
| `searchQuery` | string | `3d benchy` | Free-text query (mode=search) |
| `categoryId` | select | – | Category to browse (mode=category required; optional filter for mode=search only) |
| `designerHandleOrId` | string | `Prusa3D` | Handle, profile URL, or numeric ID (mode=byUser) |
| `modelUrlOrId` | string | – | Model URL or numeric ID (mode=modelDetail) |
| `collectionUrlOrId` | string | `2687005` | Collection URL or numeric ID (mode=byCollection) |
| `sortBy` | select | `popular` | Result order — see the 10 options above |
| `material` | select | – | Filament/resin material filter |
| `printerId` | select | – | Filter by a specific printer (curated list of ~48 common current-gen printers across Prusa, Bambu Lab, Creality, Anycubic, Elegoo, Voron, and more) |
| `modelingApp` | select | – | Filter by the modeling application source files were authored in (Fusion, Blender, SolidWorks, etc.) |
| `fileType` | select | – | Print technology: `GCODE` (FDM/FFF) / `SLA` (resin) / `NONE` (source files only) |
| `licenseType` | select | – | License filter |
| `paidStatus` | select | `all` | `all` / `free` / `paid` / `club` / `priced` |
| `aiGeneratedFilter` | select | `include` | `include` / `exclude` / `only` |
| `minPrintDurationHours` | int | – | Drop models with a shorter estimated print time |
| `maxPrintDurationHours` | int | – | Drop models with a longer estimated print time |
| `minWeightGrams` | int | – | Drop models with less estimated filament weight |
| `maxWeightGrams` | int | – | Drop models with more estimated filament weight |
| `publishedWithinDays` | int | – | Only models first published within this many days |
| `hasMakesOnly` | bool | `false` | Only models at least one user has printed and shared a photo of |
| `maxItems` | int | `50` | Hard cap (1–1000) |

#### Example: search with filters

```json
{
  "mode": "search",
  "searchQuery": "articulated dragon",
  "fileType": "GCODE",
  "material": "1",
  "sortBy": "topRated",
  "maxItems": 50
}
````

#### Example: browse a category

```json
{
  "mode": "category",
  "categoryId": "101",
  "sortBy": "trending",
  "paidStatus": "free",
  "maxItems": 100
}
```

#### Example: a designer's uploads

```json
{
  "mode": "byUser",
  "designerHandleOrId": "Prusa3D",
  "sortBy": "mostDownloaded",
  "maxItems": 200
}
```

#### Example: single model detail

```json
{
  "mode": "modelDetail",
  "modelUrlOrId": "https://www.printables.com/model/3161-3d-benchy"
}
```

#### Example: models in a public collection

```json
{
  "mode": "byCollection",
  "collectionUrlOrId": "2687005",
  "sortBy": "mostLiked",
  "maxItems": 100
}
```

#### Example: printer + modeling-app filtered search

```json
{
  "mode": "search",
  "searchQuery": "vase",
  "printerId": "20",
  "modelingApp": "7",
  "minWeightGrams": 100,
  "publishedWithinDays": 90
}
```

### Use cases

- **Maker marketplaces** — mirror or cross-list Printables catalog data
- **3D-printing content sites** — build "trending models this week" roundups
- **Print farm sourcing** — filter by print duration and weight to estimate job cost before committing
- **Designer analytics** — track a competitor's or your own upload history, likes, and download trends
- **Material/technology research** — see what's being printed in resin vs. FDM by category
- **Dataset building** — bulk-export licensing and file-format metadata for ML or cataloging projects

### FAQ

**What's Printables.com?** Prusa Research's community platform for sharing free and paid 3D-printable models — search, categories, likes, ratings, "makes" (photos of completed prints), and designer profiles. See [printables.com](https://www.printables.com).

**Is this affiliated with Prusa or Printables?** No — this is an independent third-party actor built against Printables' publicly accessible API.

**Are there rate limits?** Yes, Printables applies request-rate limiting at the CDN level. `search`, `category`, `byCollection`, and `modelDetail` use a consistently reliable API endpoint and paginate up to the 1000-item maximum without issues. `trending` and `byUser`, however, use a different upstream endpoint (`morePrints`) that has been observed to intermittently rate-limit or fully reject requests from cloud/datacenter IP ranges — including Apify's — regardless of the actor's automatic retries with exponential backoff, sometimes returning 0 results even though the same query works fine from a residential IP. This is an upstream anti-bot limitation on Printables' side, not a bug in the actor, and it cannot be reliably worked around without a paid residential proxy. **If guaranteed results matter, use `search` or `category` mode instead** — e.g. `category` with `sortBy: "trending"` gives a trending-style view of one category, and plain `search` with `sortBy: "popular"` mirrors the sitewide trending feed.

**Why is `description` only on `modelDetail`?** The full write-up can be long HTML; fetching it for every row in a 500-item search would be wasteful. Use `modelDetail` on any `modelId`/`modelUrl` returned by another mode to get the full text.

**Why no file download URLs?** Printables generates download links on demand and they aren't part of the public API. File `name`, `fileSizeBytes`, and `fileFormat` are included instead so you know exactly what a model ships before visiting the page.

**What does `printerCategory` mean?** `FFF` is standard filament (FDM) printing; `SLA` is resin printing. Some models support both.

**What's the difference between `likesCount` and `makesCount`?** `likesCount` is how many users favorited the model; `makesCount` is how many users actually printed it and posted a photo ("a make").

**Why do some sort options behave the same in `search` and `category` modes?** Both use Printables' text-search endpoint under the hood (category browsing is a category-filtered search with no keyword), which supports 5 native orderings (relevance, latest, popular, rating, most-printed); a few of the actor's 10 friendly sort labels map to their closest native equivalent there. All 10 are fully distinct in `trending` and `byUser` modes.

**Can I combine `trending` mode with a specific category?** Not currently — Printables' category-scoped browsing endpoint is rate-limited far more aggressively than its search endpoint, so `category` mode is built on search (reliable, with sortBy=`trending` giving a close popularity-based equivalent) while `trending` mode is built on the dedicated trending feed (no category filter). Use `category` mode with `sortBy: "trending"` to get a trending-style view of one category.

**Why only ~48 printers in the `printerId` dropdown when Printables tracks 600+?** That's the full stable, `<500`-cap threshold from our dropdown-completeness rule — 600+ is too many for a usable enum, so the list is curated to the most commonly searched-for current-generation printers across every major brand (Prusa, Bambu Lab, Creality, Anycubic, Elegoo, Voron, Formlabs, and more). The filter is verified against the live API and enforced both server-side (search/category modes) and client-side (every mode, since Printables' feed API silently ignores a printer filter on trending/byUser/byCollection).

**What did the "feature surface expansion" pass add?** `printerId` and `modelingApp` filters, `minPrintDurationHours`/`minWeightGrams` (symmetric to the existing max fields), `publishedWithinDays` freshness filter, a new `byCollection` mode, and `modelDetail` enrichment with `remixOf`, `relatedModels`, and `makes` (sampled community "make" photos). It also fixed a live upstream regression: Printables deprecated its offset-paginated `prints` query sometime after this actor's initial release, which silently broke `trending` and `byUser` modes (they returned 0 results). Both modes now use the still-functional cursor-paginated `morePrints` query.

**Did you consider a `byTag` mode?** Yes, but Printables' tag-scoped browsing argument (`tags`) is silently ignored by its feed API in the same way `materialIds`/`printerIds` are — verified empirically, a bogus or real tag ID returns identical unfiltered results. Implementing a reliable tag browse would require paginating the entire catalog and filtering client-side, which isn't viable within a reasonable request budget. `searchQuery` already matches against tags reasonably well as a substitute.

**How fresh is the data?** Real-time — every request reads live from Printables' own API, the same one their website uses.

# Actor input Schema

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

What to fetch. Note: `trending` and `byUser` use Printables' `morePrints` API, which has been observed to intermittently rate-limit or fully reject requests from cloud/datacenter IP ranges (including Apify's) regardless of retries, sometimes returning 0 results even though the same query works from a residential IP. `search` and `category` use a different, consistently reliable API and are recommended when guaranteed volume matters -- e.g. use `category` with `sortBy=trending` to browse a category by trending order instead of the sitewide `trending` mode.

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

Free-text query (mode=search). Matches model name, description and tags.

## `categoryId` (type: `string`):

Restrict results to this category (mode=category required; optional filter for search). Not supported for mode=trending, mode=byUser, or mode=byCollection.

## `designerHandleOrId` (type: `string`):

Whose models to list (mode=byUser). Accepts a handle (e.g. `Prusa3D`), a profile URL (e.g. `https://www.printables.com/@Prusa3D`), or a numeric user ID.

## `modelUrlOrId` (type: `string`):

The model to fetch (mode=modelDetail). Accepts a full URL (e.g. `https://www.printables.com/model/3161-3d-benchy`) or a bare numeric ID (e.g. `3161`).

## `collectionUrlOrId` (type: `string`):

The collection to list models from (mode=byCollection). Accepts a full collection URL or a bare numeric collection ID. Example: `2687005` (a public "Benchy" collection).

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

Result ordering. Not every value applies to every mode (e.g. `relevance` only fully applies to `search`; mode=byCollection maps to its own 7-value ordering) — the closest supported equivalent is used automatically.

## `material` (type: `string`):

Only include models whose recommended print material matches.

## `printerId` (type: `string`):

Only include models tagged as designed/tested for this specific printer. Curated list of common current-generation printers (Printables tracks 600+ total; this covers the most searched-for ones). Not supported for mode=trending or mode=byUser (Printables' feed API silently ignores a printer filter there) — the actor re-checks it client-side in every mode so results are always correctly filtered.

## `modelingApp` (type: `string`):

Only include models whose source files were authored in this modeling application. Not supported for mode=modelDetail (single-model lookup, filter has no effect).

## `fileType` (type: `string`):

Filter by print technology: models shipping G-code (FDM/FFF filament printers), SLA slice files (resin printers), or no pre-sliced files at all (source files only).

## `licenseType` (type: `string`):

Only include models published under this license.

## `paidStatus` (type: `string`):

Filter by whether the model is free or paid.

## `aiGeneratedFilter` (type: `string`):

Include, exclude, or require AI-generated models.

## `minPrintDurationHours` (type: `integer`):

Drop models whose estimated print time is shorter than this many hours.

## `maxPrintDurationHours` (type: `integer`):

Drop models whose estimated print time exceeds this many hours.

## `minWeightGrams` (type: `integer`):

Drop models whose estimated filament weight is lighter than this many grams.

## `maxWeightGrams` (type: `integer`):

Drop models whose estimated filament weight exceeds this many grams.

## `publishedWithinDays` (type: `integer`):

Only include models first published within this many days. Not supported for mode=modelDetail (single-model lookup, filter has no effect).

## `hasMakesOnly` (type: `boolean`):

Only include models that at least one other user has printed and shared a photo of.

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

Hard cap on emitted records. Reliably reached (verified up to the 1000 maximum) for `search`, `category`, `byCollection`, and `modelDetail` modes. `trending` and `byUser` modes may return fewer than requested -- including 0 -- on some runs due to upstream rate-limiting of their underlying API on cloud IP ranges; see the `mode` field description for a reliable alternative.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "3d benchy",
  "designerHandleOrId": "Prusa3D",
  "modelUrlOrId": "https://www.printables.com/model/3161-3d-benchy",
  "collectionUrlOrId": "2687005",
  "sortBy": "popular",
  "paidStatus": "all",
  "aiGeneratedFilter": "include",
  "hasMakesOnly": false,
  "maxItems": 50
}
```

# Actor output Schema

## `models` (type: `string`):

Dataset containing all scraped Printables models.

# 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": "search",
    "searchQuery": "3d benchy",
    "designerHandleOrId": "Prusa3D",
    "modelUrlOrId": "https://www.printables.com/model/3161-3d-benchy",
    "collectionUrlOrId": "2687005",
    "sortBy": "popular",
    "paidStatus": "all",
    "aiGeneratedFilter": "include",
    "hasMakesOnly": false,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/printables-3d-model-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": "search",
    "searchQuery": "3d benchy",
    "designerHandleOrId": "Prusa3D",
    "modelUrlOrId": "https://www.printables.com/model/3161-3d-benchy",
    "collectionUrlOrId": "2687005",
    "sortBy": "popular",
    "paidStatus": "all",
    "aiGeneratedFilter": "include",
    "hasMakesOnly": False,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/printables-3d-model-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": "search",
  "searchQuery": "3d benchy",
  "designerHandleOrId": "Prusa3D",
  "modelUrlOrId": "https://www.printables.com/model/3161-3d-benchy",
  "collectionUrlOrId": "2687005",
  "sortBy": "popular",
  "paidStatus": "all",
  "aiGeneratedFilter": "include",
  "hasMakesOnly": false,
  "maxItems": 50
}' |
apify call crawlerbros/printables-3d-model-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/printables-3d-model-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Printables 3D Model Scraper",
        "description": "Scrape Printables.com - Prusa's 3D-print model community. Search models, browse categories, fetch trending/popular feeds, list a designer's uploads, or pull full model detail (print settings, files, images, licence). HTTP-only via the public GraphQL API. No auth, no proxy.",
        "version": "1.0",
        "x-build-id": "9exlZgfYfDp0HUeJZ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/crawlerbros~printables-3d-model-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-crawlerbros-printables-3d-model-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/crawlerbros~printables-3d-model-scraper/runs": {
            "post": {
                "operationId": "runs-sync-crawlerbros-printables-3d-model-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/crawlerbros~printables-3d-model-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-crawlerbros-printables-3d-model-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "search",
                            "category",
                            "trending",
                            "byUser",
                            "byCollection",
                            "modelDetail"
                        ],
                        "type": "string",
                        "description": "What to fetch. Note: `trending` and `byUser` use Printables' `morePrints` API, which has been observed to intermittently rate-limit or fully reject requests from cloud/datacenter IP ranges (including Apify's) regardless of retries, sometimes returning 0 results even though the same query works from a residential IP. `search` and `category` use a different, consistently reliable API and are recommended when guaranteed volume matters -- e.g. use `category` with `sortBy=trending` to browse a category by trending order instead of the sitewide `trending` mode.",
                        "default": "search"
                    },
                    "searchQuery": {
                        "title": "Search query",
                        "type": "string",
                        "description": "Free-text query (mode=search). Matches model name, description and tags.",
                        "default": "3d benchy"
                    },
                    "categoryId": {
                        "title": "Category",
                        "enum": [
                            "",
                            "16",
                            "1",
                            "40",
                            "36",
                            "61",
                            "138",
                            "62",
                            "13",
                            "25",
                            "89",
                            "69",
                            "136",
                            "5",
                            "6",
                            "31",
                            "37",
                            "97",
                            "92",
                            "27",
                            "77",
                            "76",
                            "135",
                            "52",
                            "93",
                            "17",
                            "21",
                            "139",
                            "98",
                            "87",
                            "75",
                            "48",
                            "44",
                            "88",
                            "3",
                            "84",
                            "4",
                            "90",
                            "7",
                            "78",
                            "94",
                            "51",
                            "99",
                            "18",
                            "104",
                            "95",
                            "29",
                            "50",
                            "96",
                            "41",
                            "80",
                            "42",
                            "43",
                            "45",
                            "82",
                            "2",
                            "85",
                            "47",
                            "53",
                            "83",
                            "34",
                            "60",
                            "57",
                            "26",
                            "91",
                            "28",
                            "81",
                            "103",
                            "134",
                            "33",
                            "64",
                            "14",
                            "65",
                            "9",
                            "68",
                            "71",
                            "101",
                            "12",
                            "49",
                            "30",
                            "38",
                            "105",
                            "100",
                            "140",
                            "137",
                            "15",
                            "70",
                            "74",
                            "20",
                            "58"
                        ],
                        "type": "string",
                        "description": "Restrict results to this category (mode=category required; optional filter for search). Not supported for mode=trending, mode=byUser, or mode=byCollection."
                    },
                    "designerHandleOrId": {
                        "title": "Designer handle, profile URL, or numeric user ID",
                        "type": "string",
                        "description": "Whose models to list (mode=byUser). Accepts a handle (e.g. `Prusa3D`), a profile URL (e.g. `https://www.printables.com/@Prusa3D`), or a numeric user ID.",
                        "default": "Prusa3D"
                    },
                    "modelUrlOrId": {
                        "title": "Model URL or ID",
                        "type": "string",
                        "description": "The model to fetch (mode=modelDetail). Accepts a full URL (e.g. `https://www.printables.com/model/3161-3d-benchy`) or a bare numeric ID (e.g. `3161`).",
                        "default": "https://www.printables.com/model/3161-3d-benchy"
                    },
                    "collectionUrlOrId": {
                        "title": "Collection URL or ID",
                        "type": "string",
                        "description": "The collection to list models from (mode=byCollection). Accepts a full collection URL or a bare numeric collection ID. Example: `2687005` (a public \"Benchy\" collection).",
                        "default": "2687005"
                    },
                    "sortBy": {
                        "title": "Sort order",
                        "enum": [
                            "relevance",
                            "latest",
                            "popular",
                            "topRated",
                            "mostDownloaded",
                            "mostLiked",
                            "mostPrinted",
                            "mostViewed",
                            "trending",
                            "random"
                        ],
                        "type": "string",
                        "description": "Result ordering. Not every value applies to every mode (e.g. `relevance` only fully applies to `search`; mode=byCollection maps to its own 7-value ordering) — the closest supported equivalent is used automatically.",
                        "default": "popular"
                    },
                    "material": {
                        "title": "Filament / resin material",
                        "enum": [
                            "",
                            "1",
                            "8",
                            "3",
                            "4",
                            "2",
                            "7",
                            "16",
                            "15",
                            "14",
                            "11",
                            "12",
                            "13",
                            "5",
                            "6",
                            "9",
                            "10",
                            "49"
                        ],
                        "type": "string",
                        "description": "Only include models whose recommended print material matches."
                    },
                    "printerId": {
                        "title": "Printer",
                        "enum": [
                            "",
                            "749",
                            "620",
                            "14",
                            "1",
                            "18",
                            "761",
                            "532",
                            "23",
                            "17",
                            "336",
                            "768",
                            "496",
                            "652",
                            "711",
                            "682",
                            "784",
                            "20",
                            "293",
                            "292",
                            "534",
                            "699",
                            "102",
                            "551",
                            "95",
                            "648",
                            "649",
                            "684",
                            "747",
                            "73",
                            "77",
                            "327",
                            "319",
                            "305",
                            "670",
                            "309",
                            "645",
                            "696",
                            "246",
                            "280",
                            "279",
                            "278",
                            "478",
                            "238",
                            "697",
                            "609",
                            "668",
                            "499",
                            "282"
                        ],
                        "type": "string",
                        "description": "Only include models tagged as designed/tested for this specific printer. Curated list of common current-generation printers (Printables tracks 600+ total; this covers the most searched-for ones). Not supported for mode=trending or mode=byUser (Printables' feed API silently ignores a printer filter there) — the actor re-checks it client-side in every mode so results are always correctly filtered."
                    },
                    "modelingApp": {
                        "title": "Designed with (modeling app)",
                        "enum": [
                            "",
                            "1",
                            "2",
                            "3",
                            "4",
                            "5",
                            "6",
                            "7",
                            "9",
                            "10",
                            "11",
                            "12",
                            "13",
                            "14",
                            "15",
                            "16",
                            "17",
                            "19",
                            "20"
                        ],
                        "type": "string",
                        "description": "Only include models whose source files were authored in this modeling application. Not supported for mode=modelDetail (single-model lookup, filter has no effect)."
                    },
                    "fileType": {
                        "title": "Print technology / sliced-file type",
                        "enum": [
                            "",
                            "GCODE",
                            "SLA",
                            "NONE"
                        ],
                        "type": "string",
                        "description": "Filter by print technology: models shipping G-code (FDM/FFF filament printers), SLA slice files (resin printers), or no pre-sliced files at all (source files only)."
                    },
                    "licenseType": {
                        "title": "License",
                        "enum": [
                            "",
                            "7",
                            "1",
                            "2",
                            "8",
                            "3",
                            "4",
                            "6",
                            "9",
                            "12",
                            "10",
                            "11",
                            "13",
                            "14",
                            "15",
                            "16",
                            "17",
                            "19",
                            "20",
                            "21",
                            "22",
                            "23",
                            "18"
                        ],
                        "type": "string",
                        "description": "Only include models published under this license."
                    },
                    "paidStatus": {
                        "title": "Price filter",
                        "enum": [
                            "all",
                            "free",
                            "paid",
                            "club",
                            "priced"
                        ],
                        "type": "string",
                        "description": "Filter by whether the model is free or paid.",
                        "default": "all"
                    },
                    "aiGeneratedFilter": {
                        "title": "AI-generated models",
                        "enum": [
                            "include",
                            "exclude",
                            "only"
                        ],
                        "type": "string",
                        "description": "Include, exclude, or require AI-generated models.",
                        "default": "include"
                    },
                    "minPrintDurationHours": {
                        "title": "Min print duration (hours)",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Drop models whose estimated print time is shorter than this many hours."
                    },
                    "maxPrintDurationHours": {
                        "title": "Max print duration (hours)",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Drop models whose estimated print time exceeds this many hours."
                    },
                    "minWeightGrams": {
                        "title": "Min filament weight (grams)",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Drop models whose estimated filament weight is lighter than this many grams."
                    },
                    "maxWeightGrams": {
                        "title": "Max filament weight (grams)",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Drop models whose estimated filament weight exceeds this many grams."
                    },
                    "publishedWithinDays": {
                        "title": "Published within the last N days",
                        "minimum": 1,
                        "maximum": 3650,
                        "type": "integer",
                        "description": "Only include models first published within this many days. Not supported for mode=modelDetail (single-model lookup, filter has no effect)."
                    },
                    "hasMakesOnly": {
                        "title": "Only models with at least one make",
                        "type": "boolean",
                        "description": "Only include models that at least one other user has printed and shared a photo of.",
                        "default": false
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Hard cap on emitted records. Reliably reached (verified up to the 1000 maximum) for `search`, `category`, `byCollection`, and `modelDetail` modes. `trending` and `byUser` modes may return fewer than requested -- including 0 -- on some runs due to upstream rate-limiting of their underlying API on cloud IP ranges; see the `mode` field description for a reliable alternative.",
                        "default": 50
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
