How to Build URL Query Strings
dlo, api
<div class="document-view">
<div class="document-content">
<p>This syntax guide defines how to construct query parameters for filtering, searching, sorting, and paginating records across objects.</p>
<p>The same rules apply consistently across any object that accepts a query string paramter including Data List Objects (DLO) and API calls.</p>
<p><strong>Quick summary:</strong></p>
<ul>
<li>Queries are passed as standard <code>key=value</code> pairs, combined using <code>&</code> (e.g. <code>key=value&key=value</code>).</li>
<li>All normal URL query string rules apply, including URL encoding where required.</li>
<li>This system adds a small set of extensions where operators are placed directly after the <code>=</code> (for example <code>!</code>, <code>*</code>, <code>^</code>, <code>></code>, <code><</code>, and <code>NULL</code>) to control filtering and search behaviour.</li>
</ul>
<p>Once you understand the extensions below, the rest behaves like a standard <code>key=value</code> query string.</p>
<!-- ========================= --><!-- BASIC FORMAT --><!-- ========================= -->
<h2>Basic query format</h2>
<pre><code>?{table}.{field}={value}</code></pre>
<p>Selects records where a field equals the supplied value.</p>
<pre><code>?items.status=active</code></pre>
<!-- ========================= --><!-- FILTERING --><!-- ========================= -->
<h2>Filtering syntax</h2>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Syntax</th>
<th>Example</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Equals</td>
<td><code>?{table}.{field}={value}</code></td>
<td><code>?items.status=active</code></td>
<td>Selects records where the field equals the supplied value.</td>
</tr>
<tr>
<td>Not equals</td>
<td><code>?{table}.{field}=!{value}</code></td>
<td><code>?items.status=!inactive</code></td>
<td>Selects records where the field does not equal the supplied value.</td>
</tr>
<tr>
<td>Empty</td>
<td><code>?{table}.{field}=</code></td>
<td><code>?items.description=</code></td>
<td>Selects records where the field is empty.</td>
</tr>
<tr>
<td>Null</td>
<td><code>?{table}.{field}=NULL</code></td>
<td><code>?items.description=NULL</code></td>
<td>Selects records where the field is null.</td>
</tr>
<tr>
<td>Greater than or equal</td>
<td><code>?{table}.{field}=>={value}</code></td>
<td><code>?items.price=>=100</code></td>
<td>Selects records where the field is greater than or equal to the supplied value.</td>
</tr>
<tr>
<td>Less than or equal</td>
<td><code>?{table}.{field}=<={value}</code></td>
<td><code>?items.price=<=500</code></td>
<td>Selects records where the field is less than or equal to the supplied value.</td>
</tr>
</tbody>
</table>
<!-- ========================= --><!-- TEXT MATCHING --><!-- ========================= -->
<h2>Text matching syntax</h2>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Syntax</th>
<th>Example</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Contains</td>
<td><code>?{table}.{field}=*{value}</code></td>
<td><code>?items.name=*phone</code></td>
<td>For string fields configured with full-text indexing. Matches values that contain the supplied value.</td>
</tr>
<tr>
<td>Starts with</td>
<td><code>?{table}.{field}=^{value}</code></td>
<td><code>?items.name=^pro</code></td>
<td>For string fields configured with auto-complete indexing. Matches values that start with the supplied value.</td>
</tr>
</tbody>
</table>
<!-- ========================= --><!-- FULL TEXT --><!-- ========================= -->
<h2>Full-text search</h2>
<p>Full-text search parameters affect relevance scoring and result ordering. They do not filter records directly.</p>
<table>
<thead>
<tr>
<th>Search type</th>
<th>Syntax</th>
<th>Example</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Search all indexed fields</td>
<td><code>?{table}.q={value}</code></td>
<td><code>?items.q=wireless charger</code></td>
<td>Searches across all full-text indexed fields in the table and applies relevance scoring.</td>
</tr>
<tr>
<td>Search one indexed field</td>
<td><code>?{table}.{field}.q={value}</code></td>
<td><code>?items.name.q=charger</code></td>
<td>Searches a specific full-text indexed field for relevance scoring and ordering.</td>
</tr>
</tbody>
</table>
<!-- ========================= --><!-- COMBINING --><!-- ========================= -->
<h2>Combining multiple parameters</h2>
<p>Multiple query parameters can be combined using <code>&</code>.</p>
<pre><code>?items.status=active&items.price=>=100&items.name=*pro</code></pre>
<!-- ========================= --><!-- SORTING --><!-- ========================= -->
<h2>Sorting</h2>
<p>Use the <code>sort</code> parameter to control result ordering.</p>
<pre><code>?sort={field} ASC</code></pre>
<pre><code>?sort=price DESC</code></pre>
<p>Use <code>ASC</code> for ascending order or <code>DESC</code> for descending order.</p>
<h3>Sorting by multiple fields</h3>
<p>You can sort by multiple fields by separating each rule with a comma.</p>
<pre><code>?sort=price ASC,name DESC</code></pre>
<p>This sorts by <code>price</code> ascending, then by <code>name</code> descending when values are equal.</p>
<!-- ========================= --><!-- PAGINATION --><!-- ========================= -->
<h2>Pagination</h2>
<p>Use <code>pageNumber</code> and <code>pageSize</code> to control which records are returned.</p>
<pre><code>?pageNumber=1&pageSize=25</code></pre>
<!-- ========================= --><!-- RULES --><!-- ========================= -->
<h2>Query Syntax and Interpretation Rules</h2>
<h3>Object, Table, and Field Resolution</h3>
<p>Query parameters follow one of the formats below:</p>
<pre><code>?{table}.{field}={value}
?{object}.{table}.{field}={value}</code></pre>
<p>When an <code>object</code> is provided, the query is resolved only against that object. The specified <code>table</code> must belong to the object, and the <code>field</code> must exist within that table.</p>
<p>If no object is provided, the query applies to <strong>all objects on the current page</strong> that use the specified table.</p>
<p>Use the object-qualified format when:</p>
<ul>
<li>Multiple objects on the page reference the same table</li>
<li>You need to target a specific object without affecting others</li>
</ul>
<h3>Case Sensitivity</h3>
<p>Table and field names are <strong>case sensitive</strong> and must match exactly.</p>
<p>Values are <strong>not case sensitive</strong>.</p>
<pre><code>?items.status=active
?items.status=ACTIVE
?items.status=Active</code></pre>
<h3>Reserved Operators</h3>
<p>The following values are reserved because they are used as query operators:</p>
<pre><code>! , ^ , * , < , <= , > , >= , NULL</code></pre>
<p>If a value begins with a reserved character, wrap it in quotes so it is treated as a literal value.</p>
<pre><code>?items.name="!Special"</code></pre>
<!-- ========================= --><!-- COMPLETE EXAMPLE --><!-- ========================= -->
<h2>Complete example</h2>
<pre><code>/api/data-list/example-list?items.status=active&items.price=>=100&items.name=*pro&sort=price ASC,name DESC&pageNumber=1&pageSize=25</code></pre>
<p>This filters active items, restricts results to price ≥ 100, matches names containing "pro", sorts by price then name, and returns the first page of results.</p>
</div>
</div>