# Thingiverse 3D Model Scraper (`crawlerbros/thingiverse-3d-model-scraper`) Actor

Scrape Thingiverse.com - the world's largest 3D-printing design repository. Look up 3D models by thing ID or share URL, browse the newest published designs, fetch maker/uploader profiles, or keyword-search across the whole catalog.

- **URL**: https://apify.com/crawlerbros/thingiverse-3d-model-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Developer tools, Automation, 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 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

## Thingiverse 3D Model Scraper

Scrape **Thingiverse.com** — the world's largest 3D-printing design repository, home to millions of free, downloadable STL/3MF files. Look up a design by thing ID or share URL, browse the newest published designs, fetch a maker/uploader's profile, or keyword-search the whole catalog. HTTP-only. No auth, no login, no cookies.

### What this actor does

- **Five modes:** `byIds`, `byUrls`, `latest`, `byUser`, `search`
- **Full model metadata:** title, description, category, license, images, likes, comments, publish/update dates
- **Maker profiles:** display name, bio, avatar, user ID
- **Filters:** license type, minimum like count
- **Empty fields are omitted** — a field only appears on a record when Thingiverse actually published a value for it

### Output per thing (modes `byIds`, `byUrls`, `latest`, `search`)

- `thingId` — numeric Thingiverse thing ID
- `title`, `description`
- `category`, `subCategory` — e.g. `3D Printing` / `Toys & Games`
- `imageUrl` — full-resolution primary image
- `authorName`, `authorUsername`, `authorUrl` — the maker who uploaded the design
- `license` — friendly license name (e.g. `Attribution (CC BY)`, `Public Domain (CC0)`)
- `isFree` — whether the design is free to download
- `likesCount`, `commentsCount`
- `datePublished`, `dateModified`
- `commentsUrl` — link to the design's comment thread
- `thingUrl` — canonical share URL
- `recordType: "thing"`, `scrapedAt`

### Output per maker profile (mode `byUser`)

- `username` — canonical Thingiverse handle
- `displayName` — the maker's public display name
- `alternateName` — shown only when it differs from `username`
- `userId` — numeric Thingiverse user ID
- `bio`
- `avatarUrl`
- `profileUrl`
- `recordType: "maker"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `byIds` | `byIds` / `byUrls` / `latest` / `byUser` / `search` |
| `thingIds` | array | `["763622"]` | Numeric thing IDs to look up (mode=byIds) |
| `thingUrls` | array | – | Thing share URLs to look up (mode=byUrls) |
| `usernames` | array | – | Thingiverse usernames or profile URLs (mode=byUser) |
| `searchQuery` | string | `mount` | Keyword matched against recently published things (mode=search) |
| `license` | string | `any` | Only emit things under this license (`cc0`, `cc-by`, `cc-by-sa`, `cc-by-nd`, `cc-by-nc`, `cc-by-nc-sa`, `cc-by-nc-nd`, `gpl`, `lgpl`, `bsd`, `other`) |
| `minLikes` | int | – | Drop things with fewer likes than this |
| `maxItems` | int | `20` | Hard cap on emitted records (1–100) |

#### Example: batch lookup by thing ID

```json
{
  "mode": "byIds",
  "thingIds": ["763622", "3717484", "2278"]
}
```

#### Example: lookup by share URL

```json
{
  "mode": "byUrls",
  "thingUrls": ["https://www.thingiverse.com/thing:763622"]
}
```

#### Example: browse the newest published designs

```json
{
  "mode": "latest",
  "maxItems": 50
}
```

#### Example: a maker's profile

```json
{
  "mode": "byUser",
  "usernames": ["CreativeTools", "MakerBot"]
}
```

#### Example: keyword search filtered to public-domain designs

```json
{
  "mode": "search",
  "searchQuery": "mount",
  "license": "cc0",
  "maxItems": 30
}
```

### Use cases

- **3D printing marketplaces** — enrich a product catalog with real Thingiverse metadata and licensing
- **Design discovery tools** — surface newly published models for a "what's new" feed
- **License compliance** — filter a batch of designs down to only CC0/public-domain or commercial-safe licenses
- **Maker analytics** — track a designer's published work, likes, and comment engagement over time
- **Academic/dataset research** — bulk-export bibliographic-style metadata for 3D model corpora

### Limitations

- **Large `maxItems` runs take longer.** Thingiverse rate-limits individual thing/profile page requests per source IP much more aggressively than its static sitemap files. Keep `maxItems` modest (≤50) for fast, predictable runs, and budget more time for larger batches.
- **`mode=search` with a rare/absent keyword still has to scan its whole candidate window before it can report zero matches** — increase the run's timeout (Run options → Timeout) beyond the default if you search for uncommon terms with a larger `maxItems`.
- **No tag/category browse mode.** Thingiverse's `/tag:<name>` and category-browse pages don't expose server-rendered listing data (unlike individual thing/profile pages). Use the `license` filter plus `mode=search`'s category/subCategory keyword matching as a partial substitute.
- **No trending/popular mode.** Thingiverse's `/popular` and `/newest` listing pages have no public, unauthenticated data feed. `mode=latest` (sourced from the public sitemap) is the closest reliable substitute for "what's new."
- **`mode=search` is a recent-catalog keyword filter, not a full-text index search** — see the FAQ below and the input field description.

### FAQ

**What is Thingiverse?** A free community platform, owned by MakerBot/Formlabs, where makers upload and share digital designs for 3D printing, laser cutting, and other digital fabrication.

**Is this affiliated with Thingiverse?** No, this is a third-party actor that reads Thingiverse's own publicly published page data. It is not endorsed by or affiliated with Thingiverse, MakerBot, or Formlabs.

**Are all Thingiverse designs free?** Yes — every thing on Thingiverse is free to download. The `license` field tells you the terms under which you may reuse or remix the design (attribution required, non-commercial only, share-alike, or fully public domain).

**How does `mode=search` work, and why does it sometimes return fewer results than `maxItems`?** Thingiverse has no public full-text search API for its full catalog. So `search` scans the most recently published things (via the same public sitemap `mode=latest` uses) and keyword-matches each one's title/description/category. This means very specific or rare keywords may return fewer results, or none, if no match appears in the scanned window — try a more common term, or use `mode=latest` for guaranteed-fresh designs regardless of keyword. Every returned thing is a genuine, live Thingiverse page — results are just bounded to a recent-catalog window rather than an all-time index.

**Why is there only one `imageUrl` per thing?** Thingiverse's publicly published page data exposes one representative image per design. The full image gallery lives behind the site's interactive app and isn't part of the public page data.

**What does `mode=latest` actually return?** The most recently published things, sourced from Thingiverse's own public sitemap (the same file search engines use to discover new designs), each hydrated with full metadata.

**How fresh is the data?** Every run fetches live pages at request time — nothing is cached or pre-scraped.

**Why are `tags` not included?** Thingiverse only exposes per-thing tags through its interactive, login-aware web app, not on the publicly published page — including a fabricated or partial tag list would be worse than omitting it.

# Actor input Schema

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

What to fetch from Thingiverse.

## `thingIds` (type: `array`):

Numeric Thingiverse thing IDs, e.g. `763622` (the ID in `thingiverse.com/thing:763622`).

## `thingUrls` (type: `array`):

Full Thingiverse share URLs, e.g. `https://www.thingiverse.com/thing:763622`.

## `usernames` (type: `array`):

Thingiverse usernames or profile URLs, e.g. `CreativeTools` or `https://www.thingiverse.com/CreativeTools`.

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

Keyword matched (case-insensitive) against the title/description/category of the most recently published things on Thingiverse. Not a full-catalog index search — Thingiverse has no public full-text search API.

## `license` (type: `string`):

Only emit things published under this license. `any` disables the filter.

## `minLikes` (type: `integer`):

Drop things with fewer likes than this.

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

Hard cap on emitted records. Thingiverse rate-limits individual thing/profile pages per IP, so each record may need a proxy retry — keep this modest (under ~100) for a fast run; larger values still work but take longer.

## Actor input object example

```json
{
  "mode": "byIds",
  "thingIds": [
    "763622"
  ],
  "thingUrls": [],
  "usernames": [],
  "searchQuery": "mount",
  "license": "any",
  "maxItems": 5
}
```

# Actor output Schema

## `things` (type: `string`):

Dataset containing all scraped Thingiverse things and profiles.

# 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": "byIds",
    "thingIds": [
        "763622"
    ],
    "thingUrls": [],
    "usernames": [],
    "searchQuery": "mount",
    "license": "any",
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/thingiverse-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": "byIds",
    "thingIds": ["763622"],
    "thingUrls": [],
    "usernames": [],
    "searchQuery": "mount",
    "license": "any",
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/thingiverse-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": "byIds",
  "thingIds": [
    "763622"
  ],
  "thingUrls": [],
  "usernames": [],
  "searchQuery": "mount",
  "license": "any",
  "maxItems": 5
}' |
apify call crawlerbros/thingiverse-3d-model-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1MUNNIOWTtDaqWWq7/builds/7qlo7stdqkPl9HCXL/openapi.json
