Reverse-engineered GraphQL API for Printables.com. Prusa, please bless this and provide official API documentation!
View feeds at https://dyn.tedder.me/rss/printables/
Endpoint: https://api.printables.com/graphql/
Required headers:
content-type: application/json
graphql-client-version: v1.0.96
origin: https://www.printables.com
The graphql-client-version header appears to be required — requests without it may fail or return errors.
No API key or authentication token is needed for read-only public data. The code has commented-out authorization and client-uid headers captured during reverse-engineering, but they are not required.
The API supports GraphQL introspection, so you can discover available queries:
curl -s -X POST 'https://api.printables.com/graphql/' \
-H 'content-type: application/json' \
-H 'graphql-client-version: v1.0.96' \
-H 'origin: https://www.printables.com' \
-d '{"query":"{ __schema { queryType { fields { name } } } }"}'Fetching a user's models is a two-step process: resolve the handle to a numeric user ID, then query models filtered by that ID.
Use searchUsers2 with the username as a query string. The result is paginated under items.
curl -s -X POST 'https://api.printables.com/graphql/' \
-H 'content-type: application/json' \
-H 'graphql-client-version: v1.0.96' \
-H 'origin: https://www.printables.com' \
-d '{
"operationName": "SearchUsers",
"query": "query SearchUsers($query: String!) { searchUsers2(query: $query, limit: 5) { items { id publicUsername handle } } }",
"variables": {"query": "CADGuy"}
}'Response:
{
"data": {
"searchUsers2": {
"items": [
{"id": "251219", "publicUsername": "CADGUY88", "handle": "CADGUY88"},
{"id": "218560", "publicUsername": "CAD-Guy", "handle": "CADGuy"},
...
]
}
}
}Match the result where handle equals the target (case-insensitive). For @CADGuy, the ID is 218560.
Note: publicUsername is the display name; handle is the URL slug used in printables.com/@handle.
Pass userId to the morePrints query. Omit publishedDateLimitDays to get all models, not just recent ones.
curl -s -X POST 'https://api.printables.com/graphql/' \
-H 'content-type: application/json' \
-H 'graphql-client-version: v1.0.96' \
-H 'origin: https://www.printables.com' \
-d '{
"operationName": "ModelList",
"query": "query ModelList($limit: Int!, $cursor: String, $userId: ID, $ordering: String) { models: morePrints(limit: $limit, cursor: $cursor, userId: $userId, ordering: $ordering) { cursor items { id name slug firstPublish downloadCount likesCount } } }",
"variables": {
"limit": 36,
"cursor": null,
"userId": "218560",
"ordering": "-first_publish"
}
}'The response includes a cursor string. Pass it as cursor in subsequent requests to get the next page. When cursor is null in the response, you've reached the end.
{
"data": {
"models": {
"cursor": "MjAyMy0wNy0yM...",
"items": [ ... ]
}
}
}| Value | Description |
|---|---|
-first_publish |
Newest first |
-likes_count_30_days |
Trending (30-day likes) |
-rating_avg |
Top rated |
-download_count_30_days |
Most downloaded (30 days) |
| Parameter | Type | Description |
|---|---|---|
userId |
ID | Filter to a specific user's models |
categoryId |
ID | Filter by category |
publishedDateLimitDays |
Int | Only return models published within N days — omit for all-time |
featured |
Boolean | Only featured models |
paid |
PaidEnum | Filter free vs. paid models |
cursor |
String | Pagination cursor from previous response |