Skip to main content

Data Sources

A data source is a named connection to live data: a REST or GraphQL API, a function or MCP tool you already have, a stream of platform events, a webhook, or a built-in query over your own project. The platform fetches the data, caches the result, and serves it to anything that reads the source:

  • Agents read it with the read_data_source tool instead of carrying their own fetch code.
  • Dashboard tiles bound to it show its latest result and update live when it refreshes. See Dashboards.
  • Events. A source can publish a datasource.refreshed event every time it refreshes.

You manage data sources under Resources → Data Sources. The list shows each source's Name, Type (connector type, plus the event transport for streaming sources), Mode (refresh mode), Status and Last refreshed, with Refresh now, View latest data and Delete actions. Choosing a row opens its latest data as a table (or as JSON when the result is not a flat list of records).

What a data source is made of​

PartWhat it decides
Connector type and connector configWhat is fetched and how
IntegrationsWhich integrations supply credentials. Secrets are never stored on the data source
Refresh modeWhen the data is fetched: on demand, on a schedule, or when something pushes to it
Cache TTLHow long a result is served before the next read fetches again. Default 300 seconds
TransformOptional mapping that reshapes each row
Output schemaOptional declared shape; otherwise inferred from the rows
ScopeWho can see and read it
Emit eventWhether each refresh publishes a datasource.refreshed event

Connector types​

Connector typeValueWhere it runsRequired configUse for
REST APIrestPlatformurlAny JSON HTTP API. Supports method, headers, query, body, result_path and pagination (none, page, cursor, link_header, up to 50 pages)
GraphQLgraphqlPlatformurl, queryGraphQL APIs, with optional variables, headers and result_path
FunctionfunctionThe function's sandboxfunction_idAnything a declarative call cannot express: SDKs, several calls stitched together. Optional static args
MCP ToolmcpThe MCP function's runtimefunction_id, toolCalling one tool of an mcp_stdio or mcp_http function. Optional args
Internal Queryinternal_queryPlatformqueryRead-only queries over your own project (below). Optional params
Event Streamevent_streamFed by an event sourceAn event transportLive feeds; each event is folded into the cached rows
WebhookwebhookFed by a webhookNoneProvider pushes, delivered by a webhook linked to the source

The Connector type list on the New Data Source dialog shows the connector types available in your project, each with a configuration form generated from the connector's own description.

Credentials and integration placeholders​

REST and GraphQL configs reference secrets with placeholders, resolved on the server immediately before each request and never written back:

{{integration:<integration_id>:<SECRET_NAME>}}

A placeholder is only resolved for an integration that is attached to the data source (its integration_ids). A placeholder naming any other integration fails with Unresolved integration placeholder, so one source cannot read another integration's secrets. Function and MCP sources pass the attached integrations' credentials into the function's sandbox the same way a workflow node does.

Outbound requests to private, loopback and link-local addresses are always blocked.

Internal queries​

QueryReturns
mission_countsNumber of missions by status
workflow_countNumber of workflows in the project
data_source_countNumber of data sources in the project
element_countsDashboard tiles by element type
token_usageTotal input, output and overall tokens, cost and mission count; optional period such as 7d, 30d or all
active_sessionsActive chat sessions, with a breakdown by phase
manifests_by_typeEvery manifest of one type, one row per manifest (its data plus manifest_* identity fields); optional limit, default 500, maximum 2,000
manifest_countsManifests per type, or with type and group_by, counts of each value of a field within that type
workspace_summaryCounts of dashboards, elements, data sources, workflows, missions and knowledge bases

Push-fed sources: event streams and webhooks​

Event-stream and webhook sources do not fetch; something sends rows to them. Each delivery is folded into the cached rows according to Accumulate:

AccumulateEffect
AppendAdds the new rows after the existing ones
Upsert (by key)Replaces any existing row with the same Key field, appends the rest
ReplaceDiscards the existing rows

Max rows keeps only the most recent rows (default 200). An event-stream source subscribes to an Event transport (an event source). A webhook source is fed by a webhook linked to it (the webhook's data_source_id, set through the API). Through the API you can also push a payload yourself with POST /data-sources/{id}/ingest (tool ingest_data_source_payload).

Where does my dashboard data come from?​

Use the first row that fits. Each is cheaper to keep working than the one below it, because less of it is code you have to maintain.

The data is...UseWhy
The platform's own state: agents, missions, usage, spendAn internal_query source on an agent.* dataset, for example agent.top_agentsThe platform reads it under the viewer's permissions. No code and no credential, so a dashboard built on it cannot go quiet because a function broke. Inside a function the same data is platform_api.call('agentapi', 'dataset_query', ...) with agentapi:dataset_query in the function's Allowed Operations.
In an external system that has a REST or GraphQL APIA rest or graphql source through an integrationThe credential stays in the integration and the request is pinned to its allowed URLs. There is no code to sandbox.
Computed, joined across several calls, or in a protocol the declarative connectors cannot expressA function source whose code uses only the function SDKThe function runs in the sandbox and reaches other systems only through the broker.
Rows in the platform's own databaseNot available to any functionUse the dataset in the first row. A function that imports app.dependencies, connects with psycopg2 or reads DATABASE_URL cannot run in the sandbox.

A function source can use only what the sandbox provides. See What a Local Python function can and cannot do. When a function's code breaks that contract the platform says so when you create the source, and a source whose function fails in the sandbox for that reason shows unsupported_platform_access and what to use instead as its error, rather than "did not return usable data".

Refresh modes​

ModeValueWhat triggers a fetch
On demandon_demandA read that finds the cache empty or older than its TTL, or an explicit refresh
ScheduledscheduledThe platform scheduler, every interval_seconds or on a cron expression in refresh_config
StreamingstreamingEach event from the source's event transport
WebhookwebhookEach delivery from a linked webhook

Every read is served from the cache while it is fresh. Opening a dashboard also warms any bound source whose cache is empty or stale, within a short time budget, so tiles show live data rather than their sample content.

The New Data Source dialog creates on-demand sources (or streaming and webhook sources for those connector types). Create Data Source on a function sets On demand or Scheduled (interval). Any other refresh configuration, including cron schedules, is set through the API or by an agent.

Caching and limits​

  • Each distinct set of query parameters is cached separately, so two tiles that filter the same source differently are cached independently.
  • A failed fetch is cached for about a minute, then retried on the next read. The last good result stays available to serve.
  • A single fetch keeps at most 5,000 rows and 2 MB by default; anything beyond is truncated and the truncation is recorded in the cached result.
  • Old cache entries are cleared after seven days. Disabling a source deletes its cached data.

Status​

StatusMeaning
unknownNever fetched
okThe last fetch succeeded
degradedThe last fetch returned data, but the data reported its own errors (a top-level errors object). Partial data is served
errorThe last fetch failed; the error is recorded on the source

Scope: who can see a data source​

ScopeWho can see and read it
personal (default)Only the person who created it
project or sharedEveryone in the project

Sources created on the Data Sources page and from a function are personal. Set a wider scope through the API or by asking an agent. A dashboard tile bound to a source you cannot read shows its sample content and a No access marker rather than someone else's data.

Transform and output schema​

A transform maps output field names to JSONPath expressions evaluated against each row:

{ "title": "$.title", "author": "$.user.login", "opened": "$.created_at" }

The output schema tells agents and tiles what shape to expect. If you do not declare one, it is inferred from the rows of each fetch.

Agents and data sources​

Three platform functions let an agent work with data sources. An agent can use them once they are assigned to it, like any other function:

ToolWhat it does
list_data_sourcesLists the sources the agent can see: id, name, description, connector type, status, last refreshed, output schema
read_data_sourceReturns a source's rows, schema and status, serving the cache unless asked to force a refresh. Accepts query parameters
create_data_sourceCreates a source. Intended for assistant and orchestrator agents you trust to set up connections

Templates​

Data source templates are pre-configured connectors you instantiate into your project, supplying the integration that holds the credential. Templates are available through the API (/data-source-templates) and the platform tools (list_data_source_templates, instantiate_data_source_template); there is no template picker on the Data Sources page.

Events​

With Emit a datasource.refreshed event on update ticked, every refresh (and every push into an event-stream or webhook source) publishes a datasource.refreshed platform event carrying the source's id, name, row count and status.