Query Data
Query flows let an external system read local Soln form records through an OpenLink entry. A query flow belongs to an OpenLink system, is triggered by an external HTTP request, returns the requested records and their related data, and never writes data back to Soln.
Query flows differ from inbound and outbound flows:
- A query flow has no form binding and no external form mapping
- Its canvas contains exactly one start node, one query node, and one end node
- It is always triggered by
webhook; poll, push, and service call triggers are not available
Query Node Configuration
Select the query node in the design canvas to configure what the flow returns.
| Field | Required | Description |
|---|---|---|
| Root form | Yes | Local form whose records are returned. The query reads this form only |
| Fields | Yes | At least one field of the root form. Only selected fields are returned |
| Child forms | No | Direct child tables of the root form. Each child selects the fields to return |
| Related forms | No | Related local forms reached through a relation field of the root form. Each relation selects the fields to return |
| Limit | No | Default page size, 1-100. Defaults to 20 when it is not set |
After the query node is configured, save the version and publish the flow. Only published query flows accept requests.
Query Endpoint
POST <your-runtime-origin>/api/open-link/query/<flowCode>
Content-Type: application/json
<your-runtime-origin> is the address of the workspace runtime, the same address you use to open Soln in the browser, such as https://runtime.example.com. flowCode is the flow code shown on the flow record: a generated string such as open_link_flow_889b5ea7abae, not the flow definition UUID. The flow's start node in the design canvas shows the complete URL, so copy it from there instead of building it by hand:
https://runtime.example.com/api/open-link/query/open_link_flow_889b5ea7abae
The request must use POST and JSON content type. The system must be active, the flow must be published, and inbound authentication and whitelist rules configured for that system are enforced, exactly like inbound webhook flows. See Inbound Auth.
Request Body
| Field | Type | Description |
|---|---|---|
cursor | String | Opaque cursor returned as nextCursor by the previous identical request |
limit | Integer | Page size for this request. Values above 100 are capped at 100; when omitted, the query node limit is used |
filter | Object | Optional record filter, described below |
Only these three keys are accepted. Any other key, a non-JSON content type, or an invalid value returns OPEN_LINK_QUERY_REQUEST_BODY_INVALID.
Filter
filter is an object keyed by root-form field API names. Each key maps to an operator object. Filter fields must be API names of the root form.
| Operator | Value | Description |
|---|---|---|
eq / neq | Scalar | Equal or not equal |
contains / not_contains | String or string array | Text contains, or does not contain |
in | Array or comma-separated string | Matches any listed value |
gt / gte / lt / lte | Scalar | Numeric or date comparison |
between | Two values or "from,to" | Inclusive range |
empty / not_empty | Not used | Field is empty or not empty |
Add an or key to match any of several groups. Keys outside or are combined with and.
{
"limit": 20,
"filter": {
"status": { "in": ["open", "processing"] },
"created_at": { "gte": "2026-01-01" },
"or": [
{ "owner_email": { "contains": "@example.com" } },
{ "priority": { "eq": "high" } }
]
}
}
Invalid filter shapes return OPEN_LINK_QUERY_FILTER_INVALID; unknown filter fields return OPEN_LINK_QUERY_FILTER_FIELD_INVALID.
Response
{
"flowCode": "orders-query",
"items": [
{
"id": "record-uuid",
"data": { "orderCode": "SO-1" },
"children": { "order_lines": [] },
"relations": {}
}
],
"nextCursor": null
}
| Field | Description |
|---|---|
flowCode | Flow code that served the request |
items | Returned records, limited to the selected root, child, and related fields |
nextCursor | Opaque cursor for the next page, or null when there are no more records |
To read the next page, send the same request with the same filter and limit, and pass nextCursor as cursor. A cursor must be reused with the identical query.
Every request is recorded in the flow execution logs, including failed requests.
Common Errors
| Code | Meaning |
|---|---|
OPEN_LINK_QUERY_FLOW_NOT_FOUND | No query flow matches the flow code |
OPEN_LINK_FLOW_DEFINITION_NOT_PUBLISHED | The flow exists but has not been published |
OPEN_LINK_SYSTEM_NOT_ACTIVE | The OpenLink system is not active |
OPEN_LINK_CONTENT_TYPE_INVALID | The request is not application/json |
OPEN_LINK_QUERY_REQUEST_BODY_INVALID | Unknown body keys or invalid cursor, limit, or filter values |
OPEN_LINK_QUERY_FILTER_INVALID | Filter group or operator is invalid |
OPEN_LINK_QUERY_FILTER_FIELD_INVALID | Filter uses a field that is not an API name of the root form |
OPEN_LINK_INBOUND_RATE_LIMIT_EXCEEDED / OPEN_LINK_INBOUND_CONCURRENCY_LIMIT_EXCEEDED | Inbound rate or concurrency protection rejected the request |
OPEN_LINK_WEBHOOK_AUTH_INVALID / OPEN_LINK_WEBHOOK_TIMESTAMP_EXPIRED | Inbound authentication rejected the request |
OPEN_LINK_WEBHOOK_SOURCE_DENIED | Whitelist rules rejected the caller |
Query flows return data only. They cannot create, update, or delete local records, and they cannot call external systems.
Create, version, and publish query flows with the same Runtime commands as other flows. The command list is in the OpenLink system commands reference.
Recommended Workflow
- Create or select the OpenLink system that owns the query
- Configure inbound authentication and whitelist rules for that system
- Create the query flow with the Runtime command or in the flow list
- Open the design canvas and configure the query node with the root form, returned fields, child forms, related forms, and limit
- Save, publish, and enable the flow
- Call
POST /api/open-link/query/<flowCode>from the external system and review the result in the execution logs