Ponoko

Developer Resources

API documentation

» Introduction
» Materials catalog
» Uploading a product
» Making a product
» Updating a product
» Order history
» Test users
» Debugging


Introduction

We are loosely following REST principles in that all requests are either GET or POST. Requests are made over SSL. This ensures all information you pass to the API is encrypted, including the URL. To keep things as simple as possible, data is passed to the API as URL encoded parameters.

Authentication

Include your Simple access keys as URL Parameters with each API call to be granted access your Personal Factory. These keys are found on your App's detail page.

app_key=abcdefgh&user_access_key=stuvwxyz
            

We're also using the current industry standard of OAuth to grant applications access to user accounts. When you register your application with ponoko.com it will be granted immediate access to your user account to make it easy for you to get started.

At this stage your application can only access products it adds to a user's account. Your application cannot access anything the user has created themselves.

Response format

All responses are in JSON. See http://json.org/ for more information.

Object identification

We identify all objects through the API uniquely using long strings called 'keys'.

Anything you create via the API has an associated reference field ('ref'). You can use this to store your own unique reference for the created object. The field allows for a 255 character string.

You can use your reference instead of our 'key' wherever you see a 'key' variable in the PATH of an API call or as a parameter.

Required fields

Unless stated otherwise, you need to fill in all the parameters listed for an object when you create it. If you miss any, you'll get an error response instead of a created object.

Updating objects

You don't have to pass in all data fields when updating an object's data, such as a product name. Only the passed in fields will be changed.

Curl examples

The Curl examples are constructed with the “-d” or “-F” parameters for passing data. This makes them more readable. We've left out the Simple access authentication keys in these examples ‒ you'll need to include your own like this:

-d "app_key=abcdefgh" \
-d "user_access_key=stuvwxyz" \
            

Not used Curl before? This is a handy reference resource: http://linux.about.com/od/commands/l/blcmdl1_curl.htm

Passing arrays

Arrays of information are passed in the URL parameters like this:

-d “products[][key]=1234” \
-d “products[][quantity]=1” \
-d “products[][key]=5678” \
-d “products[][quantity]=5” \
            

Note the empty square brackets? This is what defines the array. The order of the keys is important too, so make sure you keep to the order shown in this document.

Errors

If a request fails, error information explaining the reason will appear in the JSON response like this:

{
  "error": {
    "message": "Bad Request. Error processing design file(s).",
    "errors": [
      {
        "name": "broken_design.stl",
        "error_code": "unfixable_mesh_errors",
        "type": "design_processing"
      }
    ], 
    << extra info >>
  }
}
              

"errors" is optionally returned when there is more than one problem, such as with multiple designs.

The << extra info >> above is for things such as key, ref and/or file names so you can trace the error more easily. See API error responses and Design file warnings and errors for more information.

Base URL

We have a sandbox server for you to test your application:
https://sandbox.ponoko.com/services/api/v2

Once we've granted your application live access, you'll need to switch to using this url:
http://www.ponoko.com/services/api/v2

Logging into the Sandbox

You can log into the sandbox server with your usual email address and password here:
https://sandbox.ponoko.com/account/login

Note: this is a cut down version of the live website focused on App development.

API reference

Don't forget to checkout the API reference section which contains a complete listing of supported countries, order events, design file errors and their meanings etc...


top
Materials catalog

You must specify which material is to be used when you make a design with ponoko.com. In order to do this, you'll first need to download the materials catalog from your preferred making node.

Find a node

The 'find a node' feature gives you a list of available making nodes the associated user account can access.

GET /nodes

No parameters.

Curl example

curl https://sandbox.ponoko.com/services/api/v2/nodes

Response example

{"nodes": [{"key": "2413", 
            "name": "Ponoko USA", 
            "materials_updated_at": "2011/01/01 12:00:00 +0000"}, ...]}

The 'materials_updated_at' field lets you know when that node's materials catalog was last changed. This means you can cache the catalog easily and only download it again when it's updated.

Download materials catalog

This feature returns the entire materials catalog for a given node.

GET /nodes/material-catalog/<< node key >>

No parameters.

Curl example

curl https://sandbox.ponoko.com/services/api/v2/nodes/material-catalog/2413

Response example

{"node_key": "1234", 
 "materials": [{"key": "1234", 
                "name": "cardboard", 
                "type": "sheet", 
                "updated_at": "2011/01/01 12:00:00 +0000", 
                <type specific data>}, ...]}

Response fields of note

  • • type specific data - will contain extra fields directly relevant to the type of material being described. See Material catalog responses for more information.
  • • updated_at – this is really important as it will help you sync changes into your cached copy of the catalog easily.


top
Uploading a product

Orders are placed for a product which is a collection of design files. Materials used to make the product can only be sourced from a single node. In other words, you can't use wood from one node and plastic from another when defining the product. Once created, a product will always 'know' its making cost, even when designs and materials are changed.

Products are added to the user's account you are accessing via OAuth.

Create the whole product in one step

This is the preferred way to create products as it combines all information, including all designs and their chosen materials, into the single API call.

POST /products

Parameters

• name - we suggest you use a file name if you don't know what to call it
• description - not required, although recommended
• ref
• designs - an array of designs
  ○ ref
  ○ file_name
  ○ uploaded_data
  ○ quantity
  ○ material_key
  ○ units - "mm" or "inches"

Curl example

curl -F "name=Lamp"\
     -F "notes=some%20long%20note%20about%20the%20design" \
     -F "ref=2413" \
     -F "designs[][ref]=42" \
     -F "designs[][file_name]=teapot.stl" \
     -F "designs[][uploaded_data]=@teapot.stl" \
     -F "designs[][quantity]=1" \
     -F "designs[][material_key]=2413" \
     -F "designs[][units]=mm" \     
     -F "designs[][ref]=11b" \
     -F "designs[][file_name]=ruler.eps" \
     -F "designs[][uploaded_data]=@ruler.eps" \
     -F "designs[][quantity]=2" \
     -F "designs[][material_key]=2413" \ 
     https://sandbox.ponoko.com/services/api/v2/products

Note: this example is passing two design files - the formatting of the parameters is important and continues the same way for any number of designs.

'Units' is only required for STL and WRL file formats.

Response example

{"product": {"key": "1234", 
             "ref": "4321", 
             "node_key": "1234", 
             "name": "tea pot, 
             "notes": "has a special non-drip spout", 
             "created_at": "2011/01/01 12:00:00 +0000", 
             "updated_at": "12011/01/01 12:00:00 +0000", 
             "locked?" :"false", 
             "materials_available?": true, 
             "designs": [{"key": "1234", 
                          "ref": "4321", 
                          "created_at": "2011/01/01 12:00:00 +0000", 
                          "updated_at": "2011/01/01 12:00:00 +0000", 
                          "size": 9999, 
                          "file_name": "teapot.stl", 
                          "units": "mm",
                          "quantity": 1, 
                          "content_type": "application/postscript", 
                          "material_key": "1234", 
                          "unmakable_materials": ["4321"],
                          "make_cost": {"currency": "USD", 
                                        "making": "56.78", 
                                        "materials": "56.78", 
                                        "total": "56.78"}}], 
             "design_images": [{"file_name": "teapot.stl.png"}],
             "total_make_cost": {"currency": "USD", 
                                 "making": "56.78", 
                                 "materials": "56.78", 
                                 "hardware": "0.0",
                                 "total": "113.56"},
             "urls": {"view": "http://www.ponoko.com/products/show/1234",
                      "make": "http://www.ponoko.com/make/new/1234"}}

Response fields of note

• locked? - products are 'locked' while they are being made and this is reflected in this field. A product cannot be changed while it is locked.
• materials_available? - this becomes 'false' when a material used in a product is no longer available.
• unmakable_materials - lists materials that a 3D design can't be made with.

Comments

A product will not be created if there are any errors when uploading. Generally, this means the design files contain problems which make them unprintable. The error response you see will be the same as for users of www.ponoko.com, see Design file warnings and errors for more information.

Designs can be added without a material specified, but for a product to be ordered at least one design must have a material.

When accessing a user's Ponoko account with OAuth the URLS fields enable your app to send the user directly to the viewing or making pages on the ponoko.com website for that product.

See Supported file formats for a list of supported file formats.

Listing your products

Once you have created at least one product, you can use this function to get a list of them.

GET /products

No parameters

Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/products

Response example

{"products": [{"key": "1234", 
               "ref": "4321", 
               "name": "tea pot", 
               "created_at": "2011/01/01 12:00:00 +0000", 
               "updated_at": "2011/01/01 12:00:00 +0000"} ...]}
Looking at a product

You can get full details for a product by entering the product key.

GET /products/<< product key >>

No parameters

Curl example

curl --get http://sandbox.ponoko.com/services/api/v2/products/2413

Response example

See 'Create the whole product in one step' above.


top
Making a product

Placing an order for a product is a two step process. First you need to 'ask' the product what the shipping options are for a given address, select one and then pass that back when creating the order.

You can only place orders for products belonging to your user account and only if you've pre- registered a credit card (or other payment option) with us. We charge your credit card when each order is placed successfully.

If the materials for the product(s) are made up of multiple making methods (e.g. laser cutting and 3D printing), they will be priced and shipped as separate deliveries.

Sandbox accounts have full access to this functionality without your needing to register a credit card first.

Shipping options

Just pass in products, quantities and the destination address. You'll then get back the available shipping options and costing. The costing is only valid for a short period of time (approx 60 minutes).

GET /orders/shipping-options

Parameters

• quantity
• products
  ○ key
  ○ quantity
• delivery_address
  ○ address_line_1
  ○ address_line_2
  ○ city
  ○ state
  ○ zip_or_postal_code
  ○ country

Note: 'country' needs to be the full country name ‒ no abbreviations.

See Country list for a full list of supported countries.

Curl example

curl -d “products[][key]=1234” \
     -d “products[][quantity]=1” \
     -d “quantity=1” \
     -d "delivery_address[address_line_1]=27%20Dixon%20Street" \
     -d "delivery_address[address_line_2]=Te%20Aro"
     -d "delivery_address[city]=Wellington" \
     -d "delivery_address[state]=na" \
     -d "delivery_address[zip_or_postal_code]=6021" \
     -d "delivery_address[country]=New%20Zealand" \
     --get https://sandbox.ponoko.com/services/api/v2/orders/shipping-options

Response example

{"shipping_options": {"products": [{"key": "1234", 
                                    "ref": "4321", 
                                    "quantity": 1}...], 
                      "quantity": 1, 
                      "currency": "USD", 
                      "options": [{"code": "ups_ground", 
                                   "name": "UPS Ground", 
                                   "price": "56.78"}...]}}
Order your product

Once you have a list of shipping options, select one of them and pass that into the 'shipping_option_code' field. This will create an order and place it into the production queue for it to be made and shipped.

POST /orders

Parameters

• ref
• products
  ○ key
  ○ quantity
• shipping_option_code
• delivery_address
  ○ first_name
  ○ last_name
  ○ address_line_1
  ○ address_line_2
  ○ city
  ○ state
  ○ zip_or_postal_code
  ○ country
  ○ phone_number
• billing_address
  ○ first_name
  ○ last_name
  ○ address_line_1
  ○ address_line_2
  ○ city
  ○ state
  ○ zip_or_postal_code
  ○ country
  ○ phone_number

Note: if you omit the 'billing_address', the 'delivery_address' is used in its place.

Curl example

curl -d "ref=42" \ 
     -d “products[][key]=1234” \ 
     -d “products[][quantity]=1” \ 
     -d “products[][key]=5678” \ 
     -d “products[][quantity]=5” \ 
     -d "shipping_option_code=ups" \
     -d "delivery_address[first_name]=Bob" \
     -d "delivery_address[last_name]=Builder" \
     -d "delivery_address[address_line_1]=27%20Dixon%20Street" \
     -d "delivery_address[address_line_2]=Te%20Aro" \
     -d "delivery_address[city]=Wellington" \
     -d "delivery_address[state]=na" \
     -d "delivery_address[zip_or_postal_code]=6021" \
     -d "delivery_address[country]=New%20Zealand" \
     -d “delivery_address[phone_number]=1234567890” \ 
     https://sandbox.ponoko.com/services/api/v2/orders

Response example

{"order": {"key": "1234", 
           "ref": "4321", 
           "products": [{"key": "1234", 
                         "ref": "4321", 
                         "quantity": 1}...], 
           "node_key": "1234", 
           "shipped": "false", 
           "created_at": "2011/01/01 12:00:00 +0000", 
           "updated_at": "2011/01/01 12:00:00 +0000", 
           "cost": {"currency": "USD", 
                    "making": "56.78", 
                    "materials": "56.78", 
                    "shipping": "56.78", 
                    "hardware": "0.00",
                    "total": "56.78"}, 
           "shipping_option_code": "ups_ground", 
           "tracking_numbers": ["xxx-yyy" ...], 
           "events": [{"name": "design_checked", 
                       "completed_at": "2011/01/01 12:00:00 +0000"} ...]}}

Response fields of note

• shipped - has the Product shipped yet? The final stage of the making process will automatically set this to 'true'.
• tracking_numbers - making and shipping a product can involve multiple packages. All their tracking codes are listed here. Tracking numbers will become available when the order has shipped.
• events - there are various stages of the making process. Each stage will be listed here as it is completed. Note; cancelling an order doesn't currently trigger an event notification.

See Order events for the complete list.

Checking order status

This is a lightweight call for checking an orders status. It simply shows if the order has shipped or not and lists the events which have been completed.

GET /orders/status/<< order key >>

No parameters

Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/orders/status/2413

Response example

{"order": {"key": "1234", 
           "ref": "4321", 
           "shipped": "false", 
           "events": [{"name": "design_checked", 
                       "completed_at": "2011/01/01 12:00:00 +0000"} ...], 
           "last_successful_callback_at": "2011/01/01 12:00:00 +0000", 
           "shipping_option_code": "ups_ground", 
           "tracking_numbers": ["xxx-yyy" ...]}}

When a callback is registered against your application, this same information will be sent to your registered callback URL. This happens whenever there is a change to the order.

Note: our preference is that you rely on the callback (below) for order status updates rather than continually polling our API.

Order status callbacks

A provided callback URL will be POSTed to whenever an event occurs for an order. For security reasons, we recommend your URL contains a secret key as a URL parameter. The callback can be made over either HTTP or HTTPS.

Your website must return with the HTTP 200 response code to indicate the call was successful, otherwise the API will try again later. When failure does occur the callback will be tried again with an increasing delay between attempts. Callback attempts will eventually stop 2 days after the last event occurs for an order or after a 200 response is received.

In our job processing back-end, operators click through as they reach set events in the making process - such as 'materials ordered', 'designs checked' etc. Sometimes they process a bunch of these all at once. For this reason, we have a delay of several minutes before callbacks are sent. This means your server won't necessarily receive one callback for each event, so several events may have occurred between callbacks.

The callback includes a 'last_successful_callback_at' field so you can easily determine what events have occurred subsequently.

Posted data example

The following is posted as JSON to an 'order' key:

{"key": "1234", 
 "ref": "4321", 
 "shipped": "false", 
 "events": [{"name": "design_checked", 
             "completed_at": "2011/01/01 12:00:00 +0000"} ...], 
 "last_successful_callback_at": "2011/01/01 12:00:00 +0000", 
 "shipping_option_code": "ups_ground", 
 "tracking_numbers": ["xxx-yyy" ...]}

This is exactly the same as the response to the /orders/status call above and includes an array of all the completed events for the order.

Simulating making on the sandbox server

Nobody actually makes products ordered on the sandbox server, so we have a special API call to pretend this is happening. This will advance the order through the various stages of making, including sending callbacks at each stage.

GET /orders/trigger-next-event/<< order key >>

No parameters

Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/orders/trigger-next-event/1234

Response example

{"order": {"key": "1234", 
           "ref": "4321", 
           "shipped": "false", 
           "events": [{"name": "design_checked", 
                       "completed_at": "2011/01/01 12:00:00 +0000"} ...]}}

Note: this API call is only available on the sandbox server and there can be a delay of several minutes between this API call and the callback being triggered.


top
Updating a product

Once created, products can be updated – for example, replacing a design or changing the material it's made from. You can even include additional designs.

Updating a product

You can update a product by changing its main details, including your ref field.

POST /products/<< product key >>/update

Parameters

• ref
• name
• description

Response example

See 'Create the whole product in one step' above.

Add new design

You can add subsequent designs once a product has been created.

POST /products/<< product key >>/add-design

Parameters

• ref
• file_name
• uploaded_data
• quantity
• material_key

Response example

See 'Create the whole product in one step' above.

Updating a design

You can replace a design's file or simply change the material.

POST /products/<< product key >>/update-design/<< design key >>

Parameters

• ref
• file_name
• uploaded_data
• quantity
• material_key

Note: you can only change the file_name when uploading a new design file.

Response example

See 'Create the whole product in one step' above.

Deleting a design

You can delete individual designs from a product. However products are only valid while they have designs and you can't delete the last design from a product.

POST /products/<< product key >>/delete-design/<< design key >>

No parameters

Response example

See 'Create the whole product in one step' above.

Add design images

You can add photos of the product.

POST /products/<< product key >>/design-images

Parameters

• design_images - an array of design images.
  ○ uploaded_data
  ○ default - optional. Set to true to make this image the default. If more than one image is marked as default the last image set will be the default.

Curl example

curl -F "design_images[][uploaded_data]=@my_image.jpg" \
     -F "design_images[][default]=1" \
     https://sandbox.ponoko.com/services/api/v2/products/2413/design-images

Response example

See 'Create the whole product in one step' above. The design image section within the product response will be as follows

{"design_images": [{"filename": "my_image.jpg", 
                    "default": true}]}
Getting a design image

Get the photos of the product.

GET /products/<< product key >>/design-images/download?filename=<< file name >>

Parameters

• filename


Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/products/2413\
/design-images/download?filename=my_image.jpg

Response example

The response will be the raw image data.

Removing a design image

Remove a photo from a product.

GET /products/<< product key >>/design-images/destroy?filename=<< file name >>

Parameters

• file name


Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/products/2413\
/design-images/destroy?filename=my_image.jpg

Response example

See 'Create the whole product in one step' above.

Adding assembly instructions

You can add assembly instructions to the product.

POST /products/<< product key >>/assembly-instructions

Parameters

• assembly_instructions - an array of assembly instruction files.
  ○ uploaded_data

Curl example

curl -d "assembly_instructions[][uploaded_data]=@instructions.pdf" \
     https://sandbox.ponoko.com/services/api/v2/products/2413/assembly-instructions

Response example

See 'Create the whole product in one step' above.The assembly instructions section within the product response will be as follows

{"assembly_instructions": [{"filename": "instructions.pdf"}]}
Getting assembly instructions

Get the assembly instructions for the product.

GET /products/<< product key >>/assembly-instructions/download?filename=<< file name >>

Parameters

• file name


Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/products/2413\
/assembly-instructions/download?filename=instructions.pdf

Response example

The response will be the raw file.

Removing assembly instructions

Remove an assembly instructions file from a product.

GET /products/<< product key >>/assembly-instructions/destroy?filename=<< file name >>

Parameters

• file name


Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/products/2413\
/assembly-instructions/destroy?filename=instructions.pdf

Response example

See 'Create the whole product in one step' above.

Add hardware

You can add hardware to your product.

POST /products/<< product key >>/hardware

Parameters

• sku
• quantity


Curl example

curl -d "sku=GPS-08254" \
     -d "quantity=3" \
     https://sandbox.ponoko.com/services/api/v2/products/2413/hardware

Response example

See 'Create the whole product in one step' above. The hardware section within the product response will be as follows

{"hardware": [{"sku": "GPS-08254", 
               "name": "Widget", 
               "quantity": "3", 
               "weight": "0.1kg", 
               "currency": "USD", 
               "cost": "9.99", 
               "total_cost": "29.97"}]}
Updating hardware quantity

You can change the hardware quantity.

POST /products/<< product key >>/hardware

Parameters

• sku
• quantity

Curl example

curl -d "sku=GPS-08254" \
     -d "quantity=3" \
     https://sandbox.ponoko.com/services/api/v2/products/2413/hardware

Response example

See the 'Add hardware' response

Removing hardware

You can remove hardware from your product.

POST /products/<< product key >>/hardware

Parameters

• sku

Curl example

curl -d "sku=GPS-08254" \
     https://sandbox.ponoko.com/services/api/v2/products/2413/hardware

Response example

See 'Create the whole product in one step' above.

Deleting a product

You can delete products which have not yet been made.

POST /products/delete/<< product key >>

No parameters

Response example

{"product_key": "1234", "deleted": true}

top
Order history
Listing your orders

You can pull up a list of orders once you have created at least one.

GET /orders

No parameters

Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/orders

Response example

{"orders": [{"key": "1234", 
             "ref": "4321", 
             "shipped": true, 
             "created_at": "2011/01/01 12:00:00 +0000", 
             "updated_at": "2011/01/01 12:00:00 +0000"} ...]}
Looking at an Order

You can get the full details for an order once you have its key.

GET /orders/<< order key >>

No parameters

Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/orders/2413

Response example

See 'Order your product' above.


top
Test users

These API calls allow you to manage test user accounts on the Ponoko Sandbox server for use by Apps using OAuth authentication. You can log into them here.

Creating a user

The call to create a user is very simple and requires no paramaters.

POST /users

No parameters.

Curl example

curl https://sandbox.ponoko.com/services/api/v2/users

Response example

{
  "sandbox_only": true,
  "user": {
    "password": "123",
    "email": "123@sandbox.ponoko.com"
  }
}

Comments

We generate a random password for your test user accounts and use it as part of the email address. Use the below API call to recover forgotten passwords/email addresses.

You can create up to a maximum of 3 users.

Listing your users

You can pull up a list of your test user accounts, this includes their passwords.

GET /users

No parameters.

Curl example

curl --get https://sandbox.ponoko.com/services/api/v2/users

Response example

{
  "sandbox_only": true,
  "users": [
    {
      "password": "123",
      "email": "123@sandbox.ponoko.com"
    },
    {
      "password": "456",
      "email": "456@sandbox.ponoko.com"
    },
    {
      "password": "789",
      "email": "789@sandbox.ponoko.com"
    }
  ]
}

top
Debugging
Request log

This gives you access to a log of your requests made to the API and their responses.

GET logs/requests

Parameters

• max


Curl example

curl -d "max=20" --get https://sandbox.ponoko.com/services/api/v2/logs/requests

Response example

{
  "requests": [
    {
      "response": {
        "nodes": [
          {
            "key": "2413",
            "name": "Ponoko USA",
            "materials_updated_at": "2011/01/01 12:00:00 +0000"
          }
        ]
      },
      "created_at": "2012/01/01 12:00:00 +0000",
      "method": "get",
      "path": "/services/api/v2/nodes",
      "params": {
      },
      "http_status": 200
    }
  ]
}

Comments

The optional 'max' parameter can be any value from 1 to 20 and will only return log entries less than 24 hours old.


top

Sign up for our newsletter
to get special offers: