Resource Query Language
Learn about Resource Query Language and how to use it.
Resource Query Language (RQL) is a query language used by the Marketplace Platform in its REST API. It's used for querying and manipulating resources in the Marketplace Platform's REST API.
With RQL, you can filter, sort, paginate, and project data. It's simple to use but flexible enough to handle complex scenarios.
Using RQL
RQL consists of a set of operators that can be classified into three main categories:
Comparison operators - These operators perform comparisons like equals, greater than, and so on.
Logical operators - These operators combine multiple conditions.
Algorithmic operators - These operators handle functionalities, like sorting and pagination.
Operators are formatted as operator(arg1,arg2,...). Complex expressions can be created by nesting these operators.
Practical examples
Let's say you want to list all users with a specific domain. Implementing filtering is essential, and this is where RQL comes in.
Basic filtering
To display all users with the first name 'Buzz, your GET request will look like this:
GET /v1/accounts/users?firstName=BuzzThe same expression can be written as:
GET /v1/accounts/users?eq(firstName,Buzz)Sorting
To sort users based on their first name, your GET request will look like this:
To sort in the opposite direction, the '-' operator can be used:
Pagination
To paginate your results with a limit of 10 users and to retrieve the third page (offset 20):
The first parameter
limit=10expresses the number of users to returnThe second parameter
offset=20offsets the starting position in the result set. The first 20 users will be skipped.
Projection
To request specific fields, such as firstName, lastName, and email to be included, the select=+ operator can be used:
To request certain fields to be excluded, the select=- operator can be used:
Search
To search for all users with the first name starting from 'Bu', the following query can be used:
the operator ilike performs a case-insensitive search.
Combining operators
Logical operators can be used to combine multiple operators. For example, to filter users with first name 'Buzz' and last name 'Astral':
In simple cases, a combined expression can also be written in the following form:
Operators
or (<condition1>, <condition2>, ...)
Returns records that satisfy at least one of the specified conditions.
and (<condition1>, <condition2>, ...)
Returns records that satisfy all of the specified conditions.
not (<condition>)
Returns records that do not satisfy the specified condition.
empty ( )
Constant that is used to represent an empty string. Example: /users?firstName=empty()
null ( )
Constant that is used to represent an unassigned ("null") value. Example: /users?firstName=null()
order = +<property1>,-<property2>, ...
Sorts the returned records by <property>. + represents the ascending order, while - represents the descending order.
select = +<property1>, -<property2>, ...
Used to add and remove certain objects from the representation.
offset = <value>
Offsets the starting position in the resulting set.
limit = <value>
Limits the number of returned records by the specified value.
eq (<property>, <value>)
Filters records where <property> exactly matches the <value>.
ne (<property>, <value>)
Filters records where <property> does not match the <value>.
gt (<property>, <value>)
Filters records where <property> is greater than the <value>.
ge (<property>, <value>)
Filters records where <property> is greater or equal to the <value>.
lt (<property>, <value>)
Filters records where <property> is less than the <value>.
le (<property>, <value>)
Filters records where <property> is less than or equal to the <value>.
ilike (<property>, <value>)
Filters records where <property> contains <value> as a substring, the comparison is case-insensitive.
in (<property>,(<value1>,<value2>,...))
Filters records where <property> matches any of the listed <value>s.
out (<property>,(<value1>,<value2>,...))
Filters records where <property> matches none of the listed <value>s.
any (<collection>, <condition>)
Filters records by applying <condition> to the nested <collection> .
all (<collection>, <condition>)
Filters records by applying <condition> to the nested <collection> .
Advanced use cases
Special characters in values
To pass special characters (like, &^$?) or whitespaces as values to RQL operators, enclose them in either double quotes (") or single quotes (') as shown in the following example:
If you need to include a quotation mark within the value, you can do so by enclosing it with a different type of quotation mark, as shown in the following example:
Allowing you to pass these special symbols as values.
The asterisk Character and the ilike operator
The asterisk (*) character has a special meaning in the ilike operator, matching zero or more characters in its place from the parameter value. For example, the "*dog" pattern will match strings like "big dog" and "dog," but it will not match "big dog!" because of the exclamation mark.
If you need to use the asterisk (*) character itself in the pattern, you can escape it as '*', as shown in the following example:
The ilike operator in this case will be searching for the literal value “The*” at the beginning of the firstName property.
Agent Integration Guide
This guide documents key findings and best practices for interacting with the SoftwareOne Platform API, specifically derived from real-world debugging and implementation sessions.
1. Authentication
The API supports standard Bearer token authentication.
Header:
Authorization: Bearer <token>
2. Querying and RQL (Resource Query Language)
One of the most critical findings is how RQL filters must be passed to the API.
The Findings
DO NOT pass RQL as a query parameter value (e.g.,
?rql=and(...)). This often results in400 Bad Requestor "Invalid equals shortcut expression".DO append the RQL string directly to the URL query string.
Syntax Pattern
Incorrect:
Correct:
Combining with Standard Parameters
You can mix RQL with standard parameters like limit and offset.
3. Efficient Resource Counting
To get the count of related resources (e.g., "How many subscriptions does this agreement have?") without fetching all the data:
Query the Child Resource: Target the specific resource endpoint (e.g.,
/commerce/subscriptions).Filter by Parent ID: Use a direct filter parameter if available, or RQL.
Finding: The API often accepts direct property filters like
?agreement.id=AGR-XXX.
Minimize Payload: Set
limit=0.Finding:
limit=0is fully supported and recommended. It returns an emptydataarray but includes the correct count in$meta.pagination.total.
Read Metadata: Extract the count from the response metadata.
Example Request:
Response Structure:
Note: Using limit=0 is the most efficient way to get counts as it minimizes data transfer.
4. Handling Large Datasets (JSONL & Redirects)
When requesting large datasets (e.g., full collections), the API might respond with a 302 Redirect to a file download URL (often for application/jsonl format).
Finding: Clients must handle redirects and potentially download from a secondary URL (e.g., AWS S3).
Header:
Accept: application/jsonlis often used for these bulk operations.
5. Advanced RQL Patterns
Date Filtering
You can filter by date ranges using ISO 8601 strings.
[!IMPORTANT] API Date Requirement: Dates must be in UTC and include 3-digit millisecond precision (e.g.,
YYYY-MM-DDTHH:mm:ss.sssZ).
Nested Collection Filtering with any()
any()The any() operator is powerful for filtering based on properties of nested objects (e.g., finding users in a specific group).
6. Response Metadata
Be aware of metadata fields that affect data processing.
$meta.pagination.total: The total number of records matching the query (useful whenlimit=0).$meta.omitted: A list of properties excluded from the response payload for security or performance reasons (e.g.,["credits"]).
7. Date Fields & Projection
Date fields like created and updated are typically nested within the audit object.
Finding: To filter by these dates OR see them in the response, you MUST explicitly select the
auditobject. The API will not filter by fields that are not selected/visible in the response context.Example:
?select=audit&and(gt(audit.created.at,"2024-01-01..."))
Further resources
For a C# reference implementation of RQL for .NET applications, see the GitHub repository at https://github.com/softwareone-platform/mpt-rql-net.
Last updated
Was this helpful?