Skip to content

Connect Hex to AI Agents: Orchestrate Project Runs and Agent Threads

Yuvraj Muley Yuvraj Muley 10 min read AI & Agents
TrutoFor teams building AI agents

Give your AI agent Hex tools.

A comprehensive engineering guide to connecting Hex to AI Agents. Discover how to bypass Hex API quirks, fetch AI-ready tools, and build multi-step LangChain workflows.

In this guide

  1. 01Configure Hex API Access
  2. 02Connect Hex to Truto
  3. 03Fetch Hex Agent Tools
  4. 04Bind Tools to the LLM Framework
  5. 05Implement Polling and Rate Limiting

The guide

Learn how to connect Hex to AI Agents using Truto's /tools endpoint. Build autonomous workflows for project runs, data queries, and AI thread orchestration.

You want to connect Hex to an AI agent so your system can autonomously orchestrate data projects, execute warehouse queries, resolve pipeline failures, and interact with native Hex agent threads. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to build and maintain a custom Hex integration from scratch.

Giving a Large Language Model (LLM) read and write access to your data analytics environment is an engineering headache. You either spend weeks building, hosting, and maintaining a custom API connector, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting Hex to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting Hex to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them directly to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for Hex, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or the Vercel AI SDK), and execute complex data orchestration workflows. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.

Why a Unified Tool Layer Matters for Agent Safety

Before writing a line of integration code, decide what layer your agent talks to. This choice determines how safe and resilient your production system will be when interacting with analytical databases and executing code cells.

Direct API tools - writing one bespoke Python or TypeScript function per raw Hex endpoint - look convenient in a sandbox. But they push provider-specific quirks directly into the LLM's context window. The model has to remember that Hex requires specific wrapped payloads for cell contents, that project statuses must be explicitly checked, and that thread follow-ups fail if the thread is not idle. Every one of those quirks is a hallucination waiting to happen.

Routing your agent through a normalized proxy layer gives you four concrete safety wins:

  1. Smaller attack surface for hallucination. The LLM only ever chooses from stable, semantically clear function names. It does not guess at endpoint structures or invent nested JSON objects.
  2. Deterministic input validation. Every tool provided by Truto has a strict JSON schema. Invalid arguments are rejected before they ever hit the Hex API, so a broken tool call fails fast instead of executing a malformed query against your data warehouse.
  3. Decoupled maintenance. When Hex changes a request format or adds a new required parameter, the proxy layer updates the tool schema dynamically. You do not have to rebuild and redeploy your agent's source code.
  4. Standardized rate limiting. Hex enforces rate limits, and Truto normalizes these into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). While Truto passes the HTTP 429 error directly to you (no silent retries), having predictable headers means you write one backoff function that works for all integrations.

The Engineering Reality of the Hex API

Giving an LLM access to external data sounds simple in a prototype. You write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production against complex analytics environments, this approach collapses.

The Hex API introduces several specific integration challenges that break standard REST assumptions. If you hardcode these interactions into your agent, you will spend your sprints writing defensive integration code instead of improving your model's reasoning.

Asynchronous State and Polling Exhaustion

Hex is designed for heavy compute. When you trigger a project run via the API, the work is not completed synchronously. The API returns a runId and a status of RUNNING. An AI agent natively expects immediate gratification - it makes a tool call and assumes the resulting string is the final answer.

If you do not strictly type and constrain the tool schemas, the LLM will hallucinate the contents of a project run that has not finished. Your agent orchestration loop must be explicitly designed to receive a tracking ID, wait, and use a separate "check status" tool. Hex does not tolerate aggressive polling without hitting rate limits, meaning your agent framework must respect elapsedTime and explicitly implement sleep mechanisms.

Strict Thread Mutexes

Hex features its own internal agent threads that allow users to interact with projects conversationally. The API allows you to programmatically create and follow up on these threads. However, Hex enforces a strict mutex: a thread must be completely IDLE before a follow-up prompt can be sent. Queuing is not supported at the API level.

If an LLM decides to fire off multiple follow-up tools in a parallel tool-calling array (a common behavior in newer models like GPT-4o), Hex will reject the subsequent calls. The integration layer must enforce synchronous execution, and the tool definitions must explicitly instruct the LLM to verify thread status before communicating.

Atomic Batch Failures on Data Connections

When updating data connection schemas - such as adding endorsements or changing statuses on databases, schemas, and tables - Hex requires a bulk update payload. This endpoint is highly volatile for an LLM to navigate because it is strictly atomic. If an agent attempts to update 15 table statuses and hallucinates a single invalid tableId or status string on the 14th item, the entire request fails validation. No changes are applied.

The agent must be equipped with tools that first accurately list queried tables and IDs, strictly map them into the required schema, and execute the batch with precise JSON structuring.

Orchestrating Hex Tools with Truto

Truto maps the underlying Hex API into a REST-based CRUD API using Resources and Methods. Every endpoint in Hex - from project runs to cell image retrieval - is represented as a Method.

Truto handles the authentication handshake, query parameter processing, and schema generation. By calling the GET /integrated-account/<id>/tools endpoint, your system dynamically retrieves all available Proxy APIs as LLM-ready tool definitions.

Below is an architectural view of how an AI agent interacts with Hex through Truto.

sequenceDiagram
    participant Agent as AI Agent Framework
    participant Truto as Truto API Proxy
    participant Hex as Hex API
    
    Agent->>Truto: GET /integrated-account/{id}/tools
    Truto-->>Agent: Return JSON tool schemas
    Agent->>Agent: Bind schemas to LLM
    
    Agent->>Truto: Call create_a_hex_project_run
    Truto->>Hex: POST /api/v1/project/{id}/run
    Hex-->>Truto: Return 200 (runId, RUNNING)
    Truto-->>Agent: Return execution context
    
    loop Polling Loop
        Agent->>Truto: Call get_single_hex_project_run_by_id
        Truto->>Hex: GET /api/v1/project/.../run/{runId}
        Hex-->>Truto: Return status (RUNNING or COMPLETED)
        Truto-->>Agent: Return status
    end

Hero Tools for Hex AI Agents

To build effective data orchestration workflows, you do not need to give the LLM access to every minor configuration endpoint. Focus on high-leverage operations. Here are the hero tools you should expose to your agent for Hex integrations.

Create a Hex Project Run

Tool Name: create_a_hex_project_run

This tool is the execution engine of your workflow. It triggers a run of the latest published version of a Hex project. The LLM must supply the project_id. The response returns crucial routing data, including the runId, runUrl, and traceId.

"Trigger a fresh run for the Q3 Financial Reporting project (ID: 9a8b7c) and give me the run ID so we can monitor its execution."

Get Project Run Status

Tool Name: get_single_hex_project_run_by_id

Because Hex runs asynchronously, this tool acts as the agent's eyes. It retrieves the current status of a specific run using the id and project_id. The agent will check fields like status, elapsedTime, and stateEvents to determine if the pipeline successfully compiled the data.

"Check the status of run ID 12345 on the Q3 Financial Reporting project. If it is still RUNNING, let me know how much time has elapsed."

List Queried Tables

Tool Name: list_all_hex_project_queried_tables

This tool allows the agent to conduct impact analysis before making changes. It lists the warehouse tables queried in a specific Hex project, returning the dataConnectionName and tableName. This is vital for agents tasked with database migrations or schema audits.

"List all the data warehouse tables that are queried by the Customer Churn Prediction project. I need to verify if it relies on the deprecated 'users_v1' table."

Update Data Connection Schemas

Tool Name: hex_data_connection_schemas_bulk_update

An administrative tool that allows the agent to add or remove statuses (like endorsements) on databases, schemas, and tables within a data connection. Because this is an atomic batch operation, the agent must construct the updates payload perfectly. If one update fails validation, the whole batch is rejected.

"Endorse the 'active_subscriptions' and 'churned_accounts' tables in the Snowflake data connection (ID: 5555) to mark them as verified for the analytics team."

Create a Hex Agent Thread

Tool Name: create_a_hex_thread

This tool bridges your external AI agent with Hex's internal agent capabilities. It starts a Hex agent thread with a specified prompt. The Hex agent analyzes the prompt and responds within the Hex environment. The tool returns a threadId, which must be tracked for follow-ups.

"Start a new Hex agent thread analyzing the recent spike in API errors documented in the observability project. Ask the Hex agent to summarize the main contributing factors."

Get Thread Response

Tool Name: get_single_hex_thread_by_id

This tool fetches the response of a Hex agent thread. It is required because thread creation is asynchronous. The external agent uses this tool to check if the Hex agent's status is RUNNING, IDLE, or ERROR, and extracts the final analytical reply content once idle.

"Fetch the response from Hex thread ID 9876. If the thread status is IDLE, output the agent's summary of the API error spike."

For the complete inventory of available Hex tools, including specific parameter requirements and strict JSON schemas, review the Hex integration page.

Workflows in Action

Individual tools are building blocks. True autonomous behavior emerges when an agent chains these tools together to solve multi-step engineering and analytics problems. Here are two concrete workflows showing how an agent navigates the Hex API.

Scenario 1: Autonomous Data Pipeline Auditing

An IT admin wants to safely execute a high-priority data model run and ensure it completes without warehouse connection errors.

"Audit the 'Revenue Forecast 2026' project. Tell me which tables it queries, trigger a new run, and wait until it finishes to give me the final status."

  1. list_all_hex_project_queried_tables: The agent fetches the tables connected to the project ID to verify dependencies.
  2. create_a_hex_project_run: The agent triggers the execution, capturing the runId from the 200 response.
  3. get_single_hex_project_run_by_id: The agent enters a controlled loop, polling this tool. It observes status: RUNNING and eventually receives status: COMPLETED, returning the final elapsedTime and execution state to the user.

Scenario 2: Conversational Data Diagnostics

A Data Scientist needs their external Slack-bot agent to leverage Hex's internal AI to analyze a specific project state, and then follow up based on the findings.

"Ask the Hex agent in a new thread to identify anomalies in the user retention project. Once it replies, send a follow-up prompt asking it to isolate the cohort with the highest drop-off rate."

  1. create_a_hex_thread: The external agent sends the initial prompt, receiving a new threadId.
  2. get_single_hex_thread_by_id: The agent polls the thread. It sees status: RUNNING. It waits, polls again, and detects status: IDLE. It reads the Hex agent's anomaly report.
  3. create_a_hex_thread_followup: Knowing the thread is safely idle, the agent submits the follow-up prompt targeting the highest drop-off cohort, ensuring the strict Hex thread mutex is respected.

Building Multi-Step Workflows

To build this in code, you need an orchestration framework. The following example uses LangChain.js combined with the TrutoToolManager from the truto-langchainjs-toolset.

This script demonstrates how to dynamically fetch Hex tools, bind them to an OpenAI model, and execute a multi-step execution loop. Crucially, it includes explicit error handling for HTTP 429 rate limits, as Truto passes these upstream errors directly to your application along with standard ratelimit-reset headers.

import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
import { TrutoToolManager } from "truto-langchainjs-toolset";
 
async function runHexAgent() {
  // Initialize the LLM
  const llm = new ChatOpenAI({
    modelName: "gpt-4o",
    temperature: 0,
  });
 
  // Initialize the Truto Tool Manager for the specific Hex integrated account
  const toolManager = new TrutoToolManager({
    trutoApiKey: process.env.TRUTO_API_KEY,
    integratedAccountId: "hex_account_abc123",
  });
 
  console.log("Fetching Hex tools via Truto...");
  const tools = await toolManager.getTools();
  
  // Bind the dynamically generated schemas to the LLM
  const llmWithTools = llm.bindTools(tools);
 
  const messages = [
    new HumanMessage("Trigger a run for project ID 'proj_999' and check its status.")
  ];
 
  console.log("Starting agent loop...");
  
  // Basic agent execution loop
  while (true) {
    const response = await llmWithTools.invoke(messages);
    messages.push(response);
 
    // If the LLM decides no more tool calls are needed, exit loop
    if (!response.tool_calls || response.tool_calls.length === 0) {
      console.log("\nFinal Agent Response:", response.content);
      break;
    }
 
    // Execute each tool call requested by the LLM
    for (const toolCall of response.tool_calls) {
      console.log(`\nExecuting tool: ${toolCall.name}`);
      const tool = tools.find((t) => t.name === toolCall.name);
      
      if (tool) {
        try {
          const result = await tool.invoke(toolCall.args);
          messages.push({
            role: "tool",
            tool_call_id: toolCall.id,
            content: JSON.stringify(result),
          });
          console.log(`Tool ${toolCall.name} succeeded.`);
        } catch (error: any) {
          // Explicitly handle HTTP 429 Rate Limits from Truto
          if (error.response && error.response.status === 429) {
            const resetTime = error.response.headers['ratelimit-reset'];
            console.error(`Rate limit hit! Hex requires a backoff. Reset at: ${resetTime}`);
            
            // Implement your retry/sleep logic here based on the resetTime
            // For this example, we push the error back to the LLM to handle gracefully
            messages.push({
              role: "tool",
              tool_call_id: toolCall.id,
              content: `Error: Rate limit exceeded. Backoff required until ${resetTime}.`
            });
          } else {
             messages.push({
              role: "tool",
              tool_call_id: toolCall.id,
              content: `Error executing tool: ${error.message}`
            });
          }
        }
      }
    }
  }
}
 
runHexAgent().catch(console.error);

This pattern works across any modern agent framework. The LLM remains completely decoupled from the auth token lifecycle, pagination logic, and base URL formatting. It simply reasons about the action, formats the JSON arguments, and reads the standardized output.

Moving from Prototype to Production

Building an AI agent that can casually read a Hex project is a fun weekend project. Building an agent that can safely navigate thread mutexes, execute atomic bulk updates against data connection schemas, and manage asynchronous project runs without hallucinating state requires rigorous infrastructure.

You can spend your engineering cycles writing defensive scripts against Hex's specific JSON structures, or you can leverage a proxy layer that normalizes the chaos into deterministic tools.

Two ways to put Hex to work

Truto

For product teams

Give your agent Hex tools

Your customers connect their own Hex accounts. Your product gets one API and MCP tools for Hex, through Truto.

FAQ

How do AI agents handle asynchronous Hex project runs?
AI agents must be programmed with a polling loop. The agent triggers the run using the create tool, receives a runId, and then repeatedly calls the get run status tool until the state resolves to COMPLETED or ERROR.
Does Truto automatically handle Hex API rate limits for my agent?
No. Truto normalizes upstream rate limit information into standard headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) and passes HTTP 429 errors back to the caller. Your agent framework must implement the retry and backoff logic.
Can I queue multiple prompts in a single Hex agent thread?
No. The Hex API enforces a strict mutex on agent threads. The thread must return to an IDLE status before the AI agent can successfully execute a follow-up prompt.
Hex HexAI agent tools Get a sandbox

More from our Blog