How to Build URL Query Strings

By diamond@localstreets.com Last updated 30/04/26 05:25
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>&amp;</code> (e.g. <code>key=value&amp;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>&gt;</code>, <code>&lt;</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}=&gt;={value}</code></td> <td><code>?items.price=&gt;=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}=&lt;={value}</code></td> <td><code>?items.price=&lt;=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>&amp;</code>.</p> <pre><code>?items.status=active&amp;items.price=&gt;=100&amp;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&amp;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>! , ^ , * , &lt; , &lt;= , &gt; , &gt;= , 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&amp;items.price=&gt;=100&amp;items.name=*pro&amp;sort=price ASC,name DESC&amp;pageNumber=1&amp;pageSize=25</code></pre> <p>This filters active items, restricts results to price &ge; 100, matches names containing "pro", sorts by price then name, and returns the first page of results.</p> </div> </div>