Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:

  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Receiving 401 Unauthorized when trying to export an STL or parasolid from Onshape API

Cappie_PomeroyCappie_Pomeroy Member Posts: 10 PRO
I have tried both from my local computer and using the API explorer application.  Every other OAuth2Read API call that I've used works as expected both locally and in the API explorer.  I've tried the /parts/d/:did/[wvm]/:wvm/e/:eid/partid/:partid/stl endpoint and the /partstudios/d/:did/[wvm]/:wvm/e/:eid/stl as well as the parasolid ones.  I've used workspace id, version id, and microversion id both locally and in the API explorer.  All result in

`{"message":"Unauthenticated API request", "status":401}`

Any ideas?


Best Answer


  • Ethan_KEthan_K Member, Onshape Employees Posts: 39
    Hi Cappie,

    This is because our STL call requires following a 307 redirect to the modeling server slated to deliver the tessellation. Upon redirection, you need to re-sign the request with the new parameters, since the request now points to a different resource path, and API key signing integrates the path and query params into the signature. We currently don't handle this correctly in the API explorer, but there is a bug already filed for this. In many clients, the way to support this is to turn off the automated redirect that they provide, and instead handle it manually in a try/catch for 3xx codes that takes the redirect and calculates the new headers for it. You can see an example of this here: https://github.com/onshape-public/onshape-clients/blob/30e9242c5544b35fcb1bb9797334a29443b1d3d8/python/onshape_client/rest.py#L255 . Note that if you are using OAuth, the automated redirect should just work as it doesn't need path-specific signing.

    Hope that helps!
  • Cappie_PomeroyCappie_Pomeroy Member Posts: 10 PRO
    Hi Ethan,

    I am using OAuth a simplified version of the python+flask I'm using is
    ONSHAPE_API_URL + '/parts'
    + '/d/' + session['onshape_document']
    + '/m/' + session['onshape_microversion']
    + '/e/' + part_studio_id
    + '/partid/' + part_id
    + '/stl'
    r = requests.get(url, headers)
    print(r.status_code) # 401
    print(r.content) #
    {"message":"Unauthenticated API request", "status":401}

    import requests
    I'll try catching the 307 and reapplying the headers, but I don't think that the OAuth 'just works' as you said.  Is there something incorrect with this approach?  The other requests that are working use this same scheme so I'm sure the token and header are being set according to Onshape's OAuth implementation.

  • Cappie_PomeroyCappie_Pomeroy Member Posts: 10 PRO
    edited October 2019
    Thanks so much for your help Ethan!  I got it working using the Session object of the requests library.  https://requests.kennethreitz.org/en/master/user/advanced/#session-objects and setting the Authorization Header on the session level then I made a while loop to attempt get requests until I get something that isn't a redirect status code.
    import requests

    def oauth_get_with_redirects(url, token, parameters={}):
        s = requests.Session()
        headers = {
            'Authorization': 'Bearer ' + token
        r = s.get(url, params=parameters, allow_redirects=False)
        while r.is_redirect:
            r = s.get(
                r.headers['Location'], params=parameters,
        return r

    Also thanks for pointing out the security flaw of passing along headers I will only use this on the endpoints you specified.
Sign In or Register to comment.