Feature List API

Onshape Part Studio Feature Access API

Summary

The Onshape Part Studio tab tracks edits in terms of a feature list. Creation and modification of geometry is performed by manipulating that list. This document describes capabilities that are intended to allow partners and customers to manipulate the feature list from software.

The feature API comprises the following API methods:

  • GET /api/partstudios/DWMVE/features - get feature list

  • GET /api/partstudios/DWMVE/featurespecs - get feature specs

  • POST /api/partstudios/DWE/features - add feature to feature list

  • POST /api/partstudios/DWE/features/featureid/:fid - update an existing feature in feature list

  • DELETE /api/partstudios/DWE/features/featureid/:fid - delete an existing feature from feature list

  • POST /api/partstudios/DWE/features/features/updates - selectively update features in feature list

  • POST /api/partstudios/DWE/features/rollback - move the rollback bar

  • POST /api/partstudios/DWMVE/featurescript - evaluate featurescript

As well as related configuration API methods:

  • GET /api/partstudios/DWMVE/configuration - get part studio configuration

  • POST /api/partstudios/DWE/configuration - update part studio configuration

Note that the use of “DWE” occurrences within this document are a shorthand notation for “d/:did/w/:wid/e/:eid” and DWMVE occurrences within this document are a shorthand notation for any of “d/:did/w/:wid/e/:eid”, “d/:did/v/:vid/e/:eid”, “d/:did/m/:mid/e/:eid”. It is assumed that the reader is familiar with these URL path patterns from the Glassworks API Explorer documentation.

API Methods

The methods described here are also documented at an overview level in the Glassworks API Explorer within the Part Studios group.

Get Feature List

GET /api/partstudios/DWMVE/features - get feature list

If you have a part studio ekement, you can call the get feature list api to find the features that are instantiated within the part studio. The return structure contains the following fields:

  • features - A list of user-define features in the part studio.

  • defaultFeatures - A list of the default feature (pre-defined) in the part studio

  • imports - A list of capabilities that may be referenced by the features. We currently only support a specific predefined set of geometry capabilities.

  • featureStates - A list of feature states, one per feature, which describe whether the feature is valid. If a feature has been added to the feature list with an incorrect definition it remains in the feature list.

  • isComplete - A boolean indicating whether the features represents the entire part studio (true) or is only a subset (false). The result is a subset if the call to the api specifies a filter on the feature ids

  • rollbackIndex - The ordinal position of the rollback bar w.r.t. the list of features. Onshape only executes features that are prior to the rollback bar.

  • serializationVersion - A string identifying the version of the structure serialization rules used to encode the output. This is included so that if the output is fed back in and the software has changed incompatibilities can be detected

  • sourceMicroversion - The microversion identifier for the document that describes the state from which the result was extracted. This is critical when attempting to use geometry ids that are included in the output, since the interpretation of a geometry id is dependent on the document microversion.

  • libraryVersion - An integer indicating the version number for FeatureScript in the Part Studio

Get Feature Specs

GET /api/partstudios/DWMVE/featurespecs - get feature specs

Returns a list of feature specs that are available within the part studio. A feature spec provides a data description of the interface to a feature. This can, in theory, allow an application to use introspection to allow dynamically generated features. In practice, we expect that the application developer understands the features ahead of time and might utilize the feature spec to understand the options available and the required format for feature addition/modification.

Add Feature

POST /api/partstudios/DWE/features

A feature can be added to the feature list by calling the add feature API. The API accepts as input a JSON structure containing the fields:

  • feature - A single feature definition, in the same format that is output by the get feature list API, except that there is no need to provide feature ids, node ids, or typeNames.

  • sourceMicroversion - The microversion of the document that is assumed. Any geometry ids included in the feature are interpreted in the context of this microversion.

  • rejectMicroversionSkew (optional) - If set to true, the call will refuse to make the addition if the current microversion for the document does not match the source Microversion. Otherwise, a best-effort attempt is made to re-interpret the feature addition in the context of a newer document microversion.

The call returns a structure with the following fields:

  • feature - The input feature, echoed back with id value assignments in place

  • featureState - The state of the feature

  • serializationVersion - As described previously

  • sourceMicroversion - The microversion of the document in which the returned feature is defined

  • microversionSkew - If rejectMicroversionSkew was not set to true on input and the document microversion had changed since the input sourceMicroversion, this is set to true to indicate that a re-interpretation was made.

  • libraryVersion - An integer indicating the version number for FeatureScript in the Part Studio

The feature is added immediately before the rollback bar. Any geometry ids specified in the feature must be valid at that point in the feature tree. For example, if applying a fillet to an edge, that edge must exist in the feature tree. Filleting the edge will normally make it invalid at future states of the feature tree, since the fillet feature removes the edge.

Update Feature

POST /api/partstudios/DWE/features/featureid/:fid

An existing feature can be modified by calling the update feature API. This API accepts the same input body format and returns the same output format as the Add Feature API. However, instead of adding a new feature prior to the rollback bar location, it replaces an existing feature in the location of the existing feature.

Update Features

POST /api/partstudios/DWE/features/updates

Multiple existing features can be modified by calling the update features API. This API accepts a list of features and to update, which must already exist in the part studio. This call does not fully re-define the features but instead, updates only the parameters supplied in the top-level feature structure, and optionally will update feature suppression attributes.

Applications that need to update parameters for multiple features can typically achieve faster model rebuild time by updating multiple features in a single call. It also has the benefit that it allows features to be suppressed or unsuppressed without specifying parameters. This is particularly useful in the unsuppress case because parameters containing query values are not populated when reading from the feature list.

Delete Feature

DELETE /api/partstudios/DWE/features/featureid/:fid

An existing feature can be removed from the feature list by calling the delete feature API. The API accepts only URL path parameters and return only the following fields:

  • serializationVersion - As described earlier

  • sourceMicroversion - As described earlier

Move Rollback Bar

POST /api/partstudios/DWE/features/rollback

The rollback bar can be moved using this API. This is useful if a feature needs to be added at a location other than the current rollback bar location. As input, it accepts the following fields:

  • rollbackIndex - The index at which the rollback index should be placed. Features with entry index (0-based) higher than or equal to this value are rolled back. The value must be in the range 0 to the number of entries in the feature list

  • serializationVersion

  • sourceMicroversion

    The result returned by the API includes the fields

  • rollbackIndex - The rollback index in the updated state

  • serializationVersion - As described previously

  • sourceMicroversion - As described previously

  • microversionSkew - As described previously

Evaluate FeatureScript

POST api/partstudios/DWMVE/featurescript

This API allows the caller to execute a FeatureScript function to query information about the existing feature tree that is not exposed through the other methods described here. As input, it accepts the following fields:

  • script - The definition of a FeatureScript function that takes a Context argument and a map argument

  • queries - A list of key, value pairs, where the key is a FeatureScript identifier that will appear as a key in the map supplied to the script function and the valid is a list of geometry Id strings, where the list is converted to “query” form form use within the script function.

See the example below to better understand this usage.

Configuration API Methods

Part Studios may be unconfigured or configured. A configured part studio has a list of configuration parameters that define the knobs that allow adjustment of the part studio part content. Configuration parameters are referred to as “inputs” in the UI and may be one of Enum (or List), Boolean, Quantity or String. Each parameter includes a default value setting that is used if the parameter is not otherwise set.

Configured part studios also have a “current” configuration. This is a list of configuration parameter settings for the current representation of the part studio. Alternate configurations of the part studio may be used concurrently, but the current configuration defines the parts seen by the user within in the part studio.

Get Configuration

GET /api/partstudios/DWMVE/configuration - get part studio configuration

This method reads the current configuration information for a Part Studio. The return structure contains the following fields:

  • configurationParameters - A list of the parameters that allow configuration of the part studio.

  • currentConfiguration - A list of configuration parameter settings for the current representation of the part studio.

  • serializationVersion - As described previously

  • sourceMicroversion - As described previously

  • microversionSkew - As described previously

  • libraryVersion - As described previously

Update Configuration

POST /api/partstudios/DWE/configuration - update part studio configuration

This method modifies the current configuration information for a Part Studio. When changing configuration parameters it is important that parameterId values be maintained consistently across changes so that features that reference the parameter do not get broken. The API accepts as input a JSON structure containing the fields:

  • configurationParameters - A list of the parameters that allow configuration of the part studio.

  • currentConfiguration - A list of configuration parameter settings for the current representation of the part studio.

  • sourceMicroversion (optional) - The microversion of the document that is assumed.

  • rejectMicroversionSkew (optional) - If set to true, the call will refuse to make the addition if the current microversion for the document does not match the source Microversion.

The call returns a structure with the following fields:

  • configurationParameters - A list of the parameters that allow configuration of the part studio.

  • currentConfiguration - A list of configuration parameter settings for the current representation of the part studio.

  • serializationVersion - As described previously

  • sourceMicroversion - As described previously

  • microversionSkew - As described previously

  • libraryVersion - As described previously

API Usage Details

The feature access and modification API in Onshape presents the internal form of feature definitions rather than providing a translation layer between external form and internal form. We suggest that you familiarize yourself with the formats involved by calling the Get Feature List API on existing part studios in order to understand the encoding of features.

Some important things to know about the JSON encoding are:

  • Default values are omitted in the encoded output. For string fields the default value is “”, for boolean fields it is false, and for numeric fields it is 0.

  • It uses a special tagging system in order to manage polymorphic data structures. Specifically, objects generally are encoded by enclosing them within another object that declares the type information for the enclosed object.

As an example of the type tagging mechanism, the GET features api might return a structure that looks like this:

{
  "features": [
    {
      "type": 134,
      "typeName": "BTMFeature",
      "message": {
        "featureType": "cube",
        "featureId": "FLqo5rpNof3IXgh_0",
        "name": "Cube 1",
        "parameters": [
          {
            "type": 147,
            "typeName": "BTMParameterQuantity",
            "message": {
              "expression": "1.0*in",
              "parameterId": "sideLength",
              "nodeId": "TyUNOSxJ/f9z5t1T"
            }
          }
        ],
        "nodeId": "Mr60Xw6RGWdr0MfYV"
      }
    }
  ],
  "imports": [
    {
      "type": 136,
      "typeName": "BTMImport",
      "message": {
        "path": "onshape/std/geometry.fs",
        "version": "268.0",
        "nodeId": "M2/0RrOwK0Q+hWr9z"
      }
    }
  ],
  "featureStates": [
    {
      "key": "FLqo5rpNof3IXgh_0",
      "value": {
        "type": 1688,
        "typeName": "BTFeatureState",
        "message": {
         "featureStatus": "OK"
        }
      }
    }
  ],
  "isComplete": true,
  "rollbackIndex": 1,
  "serializationVersion": "1.1.6",
  "sourceMicroversion": "b5b4834bd0674b4489b2b2b7"
}

We see that in this case, the features array contains a single feature. The “type” and “typeName” fields describe the type that is encoded within the “message” field. The “type” field provides definitive type information and is the type number assigned to the structure. This type number is a permanent assignment. The “typeName” field is a convenience field that is generated on output and ignored on input. It is intended to allow developers to associate meaningful names with the type numbers.

General Features

In the example above, we see that the single feature is of type 134, which is the general feature type. A general feature is an instantiation of the feature template that is describe by its corresponding feature spec. The BTMFeature structure includes the following fields:

  • featureType - Specifies the name of the feature spec that this instantiates

  • featureId - The internal identifier of the feature instance within this part studio. It is internally generated when a feature is added.

  • nodeId - An internal identifier for the feature node. This is also internally generated when the feature is added.

  • name - The user visible name of the feature.

  • namespace - An indicator of where the feature definition can be found. Features in the FeatureScript standard library have a namespace value of "" whereas custom features identify the featurestudio that contains the definition. See the Custom Features section below for more information.

  • parameters - A list of parameter values for instantiation of the feature spec. Parameters are present for all defined parameters, even if not used in a specific instantiation.

All parameters have the following fields in common:

  • parameterId - The name of the parameter spec that this applies to

  • nodeId - An internal identifier for the parameter node

Parameters are typically one of the following types:

  • BTMParameterQuantity (type 147) - specifies the value for a parameter defined in the feature spec as a BTParameterSpecQuantity. It has the field:

    • expression - An expression defining the value for the parameter.

    An example of its usage is in the depth parameter in the extrude feature.

  • BTMParameterQueryList (type 148) - specifies the value for a parameter defined in the feature spec as a BTParameterSpecQuery. It has the field:

    • queries - a list of query objects. The query objects could be either

      • SBTMIndividualQuery objects (type 138) with the field:

        • geometryIds - A list of geometry id values indentifying geometry that the feature applies to.
      • SBTMIndividualSketchRegionQuery objects (type 140) with the field:

        • featureId - The featureId of a sketch, with the query identifying all regions of the sketch

    An example of its usage is in the entities parameter in the extrude feature.

  • BTMParameterBoolean (type 144) - specifies the value for a parameter defined in the feature spec as a BTParameterSpecBoolean. It has the field:

    • value - The boolean value

    An example of its usage is in the oppositeDirection parameter in the extrude feature.

  • BTMParameterEnum (type 145) - specifies the value for a parameter defined in the feature spec as a BTParameterSpecEnum. It has the fields:

    • enumName - The name of the enum type that value is a member of

    • value - The name of the enum member

    An example of its usage is in the bodyType parameter in the extrude feature.

Other parameter types exist for special cases and are not described here.

Sketches

Although most features are of type BTMFeature, there is also a BTMSketch type, which defines a sketch. The structure of a sketch feature extends the BTMFeature and is relatively complex. It is suggested that the developer use a manually edited sketch as a template for any sketches that they want to create programmatically. However, we will give a high-level overview of the content for the sketch.

Sketches have top-level fields:

  • entities - the sketch geometry

  • constraints - the geometric relationship constraints and dimensions for the sketch

  • parameters - the sketch parameters. The only parameter is the parameter that identifies the sketch plane

  • featureType - set to “newSketch”

  • featureId - the feature id

  • name - the sketch name

The entities describe curves in terms of unbounded curves plus parameterized ranges. The geometry is always specified in meters, regardless of the user’s choice of units. This geometry provides an initial guess for the sketch. The actual solve state may differ, depending on whether the input constraints are satisfied.

The constraints describe the requirements for sketch solution. These typically include constraints such as COINCIDENT, HORIZONTAL, VERTICAL, PARALLEL, PERPENDICULAR, TANGENT that control geometric positioning and constraints such as DISTANCE, RADIUS, DIAMETER, ANGLE that provide dimensional constraints. The constraints typically have one or two objects that are constrained. These are referenced as localFirst for the first constrained entity, which is within the sketch, and either localSecond or externalSection, depending on whether the second constrained entity is local to the sketch. When entities are local to the sketch they are identitified by entity ids (long unique names) and when external they are identified by a BTMIndiviualQuery.

Feature Specs

The feature spec for a feature provides a description of the inputs that it accepts. As an example, the feature spec for a cube is shown below. It defines a single parameter named “sideLength”. The parameter spec includes a list of ranges that specify valid ranges for the parameter value. Each range is specific to a particular unit and has a defaultValue for that unit. Some parameters described by the feature spec may be optional. These normally have a visibilityCondition that describes a logical test as to whether the parameter should be exposed for editing, based on other parameter values. This provides a fairly reliable way to determine whether the parameter is required for a particular feature instance, but it is safe to include default values for a feature even if it has a visibilityCondition that indicates it is not visible.

{
  "type": 129,
  "typeName": "BTFeatureSpec",
  "message": {
    "featureType": "cube",
    "featureTypeName": "Cube",
    "parameters": [
      {
        "type": 173,
        "typeName": "BTParameterSpecQuantity",
        "message": {
          "quantityType": "LENGTH",
          "ranges": [
            {
              "type": 181,
              "typeName": "BTQuantityRange",
              "message": {
                "units": "meter",
                "minValue": 0.00001,
                "maxValue": 500,
                "defaultValue": 0.025,
                "location": {
                  "type": 226,
                  "typeName": "BTLocationInfo",
                  "message": {
                    "document": "onshape/std/primitives.fs",
                    "parseNodeId": "PX2DsNKne8oO7ilPS",
                    "languageVersion": 268,
                    "nodeId": "t8iQqgzAr/bCB2AZ"
                  }
                }
              }
            },
            {
              "type": 181,
              "typeName": "BTQuantityRange",
              "message": {
                "units": "centimeter",
                "minValue": 0.001,
                "maxValue": 50000,
                "defaultValue": 2.5,
                "location": {
                  "type": 226,
                  "typeName": "BTLocationInfo",
                  "message": {
                    "document": "onshape/std/primitives.fs",
                    "parseNodeId": "PKXPCya7aeoNITDFW",
                    "languageVersion": 268,
                    "nodeId": "69sE3wOlv3FLiJxn"
                  }
                }
              }
            },
            {
              "type": 181,
              "typeName": "BTQuantityRange",
              "message": {
                "units": "millimeter",
                "minValue": 0.01,
                "maxValue": 500000,
                "defaultValue": 25,
                "location": {
                  "type": 226,
                  "typeName": "BTLocationInfo",
                  "message": {
                    "document": "onshape/std/primitives.fs",
                    "parseNodeId": "P8uyYds3YIBBpzlVN",
                    "languageVersion": 268,
                    "nodeId": "8huKnMQb9mH9B+ef"
                  }
                }
              }
            },
            {
              "type": 181,
              "typeName": "BTQuantityRange",
              "message": {
                "units": "inch",
                "minValue": 0.0003937007874015748,
                "maxValue": 19685.03937007874,
                "defaultValue": 1,
                "location": {
                  "type": 226,
                  "typeName": "BTLocationInfo",
                  "message": {
                    "document": "onshape/std/primitives.fs",
                    "parseNodeId": "P4MfX8crrr+qc9vFS",
                    "languageVersion": 268,
                    "nodeId": "BMU3SmZpR83uoKkd"
                  }
                }
              }
            },
            {
              "type": 181,
              "typeName": "BTQuantityRange",
              "message": {
                "units": "foot",
                "minValue": 0.00003280839895013123,
                "maxValue": 1640.4199475065616,
                "defaultValue": 0.1,
                "location": {
                  "type": 226,
                  "typeName": "BTLocationInfo",
                  "message": {
                    "document": "onshape/std/primitives.fs",
                    "parseNodeId": "P60BmwPj7LnRT0CTh",
                    "languageVersion": 268,
                    "nodeId": "ywVSbQADr8dRv9+s"
                  }
                }
              }
            },
            {
              "type": 181,
              "typeName": "BTQuantityRange",
              "message": {
                "units": "yard",
                "minValue": 0.000010936132983377077,
                "maxValue": 546.8066491688538,
                "defaultValue": 0.025,
                "location": {
                  "type": 226,
                  "typeName": "BTLocationInfo",
                  "message": {
                    "document": "onshape/std/primitives.fs",
                    "parseNodeId": "PsE6sGD66MJVH2xQh",
                    "languageVersion": 268,
                    "nodeId": "zAy0tYs5aC0clPLL"
                  }
                }
              }
            }
          ],
          "parameterId": "sideLength",
          "parameterName": "Side length",
          "defaultValue": {
            "type": 147,
            "typeName": "BTMParameterQuantity",
            "message": {
              "units": "meter",
              "value": 0.025,
              "parameterId": "sideLength",
              "nodeId": "MC6QUqafapZdxtrDy"
            }
          }
        }
      }
    ]
  }
}

Visibility conditions come in 3 variants:

  • BTParameterVisibilityAlwaysHidden - Special-case parameters that are not directly shown to the user

  • BTParameterVisibilityLogical - Allows a logical condition to express when a parameter is visible. Allows nested AND/OR/NOT expressions. The leaves of the expression tree are BTParameterVisibilityOnEqual

  • BTParameterVisibilityOnEqual - A simple test that a parameter has been assigned a specific value.

A ParameterSpec can be one of numerous types. The most commonly used types are:

  • BTParameterSpecQuery - indicates that a query parameter should be supplied. The parameter spec has an allowable number of selections and query filter that describes the allowable types that can be selected. See below for additional information about query filters. An example usage is identifying the entities to chamfer in a “Chamfer” feature.

  • BTParameterSpecString - indicates that a string value should be supplied. For example, this is used for the name of a variable in a “Variable” feature.

  • BTParameterSpecQuantity - indicates that a number value should be supplied. In allows a quantityType, which describes the type of number (length, angle, mass, count, etc.) and range limits on the value. An example usage is the depth parameter in an “Extrude” feature.

  • BTParameterSpecEnum - indicates that an enumerated value should should be provided. An example usage is the operationType parameter in an “Extrude” feature.

  • BTParameterSpecBoolean - indicates that a boolean true/false value should be specified. An example usage is the offset parameter in the “Boolean” feature

Some less commonly used parameter spec types are:

  • BTParameterSpecDerived - indicates that an import of a part from another Part Studio should be specified.

  • BTParameterSpecLookupTablePath - provides a list of string values that can be chosen.

  • BTParameterSpecForeignId - indicates that a “foreign id” value should be supplied. Foreign ids are currently not generally accessible through the API, but identify a file that is made available throughout the system.

Parameter Spec query filters:

Query Filters are even more numerous than parameter spec types.

Basic selections:

  • BTBodyTypeFilter - a specific body type (solid, sheet, wire, acorn, mate_connector)

  • BTClosedCurveFilter - a curve that is either closed or not closed, depending on the isClosed value. (NO)

  • BTConstructionObjectFilter - an object that either is or is not identified as “construction”, depending on the isConstruction value.

  • BTEdgeTopologyFilter - an edge that either is or is not an internal edge, depending on the isInternalEdge value.

  • BTEntityTypeFilter - selects a specific type of entity based on the entityType value (vertex, edge, face, body, degenerate_edge).

  • BTFeatureTypeFilter - selects a specific type of feature base on the featureType value. (NO)

  • BTGeometryFilter - select specific geometry types based on the geometryType value (line, circle, arg, plane, cylinder,cone sphere torus, spline, ellipse).

  • BTImageFilter - an entity that either is or is not an image, based on the isImage value. (no)

  • BTMateConnectorFilter - a mate connector (NO)

  • BTMateFilter - a mate object

  • BTPlaneOrientationFilter - excludes planes that are aligned with another plane, based on the normal value.

  • BTSketchObjectFilter - an object that either is or is not a sketch object, or is a sketch object created by the user, depending on the objectType value (not_sketch_object, any_sketch_object, user_entity).

  • BTTextObjectFilter - an object that either is or is not a text object, depending on the isText value.

  • BTTextStrokeFilter - an object that either is or is not a text stroke, depending on the isStroke value.

Logical operations:

  • SBTAndFilter - combines query filters with “AND”

  • SBTOrFilter - combines query filters with “OR”

  • SBTNotFilter - negates query filters

Feature Script Evaluation

For certain tasks when creating and updating features, there may be information needed that is embedded within the existing model. You can often access it by running a Feature Script function. Feature Script is a language that is used to define the behavior of features.

As an example of its usage, consider the case of using a face of an existing part to define new geometry. A plane is defined in FeatureScript as an origin, x-direction vector and normal vector. These can be queried from FeatureScript by using the evPlane function, but it wants a “query” that identifies the face. Here is an example of how you might do this with a call to the Evaluate FeatureScript API call. Suppose you know that “JCC” is the geometry Id of a particular face. The following body can be passed to the evaluate function.

{
  "script" : "function (context is Context, queries is map) {
              return evPlane(context, {face:queries.id});
              }",
  "queries" : [ { "key" : "id", "value" : [ "JCC" ] } ]
}

Assuming that we have done everything right, the output of this might look something like this:

{
  "result": {
    "type": 2062,
    "typeName": "BTFSValueMap",
    "message": {
      "value": [
        {
          "type": 2077,
          "typeName": "BTFSValueMapEntry",
          "message": {
            "key": {
              "type": 1422,
              "typeName": "BTFSValueString",
              "message": {
                "value": "normal"
              }
            },
            "value": {
              "type": 1499,
              "typeName": "BTFSValueArray",
              "message": {
                "value": [
                  {
                    "type": 772,
                    "typeName": "BTFSValueNumber",
                    "message": {
                      "value": -1
                    }
                  },
                  {
                    "type": 772,
                    "typeName": "BTFSValueNumber",
                    "message": {}
                  },
                  {
                    "type": 772,
                    "typeName": "BTFSValueNumber",
                    "message": {}
                  }
                ],
                "typeTag": "Vector"
              }
            }
          }
        },
        {
          "type": 2077,
          "typeName": "BTFSValueMapEntry",
          "message": {
            "key": {
              "type": 1422,
              "typeName": "BTFSValueString",
              "message": {
                "value": "origin"
              }
            },
            "value": {
              "type": 1499,
              "typeName": "BTFSValueArray",
              "message": {
                "value": [
                  {
                    "type": 1817,
                    "typeName": "BTFSValueWithUnits",
                    "message": {
                      "unitToPower": [
                        {
                          "key": "METER",
                          "value": 1
                        }
                      ],
                      "typeTag": "ValueWithUnits"
                    }
                  },
                  {
                    "type": 1817,
                    "typeName": "BTFSValueWithUnits",
                    "message": {
                      "value": 0.012700000000000001,
                      "unitToPower": [
                        {
                          "key": "METER",
                          "value": 1
                        }
                      ],
                      "typeTag": "ValueWithUnits"
                    }
                  },
                  {
                    "type": 1817,
                    "typeName": "BTFSValueWithUnits",
                    "message": {
                      "value": 0.012700000000000001,
                      "unitToPower": [
                        {
                          "key": "METER",
                          "value": 1
                        }
                      ],
                      "typeTag": "ValueWithUnits"
                    }
                  }
                ],
                "typeTag": "Vector"
              }
            }
          }
        },
        {
          "type": 2077,
          "typeName": "BTFSValueMapEntry",
          "message": {
            "key": {
              "type": 1422,
              "typeName": "BTFSValueString",
              "message": {
                "value": "x"
              }
            },
            "value": {
              "type": 1499,
              "typeName": "BTFSValueArray",
              "message": {
                "value": [
                  {
                    "type": 772,
                    "typeName": "BTFSValueNumber",
                    "message": {}
                  },
                  {
                    "type": 772,
                    "typeName": "BTFSValueNumber",
                    "message": {
                      "value": -1
                    }
                  },
                  {
                    "type": 772,
                    "typeName": "BTFSValueNumber",
                    "message": {}
                  }
                ],
                "typeTag": "Vector"
              }
            }
          }
        }
      ],
      "typeTag": "Plane"
    }
  },
  "serializationVersion": "1.1.6",
  "sourceMicroversion": "27db48fb62bf6ac3b3ddaeaa",
  "libraryVersion": 296
}

You can see from the output that the FeatureScript object representation uses the same typing rules that is used for other output. In addition, FeatureScript objects may have a typeTag field associated with them, which indicates that type-specific behavior should be applied. For instance, we see cases where a BTFSValueArray has a typeTag of “Vector”, which allows the array to be accepted where a Vector is declared to be required.

In order to help describe the interpretation of the structure above, here is a possible JSON representation of the result from the output shown above, but with weaker typing:

{
  "normal" : [ -1, 0, 0 ],
  "origin" : { "value" : [ 0,
                           0.012700000000000001,
                           0.012700000000000001 ],
               "units" : "meter" },
  "x" : [ 0, -1, 0 ]
}

Custom Features

Custom features can be used in the feature apis with a little additional work. The key to using custom features is that you must set a namespace field in the feature to tell Onshape where to look for the feature defintion. The namespace field identifies a specific version of a feature studio. There are two standard forms for the namespace field to consider:

  • Intra-workspace - In this case, the namespace field has the form “e::m” where elementId is the elementId of the FeatureStudio that defines the feature and microversionId is the element microversionId of the FeatureStudio. It is important to note that the element microversionId is different from the document microversionId that is more typically encountered in API usage.

  • External - When the definition to be used lives in a different document or in a specific version of the current document it is referenced using the form “d::v::e::m” This is the same form as for the intra-workspace case but with a documentId and versionId additionally specified. The documentId is the id of the document containing the FeatureStudio and the versionId is the version of the document to be used.

In both of the forms listed, it is necessary to determine the FeatureStudio element microversionId. One way to do this is to call the GET /api/documents/DWMV/elements API, which reports the element microversion for each of the elements. There is also a GET /api/featurestudios/DWMV/featurespecs API that provides a featurespec for each of the features defined in the FeatureStudio. These featurespecs also have a namespace field that reports the namespace of the FeatureStudio in the intra-workspace form.

Examples

Below are several examples of how the API can be used in order to help you get started. The examples are quite trivial, but should provide a basic demonstration of how to use these API methods. You should be able to execute the calls against a part studio of yours and see results immediately. The calls could be executed using your preferred software environment but interactive use in a REST-aware tool is likely the easiest way to try the examples.

Example 1

In our first example we will create a cube using the cube feature. The feature accepts only a single parameter, which is the length of a side, and creates a cube with a corner at the origin and aligned with the three default planes. In running the example, be sure to replace DWE with the the d/:did/w/:wid/e/:eid that is appropriate for the part studio that you are operating against.

POST /api/partstudios/DWE/features

{
  "feature" : {
    "type": 134,
    "typeName": "BTMFeature",
      "message": {
        "featureType": "cube",
        "name": "Cube 1",
        "parameters": [
          {
             "type": 147,
             "typeName": "BTMParameterQuantity",
             "message": {
               "expression": "1*in",
               "parameterId": "sideLength"
             }
           }
        ]
      }
    }
}

This returns output similar to the following:

{
    "feature": {
        "type": 134,
        "typeName": "BTMFeature",
        "message": {
            "featureType": "cube",
            "featureId": "FuJu9c8PvO5oyTgaV",
            "name": "Cube 1",
            "parameters": [
                {
                    "type": 147,
                    "typeName": "BTMParameterQuantity",
                    "message": {
                        "expression": "1*in",
                        "parameterId": "sideLength",
                        "nodeId": "M+iZRdlIZjnuz8DSS"
                    }
                }
            ],
            "nodeId": "MUdiYYWlCa3arVy8q"
        }
    },
    "featureState": {
        "type": 1688,
        "typeName": "BTFeatureState",
        "message": {
            "featureStatus": "OK"
        }
    },
    "serializationVersion": "1.1.6",
    "sourceMicroversion": "2d31ccc170551a83995b89c8"
}

The output returns us the feature definition that we provided as input with nodeIds and a featureId, plus information telling us that that the feature executed correctly and information about the serialization version and microversion of the document that resulted from our feature addition.

Example 2

In our second example we will create a cube where the sideLength parameter is defined by a variable and will then update the variable to have a new value.

Step 1) Create a variable - we create a feature of type assignVariable, which defines a variable and assigns it a value. Here, the variables name is “size” and is displayed in the feature list as “Cube size”, and it is assigned to have the value “1*in” with a variableType of ANY. Once again, be sure to replace DWE with the the d/:did/w/:wid/e/:eid that is appropriate for the part studio that you are operating against.

A variable can be created with variableType set to “ANY”, “LENGTH”, “ANGLE”, or “NUMBER”. This supplies a constraint on the supplied value and each type requires setting the appropriate corresponding parameter, which would be anyValue, lengthValue, angleValue or numberValue, respectively in addition to setting the value parameter. For the intended purpose of using it as a length value it might be more appropriate to use “LENGTH” as the type, which would require setting the lengthValue and value parameters to a length value. We have chosen to demonstrate the use of the “ANY” type here because it can be used in a wider range of applications than a “LENGTH” variable, but does not provide the value type checking that is provided by “LENGTH”, “ANGLE” or “NUMBER” types.

POST /api/partstudios/DWE/features

{
  "feature" : {
    "type": 134,
    "typeName": "BTMFeature",
    "message": {
        "featureType": "assignVariable",
        "name": "Cube size",
        "parameters": [
            {
                "type": 145,
                "typeName": "BTMParameterEnum",
                "message": {
                    "enumName": "VariableType",
                    "value": "ANY",
                    "parameterId": "variableType"
                }
            },
            {
                "type": 149,
                "typeName": "BTMParameterString",
                "message": {
                    "value": "size",
                    "parameterId": "name"
                }
            },
            {
                "type": 147,
                "typeName": "BTMParameterQuantity",
                "message": {
                    "expression": "1*in",
                    "parameterId": "anyValue"
                }
            }
        ]
    }
  }
}

The returned structure will include a featureId value for the variable. Make note of this value and we will use it in step 3 below.

  1. Create the cube feature, referencing the variable created

POST /api/partstudios/DWE/features

{
  "feature" : {
    "type": 134,
    "typeName": "BTMFeature",
      "message": {
        "featureType": "cube",
        "name": "Cube 1",
        "parameters": [
          {
            "type": 147,
            "typeName": "BTMParameterQuantity",
            "message": {
              "expression": "#size",
              "parameterId": "sideLength"
            }
          }
        ]
      }
    }
}
  1. Update the variable to have a new value. We assume here that the featureId value returned in step 1 is “FuJu9c8PvO5oyTgaV” and we will change the cube size from 1 inch to 10 centimeters.

POST /api/partstudios/DWE/features/featureid/FuJu9c8PvO5oyTgaV

{
  "feature" : {
    "type": 134,
    "typeName": "BTMFeature",
    "message": {
        "featureType": "assignVariable",
        "name": "Cube size",
        "parameters": [
            {
                "type": 145,
                "typeName": "BTMParameterEnum",
                "message": {
                    "enumName": "VariableType",
                    "value": "ANY",
                    "parameterId": "variableType"
                }
            },
            {
                "type": 149,
                "typeName": "BTMParameterString",
                "message": {
                    "value": "size",
                    "parameterId": "name"
                }
            },
            {
                "type": 147,
                "typeName": "BTMParameterQuantity",
                "message": {
                    "expression": "10*cm",
                    "parameterId": "anyValue"
                }
            }
        ]
    }
  }
}

Take a look at the part studio and you will see the cube at its new size. You can edit the Cube size variable and change the value again.

Example 3

In this example, we create a Sketch and extrude it. This demonstrates relationships betweeen features. First, the sketch must be created on a plane, and for convenience, we will use the pre-defined front plane. Then, the extrude needs to describe what is to be extruded, and for convenience, we use the BTMIndividualSketchRegionQuery.

  1. Determine the geometryId for the front plane.

POST /api/features/DWE/featurescript

{
  "script" :
    "function(context is Context, queries)
      {
        return transientQueriesToStrings(evaluateQuery(context, qCreatedBy(makeId(\"Front\"), EntityType.FACE)));
      }",
  "queries" : []
}

This will likely return something like this:

{
  "result": {
    "type": 1499,
    "typeName": "BTFSValueArray",
    "message": {
      "value": [
        {
          "type": 1422,
          "typeName": "BTFSValueString",
          "message": {
            "value": "JCC"
          }
        }
      ]
    }
  },
  "serializationVersion": "1.1.6",
  "sourceMicroversion": "a53cabe7d36e30ee100b1d2a",
  "libraryVersion": 298
}

This tells us that the geometryId for the face created by the “Front” feature is “JCC”.

  1. Determine the geometryId for the Origin

POST /api/features/DWE/featurescript

{
  "script" :
    "function(context is Context, queries)
      {
        return transientQueriesToStrings(evaluateQuery(context, qCreatedBy(makeId(\"Origin\"), EntityType.VERTEX)));
      }",
  "queries" : []
}

This will report the geometryId for the origin (probably with the value “IB”) which we will use in the sketch.

  1. Create the sketch. This will be just a circle on the front plane with its center at the origin and diameter of 1 inch.

POST /api/partstudios/DWE/features

{
  "feature" : {
    "type": 151,
    "typeName": "BTMSketch",
    "message": {
      "entities": [
        {
          "type": 4,
          "typeName": "BTMSketchCurve",
          "message": {
            "geometry": {
              "type": 115,
              "typeName": "BTCurveGeometryCircle",
              "message": {
                "radius": 0.025400000000000002,
                "xDir": 1,
                "yDir": 0
              }
            },
            "centerId": "clAhDfZz-Dgmb-d0AJ-01Cv-JINJdWZLbVj1.center",
            "entityId": "clAhDfZz-Dgmb-d0AJ-01Cv-JINJdWZLbVj1"
          }
        }
      ],
      "constraints": [
        {
          "type": 2,
          "typeName": "BTMSketchConstraint",
          "message": {
            "constraintType": "COINCIDENT",
            "parameters": [
              {
                "type": 149,
                "typeName": "BTMParameterString",
                "message": {
                  "value": "clAhDfZz-Dgmb-d0AJ-01Cv-JINJdWZLbVj1.center",
                  "parameterId": "localFirst"
                }
              },
              {
                "type": 148,
                "typeName": "BTMParameterQueryList",
                "message": {
                  "queries": [
                    {
                      "type": 138,
                      "typeName": "BTMIndividualQuery",
                      "message": {
                        "geometryIds": [
                          "IB"
                        ]
                      }
                    }
                  ],
                  "parameterId": "externalSecond"
                }
              }
            ],
            "entityId": "clAhDfZz-Dgmb-d0AJ-01Cv-JINJdWZLbVj1.centerSnap0"
          }
        },
        {
          "type": 2,
          "typeName": "BTMSketchConstraint",
          "message": {
            "constraintType": "DIAMETER",
            "parameters": [
              {
                "type": 149,
                "typeName": "BTMParameterString",
                "message": {
                  "value": "clAhDfZz-Dgmb-d0AJ-01Cv-JINJdWZLbVj1",
                  "parameterId": "localFirst"
                }
              },
              {
                "type": 147,
                "typeName": "BTMParameterQuantity",
                "message": {
                  "expression": "1*in",
                  "parameterId": "length"
                }
              },
              {
                "type": 147,
                "typeName": "BTMParameterQuantity",
                "message": {
                  "expression": "0.637419526959446*rad",
                  "parameterId": "labelAngle"
                }
              },
              {
                "type": 147,
                "typeName": "BTMParameterQuantity",
                "message": {
                  "expression": "1.76201395706607",
                  "parameterId": "labelRatio"
                }
              }
            ],
            "entityId": "22b5a2c0-d3ea-4376-969d-8b81944035b2"
          }
        }
      ],
      "featureType": "newSketch",
      "name": "Sketch 1",
      "parameters": [
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "queries": [
              {
                "type": 138,
                "typeName": "BTMIndividualQuery",
                "message": {
                  "geometryIds": [
                    "JCC"
                  ]
                }
              }
            ],
            "parameterId": "sketchPlane"
          }
        }
      ]
    }
  }
}
  1. Create the extrude. Here we assume that the previous call returned the sketch with a feature id of “Fj1THqyY7u36ktGSr”. The extrude uses the BTMIndividualSketchRegionQuery, identifying the sketch feature in order to indicate what is to be extruded. The depth of extrude is 1 inch.

POST /api/partstudios/DWE/features

{
  "feature" : {
    "type": 134,
    "typeName": "BTMFeature",
    "message": {
      "featureType": "extrude",
      "name": "Extrude 1",
      "parameters": [
        {
          "type": 145,
          "typeName": "BTMParameterEnum",
          "message": {
            "enumName": "ToolBodyType",
            "value": "SOLID",
            "parameterId": "bodyType"
          }
        },
        {
          "type": 145,
          "typeName": "BTMParameterEnum",
          "message": {
            "enumName": "NewBodyOperationType",
            "value": "NEW",
            "parameterId": "operationType"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "queries": [
              {
                "type": 140,
                "typeName": "BTMIndividualSketchRegionQuery",
                "message": {
                  "featureId": "Fj1THqyY7u36ktGSr"
                }
              }
            ],
            "parameterId": "entities"
          }
        },
        {
          "type": 145,
          "typeName": "BTMParameterEnum",
          "message": {
            "enumName": "BoundingType",
            "value": "BLIND",
            "parameterId": "endBound"
          }
        },
        {
          "type": 147,
          "typeName": "BTMParameterQuantity",
          "message": {
            "expression": "1*in",
            "parameterId": "depth"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "parameterId": "surfaceEntities"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "oppositeDirection"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "parameterId": "endBoundEntityFace"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "parameterId": "endBoundEntityBody"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "hasDraft"
          }
        },
        {
          "type": 147,
          "typeName": "BTMParameterQuantity",
          "message": {
            "expression": "3.0*deg",
            "parameterId": "draftAngle"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "draftPullDirection"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "hasSecondDirection"
          }
        },
        {
          "type": 145,
          "typeName": "BTMParameterEnum",
          "message": {
            "enumName": "SecondDirectionBoundingType",
            "value": "BLIND",
            "parameterId": "secondDirectionBound"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "value": true,
            "parameterId": "secondDirectionOppositeDirection"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "parameterId": "secondDirectionBoundEntityFace"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "parameterId": "secondDirectionBoundEntityBody"
          }
        },
        {
          "type": 147,
          "typeName": "BTMParameterQuantity",
          "message": {
            "expression": "1.0*in",
            "parameterId": "secondDirectionDepth"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "hasSecondDirectionDraft"
          }
        },
        {
          "type": 147,
          "typeName": "BTMParameterQuantity",
          "message": {
            "expression": "3.0*deg",
            "parameterId": "secondDirectionDraftAngle"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "secondDirectionDraftPullDirection"
          }
        },
        {
          "type": 144,
          "typeName": "BTMParameterBoolean",
          "message": {
            "parameterId": "defaultScope"
          }
        },
        {
          "type": 148,
          "typeName": "BTMParameterQueryList",
          "message": {
            "parameterId": "booleanScope"
          }
        }
      ]
    }
  }
}

We see here that there are a lot of parameters that have no values set in them. This is the way features are created by the Onshape web client, buty the unneeded ones could be left out. All of the parameters after “depth” could be omitted without changing the result. However, leaving out a required parameter will normally result in the result reporting a featureStatus of “ERROR”.

Example 4

This example shows an example of configuring a Part Studio with a single Enum (List) input, and a cube feature is created that has its size vary based on the configuration of the Part studio.

  1. Create a configuration for the part studio. This example assumes that you are starting with an unconfigured Part Studio. The Enum input is named “Size”, which 2 options available, “Small” and “Large”.

POST /api/partstudios/DWE/configuration

{
    "configurationParameters": [
        {
            "type": 105,
            "typeName": "BTMConfigurationParameterEnum",
            "message": {
                "enumName": "Size_conf",
                "options": [
                    {
                        "type": 592,
                        "typeName": "BTMEnumOption",
                        "message": {
                            "option": "Small",
                            "optionName": "Small"
                        }
                    },
                    {
                        "type": 592,
                        "typeName": "BTMEnumOption",
                        "message": {
                            "option": "Large",
                            "optionName": "Large"
                        }
                    }
                ],
                "namespace": "",
                "defaultValue": "Small",
                "parameterId": "Size",
                "parameterName": "Size",
                "hasUserCode": false,
                "nodeId": "MgfIjLtd/DvuaT/P/"
            }
        }
    ],
    "currentConfiguration": [
        {
            "type": 145,
            "typeName": "BTMParameterEnum",
            "message": {
                "enumName": "Size_conf",
                "value": "Large",
                "namespace": "",
                "parameterId": "Size"
            }
        }
    ]
}
  1. Create a cube feature in the Part Studio. When the Size configuration input is set to “Small”, the cube will have a sideLength value of “1 in” and when the Size input is set to “Large” it will have a sideLength value of “2 in”.

POST /api/partstudios/DWE/features

{
    "feature": {
        "type": 134,
        "typeName": "BTMFeature",
        "message": {
            "featureType": "cube",
            "name": "Cube 1",
            "parameters": [
                {
                    "type": 2222,
                    "typeName": "BTMParameterConfigured",
                    "message": {
                        "configurationParameterId": "Size",
                        "values": [
                            {
                                "type": 1923,
                                "typeName": "BTMConfiguredValueByEnum",
                                "message": {
                                    "namespace": "",
                                    "enumName": "Size_conf",
                                    "enumValue": "Default",
                                    "value": {
                                        "type": 147,
                                        "typeName": "BTMParameterQuantity",
                                        "message": {
                                            "expression": "1 in"
                                        }
                                    }
                                }
                            },
                            {
                                "type": 1923,
                                "typeName": "BTMConfiguredValueByEnum",
                                "message": {
                                    "namespace": "",
                                    "enumName": "Size_conf",
                                    "enumValue": "Large",
                                    "value": {
                                        "type": 147,
                                        "typeName": "BTMParameterQuantity",
                                        "message": {
                                            "expression": "2 in"
                                        }
                                    }
                                }
                            }
                        ],
                        "parameterId": "sideLength"
                    }
                }
            ]
        }
    }
}