Functions reference
CALL steps invoke functions by function_id. Each function validates its arguments; failures surface as step errors (the run stops along that path).
Use Vibe coding so an assistant can query the semantic schema and wire arguments safely.
Argument and return shapes, edge cases, and SQL dialect notes live in the flow authoring guide.
Data
semantic.query
Runs SQL against the workspace semantic database (accounts, metrics, conversations, tickets, etc.).
Returns: { "results": [...], "columns": [...], "total_rows": N }
{
"function_id": "semantic.query",
"args": {
"query": "SELECT account_id, name, health_score FROM accounts WHERE churned = 0 LIMIT 100"
}
}
Common tables include accounts, meetings, conversations, tickets, topics, notes, tasks, activities, contacts, workspace_users, account_metrics, and dataset_records('your_dataset') for dataset-backed tables. Column lists and types are documented in the flow authoring guide.
data_connection.query
Runs SQL against a configured external connection (warehouse, CRM mirror, etc.).
Args: data_connection_id, query
Returns: Same general shape as semantic.query.
{
"function_id": "data_connection.query",
"args": {
"data_connection_id": "019b3c9e-aaaa-bbbb-cccc-ddddeeeeffff",
"query": "SELECT id, name FROM companies WHERE updated_at > current_timestamp - interval '1' day"
}
}
data_connection.request
Makes an authenticated HTTP request to a vendor's API using a workspace connection's stored credentials — useful for action-only connections (for example DevRev) that don't back a data model, or for calling an endpoint a model doesn't cover.
Args: data_connection_id, method (GET/POST/PUT/PATCH/DELETE), path (no scheme or host — the connection supplies the base URL), optional query, body, and headers (only Accept and Content-Type are forwarded; never pass auth headers here — the connection handles authentication).
Returns: { "status_code": N, "body": ... } — non-2xx responses are still returned, not treated as errors; only transport/read failures raise a step error.
{
"function_id": "data_connection.request",
"args": {
"data_connection_id": "019b3c9e-aaaa-bbbb-cccc-ddddeeeeffff",
"method": "GET",
"path": "/works",
"query": { "id": "{{ $.devrev_issue_id }}" }
}
}
accounts.select
Returns account IDs matching a filter group (AND of OR groups of filters)—the same structured filters used elsewhere in FunnelStory.
Returns: { "total_count": N, "account_ids": ["..."] }
{
"function_id": "accounts.select",
"args": {
"filter": {
"and_group": [
{
"or_group": [
{
"filter": {
"name": "",
"metric_filter": {
"metric_id": "product_engagement",
"condition": "equal",
"value": "daily_active"
}
}
}
]
}
]
}
}
}
Metric and activity IDs are workspace-specific—look them up in your configuration; do not guess.
Datasets
dataset.record.upsert
Creates or replaces a record keyed by string key.
Returns: { "dataset": "...", "key": "..." }
{
"function_id": "dataset.record.upsert",
"args": {
"dataset": "qbr_notes",
"key": "{{ $.account_id }}",
"record": {
"summary": "$.llm_output",
"updated_at": "{{ $.now }}"
}
}
}
Use quoted "$.var" form when passing whole objects; use {{ $.id }} for string interpolation inside SQL or text.
dataset.record.set_field
Updates a single field on an existing record.
dataset.record.delete
Deletes a record by key.
Communication
slack.send_message
Required: connection_id, channel_id, and at least one of text or blocks.
Optional: thread_ts (reply in a thread); attachments — an array of files (filename, data, optional title; up to 10 files, 25 MB total) to share instead of a plain message. data accepts plain text, raw base64, or a data:<mime>;base64,... string. attachments and blocks are mutually exclusive — when you attach files, any text becomes the caption on the file share rather than a separate message.
Returns: { "success": true, "response_channel": "...", "response_timestamp": "..." } (response_timestamp is omitted for file-attachment sends).
{
"function_id": "slack.send_message",
"args": {
"connection_id": "slack_conn_123",
"channel_id": "C01234567",
"text": "{{ $.message }}"
}
}
With a file attachment:
{
"function_id": "slack.send_message",
"args": {
"connection_id": "slack_conn_123",
"channel_id": "C01234567",
"text": "This week's QBR summary",
"attachments": [
{ "filename": "qbr-summary.pdf", "data": "{{ $.report_base64 }}" }
]
}
}
slack.list_users
Lists the users in a Slack workspace, optionally filtered by a search term matched against name, real name, or email. Bots, deleted, and restricted users are excluded.
Args: connection_id, optional search
Returns: { "users": [{ "id": "...", "name": "...", "real_name": "...", "email": "..." }] }
{
"function_id": "slack.list_users",
"args": {
"connection_id": "slack_conn_123",
"search": "priya"
}
}
slack.open_conversation
Opens a direct message (one user) or group DM (2 –8 users), returning a channel id you can pass to slack.send_message.
Args: connection_id, user_ids (1–8 Slack user IDs)
Returns: { "channel_id": "...", "is_mpim": false }
email.send
Required: to, subject, body (plain text). html is optional; body is still required.
Optional: cc, bcc, send_separately, data_connection_id. from is required when data_connection_id is set.
Returns: { "sent": true, "recipients": [...], "recipient_count": N }
{
"function_id": "email.send",
"args": {
"bcc": [],
"send_separately": false,
"subject": "Weekly summary",
"body": "Your weekly summary is ready",
"html": "<p>Your weekly summary is ready</p>"
}
}
Connection-backed send (requires data_connection_id and from):
{
"function_id": "email.send",
"args": {
"data_connection_id": "019b3c9e-...",
"subject": "Weekly summary",
"body": "Your weekly summary is ready"
}
}
CRM
salesforce.read_record / salesforce.update_record
Args: data_connection_id, object_type, record_id, plus fields array for reads or fields object for updates.
salesforce.create_record
Args: data_connection_id, object_type (sObject API name), fields (non-empty object — create body; values may be strings, numbers, booleans, or nested objects where Salesforce accepts them).
Returns: { "id": "<Salesforce Id>", "ok": true }
hubspot.read_record / hubspot.update_record
Args: data_connection_id, object_type (e.g. companies), record_id, and fields as above.
Utility
tasks.create
Creates a FunnelStory task. Title can be driven from template fields; see the flow authoring guide for optional priority, assignee, due date, actions, and references.
template.render
Renders a stored message template by template_id with a vars map.
search.web
Runs a web search; optional recency_filter: 7d, 30d, 90d, 1y.
http.request
Makes a GET request to any public https URL — no connection or authentication required. Use it to pull a public API response or download a public file into the flow.
Args: url (absolute https URL, including any query string)
Returns: { "status_code": N, "body": ... } when the response is JSON, or { "status_code": N, "body_base64": "..." } otherwise.
Responses are capped at 8 MB, and requests to private, loopback, or internal-network hosts are rejected (including redirect targets) — this function can only reach the public internet.
{
"function_id": "http.request",
"args": {
"url": "https://api.example.com/status?id={{ $.record_id }}"
}
}
Related
- Variables and data — interpolation and
$.vs@. - LLM steps — which functions may appear as AGENT tools
- Examples