OData Query Parameters
Windchill REST Services supports the following query parameters from the OData standard:
$filter—Query criteria to filter the entities in a collection. When you access an entity set, an expression can be specified in the $filter query parameter. With the expression, you can restrict an entity set to only show entities for which the expression evaluation results to true value. OData supports filter expressions for a broad range of primitives. The framework only supports the following subset of OData expressions:
Expressions that use String, Int16, Int32, Int64, Boolean, DateTimeOffset, Single and Double types
Expressions that use comparison operators EQ, NE, GT, LT, GE, LE
Expressions that use logical operators AND, OR
Expressions that use unary operator NOT
Expressions that use the methods startswith, endswith and contains
Expressions that use the isof type checking function with a single argument.
Expressions that use the properties ID, CreatedBy, ModifiedBy, and View
* 
The methods startswith, endswith and contains are not supported for the ID property. For example, $filter=contains(ID,'OR:wt.part.WTPart:112022') is not supported for the ID property.
Windchill REST Services supports $filter query parameter on navigation properties. See the sections Configuring Navigation Properties and Support for $filter on Navigation Properties for more details.
OData enables services to specify the properties of an entity that must not be used in $filter expressions. OData services usually choose to restrict the use of certain properties in $filter expressions because of performance problems. The properties which are restricted for use in the $filter expressions are automatically specified by the framework for Windchill REST Services domains. The FilterRestrictions annotation defined in the Capabilities Vocabulary of OData is used to specify the restricted properties. This annotation is applied to the entity sets available in the domain and is seen in the EDM. Properties that are specified in this annotation are the nonpersistent or server calculated properties of Windchill.
The framework prevents properties specified in this annotation to be queried in the $filter expressions. If clients build query expression with these properties, the server returns an error message. For example, the sample below shows FilterRestrictions annotation applied to the Parts entity set:
<EntitySet Name="Parts" EntityType="PTC.ProdMgmt.Part">

<Annotation Term="Org.OData.Capabilities.V1.FilterRestrictions">
<Record>
<PropertyValue Property="NonFilterableProperties">
<Collection>
<String>VersionID</String>
<String>ChangeStatus</String>
<String>CabinetName</String>
</Collection>
</PropertyValue>
</Record>
</Annotation>

</EntitySet>
* 
It is recommended to apply filtering query criteria on entity set in a large dataset, otherwise it could increase the response time of the request.
$select—Comma-separated list of entity properties that must be returned as a part of the response. For example, in the URL you can list the Document attributes such as, Name and CheckoutState, to display only the name of the document and its checkout status in the response.
$expand—Used to specify the related resources that are to be included in line with retrieved resources. The value of $expand is a comma-separated list of navigations. Each expand item is evaluated relative to the retrieved resource being expanded.
For example, in this POST request you retrieve the component list for a part structure with the action GetPartsList. You can expand the navigation properties Part and PartUses to get more information about the components.
POST /Windchill/servlet/odata/ProdMgmt/Parts('OR:wt.part.WTPart:157919')/PTC.ProdMgmt.GetPartsList?$expand=Part,PartUses HTTP/1.1
$levels—This option is used along with $expand to specify how much information is fetched and returned to the client. The value of the $levels option is either a positive integer to specify the number of levels to expand, or the literal string max which is the maximum expansion level supported by the Windchill Rest Services.
For example, when retrieving large structures, the $levels option limits how much information is returned. To limit structure expansion to N levels, specify $levels=N where N is a positive integer.
$top—Returns the specified number (N) of entities from the top, that is, the first N entities, in a collection.
$skip—Skips the specified number (N) of entities from the top of a collection, and displays the set of entities, N+1 entity onward.
$orderby—Sorts the entities in ascending and descending order. The query parameter is supported for the following:
Primitive attributes—String, Boolean, Integer, Real Number (Double), Date and Time types. See the following sample URL:
//Windchill/servet/odata/ProdMgmt/Parts?$orderby=<Primitive Property> <asc/desc>
Properties—ID, CreatedBy, and ModifiedBy. See the following sample URL:
//Windchill/servet/odata/ProdMgmt/Parts?$orderby=<Property> <asc/desc>
Complex types—The following properties of a complex type support sorting:
QuantityOfMeasureType—Supported for value property. The properties Unit, Precision, and Display do not support sorting.
EnumType—Supported for InternalName property. The property Display does not support sorting.
Hyperlink—Supported for URL property. The property Label does not support sorting.
See the following sample URL:
//Windchill/servet/odata/ProdMgmt/Parts?$orderby=<Complex Property>/<Property> <asc/desc>
Windchill REST Services supports $orderby query parameter on navigation properties. See the sections Configuring Navigation Properties and Support for $orderby on Navigation Properties for more details.
OData enables services to specify the properties of an entity that must not be used in $orderby expressions. The properties which are restricted for use in the $orderby expressions are automatically specified by the framework for Windchill REST Services domains. The SortRestrictions annotation is used to specify the restricted properties. This annotation is applied to the entity sets and complex types available in the domain, and is seen in the EDM. $orderby is not supported for the following properties. These properties are specified by the framework in the SortRestrictions annotation:
Nonpersistent or server calculated properties of Windchill
Properties of complex types that do not support sorting
The framework prevents properties specified in this annotation from being queried in the $orderby expressions. If clients build query expression with these properties, the server returns an error message.
For example, the sample below shows SortRestrictions annotation applied to the QuantityOfMeasureType complex type:
<ComplexType Name="QuantityOfMeasureType">
<Property Name="Value" Type="Edm.Double"/>
<Property Name="Unit" Type="Edm.String">
<Annotation Term="PTC.NonSortable"/>
</Property>
<Property Name="Precision" Type="Edm.Int64">
<Annotation Term="PTC.NonSortable"/>
</Property>
<Property Name="Display" Type="Edm.String">
<Annotation Term="PTC.ReadOnly"/>
<Annotation Term="PTC.NonSortable"/>
</Property>
<Annotation Term="Core.Description">
<String>Used to for Windchill Quantity Of Measure types.</String>
</Annotation>
<Annotation Term="Org.OData.Capabilities.V1.SortRestrictions">
<Record>
<PropertyValue Property="NonSortableProperties">
<Collection>
<String>Precision</String>
<String>Unit</String>
<String>Display</String>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</ComplexType>
$count—Returns the number of items in a collection. When you specify the $count parameter in the URL, it is mandatory to specify the value as either true or false. If no value is specified, an error message is returned.
The count is returned in the response body as "@odata.count": <count_value>.
The following URLs support $count:
URLs for direct entities
URLs for navigation properties
URLs for expanding navigation properties
For example, in the following URL $count is specified as true. The URL returns the count of all the parts available on the server.
ProdMgmt/Parts?$count=true
The query parameters can be used in the following situations:
When you access the entity sets defined in the domain
When you navigate to a collection of entities from a given entity
When you expand navigation properties of entities
Examples of how to use query parameters:
GET request:
ProdMgmt/Parts?$filter=startswith(Number, '00')
The response shows only those parts that start with ‘00’ in the entity set.
GET request:
ProdMgmt/Parts(‘OR:wt.part.WTPart:992345’)/Uses?$filter=Quantity eq 1&$top=1
The response shows the first PartUse entity from the collection of PartUse entities that have Quantity equal to one.
GET request:
ProdMgmt/Parts(‘OR:wt.part.WTPart:992345’)/UsedBy?$filter=ID eq ‘OR:wt.part.WTPart:999999’&$select=Name
The response shows the ID and Name of the part OR:wt.part.WTPart:999999. This denotes that OR:wt.part.WTPart:992345is used by the part OR:wt.part.WTPart:999999.
GET request:
ProdMgmt/Parts(‘OR:wt.part.WTPart:999999’)?$expand=Uses($select=ID;$filter=ID eq ‘OR:wt.part.WTPartUsageLink:260222’)&$select=Name
The response shows the ID and Name of the part OR:wt.part.WTPart:999999 along with the Uses that are filtered based on the usage link ID equals to OR:wt.part.WTPartUsageLink:260222.
GET request:
ProdMgmt/Parts?$filter=ID eq ‘OR:wt.part.WTPart:112022’
The response shows the information of the part with ID equals to ‘OR:wt.part.WTPart:112022’ in the entity set.
GET request:
ProdMgmt/Parts?$filter=ID ne ‘OR:wt.part.WTPart:112022’
The response shows the information of all the parts in the entity set excluding the part with ID equals to ‘OR:wt.part.WTPart:112022’.
GET request:
PrincipalMgmt/Users?$filter=ID eq ‘OR:wt.org.WTUser:11’
The response shows the information of the user with ID equals to ‘OR:wt.org.WTUser:11’.
GET request:
ProdMgmt/Parts?$filter=CreatedBy eq ‘Demo, User’
The response shows the information of the parts that are created by the user ‘Demo, User’ in the entity set.
GET request:
ProdMgmt/Parts?$filter=View eq ‘Service’&ptc.search.latestversion=true
The response shows the information of the parts of only the latest version with the view ‘Service’ in the entity set.
* 
Empty or null search is not supported for the View property. For example, the GET request
ProdMgmt/Parts?$filter=View eq ‘’&ptc.search.latestversion=true
returns an error.
The example below shows how to perform a wildcard (*) search on the structural properties of an entity. Set “PTC-WildcardSearch” to true in the request header to enable wildcard search.
GET request:
ProdMgmt/Parts?$filter=Name eq 'Golf*'
The response shows all the parts with Name equal to the value that matches the wildcard search criteria, that is, Golf*.
* 
Wildcard filtering only supports eq, ne, startswith, endswith, and contains.
Wildcard filtering is not supported for actions, functions, navigation properties, enum and complex types.
GET request:
ProdMgmt/Parts?$expand=Uses($select=Quantity,TraceCode;$filter= Quantity gt 1)
Send this request to server, if you want to expand Uses navigation to only show Quantity and TraceCode properties of PartUse entities that have quantity greater than one.
GET request:
ProdMgmt/Parts(‘OR:wt.part.WTPart:99999’)/Uses?$orderby=Quantity
The response sorts the PartUse entities in ascending order of quantity.
GET request:
ProdMgmt/Parts(‘OR:wt.part.WTPart:99999’)/Uses?$orderby=CreatedOn,Quantity
The response sorts the PartUse entities in ascending order of date on which the entities were created and then on quantity. This sorting is possible when two entities have the same CreatedOn date and different Quantity. The entities are sorted, based on the quantity. However, if the entities have different CreatedOn dates, then the entities are sorted based only on date property.
GET request:
ProdMgmt/Parts?$orderby=ID desc&$select=ID,Name
The response displays the parts with ID and Name attributes while sorting the parts in descending order of ID.
GET request:
ProdMgmt/Parts?$orderby=ModifiedBy asc&$select=ID,Name,ModifiedBy
The response displays the parts with ID, Name, and ModifiedBy attributes while sorting the parts in ascending order of ModifiedBy.
GET request:
ProdMgmt/Parts(‘OR:wt.part.WTPart:99999’)/Uses?$orderby=ID asc&$select=ID
The response shows the usage links for the part in the entity set. The usage links are sorted in ascending order based on the ID property.
GET request:
DocMgmt/Documents?$filter=startswith(Name,'Demo')&$orderby=ZipCodeInasc&$top=2
The response shows the top two documents whose name starts with Demo. The documents are sorted in ascending order of ZipCodeIn.
GET request:
ProdMgmt/Parts('OR:wt.part.WTPart:897988')/UsedBy?$count=true
The example is created for UsedBy navigation. The navigation is available on the Part entity. The response returns the count as "@odata.count": 2.
{
"@odata.context": "//Windchill/servlet/odata/ProdMgmt/$metadata#Parts",
"@odata.count": 2,
"value": [
{
"@odata.type": "#PTC.ProdMgmt.Part",
"ID": "OR:wt.part.WTPart:897456",
...
},
{
"@odata.type": "#PTC.ProdMgmt.Part",
"ID": "OR:wt.part.WTPart:897234",
...
}
]
}
GET request:
ProdMgmt/Parts?$expand=UsedBy($count=true)
The example is created for expanding the UsedBy navigation. The navigation is available on the Part entity. The response returns the count as UsedBy@odata.count": 2.
{
"@odata.context": "//Windchill/servlet/odata/ProdMgmt/$metadata#Parts",
"value": [
{
"@odata.type": "#PTC.ProdMgmt.Part",
"ID": "OR:wt.part.WTPart:89798",
...
"UsedBy@odata.count": 2,
"UsedBy": [
{
"@odata.type": "#PTC.ProdMgmt.Part",
"ID": "OR:wt.part.WTPart:897456",
...
},
{
"@odata.type": "#PTC.ProdMgmt.Part",
"ID": "OR:wt.part.WTPart:897234",
...
}
]
}
]
}