Skip to content

Connect Ashby to ChatGPT: Manage Hiring Pipelines & Candidate Data

Learn how to connect Ashby to ChatGPT using a managed MCP server. Automate candidate sourcing, application updates, and interview scheduling without custom code.

Uday Gajavalli Uday Gajavalli · · 9 min read
Connect Ashby to ChatGPT: Manage Hiring Pipelines & Candidate Data

You want to connect Ashby to ChatGPT so your AI agents can read candidate profiles, update application stages, and draft interview debriefs based on historical context (if you're looking to automate customer support instead, check out our guide on connecting Pylon to ChatGPT). Here is exactly how to do it using a Model Context Protocol (MCP) server.

Giving a Large Language Model (LLM) read and write access to your Ashby Applicant Tracking System (ATS) is an engineering challenge. You either spend weeks building, hosting, and maintaining a custom MCP server, or you use a managed infrastructure layer that handles the boilerplate for you. This guide breaks down exactly how to use Truto's SuperAI to generate a secure, managed MCP server for Ashby, connect it natively to ChatGPT, and execute complex recruiting workflows using natural language.

The Engineering Reality of Custom Ashby Connectors

A custom MCP server is a self-hosted integration layer that translates an LLM's tool calls into REST API requests.

While Anthropic's open standard provides a predictable way for models to discover tools, implementing it against vendor APIs is painful. If you decide to build a custom MCP server for Ashby, you are responsible for the entire API lifecycle.

Pagination and Sync Tokens

Ashby relies heavily on opaque cursors and syncToken logic for incremental synchronization. As we noted when connecting Kandji to ChatGPT, LLMs are notoriously bad at managing pagination state on their own. If you build a custom server, you must explicitly instruct the LLM to pass the nextCursor value back exactly as received. If the model modifies the cursor string, the pagination breaks. You also have to write the logic to handle the syncToken to ensure you only fetch records updated since the last API request.

Strict Schema Maintenance

Ashby's API requires strict adherence to its data types. When moving a candidate to a new stage, you cannot just pass a string - you need the exact interviewStageId. Maintaining massive JSON schemas for 30+ endpoints so the LLM knows exactly which parameters are required takes constant upkeep.

Rate Limits and 429 Errors

Ashby enforces rate limits per API key. While the limits are generous for standard usage, an AI agent summarizing hundreds of candidate notes can easily trigger a 429 Too Many Requests error (a challenge we also covered in our Zendesk integration guide). Your custom server must implement exponential backoff and retry logic, otherwise the LLM simply crashes mid-thought.

How SuperAI Solves This

Instead of forcing a unified data model, SuperAI exposes the raw Ashby API directly to the LLM, but makes it intelligent. Truto automatically injects the necessary semantic descriptions, parameters, and schemas required to turn a raw Ashby endpoint into a highly reliable MCP tool.

When you point ChatGPT at SuperAI, you outsource the integration boilerplate. We handle the pagination instructions, the schema generation, and the rate-limit retries.

Step-by-Step: Connecting Ashby to ChatGPT

Step 1: Obtain your Ashby API Key

Ashby uses Basic Authentication with an API key.

  1. Log into Ashby as an administrator.
  2. Navigate to Settings > API Keys.
  3. Generate a new API key. Ensure it has the necessary permission scopes for the workflows you want to automate (e.g., candidatesRead, candidatesWrite, jobsWrite).

Step 2: Connect the Ashby Account in Truto

Pass the API key into Truto to create an integrated account. Truto securely encrypts and stores the credential, associating it with a unique integrated_account_id.

Step 3: Generate the MCP Server

Truto allows you to generate a self-contained MCP server URL scoped to your specific Ashby account. You can do this via the Truto UI or the API.

Method 1: Via the Truto UI

  1. Navigate to the integrated account page for your Ashby connection.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Select your desired configuration (e.g., restrict to read-only methods, or filter by specific tags).
  5. Copy the generated MCP server URL.

Method 2: Via the API You can programmatically generate the server by making a POST request to the Truto API. This is the preferred method if you are provisioning AI agents for your own customers.

curl -X POST https://api.truto.one/integrated-account/<integrated_account_id>/mcp \
  -H "Authorization: Bearer <your_truto_api_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ashby Recruiting Agent",
    "config": {
      "methods":["read", "write"]
    }
  }'

The API returns a secure URL containing a cryptographic token. This URL alone is enough to authenticate and serve tools to the LLM.

Step 4: Add the MCP Server to ChatGPT

  1. Open ChatGPT and navigate to Settings > Apps > Advanced settings.
  2. Enable Developer mode (requires a Plus, Pro, Team, or Enterprise account).
  3. Under MCP servers / Custom connectors, click Add new.
  4. Name the connector (e.g., "Ashby ATS").
  5. Paste the Truto MCP server URL.
  6. Click Save.

ChatGPT will immediately connect to the URL, execute the MCP handshake, and discover all available Ashby tools.

The Architecture

Here is exactly how the data flows when ChatGPT executes a tool call against Ashby.

sequenceDiagram
    participant LLM as ChatGPT
    participant MCP as Truto MCP Router
    participant Proxy as Truto Proxy API
    participant Ashby as Ashby API

    LLM->>MCP: Call list_all_ashby_candidates (limit: 50)
    Note over MCP: Validates token & extracts integrated account context
    MCP->>Proxy: Route to Ashby candidate.list endpoint
    Note over Proxy: Injects Ashby API Key & handles formatting
    Proxy->>Ashby: POST /candidate.list
    Ashby-->>Proxy: Returns candidate data + nextCursor
    Proxy-->>MCP: Normalizes response
    MCP-->>LLM: Returns JSON with explicit cursor instructions

Full Tool Inventory for Ashby

Once connected, ChatGPT has access to the following tools. We derive these dynamically from Ashby's API definitions. You can view the full list of available tools and their descriptions on the Ashby integration page.

Candidate Management

Candidates are the core entity representing an individual person applying for a job.

  • ashby_candidates_tag: Add a tag to a candidate using candidateId and tagId. Returns candidate details including id and name.
  • ashby_candidates_anonymize: Anonymize a candidate by id. Requires candidateId. This action cannot be reversed and requires high-level permissions.
  • update_a_ashby_candidate_by_id: Update an existing candidate by candidateId. Returns updated candidate fields including id, name, and primaryEmailAddress.
  • ashby_candidates_project: Add a candidate to a project. Requires candidateId and projectId. Returns candidate details.
  • get_single_ashby_candidate_by_id: Get a single candidate by externalMappingId. 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

Applications link a Candidate to a specific Job and track their progress through interview stages.

  • 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

Jobs represent the open roles you are actively hiring for.

  • 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.

Departments and Organization

Departments provide structural categorization for job listings.

  • 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 and Offers

Manage the evaluation loop and final hiring outcomes.

  • 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.
  • 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.

Users

Users represent the recruiters, hiring managers, and interviewers in the system.

  • 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.

Real-World ChatGPT Prompts for Recruiting Workflows

Once connected, you can execute complex, multi-step workflows using plain English. Because the LLM understands the schemas, it knows exactly which tools to chain together.

Scenario 1: Candidate Triage and Tagging

Prompt: "Find all active applications for the 'Senior Frontend Engineer' job. If the candidate applied more than 14 days ago and is still in the 'Initial Screen' stage, tag their candidate profile with 'Needs Review'."

Execution Flow:

  1. ChatGPT calls list_all_ashby_jobs to find the ID for 'Senior Frontend Engineer'.
  2. It calls list_all_ashby_applications filtering by the job ID.
  3. It evaluates the createdAt timestamps and current stage.
  4. For matching records, it calls ashby_candidates_tag using the respective candidateId.

Scenario 2: Orchestrating an Offer

Prompt: "Draft an offer for John Doe for the Data Scientist role. Use the standard engineering offer form. Set the decision deadline to next Friday."

Execution Flow:

  1. ChatGPT calls list_all_ashby_candidates searching for "John Doe".
  2. It calls list_all_ashby_applications to find his active application for the Data Scientist role.
  3. It calls create_a_ashby_offer passing the applicationId, the correct offerFormId, and populating the fieldSubmissions with the deadline date.

Scenario 3: Anonymizing Rejected Candidates (Compliance)

Prompt: "Find all candidates who were rejected more than 2 years ago and anonymize their records to comply with GDPR."

Execution Flow:

  1. ChatGPT calls list_all_ashby_applications filtering by the rejected status.
  2. It checks the updatedAt timestamp.
  3. For applications older than 2 years, it extracts the candidateId.
  4. It calls ashby_candidates_anonymize for each ID.
Warning

The anonymize action is permanent. Always ensure your API key permissions are strictly scoped, and consider requiring a human-in-the-loop confirmation before allowing an AI agent to execute destructive actions.

Strategic Wrap-Up

Building AI agents that interact with your ATS is no longer an API integration problem. It is an orchestration problem.

By using an MCP server, you decouple the complexity of Ashby's API from your agent's core logic. You do not need to write code to handle cursor pagination, manage API keys, or keep JSON schemas up to date. You simply provide the LLM with the right tools and focus on designing the prompts that drive your hiring workflows.

FAQ

How does the Truto MCP server handle Ashby's API rate limits?
Truto's proxy layer automatically manages rate limits and 429 errors. It implements exponential backoff and retries, ensuring the LLM doesn't crash mid-execution when processing large volumes of candidate data.
Can I restrict which Ashby endpoints the AI agent can access?
Yes. When creating the MCP server in Truto, you can use method filtering (e.g., read-only) or tag filtering to strictly limit which tools are exposed to ChatGPT.
Does the LLM handle Ashby's cursor pagination automatically?
Yes. Truto injects explicit instructions into the tool schemas, telling the LLM exactly how to pass the nextCursor value back in subsequent requests without modifying it.

More from our Blog