MeshScout

MeshScout API

API reference

Build search, discovery, model detail, and collection experiences on top of MeshScout's indexed 3D model catalog.

Overview

Service endpoint

The MeshScout API returns JSON over HTTPS. Public read routes may be available anonymously; protected or higher-volume usage may require an API key issued by MeshScout.

https://meshscout.net
Accept: application/json
JSON everywhere

Unless noted otherwise, API responses are JSON and use regular HTTP status codes.

Respect the source

MeshScout is a discovery layer. Show source, creator, and license context, and link users back to the original page.

Build gently

Use sensible page sizes, cache what you can, and back off when the API tells you to slow down.

Auth

Authentication

Public read endpoints can be called anonymously unless the server is configured to require API keys.

X-API-Key: $MESHSCOUT_API_KEY
Authorization: Bearer $MESHSCOUT_API_KEY
Auth typeUse it forHow it is sent
AnonymousPublic read routes when enabled.No header or cookie required.
API keyApproved API usage and protected public reads.X-API-Key or Authorization: Bearer.

Models

Search and model details

GET/api/search

Search the indexed model catalog.

GET/api/models/{id}

Fetch detail data, images, tags, source variants, and related models.

POST/api/search/feedback

Queue bounded result-quality feedback for staff review. Reports never change public catalog data automatically.

Search query parameters

NameDefaultNotes
qemptySearch text. Empty searches return popular models.
limit48Page size. Use 1 through 240.
offset0Zero-based pagination offset.
sourceemptyFilter to one source ID.
sourcesemptyComma-separated source IDs.
categoryemptyExact normalized category.
group / collapsefalseCollapse likely duplicate uploads across sources.
variantsfalseInclude grouped source variants when available.
sortrelevanceDownloads, likes, views, newest, or default relevance.
deepfalseAlso search description text. Use only when needed.

Advanced search tags

The search box parser also understands inline tags in q. Example: gridfinity author:Zack tag:storage before:2024-01-01.

author: tag: before: after: license: commercial:

Search response

{
  "hits": [],
  "query": "gridfinity",
  "filters": [],
  "offset": 0,
  "limit": 24,
  "grouped": true,
  "shown": 24,
  "estimatedTotalHits": 120000,
  "processingTimeMs": 42,
  "cached": false
}

Model object

{
  "id": "785e340f-b563-4132-9782-924d068096b0",
  "modelId": "668856af-7ecf-4f78-b46c-607c1f375971",
  "groupKey": "author:example",
  "source": "cults",
  "sourceName": "Cults",
  "sourceColor": "#e35b64",
  "sourceFavicon": "https://cults3d.com/favicon.ico",
  "sourceModelId": "external-source-id",
  "url": "https://source-site.example/model",
  "title": "Example model",
  "description": "Short indexed description.",
  "author": "ExampleAuthor",
  "authorUrl": "https://source-site.example/author",
  "category": "Organization",
  "license": "CC BY",
  "commercialAllowed": true,
  "image": "https://cdn.example/image.jpg",
  "tags": ["gridfinity", "storage"],
  "downloads": 1200,
  "likes": 50,
  "views": 8000,
  "publishedAt": "2026-01-01T00:00:00.000Z",
  "indexedAt": "2026-07-30T00:00:00.000Z"
}

Model detail response

{
  "model": {},
  "images": [{ "image_url": "https://..." }],
  "tags": ["gridfinity"],
  "variants": [],
  "relatedByAuthor": [],
  "generatedAt": "2026-07-30T00:00:00.000Z"
}

Search quality feedback

Supported feedback types are not_relevant, duplicate_result, wrong_creator, broken_media, missing_details, and unsafe_preview. Duplicate reports also require comparedSourceModelId. Anonymous and signed-in submissions use separate daily limits.

{
  "sourceModelId": "785e340f-b563-4132-9782-924d068096b0",
  "feedbackType": "broken_media",
  "queryText": "gridfinity",
  "resultPosition": 3,
  "resultPage": 1
}

Signed-in source choice

PATCH /api/auth/profile accepts a modelDiscovery object. It controls which available source copy a grouped card opens automatically, while preserving every source variant in search and model details. An explicit source selected in the search toolbar overrides the account order for that search.

{
  "modelDiscovery": {
    "sourceOrder": ["makerworld", "printables", "thingiverse"],
    "avoidPaidWhenFree": true,
    "preferVerifiedCreator": true,
    "rankingMode": "balanced",
    "neverAutoOpenUnreachable": true
  }
}

Discovery

Homepage, categories, spotlight, and totals

GET/api/discovery

Popular front-page model lanes grouped by source.

GET/api/discover

Discovery browse feed used by the discover page.

GET/api/categories

Normalized category buckets and counts.

GET/api/categories/tree

Hierarchical category tree.

GET/api/taxonomy

Taxonomy metadata used by category UIs.

GET/api/featured

Curated Spotlight models.

GET/api/settings

Public site feature flags.

GET/api/overview

Public index totals and source counts.

GET/api/catalog-quality

Strict per-source creator, description, image, license, scan-progress, and search-reconciliation measurements.

GET/api/health

Lightweight health check.

Discovery parameters

NameDefaultNotes
limitPerSource12Use 1 through 24.
sourceIdemptyBrowse one source instead of all lanes.
limitlimitPerSourceUsed with sourceId. Use 1 through 60.
offset0Used with sourceId.
{
  "sources": [
    {
      "id": "makerworld",
      "name": "MakerWorld",
      "color": "#00b578",
      "favicon": "https://makerworld.com/favicon.ico",
      "total": 2000000,
      "offset": 0,
      "limit": 10,
      "hasMore": true,
      "models": []
    }
  ],
  "cached": true,
  "generatedAt": "2026-07-30T00:00:00.000Z"
}

Collections

Public and signed-in collections

GET/api/collections

Signed-in user's collections.

POST/api/collections

Create a signed-in user's collection.

GET/api/collections/public

Public collection discovery.

GET/api/collections/{collectionId}

Collection details. Public collections are anonymous-readable.

PATCH/api/collections/{collectionId}

Update an owned collection.

DELETE/api/collections/{collectionId}

Delete an owned collection. A linked saved search is preserved.

POST/api/collections/{collectionId}/models

Add a model to an owned collection.

DELETE/api/collections/{collectionId}/models/{sourceModelId}

Remove a model from an owned collection.

POST/api/collections/{collectionId}/like

Like or unlike a collection.

GET/api/collections/{collectionId}/comments

List collection comments.

POST/api/collections/{collectionId}/comments

Add a signed-in collection comment.

PATCH/api/collections/{collectionId}/comments/{commentId}

Edit your collection comment.

DELETE/api/collections/{collectionId}/comments/{commentId}

Delete your collection comment.

POST/api/collections/{collectionId}/comments/{commentId}/vote

Vote on a collection comment.

GET/api/smart-collection-recipes

List guided Smart Collection recipes and public model sources.

POST/api/smart-collection-recipes/{recipeId}/preview

Validate a recipe and preview its current matches without creating a collection.

POST/api/smart-collection-recipes/{recipeId}

Create the saved search and Smart Collection together.

GET /api/collections/public accepts q, limit, and offset. While curated public collections are enabled, curated=1 returns only reviewed Staff Picks and excludeCurated=1 keeps those picks out of a separate ordinary-results request.

Staff publishing tools use GET /api/admin/weekly-reports, POST /api/admin/weekly-reports/generate, PATCH /api/admin/weekly-reports/{reportId}, and explicit blog-draft or publish actions. Generated datasets remain private until a reviewer sends one to the blog, and public publishing is separately feature controlled.

Create/update collection body

{
  "name": "Print Soon",
  "description": "Weekend projects",
  "visibility": "private"
}

Collection object

{
  "id": "collection-id",
  "name": "Print Soon",
  "description": "Weekend projects",
  "visibility": "public",
  "owner_username": "Grim",
  "model_count": 10,
  "images": ["https://..."],
  "curation_status": "featured",
  "curation_theme": "practical",
  "curation_note": "A useful starting point for workshop upgrades.",
  "curation_quality_score": 91,
  "created_at": "2026-07-30T00:00:00.000Z",
  "updated_at": "2026-07-30T00:00:00.000Z"
}

Creator discovery

Creator release history

Release history is available for verified or claimed creators while the feature is enabled. Cross-posts are shown once, with exact source listings retained as variants.

GET/api/authors/{creatorId}/releases

List newest releases with source, date provenance, and known public variants.

Signed-in activity

Watches and activity

These routes use the signed-in account session. Watch previews and tests are read-only and do not move the Watch cursor or send notifications.

GET/api/watches

List model, creator, and saved-search Watches with their recent durable events.

POST/api/watches/preview

Preview a saved search, recent activity level, broad-filter warning, and sample matches before enabling it.

POST/api/watches/{id}/test

Explain what an existing Watch would fire right now without changing its state.

GET/api/watches/digest-preview

Review the next bounded Watch email digest without attempting delivery.

GET/api/activity

Read the unified Watch, collection, comment, and commission activity feed.

Behavior

Errors, pagination, caching, and limits

Common errors

400 Invalid request parameters or body 401 Missing sign-in or API key 403 Valid identity, missing permission or scope 404 Record not found or not visible 429 Rate limit exceeded 500 Server error

Rate-limit headers

API responses, except the health check, include rate-limit headers. Treat X-RateLimit-Reset as the time to retry after a 429.

X-RateLimit-Limit: 240
X-RateLimit-Remaining: 239
X-RateLimit-Reset: 2026-07-30T00:00:00.000Z

Pagination

Most lists use limit and offset. Model search returns estimatedTotalHits and shown.

/api/search?q=frog&limit=48&offset=96

Caching

Some responses include cached and generatedAt. Cached responses are safe to use and are normal for search, discovery lanes, and model details.

Integration tips

  • Use grouping for search interfaces so duplicate uploads collapse into one card.
  • Use variants when you want all known source copies for each grouped result.
  • Use page sizes around 24-48 for interactive UIs.
  • Use deep search only for deliberate advanced searches.
  • Always link users back to the original model URL and show source/license attribution.
  • Do not assume a license allows commercial use. Check commercialAllowed and still point users to the source page.