This documentation covers some common use cases for the API, which are outlined in the table of contents below. Where relevant, these use cases include links to endpoints as described in the API documentation.
Create a Quote based on a RequestForQuote while choosing a custom price for the Quote-Lines
Use the Create a Quote based on a RequestForQuote endpoint. Make sure to use the correct service_id
in the URL and requestForQuoteId
in the request body. Provide an array of lines
in the request body, where you will specify a custom unitPrice
for each line.
import requests data = { "requestForQuoteId": 1, "lines": [{"id": 1, "unitPrice": "12.34"}, {"id": 2, "unitPrice": "5.22"}], } url = "https://my-platform.com/api/v2.0/service-panel/services/1/quotes/" requests.post( url, json=data, headers={"Authorization": "Token my-super-secure-token"}, )
Python Example
Upload an Internal Attachment
In this example, we will be uploading a Quote-Attachment, but you can get inspired by this example to upload Attachments for other Sales-Transactions.
Use the Create a Quote-Attachment endpoint. Make sure to use the correct service_id
and quote_id
in the URL. Attach the file, and add isInternal
flag as a query parameter.
import requests files = { "file": open("file.txt", "rb"), } params = { "isInternal": True, } url = "https://my-platform.com/api/v2.0/service-panel/services/1/quotes/1/attachments/" requests.post( url, files=files, params=params, headers={"Authorization": "Token my-super-secure-token"}, )
Python Example
Edit a Quote
In order to edit a quote, you need to:
Create a Basket from the desired Quote using the Create a Basket based on an Quote endpoint
List the Basket-Lines using the List Basket-Lines endpoint
Perform the desired changes to the Basket-Lines using the Update a Basket-Line endpoint
Create a new Quote from the Basket using the Create a Quote based on a Basket (edit mode) endpoint
import requests # 1. Create a Basket from the desired Quote url = "https://my-platform.com/api/v2.0/service-panel/services/1/baskets/from-quote/1/" created_basket = requests.post( url, headers={"Authorization": "Token my-super-secure-token"}, ) customer_id = created_basket.json()["customer"]["id"] basket_id = created_basket.json()["id"] # 2. List the Basket-Lines # In this example, the desired line will be chosen using the filename url = ( f"https://my-platform.com/api/v2.0/service-panel/services/1/baskets/{basket_id}/lines/" ) lines = requests.get( url, headers={"Authorization": "Token my-super-secure-token"}, ) desired_basket_line = next( ( line for line in lines.json() if line["file"]["originalFileName"] == "Drone_V2_Print_Arm_A_x6.stl" ) ) desired_basket_line_id = desired_basket_line["id"] # 3. Perform the desired changes to the Basket-Lines # In this example, the unitPrice will be changed data = { "unitPrintPrice": "46.50", } url = f"https://my-platform.com/api/v2.0/service-panel/services/1/baskets/{basket_id}/lines/{desired_basket_line_id}/" requests.patch( url, json=data, headers={"Authorization": "Token my-super-secure-token"}, ) # 4. Create a new Quote from the Basket data = { "basketId": basket_id, "userId": customer_id, } url = f"https://my-platform.com/api/v2.0/service-panel/services/1/edit-quote/" requests.post( url, json=data, headers={"Authorization": "Token my-super-secure-token"}, )
Python Example
Below there are some examples, on how to edit some of the attributes of a Basket-Line.
How to change the price of a Basket-Line
data = { "unitPrintPrice": "46.50", } url = f"https://my-platform.com/api/v2.0/service-panel/services/1/baskets/1/lines/1/" requests.patch( url, json=data, headers={"Authorization": "Token my-super-secure-token"}, )
Python Example
How to change the material of a Basket-Line
List the available Material-Offers using the List Material-Offers endpoint. Get the ID of the desired offer, and then use it in the payload body of the update request. Make sure to set autoSetPrice
to True
in the payload body, so that the price of the material is calculated.
# 1. List the available Material-Offers # In this example, the desired material will be chosen using it's name url = f"https://my-platform.com/api/v2.0/service-panel/services/1/offers/" material_offers = requests.get( url, headers={"Authorization": "Token my-super-secure-token"}, ) desired_material_offer = next( ( offer for offer in material_offers.json() if offer["materialName"] == "Accura Xtreme" ) ) desired_material_offer_id = desired_material_offer["id"] # 2. Send the update request data = { "offerId": desired_material_offer_id, "autoSetPrice": True, } url = f"https://my-platform.com/api/v2.0/service-panel/services/1/baskets/1/lines/1/" requests.patch( url, json=data, headers={"Authorization": "Token my-super-secure-token"}, )
Python Example
How to change the post-processings of a Basket-Line
List the available Post-Processings for a material that is assigned to a given Basket-Line, using the List Post-Processings for a Material-Offer endpoint. Get the ID of the desired Post-Processing, and then use it in the payload body of the update request. Make sure to set autoSetPrice
to True
in the payload body, so that the price of the Post-Processing is calculated.
# 1. List the available Post-Processings # In this example, the desired Post-Processing will be chosen using it's title url = f"https://my-platform.com/api/v2.0/service-panel/services/1/offers/1/post-processings/" post_processings = requests.get( url, headers={"Authorization": "Token my-super-secure-token"}, ) desired_post_processing = next( ( post_processing for post_processing in post_processings.json() if post_processing["title"] == "Polishing" ) ) desired_post_processing_id = desired_post_processing["id"] # 2. Send the request data = { "postProcessings": [ {"postProcessingId": desired_post_processing_id, "autoSetPrice": True} ], } url = f"https://my-platform.com/api/v2.0/service-panel/services/1/baskets/1/lines/1/" response = requests.patch( url, json=data, headers={"Authorization": "Token my-super-secure-token"}, )
Python Example
Upload a File into a Basket
For as many files as you would like to add, follow the steps below:
Upload a 3D File into the basket line (Use Option 2).
Use the Get file status endpoint to wait until the file is analysed.
Programmatically upload files and redirect your users to the 3YOURMIND frontend
If your application generates 3D data and you want to use the Order Management System, you may want to upload 3D models and redirect the user to the 3YOURMIND platform.
The workflow for this is:
Let your users click on a button like "Order with 3YOURMIND"
Upload a file with the Upload 3D File endpoint.
Redirect the user to the URL returned in the response (or open a browser with the URL)
Place Orders Programmatically
This is useful when the order is created in another system and should be placed in the 3YOURMIND system for tracking and processing.
You can place entire orders programmatically. There are 2 different workflows for creating orders:
Place order with User Panel API
This is the older legacy API. Use it if you want to offer your customers a UI for creating orders, that is very similar to the 3yourmind User Panel.
Place order with Service Panel API
This is the newer API, it is easier to work with. Use it if you want to interface with the 3yourmind API, from some other backend service, or if you already have your own UI for order creation.
Place order with User Panel API
Do all the steps in Upload a file
For every line: Update the basket line to set an offer and post-processing.
(optional) Create Shipping and billing addresses.
(optional) Check the order total with the Get Basket Price endpoint.
Create order for basket. Depending on your Printing Service, you will have to choose:
way of delivery
and a Payment method.
Place order with Service Panel API
Choose user for which to create order (from all users of the service). Fetch users - GET
Assign the previous chosen user to the basket Update basket with user - PATCH
Get addresses of the user, choose address for this order Fetch addresses of user - GET
Choose payment method Fetch available payment methods - GET
Choose shipping method Fetch available shipping methods - GET
Choose material for this line Fetch available materials - GET
Update print price and material/offer and post processings for this line - PATCH
Wait until file upload has finished, periodically call this endpoint (each 1s): Fetch the file upload status - GET
Submit the final order, that links all previous steps together
See the following code, as an example of all the steps. It is written as JetBrains .http file format, even if you can not execute with your IDE, you can still read the code examples in it.
### < {% client.global.set("token", "dd247ae0d9cddcefa32e3ef502c4798b6ae531d8"); client.global.set("service_id", "1"); %} GET http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/internal-ordering/users/?search=Ortega Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("customer_id", response.body.results[0].id); client.log(JSON.stringify(client.global["vars"]["customer_id"])) %} ### POST http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/baskets/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("basked_id", response.body.id); client.log(JSON.stringify(client.global["vars"]["basked_id"])) %} ### PATCH http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/baskets/{{basked_id}}/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} { "customer_id": {{customer_id}} } ### GET http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/internal-ordering/users/{{customer_id}}/addresses/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("customer_address_id", response.body[2].id); client.log(JSON.stringify(client.global["vars"]["customer_address_id"])) %} ### GET http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/payment-methods/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("payment_method_id", response.body[0].id); client.log(JSON.stringify(client.global["vars"]["payment_method_id"])) %} ### GET http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/shipping-methods/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("shipping_method_id", response.body[0].id); client.log(JSON.stringify(client.global["vars"]["shipping_method_id"])) %} ### GET http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/offers/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("offer_id", response.body[0].id); client.log(JSON.stringify(client.global["vars"]["offer_id"])) %} ### POST http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/baskets/{{basked_id}}/lines/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} > {% client.global.set("line_id", response.body.id); client.log(JSON.stringify(client.global["vars"]["line_id"])) %} ### PATCH http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/baskets/{{basked_id}}/lines/{{line_id}}/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} { "offer_id": {{offer_id}}, "postProcessings": [], "unitPrintPrice": "12.34" } ### POST http://multi.my.3yd/api/v2.0/files/ Content-Type: multipart/form-data; boundary=boundary --boundaryd Content-Disposition: form-data; name="file"; filename="test_areas (copy).stl" Content-Type: model/x.stl-binary < ./cube_10_inch.stl --boundary Content-Disposition: form-data; name="basket_id" {{basked_id}} --boundary Content-Disposition: form-data; name="line_id" {{line_id}} --boundary Content-Disposition: form-data; name="unit" inch ### GET http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/baskets/{{basked_id}}/lines/{{line_id}}/file-status/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} ### POST http://multi.my.3yd/api/v2.0/service-panel/services/{{service_id}}/internal-ordering/orders/ Accept: application/json Content-Type: application/json Authorization: Token {{token}} { "additionalInformation": { "reference": "some test reference" }, "basketId": {{basked_id}}, "billingAddressId": {{customer_address_id}}, "pickupLocationId": null, "fees": [], "shippingPrice": "12.34", "shipping": { "methodId": {{shipping_method_id}}, "addressId": {{customer_address_id}}, "deliveryInstructions": "string" }, "payment": { "methodId": {{payment_method_id}}, "authorizedAmount": "12.34", "currency": "EUR", "details": { } }, "voucherCode": null, "userId": {{customer_id}} }
example.http
Place Orders from a Catalog Item
Instead of uploading 3D files, you can order files from the catalog.
Instead of uploading the 3D Files, you can add items from the Catalog to the basket. The workflow to place an order from the Digial catalog is as follows:
Create a basket line with an
catalogItemId
in the payload.(optional) Update the basket line and overide the offer and post-processing.
(optional) Create Shipping and billing addresses.
(optional) Check the order total with the Get Basket Price endpoint.
Create / List Customers Programmatically
Either create a customer data set (by creating a user and disabling email sending for that user) or invite a new user to use the platform. All existing customers can also be obtained.
The Organization Users endpoints are for creating and updating User information. In order to use those endpoints, the user with the ApiToken needs to have the "Organization Admin" Role.
Further information about this use case can be found in the linked documentation: Organization Users
Get Prices for 3D Models
You can obtain prices for 3D models using the REST API. For this, please follow the steps outlined below:
Complete all the steps in Upload a file
Get pricing information by reaching the below endpoints:
Materials using List materials
Services with List offers
Post-processings with Get an offer
Prices are calculated by the 3YOURMIND pricing engine which can be configured / scripted in the service panel.
Analyze and Optimize 3D Models
Upload 3D files to get printability information (wall thickness check, bounding box check, multi-shell check), geometric information (volume, area, dimensions, convex hull, concave hull, etc.) and the optimized 3D file (using our mesh healing algorithms).
After uploading a 3D file our backend optimizes and analyzes it. You can then retrieve its parameter and printability details.
Upload a 3D File, using option one in the linked API specification. You do not need to redirect the user to our frontend.
Wait until the file has been processed by repeatedly requesting Get File Optimization Status.
Use any of the other 3D Files endpoints to get information about:
Printability
3D model parameter, like volume and surface area
Download links
Transfer Sales Transactions into Another System
A user of your application placed requests, quotes or orders in 3YOURMIND's system and you want to transfer the data information to your ERP, CRM, accounting or similar system. Depending on your data receiving System and your real-time requirements you can use one of the two following options:
CSV Export: Recommended for integrations to systems with CSV interface (polling)
Webhooks: Recommended for integrations that can receive HTTP callbacks (event driven)