The MeshWeave converter, from your own server. SolidWorks, STEP, Parasolid, IGES, Rhino, STL, OBJ and 3MF in; the format your product needs out. One key, two endpoints, billed by the month.
25 conversions a month free on any account. No card to try it.
Create free account then API keys… in the account menu.
Extras on top of a conversion (Fine or Ultra detail, repair, a larger triangle budget) are paid in credits, as on the pricing page; each API plan includes credits every month, and each key has its own credit ceiling.
POST /api/convert with the file and a target_format. The answer is 202 with a job id.GET /api/convert-job/<id> until it is not 202. A 200 is the converted file.curl -s https://meshweave.app/api/convert \
-H "Authorization: Bearer $MESHWEAVE_API_KEY" \
-F file=@bracket.step \
-F target_format=stl
# 202 {"job": "3f9c0a1e5b7d2c4e6a8f0b1d"}curl -s -o bracket.stl -w "%{http_code}\n" \
-H "Authorization: Bearer $MESHWEAVE_API_KEY" \
https://meshweave.app/api/convert-job/3f9c0a1e5b7d2c4e6a8f0b1d
# 202 while it runs; 200 with the file when done; 4xx/5xx with {"detail": "..."} if notimport os, time, httpx
API = "https://meshweave.app"
HEAD = {"Authorization": f"Bearer {os.environ['MESHWEAVE_API_KEY']}"}
def convert(path: str, target: str) -> bytes:
with httpx.Client(base_url=API, headers=HEAD, timeout=60, follow_redirects=False) as c:
with open(path, "rb") as f:
r = c.post("/api/convert", files={"file": f}, data={"target_format": target})
r.raise_for_status()
job = r.json()["job"]
deadline = time.time() + 600
while time.time() < deadline:
r = c.get(f"/api/convert-job/{job}")
if r.status_code == 202:
time.sleep(2)
continue
if r.status_code == 200:
return r.content
raise RuntimeError(r.json().get("detail", r.text))
raise TimeoutError(job)POST /api/convertMultipart form. file (required), target_format (required, e.g. stl, step, 3mf), and the same options the converter page offers: quality (standard, fine, ultra), repair (1), target_release (a SolidWorks year, for SLDPRT out). Always answers 202 {"job": id} or an error; it never holds the connection while it converts.
GET /api/convert-job/<id>202 {"status": "running", "elapsed": s} while it runs; 200 with the file (its name in Content-Disposition) when done; the conversion's error when not. Results are kept for a short while, then deleted.
GET /api/convert/formatsEvery input format and what it can become.
GET /api/api-usageThis month: used, included, hardCap, overage, inflightLimit. The same count rides on every API answer as X-MeshWeave-Quota-Used, -Included and -Limit.
The live list is at GET /api/convert/formats.
Every error has a JSON body {"detail": "..."} written for a person: log it or show it.
400 | The file or the format pair cannot be converted; or a key was sent in a URL (that key is then marked exposed). |
401 | The key is not valid, has expired or was revoked. |
402 | The month’s limit for the plan is reached, or the key’s credit ceiling for extras. |
403 | The key may not call this path, the request came from an address off the key’s list, or from a web page. |
404 | No such job, or it belongs to another account. |
409 | The file needs a choice first (several bodies, a triangle budget); the body says which. |
413 | The file is larger than the plan converts. |
429 | Too many requests a minute, or too many conversions running at once. Wait for Retry-After. |
Authorization: Bearer <key>. A key found in a URL is refused and marked exposed, because URLs are logged.Origin is refused: a key in a web page can be read by anyone who opens it.See also the privacy policy, the terms and the refund policy.