Quickstart
Four calls from a model to an order. Every call sends the key as a bearer token. A test key (pg_test_...) does everything except make a real order.
1. Send the model
curl https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/v1/files \ -H "Authorization: Bearer pg_test_..." \ -F "file=@bracket.stl"Returns an
id, its size and volume. If the part looks too small, it warns you to check the units; sendunits=inchesto fix it.2. Get a price
curl https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/v1/quotes \ -H "Authorization: Bearer pg_test_..." -H "Content-Type: application/json" \ -d '{"lines":[{"file_id":"FILE_ID","quantity":10,"technology":"SLS","material":"PA12", "black_dye":true,"finishes":["Polish"],"speed":"priority"}]}'The price per part already includes quantity pricing; group and volume discounts come back as their own lines. Split parts that are too big for one build are priced with their bonding. Every line has a ship-by date.
3. See shipping
curl https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/v1/quotes/QUOTE_ID/shipping \ -H "Authorization: Bearer pg_test_..." -H "Content-Type: application/json" \ -d '{"ship_to":{"name":"Jane Buyer","street1":"200 S Biscayne Blvd","city":"Miami","state":"FL","zip":"33131"}}'4. Order it
curl https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/v1/orders \ -H "Authorization: Bearer pg_test_..." -H "Content-Type: application/json" \ -d '{"quote_id":"QUOTE_ID","ship_to":{...},"shipping_option":"UPS:Ground","reference":"PO-1042"}'Returns the order with items, shipping, tax and total. With a live key and a card on file it is charged at once (status
paid); otherwise it has acheckout_urlfor the buyer to pay, and the order starts as soon as it is paid. Then follow it withGET /v1/orders/ORDER_ID.
Try it live
This panel calls the real API from your browser with a public test key. Upload a part, price it, pick shipping, place a test order and pay on Stripe's test checkout with the card 4242 4242 4242 4242. Nothing is charged and nothing is made.
The public sandbox is switched off right now. Paste your own test key (pg_test_...) to use this panel.
1Send a model
2Choose options and get a price
Send a model first.
3Ship to
Get a price first.
4Order and pay
Pick a shipping option first.
Each request and its response shows up here.
Keys and test mode
Test keys, pg_test_...
Real catalog, real measuring, real prices. Shipping rates are made up, payment is Stripe test mode, and orders are pretend: move them along with /simulate to build your status handling.
Live keys, pg_live_...
Real carrier rates, real payment and real orders, made and shipped like any partguys.io order and tied to your PartGuys account.
Get your own keys
- Sign in or create a free account on partguys.io.
- Go to Profile, API access and request access. We review requests within a business day.
- Once approved, make test keys yourself right there, with an optional expiry, and revoke them any time.
- When you are ready to order for real, ask us to turn on live keys for your account. If you want orders charged without a payment page, add a card.
Keep live keys on your server or in your AI app's settings, never in a web page. Send X-PartGuys-Source: mcp on calls made by an MCP server.
Ordering and payment
- Card on file: add a card in Profile, API access and live orders are charged to it the moment they are placed, then go straight into production (status
paid). No payment page, so an app or AI agent can order on its own. Send"payment": "checkout"to get a payment link instead. - Payment link: without a card on file, an order comes back with a Stripe
checkout_urlfor the buyer to pay. Givesuccess_urlandcancel_urlto bring them back to your site;?order_id=is added. - If a saved card is declined or the bank asks the cardholder to confirm, the order comes back with
payment_errorand acheckout_url, and nothing is charged. - Ordering the same quote again returns the order already waiting for payment, so a retried request never makes two.
- Statuses:
awaiting_payment,paid,in_production,ready_to_ship,shipped,delivered,on_hold,cancelled,refunded. Once shipped, the order carries the tracking number and link. - Tax is added for the ship-to state where it applies. An approved tax exemption on your account is honoured.
- Shipping is within the US. Your account may have a per-order and a monthly spending limit; ask PartGuys to change them.
Endpoints
GET | /v1/account | Who the key belongs to, test or live, and its limits. |
GET | /v1/catalog | Technologies, materials, colours, finishes, black dye, speeds with ship days, FDM nozzle and infill. |
POST | /v1/files | Send a model: multipart `file`, or JSON with `content_base64` and `filename`, or a public `url`. Optional `units`. |
GET | /v1/files/{id} | A file and its measurements. |
POST | /v1/uploads | A private link for a person to upload a model from their browser, when your app cannot send the file itself. One link takes up to 20 files and expires in an hour. |
GET | /v1/uploads/{id} | Waiting, partial, done (with the file_id or file_ids) or expired. |
POST | /v1/quotes | Price lines of files with options. Held for 14 days. |
GET | /v1/quotes/{id} | A quote. |
POST | /v1/quotes/{id}/shipping | Shipping options to an address, and the default. |
POST | /v1/orders | Order a quote. Charged to the card on file, or returns a `checkout_url` to pay. |
GET | /v1/orders | Recent orders, newest first. `limit`, `created_before`. |
GET | /v1/orders/{id} | Status, order number, dates and tracking. |
POST | /v1/orders/{id}/cancel | Cancel before it is paid. |
POST | /v1/orders/{id}/simulate | Test keys only. Move a test order to paid, in_production, shipped, delivered and so on. |
Full request and response shapes are in the OpenAPI spec.
Errors
Every error has the same shape: a stable code to branch on and a message a person can act on. Codes are never renamed. Quote the request_id if you contact us.
{ "error": { "code": "invalid_option", "message": "lines[0]: colour \"Black\" is not available in ASA.", "line": 0, "colors": ["White", "Gray"] },
"request_id": "6f1c..." }| Status | Codes | Meaning |
|---|---|---|
| 401 | missing_key, invalid_key, key_revoked, key_expired | No key, a mistyped key, or one that was revoked or has expired. |
| 403 | key_paused, account_paused, account_pending, ordering_disabled | Paused by PartGuys, access not approved yet, or ordering switched off for now. |
| 404 | not_found, unknown_path | No such id for this account, or no such endpoint. |
| 409 | already_ordered, not_cancellable, already_uploaded, confirmation_required, total_changed | The quote was ordered already, the order is paid, the upload link was used, or the total needs confirming or has changed. |
| 410 | quote_expired, file_expired, link_expired | Quote again, upload again, or make a new upload link. |
| 413 / 415 | file_too_large, unsupported_format | Up to 50 MB; STL, 3MF, OBJ or PLY. |
| 422 | invalid_option, invalid_address, rush_below_minimum, order_limit, no_card_on_file, unpriceable, ... | The message says what was refused and how to fix it, and names the line. |
| 429 | rate_limited, quote_limit, sandbox_limit | Wait for Retry-After. |
| 503 | api_paused, maintenance | Nothing wrong with your request; try again after Retry-After. |
MCP and AI agents
PartGuys runs a hosted MCP server, so Claude, ChatGPT, Cursor and other AI apps can quote and order parts with nothing to install. Step-by-step setup for Claude and ChatGPT: Use PartGuys in Claude and ChatGPT. Connect it by signing in with your PartGuys account (or with a key) and ask in plain words, for example "price 10 of this bracket in black nylon and ship it to our Miami office".
Claude Code
claude mcp add --transport http partguys https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/mcp --header "Authorization: Bearer pg_test_..."Claude, ChatGPT and other AI apps: sign in, no key
Add a connector with this address. The app opens a PartGuys page where you sign in (or sign up) and choose real orders or test mode. Nothing to copy, and you can disconnect it any time in Profile, API access.
https://partguys.io/mcpWith an API key instead
For apps that take a header: this address, with the header Authorization set to Bearer pg_test_... (your key).
https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/mcpFor an app that only takes an address, put the key on the end instead: https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/mcp/pg_test_.... Treat that address like a password.
Cursor, Windsurf and other apps (mcp.json)
{
"mcpServers": {
"partguys": {
"url": "https://hskihhpzveqtassiijkt.supabase.co/functions/v1/partguys-api/mcp",
"headers": { "Authorization": "Bearer pg_test_..." }
}
}
}Start with a test key: the agent can run the whole flow, including a Stripe test payment, and nothing is made. Large files: when a model is too big to pass through the chat, the agent gives you a private upload link instead of guessing at the shape, and prices your exact file once you drop it there. With a live key and a card on file, the agent can place the order on its own once you confirm the total. Connected by signing in instead, every order comes back with a checkout page for you to pay.
The tools:
- partguys_get_catalog
- partguys_upload_model
- partguys_create_upload_link
- partguys_get_upload
- partguys_get_quote
- partguys_get_shipping_options
- partguys_place_order
- partguys_get_order
- partguys_list_orders
- partguys_cancel_order
Running your own MCP server instead? mcp-tools.json has the same tools (name, description, input schema and the HTTP call behind each) to expose from it. Send X-PartGuys-Source: mcp on its calls.
