Skip to content

Connect Ashby to AI Agents: Automate Talent Sourcing & Offer Processes

Learn how to connect Ashby to AI Agents using Truto's /tools endpoint. A complete guide to bypassing API quirks, binding 33 Ashby tools, and automating ATS workflows.

Uday Gajavalli Uday Gajavalli · · 7 min read
Connect Ashby to AI Agents: Automate Talent Sourcing & Offer Processes

A recent Gartner study shows that 38% of companies are now incorporating AI into their HR operations, with this number expected to surge to 81%. The mandate is clear: move beyond simple chatbots and build autonomous systems that can actually execute recruiting workflows. Ashby has rapidly become the default Applicant Tracking System (ATS) for high-growth companies, doubling its customer base to over 2,700 organizations - including OpenAI and Shopify - while growing ARR by 135% year-over-year.

When you want to connect Ashby to AI Agents (whether you are connecting Ashby to ChatGPT or Claude) to automate candidate sourcing, update interview stages, or draft offer letters, you hit an immediate engineering wall. As we've seen when connecting other platforms like Pylon to AI agents, giving a Large Language Model (LLM) access to external data sounds simple in a prototype. You write a Node.js function that makes a fetch request, wrap it in an @tool decorator, and call it a day. In production, this approach collapses entirely.

This guide breaks down exactly how to use Truto's /tools endpoint to generate AI-ready tools for Ashby, bind them natively to your LLM using LangChain, and execute complex recruiting workflows autonomously.

The Engineering Reality of the Ashby API

Building AI agents that interact with Ashby requires handling pagination cursors, unique error mapping, and strict rate limits.

If you decide to build a custom integration layer for Ashby, you are responsible for the entire API lifecycle. You have to write and maintain massive JSON schemas for every endpoint you want the LLM to access. You also have to handle a few very specific API quirks that break naive agent implementations.

The HTTP 200 OK Error Trap

Ashby employs a unique approach where many errors return an HTTP 200 status code with a success: false flag buried in the response body. If your AI agent relies on standard HTTP status codes to detect tool failure, it will hallucinate successful operations. The LLM will tell the user "I successfully moved the candidate to the Onsite stage!" when the API actually rejected the payload.

Pagination and Sync Tokens

Many of the list endpoints in Ashby's API (like candidate.list and job.list) implement pagination and incremental synchronization using opaque cursors and syncTokens. LLMs are notoriously bad at managing pagination state on their own. If you build a custom tool, you must explicitly instruct the LLM to pass the nextCursor value back exactly as received. If the model modifies or hallucinates the cursor string, the pagination breaks entirely.

Organizational Rate Limits

Ashby enforces strict rate limits depending on the endpoint. For example, the synchronous reporting endpoint has a limit of 15 requests per minute per organization, with a maximum of 3 concurrent report operations. If your agent runs a parallel execution loop (like a LangGraph executor) without intelligent backoff logic, it will immediately trigger HTTP 429 Too Many Requests errors.

How Truto Normalizes Ashby for AI Agents

Instead of writing 33 custom tool schemas and error handlers, you can use Truto to handle the boilerplate. Truto acts as a proxy and normalization layer between your AI agent and the Ashby API.

  • Dynamic Tool Generation: Truto reads the integration configuration and dynamically generates OpenAPI-compliant tool schemas for every Ashby endpoint. You do not have to write manual JSON schemas for your LLM.
  • Error Expressions: Truto uses JSONata error expressions to intercept Ashby's success: false HTTP 200 responses and remap them to proper HTTP 400 errors. When a tool call fails, the LLM receives a clear, structured error message it can understand and correct.
  • Managed Authentication: Truto handles the entire OAuth lifecycle and API key management. Your agent simply passes a single Truto integrated_account_id.
Info

Not using LangChain? Truto's /tools endpoint returns standard JSON schemas that work with any agent framework, including CrewAI, Vercel AI SDK, and custom LangGraph implementations. Reference our guide on Architecting AI Agents for framework-agnostic approaches.

The Complete Ashby AI Tool Inventory

Truto exposes 33 distinct Ashby operations as ready-to-use tools. When you connect Ashby to AI Agents via Truto, your LLM immediately gains access to the following capabilities. For full schema details, visit the Ashby Integration Page.

Candidate Management

  • ashby_candidates_tag: Add a tag to a candidate in Ashby using candidateId and tagId. Returns candidate details including id and name.
  • ashby_candidates_anonymize: Anonymize a candidate by id in Ashby. Requires candidateId. This action cannot be reversed and requires high-level permissions.
  • update_a_ashby_candidate_by_id: Update an existing candidate by candidateId in Ashby. Returns updated candidate fields including id, name, and primaryEmailAddress.
  • ashby_candidates_project: Add a candidate to a project in Ashby. Requires candidateId and projectId. Returns candidate details.
  • get_single_ashby_candidate_by_id: Get a single candidate by externalMappingId in Ashby. Returns candidate details including id, name, and email address.
  • list_all_ashby_candidates: List candidates in Ashby. Returns candidate id, createdAt, updatedAt, name, primaryEmailAddress, and emailAddresses.

Application Tracking

  • ashby_applications_change_source: Change the source of an application in Ashby. Requires applicationId and sourceId. Returns updated application details.
  • ashby_applications_transfer: Transfer an application with applicationId to a different job with jobId, interviewPlanId, and interviewStageId.
  • update_a_ashby_application_by_id: Update an application by id in Ashby. Requires applicationId. Returns updated application fields including id, status, and candidate info.
  • create_a_ashby_application: Create an application by considering a candidate for a job in Ashby. Requires candidateId and jobId.
  • ashby_applications_change_stage: Change the stage of an application by applicationId and interviewStageId in Ashby. Returns updated application details.
  • get_single_ashby_application_by_id: Fetch application details by id in Ashby. Requires applicationId. Returns id, createdAt, updatedAt, status, and candidate info.
  • list_all_ashby_applications: Get all applications in the organization in Ashby. Returns application id, createdAt, updatedAt, status, and candidate details.

Job Requisitions

  • update_a_ashby_job_by_id: Update an existing job in Ashby by jobId. Returns updated job fields including id, title, status, and locationId.
  • create_a_ashby_job: Create a new job in Ashby with required parameters title, teamId, and locationId. Returns job id, title, and status.
  • ashby_jobs_set_status: Set the status of a job by id in Ashby. Requires jobId and status. Returns updated job fields.
  • list_all_ashby_jobs: List all jobs in Ashby with optional filtering by status. Returns job id, title, status, and employmentType.
  • get_single_ashby_job_by_id: Get information about a specific job in Ashby. Returns fields including id, title, status, and location.

Offer Management

  • get_single_ashby_offer_by_id: Get details about a single offer by id in Ashby. Requires offer id. Returns fields including id, decidedAt, and applicationId.
  • create_a_ashby_offer: Create a new offer with offerProcessId, offerFormId, and offerForm containing fieldSubmissions in Ashby.
  • update_a_ashby_offer_by_id: Update an existing offer by providing offerId and offerForm with fieldSubmissions in Ashby.
  • list_all_ashby_offers: Get a list of all offers with their latest version in Ashby. Returns id, decidedAt, and status.

Department Organization

  • ashby_departments_restore: Restore a department by departmentId in Ashby. Returns the department's id, name, isArchived status, and parentId.
  • delete_a_ashby_department_by_id: Archive a department by departmentId in Ashby. Returns the department's id, name, and isArchived status.
  • ashby_departments_move: Move a department by departmentId to another parent using parentId in Ashby. Returns id, name, and isArchived status.
  • update_a_ashby_department_by_id: Update a department using departmentId and name in Ashby. Returns id, name, isArchived, and parentId.
  • create_a_ashby_department: Create a department with name and optional parentId in Ashby. Returns id, name, isArchived, and parentId.
  • get_single_ashby_department_by_id: Fetch department details by id in Ashby. Requires departmentId. Returns id, name, isArchived, and parentId.
  • list_all_ashby_departments: List all departments in Ashby. Returns id, name, isArchived, and parentId fields for each department.

Interviews & Users

  • get_single_ashby_interview_by_id: Fetch interview details by id in Ashby. Requires id. Returns id, title, isArchived, isDebrief, and instructions.
  • list_all_ashby_interviews: List all interviews in Ashby. Returns id, title, isArchived, isDebrief, and instructionsHtml.
  • list_all_ashby_users: Get a list of all Ashby users. Returns id, firstName, lastName, email, and globalRole.
  • get_single_ashby_user_by_id: Get an Ashby user by id. Requires userId. Returns id, name, email, globalRole, and enabled status.

Step-by-Step Guide: Binding Ashby Tools to Your AI Agent

To connect Ashby to AI Agents, we will use the TrutoToolManager from the official Truto LangChain SDK. This abstracts away the REST API calls and provides native LangChain tool objects that your LLM can invoke.

1. Install the SDK

First, install the Truto LangChain toolset alongside your preferred LLM provider.

npm install @truto/langchainjs-toolset @langchain/openai

2. Initialize the Tool Manager

You need a Truto API key and the integrated_account_id of the specific Ashby account you want the agent to act on.

import { TrutoToolManager } from "@truto/langchainjs-toolset";
import { ChatOpenAI } from "@langchain/openai";
import { createOpenAIToolsAgent, AgentExecutor } from "langchain/agents";
 
// Initialize the Truto Tool Manager
const toolManager = new TrutoToolManager({
  trutoApiKey: process.env.TRUTO_API_KEY,
  integratedAccountId: process.env.ASHBY_INTEGRATED_ACCOUNT_ID,
});

3. Fetch and Bind the Tools

The getTools() method calls Truto's /tools endpoint, fetching the descriptions and JSON schemas for all 33 Ashby operations listed above. It formats them directly into LangChain's expected format.

// Fetch all available Ashby tools dynamically
const tools = await toolManager.getTools();
 
// Initialize your LLM
const llm = new ChatOpenAI({ 
  modelName: "gpt-4o", 
  temperature: 0 
});
 
// Bind the Ashby tools to the LLM
const llmWithTools = llm.bindTools(tools);

4. Execute the Agent Workflow

When the user asks the agent to perform a task, the LLM will select the appropriate tool (e.g., ashby_applications_change_stage), generate the required arguments, and execute the function. Truto handles the actual HTTP request to Ashby.

sequenceDiagram
    participant User
    participant Agent as AI Agent (LangChain)
    participant Truto as Truto Proxy API
    participant Ashby as Ashby API
    
    User->>Agent: "Move John Doe to the Onsite stage"
    Agent->>Truto: Call ashby_applications_change_stage<br>with applicationId & stageId
    Truto->>Ashby: POST /application.changeStage
    Ashby-->>Truto: 200 OK (success: true)
    Truto-->>Agent: Unified JSON Response
    Agent-->>User: "John Doe has been moved to Onsite."

Strategic Next Steps

Building AI agents that execute recruiting workflows requires a reliable integration layer. Writing custom fetch wrappers for Ashby's 33 endpoints is a massive drain on engineering resources, especially when you factor in pagination, rate limiting, and custom error mapping.

By routing your agent's tool calls through Truto, you offload the entire API lifecycle. You get instant access to well-documented tools, robust error handling, and a scalable architecture that works with any LLM framework.

FAQ

How do I connect Ashby to an AI Agent?
You can connect Ashby to an AI agent by using Truto's `/tools` endpoint, which dynamically generates OpenAI-compatible tool schemas for 33 Ashby API operations. This allows frameworks like LangChain or LangGraph to interact with Ashby natively.
What is the 200 OK error trap in the Ashby API?
Ashby often returns an HTTP 200 status code for failed requests, embedding a `success: false` flag in the response body. Truto automatically intercepts and remaps these to proper HTTP errors so your LLM doesn't hallucinate successful tool calls.
Does Truto support LangChain for Ashby integrations?
Yes. Truto provides an official `@truto/langchainjs-toolset` SDK that fetches Ashby tools and binds them directly to your LangChain agents using the `bindTools()` method.
Can my AI agent create job offers in Ashby?
Yes. The `create_a_ashby_offer` tool allows your AI agent to programmatically generate new offers by submitting the required offer process IDs and form submissions directly to Ashby.

More from our Blog

Introducing Truto Agent Toolsets
AI & Agents/Product Updates

Introducing Truto Agent Toolsets

Newest offering of Truto SuperAI. It helps teams using Truto convert the existing integrations endpoints into tools usable by LLM agents.

Nachi Raman Nachi Raman · · 2 min read