API Reference
https://api.tryar.in

API Reference

The MakerWorld Estimator API provides endpoints for fetching filament presets, scraping model metadata from MakerWorld, uploading geometry files for instant cost estimates, and querying the community directory and leaderboard.

REST JSON multipart/form-data No signup required

Authentication

Most endpoints are open. If the server administrator has set the API_KEY environment variable, all requests must include one of these headers:

HTTP
Authorization: Bearer YOUR_API_KEY
# — or —
X-API-Key: YOUR_API_KEY
Rate limiting: The /api/estimate/upload endpoint is rate-limited to 5 requests per minute per IP. All other endpoints are unrestricted.

Endpoint Index

MethodPathDescription
GET / Service health check & link directory
GET /api/presets Filament colours, multipliers, hardware kits
GET /api/detect-currency Geo-IP currency resolution
GET /api/models Searchable model directory index
GET /api/leaderboard All-time popular & weekly trending models
GET /api/scrape MakerWorld model scrape & DB cache
GET /api/scrape/collection Scrape all models in a MakerWorld collection
POST /api/estimate/upload Upload STL / 3MF and get cost estimate

All responses use Content-Type: application/json. The upload endpoint accepts multipart/form-data.

Service Status

Returns a 200 OK when the service is up, along with a directory of all endpoint paths and links.

GET https://api.tryar.in/

Request

cURL
curl https://api.tryar.in/

Response 200 OK

JSON
{
  "status": "OK",
  "name": "MakerWorld Estimator API",
  "version": "1.0.0",
  "endpoints": {
    "presets": "/api/presets",
    "detectCurrency": "/api/detect-currency",
    "models": "/api/models",
    "leaderboard": "/api/leaderboard",
    "scrape": "/api/scrape?url={model_url}",
    "upload": "/api/estimate/upload"
  },
  "links": {
    "homepage": "https://estimator.tryar.in",
    "docs": "https://estimator.tryar.in/api.html"
  }
}

Get Presets

Returns the shared filament colour lookup table (name, hex, cost multiplier) and hardware kit accessory presets consumed by the frontend and browser extensions.

GET https://api.tryar.in/api/presets

Request

cURL
curl https://api.tryar.in/api/presets

Response 200 OK

JSON
{
  "presetColors": [
    {
      "hex":        "#000000",
      "name":       "Basic Black",
      "multiplier": 1
    },
    {
      "hex":        "#ffd700",
      "name":       "Silk Gold",
      "multiplier": 1.5
    }
  ],
  "hardwarePresets": [
    {
      "keyword": "keychain",
      "name":    "Keychain Ring",
      "cost":    5
    }
  ]
}

Detect Currency

Resolves a billing currency from the incoming request's geographic headers (set automatically by Cloudflare). Returns the detected country code and mapped currency string.

GET https://api.tryar.in/api/detect-currency

Request

cURL
curl https://api.tryar.in/api/detect-currency
# Cloudflare sets CF-IPCountry automatically.
# Override for local testing:
curl -H "CF-IPCountry: US" \
     https://api.tryar.in/api/detect-currency

Response 200 OK

JSON
{
  "success": true,
  "country":  "US",
  "currency": "USD"
}

// Supported mappings:
// IN → INR | US → USD | GB → GBP
// DE,FR,IT,ES → EUR | JP → JPY
// AU → AUD | CA → CAD | SG → SGD
// Fallback for all other countries → USD

Models Directory

Returns a list of cached/indexed print profiles from the database. Supports full-text search on model titles and creator names, plus sort ordering.

GET https://api.tryar.in/api/models

Query Parameters

ParameterTypeRequiredDefaultDescription
q string optional Search keyword matched against model title and creator name.
sort string optional popular Sort order. One of: popular · recent · weight · time · price_asc · price_desc
min_price number optional Filter models with estimated cost greater than or equal to this amount.
max_price number optional Filter models with estimated cost less than or equal to this amount.

Request

cURL
curl "https://api.tryar.in/api/models\
  ?q=keychain&sort=popular"

Response 200 OK

JSON
{
  "success": true,
  "models": [
    {
      "profileId":     1254079,
      "modelId":       1717122,
      "modelName":     "Lamborghini Keychain",
      "modelImage":    "https://...",
      "profileName":   "Default Profile",
      "printTimeHours": 0.63,
      "weightGrams":   10,
      "plateCount":    1,
      "estimatedCost": 150,
      "creatorName":   "3DSpec_pl",
      "license":       "Standard Digital File License",
      "cleanUrl":      "https://makerworld.com/en/models/1717122"
    }
  ]
}

Leaderboard

Returns the top 10 all-time models ranked by calculation count, and the top 10 trending models calculated within the last 7 days.

GET https://api.tryar.in/api/leaderboard

Request

cURL
curl https://api.tryar.in/api/leaderboard

Response 200 OK

JSON
{
  "success": true,
  "topAllTime": [
    {
      "profileId":        1254079,
      "modelName":        "Lamborghini Keychain",
      "estimatedCost":    150,
      "calculationCount": 120
    }
  ],
  "trending": [
    {
      "profileId":           1254079,
      "modelName":           "Lamborghini Keychain",
      "estimatedCost":       150,
      "recentCalculations":  45
    }
  ]
}

Scrape & Cache

Fetches print profile metadata directly from the MakerWorld JSON API for a given model URL, caches the result in the database, and returns structured plate and filament data.

GET https://api.tryar.in/api/scrape

Query Parameters

ParameterTypeRequiredDefaultDescription
url string required Full MakerWorld model URL. Model ID is extracted via /\/models\/(\d+)/
nocache boolean optional false Set to true to bypass DB cache and force a fresh fetch.

Request

cURL
curl "https://api.tryar.in/api/scrape\
  ?url=https%3A%2F%2Fmakerworld.com\
       %2Fen%2Fmodels%2F1717122"

# Force cache bypass:
curl "https://api.tryar.in/api/scrape\
  ?url=...&nocache=true"

Response 200 OK

JSON
{
  "success":        true,
  "modelName":      "Lamborghini Keychain",
  "profileId":      1254079,
  "profileName":    "Default Profile",
  "printTimeHours": 0.63,
  "weightGrams":    10,
  "plateCount":     1,
  "plates": [
    {
      "index":      1,
      "prediction": 2280,
      "weight":     10,
      "filaments": [
        { "type": "PLA", "color": "#ffdd00", "usedG": 10 }
      ]
    }
  ],
  "license":  "Standard Digital File License",
  "cleanUrl": "https://makerworld.com/en/models/1717122"
}

Scrape Collection

Fetches MakerWorld collection details and batch-scrapes/looks up all models in the collection in parallel. If any individual model fails to scrape, its error is captured and returned inside the models array so that the rest of the collection continues to compute.

GET https://api.tryar.in/api/scrape/collection

Query Parameters

ParameterTypeRequiredDefaultDescription
urlstringrequiredFull URL of the MakerWorld collection page (e.g. https://makerworld.com/en/collections/27910720-large-prints).
nocachebooleanoptionalfalseSet to true to force fresh MakerWorld fetches for each model.

Request

cURL
curl "https://api.tryar.in/api/scrape/collection?url=https://makerworld.com/en/collections/27910720-large-prints"

Response 200 OK

JSON
{
  "success": true,
  "isCollection": true,
  "collectionId": 27910720,
  "collectionTitle": "Large Prints",
  "creatorName": "Hirawat",
  "models": [
    {
      "success": true,
      "modelName": "Borsa Summer (Style Bogg)",
      "printTimeHours": 2.04,
      "weightGrams": 140.2,
      "estimatedCost": 120.0
    }
  ]
}

Upload & Estimate

Accepts a 3D geometry file (.stl or .3mf) via multipart/form-data, parses slicing metadata, and returns a full cost breakdown. For .3mf files containing BambuStudio metadata, exact print times and filament weights are extracted directly — no slicing heuristics applied.

POST https://api.tryar.in/api/estimate/upload
Rate limited: 5 requests per minute per IP address. Exceeding this returns 429 Too Many Requests.

Request Body — multipart/form-data

FieldTypeRequiredDefaultDescription
fileFilerequired.stl or .3mf file, max 15 MB.
qtyintegeroptional1Print quantity. Used to calculate bulk plate-sharing capacity.
timeRatefloatoptional50Hourly printer operational rate.
weightRatefloatoptional2.0Filament cost per gram.
plateFeefloatoptional20Setup fee per build plate run.
multicolorFeefloatoptional30AMS filament-swap fee per colour change.
labourFeefloatoptional0Flat-rate manual handling charge.
profitMarginfloatoptional0Profit margin percentage added on top of subtotal.
roundingFactorfloatoptional10Round final cost to the nearest n.
currencySymbolstringoptional"Rs."Symbol embedded in formula output string.
currencystringoptional""Optional 3-letter currency code (e.g., USD, EUR, JPY) to resolve the exchange rate.

Request

cURL
curl -X POST \
  https://api.tryar.in/api/estimate/upload \
  -F "file=@./my_model.stl" \
  -F "qty=5" \
  -F "timeRate=60" \
  -F "weightRate=2.5" \
  -F "currencySymbol=₹"

JavaScript

JavaScript
const fd = new FormData();
fd.append('file', fileInput.files[0]);
fd.append('qty',      '5');
fd.append('timeRate', '60');

const res = await fetch(
  'https://api.tryar.in/api/estimate/upload',
  { method: 'POST', body: fd }
);
const data = await res.json();
console.log(data.pricing.estimatedCost);

Response 200 OK

JSON
{
  "success":  true,
  "filename": "my_model.stl",
  "type":     "STL",
  "parsedData": {
    "weightGrams":     45.2,
    "printTimeHours":  1.25,
    "printTimeSeconds":4500,
    "widthMm":         50.5,
    "lengthMm":        45.0,
    "heightMm":        22.0,
    "isFromMetadata":  false,
    "filaments": [
      {
        "type":       "PLA",
        "color":      "#10b981",
        "usedG":      45.2,
        "name":       "Emerald Green",
        "multiplier": 1
      }
    ]
  },
  "pricing": {
    "qty":            5,
    "estimatedCost":  160.0,
    "currencySymbol": "₹",
    "totalTimeCost":  75.0,
    "totalMaterialCost": 90.4,
    "plateCost":     0,
    "subtotal":      152.9,
    "formula":       "5 unit(s) · 1.25h · ₹160",
    "savings":       0
  }
      
      

GET POST /api/user/presets

Fetch or save custom pricing defaults (time rate, weight rate, plate fee, multicolor fee, labour fee, profit margin, currency) for a logged-in user.

JSON Response (GET /api/user/presets)
{
  "success": true,
  "presets": {
    "timeRate": 50,
    "weightRate": 2,
    "plateFee": 20,
    "multicolorFee": 30,
    "labourFee": 0,
    "profitMargin": 0,
    "currency": "INR"
  }
}

GET POST /api/user/api-key

Retrieve or generate a user-scoped API Key (usr_...) for authenticating programmatic requests to /api/scrape and /api/estimate/upload.

JSON Response
{
  "success": true,
  "apiKey": "usr_a1b2c3d4e5f67890"
}

Response Status Codes

Standard HTTP status codes indicate the outcome of each request.

200OKRequest succeeded. Body contains the response data.
400Bad RequestMissing required fields, invalid file extension, or malformed parameters.
401UnauthorizedAPI key authentication failed. Check your Authorization or X-API-Key header.
413Payload Too LargeUploaded file exceeds the 15 MB maximum size limit.
429Too Many RequestsIP rate limit exceeded (5 uploads/min). Wait 60 seconds before retrying.
500Internal ErrorFile parsing failed or an unexpected server error occurred.