Data Source Types
A data source is one of two kinds: an API Endpoint call or a Platform Query. The kind determines what you configure — an HTTP request for the first, a query over platform-managed records for the second. The kind is fixed at creation; you cannot switch between types without recreating the data source.
Warning: Each type stores a fundamentally different configuration shape. To convert one type to the other you must create a new data source and reconfigure it from scratch.
API Endpoint
An API endpoint data source calls an HTTP endpoint you point it at. You configure the parts of a standard HTTP request. Method and URL are the only required fields; everything else is optional.
Request Fields
| Field | Type | Required | Description |
| Method | enum | Required (required) | HTTP verb: GET, POST, PUT, PATCH, or DELETE. |
| URL | string | Required (required) | The address to call. Supports binding expressions so the URL can be dynamic. |
| Query Parameters | string map | Optional (optional) | Name–value pairs appended to the URL. Values are strings; bind an expression when a value should follow page state. Structured values must be serialized to a string — there is no nested object support. |
| Headers | string map | Optional (optional) | Name–value pairs sent with the request, such as auth tokens or content-type headers. Values are strings only. |
| Body | object or string | Optional (optional) | Choose none (no body) or raw. A raw body declares its content type: json, xml, text, javascript, or html. A JSON body is edited as a structured object; all other languages are a single text value. |
Note: Only a JSON body is edited field-by-field in the inspector. XML, text, JavaScript, and HTML bodies are a single text value you compose yourself. The response comes back exactly as the endpoint returns it — add a response transform if you need to reshape it.
Example — POST request with JSON body
Method: POST URL: https://api.example.com/orders Headers: Authorization → Bearer {{ envVariables.API_TOKEN }} Body (JSON): { "customerId": "{{ customer_select.value }}", "items": "{{ cart_variable.value }}", "total": "{{ cart_total.value }}" }
Platform Query
A platform query reads data the platform already manages — entity records, stored tables, and other built-in stores — without you writing or hosting an API. Instead of an HTTP request, you use the Query Builder to describe which records you want.
Query Fields
| Field | Required | Description |
| Operation | Required (required) | What kind of read: Lookup (fetch records by query or by keys) or Aggregate (compute over records — counts, sums, averages). |
| Returned Fields | Required (required) | The fields each result row includes. The query returns only what you name; blocks binding to an unselected field read an empty value — no error. |
| Filter Conditions | Optional (optional) | Narrows results on the server. Each condition: a field, an operator (Equals or In), and values. Values can be bound expressions. |
| Sort | Optional (optional) | Orders results server-side before paging. Each sort entry: a field and direction (ASC or DESC). Multiple entries are stacked for tie-breaking. |
| Paging | Optional (optional) | Limit (records per page, default 10) and offset (records to skip). Offset paging replaces the window; for append-on-scroll see Infinite Loading. |
Output Schema — Knowing What a Run Returns
After running a data source, the platform may record an output schema: a JSON Schema describing the shape of the data the run produced. Fetch it from the data source's Output panel after a successful run.
Before binding any block to a data source result, confirm the exact path in the output schema. A wrong path renders empty with no error.
Common Output Shapes
| Source type | Result envelope | Binding path for the list |
| Platform query — multiple records | Object with objects array inside | {{ orders_query.data.objects }} |
| Platform query — single record | Single object (no wrapping array) | {{ order_query.data }} |
| API endpoint | Whatever the endpoint returns | Depends on the API — inspect the Output panel |
Warning: A source configured to return a single record returns an object, not an array. Binding that object where an array is expected (e.g. a Repeatable's data property) renders nothing, silently. Always confirm top-level type — object vs array — before binding.
Note: Most data sources have no output schema until they are run at least once. Before running, you cannot confirm any result path. Run the source in the builder, inspect the Output panel, then bind.
When to Pick Which
| You want to… | Pick |
| Call your own backend or any third-party REST API | API Endpoint |
| Read records the platform stores (entities, tables, audit data) | Platform Query |
| Control the exact HTTP request — verb, headers, raw body | API Endpoint |
| Filter, sort, and page on the server without building an API | Platform Query |
| Data lives inside the platform and you want server-side narrowing for free | Platform Query |
Shared Capabilities
Both kinds share identical capabilities for run timing, caching, and response shaping:
Run Behavior & Triggering — Automatic vs manual, dependency ordering, disable conditions.
Caching & Refetch — Polling, focus refetch, retry, and explicit refresh.
Response Transforms — A JavaScript step to reshape the response before blocks read it.
Infinite Loading — Append-on-scroll pagination for supported operations.
Gotchas
| Gotcha | Details |
| Query parameter and header values are text only | Structured values must be serialized to a string. There is no nested object support in query parameters or headers. |
| A raw non-JSON body is one opaque string | Only a JSON body is edited field-by-field. XML, text, JavaScript, and HTML bodies are a single text value. |
| Unselected fields are simply absent | For platform queries, the response contains only the fields you named. Binding to an unselected field resolves empty — no warning. |
| Wrong top-level type is silent | Binding a single-record object where an array is expected renders nothing. Always check the output schema's top-level type before binding. |
Frequently Asked Questions
Can I switch a data source from API Endpoint to Platform Query later?
No — the type is fixed at creation because each type stores a fundamentally different configuration shape. If you need to change the type, create a new data source of the correct type, reconfigure it, and update all block bindings to reference the new source. Then delete the old one.
My API endpoint returns a deeply nested object. How do I flatten it for my blocks?
Add a Response Transform to the data source. In the transform editor, reshape data — the raw response — into the flat structure your blocks expect, and return it. Blocks then bind to the clean transformed shape. See Response Transforms.
Why does my platform query return an empty value even though data exists?
The most likely cause is that the field you're binding to was not selected in the query's Returned Fields list. The platform query returns only the fields you explicitly name — unselected fields are simply absent, with no warning. Open the query configuration, ensure all needed fields are checked, re-run the source, and verify the shape in the Output panel.
When should I use a Platform Query vs an API Endpoint for the same data?
If the data lives inside the platform (entity records, stored tables, audit logs), use a Platform Query — you get server-side filtering, sorting, and paging without writing any API code. Use an API Endpoint when the data lives outside the platform, when you need a specific HTTP verb (POST, DELETE), or when you need full control over request headers, body format, or authentication.