---
title: "Connect Diligent to AI Agents: Sync Evidence and Results Analytics"
slug: connect-diligent-to-ai-agents-sync-evidence-and-results-analytics
date: 2026-10-22
author: Sidharth Verma
categories: ["AI & Agents"]
excerpt: "Learn how to connect Diligent to AI agents using Truto's /tools API. Automate evidence collection, control audits, and risk management with LLMs."
tldr: "A comprehensive engineering guide to building autonomous AI agents on top of Diligent. Bypass JSON:API complexity and ephemeral attachment URLs to automate GRC workflows, evidence syncing, and issue creation."
canonical: https://truto.one/blog/connect-diligent-to-ai-agents-sync-evidence-and-results-analytics/
---

# Connect Diligent to AI Agents: Sync Evidence and Results Analytics


You want to connect Diligent to an AI agent so your system can autonomously sync audit evidence, trigger robot analytics tasks, flag compliance issues, and retrieve control details. Here is exactly how to do it using Truto's `/tools` endpoint and SDK, bypassing the need to build and maintain a custom GRC integration from scratch.

[Governance, Risk, and Compliance (GRC) data](https://truto.one/zero-data-retention-for-ai-agent-security-the-2026-infosec-checklist/) is highly structured and unforgiving. When you give a Large Language Model (LLM) read and write access to your Diligent One Platform, it cannot afford to hallucinate payload structures or misunderstand complex relationship models. If your team uses standard conversational AI interfaces, check out our guide on [connecting Diligent to ChatGPT](https://truto.one/connect-diligent-to-chatgpt-automate-risk-and-compliance-governance/), or if you are building on Anthropic's models, read our guide to [connecting Diligent to Claude](https://truto.one/connect-diligent-to-claude-orchestrate-audit-projects-and-robots/). For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and [bind them](https://truto.one/what-is-llm-function-calling-for-integrations-2026-guide/) to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for Diligent, bind them natively to an LLM using frameworks like LangChain, LangGraph, CrewAI, or the Vercel AI SDK, and execute complex compliance operations. For a broader look at this design pattern across multiple SaaS verticals, read our guide on [Architecting AI Agents: LangGraph, LangChain, and the SaaS Integration Bottleneck](https://truto.one/architecting-ai-agents-langgraph-langchain-and-the-saas-integration-bottleneck/).

## The Engineering Reality of the Diligent API

Giving an LLM access to external GRC data sounds straightforward in a whiteboard session. You write a Node.js function that makes a fetch request and wrap it in a tool decorator. In production against Diligent HighBond, this approach collapses under the weight of the vendor's specific architectural patterns.

Diligent's API introduces several specific integration challenges. If you hardcode these interactions directly into your agent tools, you will spend your engineering cycles writing defensive integration code instead of improving your model's reasoning capabilities.

### The JSON:API Specification Trap

Diligent strictly adheres to the JSON:API specification. Standard LLMs are trained to expect and emit flat, intuitive JSON objects. When an agent wants to create a new compliance issue, it naturally attempts to send a payload like `{"title": "Missing SOC 2 Report", "project_id": "12345"}`. 

Diligent will reject this immediately. The API requires a heavily nested structure defining the data type, ID, attributes, and explicit relationship objects. You must send:

```json
{
  "data": {
    "type": "issues",
    "attributes": {
      "title": "Missing SOC 2 Report"
    },
    "relationships": {
      "project": {
        "data": { "type": "projects", "id": "12345" }
      }
    }
  }
}
```

Forcing an LLM to consistently generate this nested boilerplate across dozens of distinct endpoints leads to high hallucination rates. Truto's Proxy APIs absorb this complexity. The LLM sees a clean, flat tool schema, and Truto maps the outgoing request into the strict JSON:API envelope Diligent requires.

### Ephemeral S3 Redirects for Evidence Files

Retrieving evidence from Diligent is not a simple REST call that returns a binary blob or a permanent URL. When you request to download an attachment (e.g., via the `get_single_diligent_attachment_download_by_id` tool), the API does not return a JSON object. Instead, if the file is stored remotely, Diligent returns a `302 Redirect` to a pre-signed AWS S3 URL.

This pre-signed URL is strictly temporary - often expiring in exactly two minutes. If your agent logic attempts to fetch the URL, pass it to an asynchronous human-in-the-loop review queue, and then download it later, the request will fail. Your tool abstraction must immediately resolve the redirect and buffer the bytes into your own durable storage or directly into the agent's context window.

### Strict Rate Limits with Zero Forgiveness

Diligent enforces strict rate limiting to protect platform stability. Truto's architectural stance on rate limits is explicit: **Truto does not retry, throttle, or apply backoff on rate limit errors.** 

When Diligent returns an HTTP 429 Too Many Requests, Truto passes that error directly to the caller. We normalize the upstream rate limit information into standardized headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`) conforming to the IETF specification. This means your agent runtime is fully responsible for intercepting the 429, reading the reset header, and instructing the LLM to pause or queue the task.

## Diligent Hero Tools for AI Agents

Instead of building individual API wrappers for every Diligent endpoint, Truto exposes `Methods` defined on `Resources` as LLM-ready tools. The agent selects from a deterministic list of [functions](https://truto.one/what-is-llm-function-calling-for-integrations-2026-guide/) with guaranteed schemas.

Here are six high-leverage tools available for Diligent integration.

### Create an Evidence Record

**Tool:** `create_a_diligent_org_evidence`

This tool allows the agent to create a new evidence record in the Diligent Evidence Hub. This is critical for agents acting as automated compliance collectors, taking screenshots or logs from other systems (like AWS or GitHub) and pushing them directly into the GRC platform.

> "I just validated the IAM access logs from AWS. Create a new evidence record in Diligent named 'Q3 AWS IAM Access Review' and attach the validation summary."

### List Table Records

**Tool:** `list_all_diligent_table_records`

Diligent Results relies heavily on data analytic tables. This tool allows the agent to query the raw rows of a data table. Because tables can contain up to 100,000 records, agents must use the query schema to filter by table fields to narrow results down to manageable context sizes.

> "Fetch the records from the 'Failed Login Attempts' table in Diligent Results. Filter for any records where the attempt count is greater than 50 in the last 24 hours."

### Create a Project Issue

**Tool:** `create_a_diligent_project_issue`

When an agent identifies a compliance failure or a control gap, it needs a way to flag it for human review. This tool creates a new issue directly inside a Diligent project. Issues can only be created under active projects.

> "We are missing the SOC 2 Type II report for our new vendor, Acme Corp. Create a high-priority project issue in the 'Vendor Risk Management 2026' project flagging this missing document."

### Retrieve Control Details

**Tool:** `get_single_diligent_org_control_by_id`

Agents tasked with answering GRC questionnaires or verifying configurations need to read the canonical definition of a control. This tool fetches the full JSON:API resource for a control, including its description, framework links, and testing status.

> "Look up control ID 8847 in Diligent. What is the stated frequency for testing this control, and who is the executive owner?"

### Run a Robot Task Immediately

**Tool:** `create_a_diligent_robot_task_run_now`

Diligent ACL Robotics automates data analysis. If an agent needs fresh analytic results before making a decision, it can trigger a robot task to run on-demand. The tool returns the job ID and status, allowing the agent to poll for completion.

> "Trigger the 'Weekly Payroll Exception' robot task in Diligent right now. Let me know when the job queues, and we will wait for the analytic results."

### Download an Attachment

**Tool:** `get_single_diligent_attachment_download_by_id`

Agents often need to read the contents of an uploaded policy document or CSV file. This tool triggers the download flow, handling the 302 redirect to the pre-signed S3 URL. Your agent code must be prepared to handle raw file content rather than a JSON record.

> "Download the attachment with ID 109384 from Diligent. Extract the text from the policy document and check if it mentions 'Zero Trust Architecture'."

For the complete list of Diligent tools and their corresponding JSON schemas, visit the [Diligent integration page](https://truto.one/integrations/detail/diligent).

## Workflows in Action

By chaining these tools, you can build agents that handle complex GRC logic autonomously. Here are two real-world workflows.

### Workflow 1: Continuous Control Monitoring

An IT Compliance Administrator uses an agent to continuously monitor infrastructure configurations and log evidence against Diligent controls.

> "Check the status of the 'AWS IAM MFA' control. If the latest robot analytic shows any users without MFA, create a project issue for them and upload the raw log as a new evidence record."

**Execution Steps:**
1.  The agent calls `get_single_diligent_org_control_by_id` to verify the control exists and belongs to the correct active project.
2.  The agent calls `list_all_diligent_table_records` targeting the Results table that the Diligent robot populates with MFA exceptions.
3.  Finding 3 users without MFA, the agent calls `create_a_diligent_project_issue` under the active project, noting the violation.
4.  The agent formats the log data and calls `create_a_diligent_org_evidence` to permanently seal the finding in the Evidence Hub.

### Workflow 2: Automated Audit Remediation

An Internal Auditor uses an agent to chase down missing documentation and verify robot task execution.

> "Run the 'Stale User Deactivation' robot task in Diligent now. If the job completes successfully, download the output CSV attachment and summarize the terminated users."

**Execution Steps:**
1.  The agent calls `create_a_diligent_robot_task_run_now` passing the specific task ID.
2.  The agent observes the `queued_at` status and enters a wait loop, polling until the job shows `completed_at`.
3.  Once complete, the agent extracts the generated attachment ID and calls `get_single_diligent_attachment_download_by_id`.
4.  The agent intercepts the 302 redirect, downloads the file content before the 2-minute expiration, and reads the CSV to summarize the findings to the auditor.

## Building Multi-Step Workflows

Integrating Diligent tools into your agent framework requires fetching the schemas from Truto and binding them to the model. Because Truto standardizes rate limits into IETF headers but does not absorb them, your agent loop must implement backoff logic natively.

Here is how you architect this using TypeScript, LangChain's `.bindTools()`, and the Truto `/tools` endpoint. This exact pattern applies equally to Vercel AI SDK or CrewAI.

```typescript
import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
import { HumanMessage } from "@langchain/core/messages";

// 1. Initialize the LLM
const model = new ChatOpenAI({
  modelName: "gpt-4o",
  temperature: 0,
});

// 2. Fetch Diligent tools from Truto for this specific integrated account
const trutoManager = new TrutoToolManager({
  apiKey: process.env.TRUTO_API_KEY,
  integratedAccountId: "diligent-account-id-123",
});

const diligentTools = await trutoManager.getTools();

// 3. Bind the Truto tools directly to the LLM
const agentWithTools = model.bindTools(diligentTools);

// 4. Implement a resilient execution loop to handle 429 Rate Limits
async function executeAgentWorkflow(prompt: string) {
  let messages = [new HumanMessage(prompt)];
  let isComplete = false;

  while (!isComplete) {
    try {
      const response = await agentWithTools.invoke(messages);
      messages.push(response);

      if (response.tool_calls && response.tool_calls.length > 0) {
        // The LLM decided to call a Diligent tool
        for (const toolCall of response.tool_calls) {
          console.log(`Executing: ${toolCall.name}`);
          
          // Execute the tool via the Truto manager
          const toolResult = await trutoManager.executeTool(
            toolCall.name,
            toolCall.args
          );
          
          messages.push({
            role: "tool",
            tool_call_id: toolCall.id,
            content: JSON.stringify(toolResult),
          });
        }
      } else {
        // No more tools to call, workflow complete
        isComplete = true;
        return response.content;
      }
    } catch (error) {
      // 5. Handle HTTP 429 Too Many Requests explicitly
      if (error.response && error.response.status === 429) {
        const resetInSeconds = error.response.headers['ratelimit-reset'] || 60;
        console.warn(`Rate limit hit. Agent sleeping for ${resetInSeconds} seconds...`);
        
        // Sleep the agent runtime, then loop will retry the invoke
        await new Promise(resolve => setTimeout(resolve, resetInSeconds * 1000));
      } else {
        throw error;
      }
    }
  }
}

// Trigger the agent
const result = await executeAgentWorkflow(
  "Find control ID 8847. If the test frequency is weekly, trigger the matching robot task now."
);
console.log(result);
```

The architectural flow for this multi-step execution looks like this:

```mermaid
sequenceDiagram
    participant LLM as Agent LLM
    participant Runtime as Agent Runtime
    participant Truto as Truto Proxy API
    participant Diligent as Diligent HighBond

    Runtime->>Truto: GET /integrated-account/{id}/tools
    Truto-->>Runtime: Return JSON schemas for Diligent
    Runtime->>LLM: Bind schemas via .bindTools()
    
    LLM->>Runtime: Emits tool_call (get_single_diligent_org_control_by_id)
    Runtime->>Truto: GET /proxy/controls/8847
    Truto->>Diligent: GET /v1/orgs/{org_id}/controls/8847
    Diligent-->>Truto: Return JSON:API Control Object
    Truto-->>Runtime: Flattened Control JSON
    Runtime->>LLM: Provide tool result
    
    LLM->>Runtime: Emits tool_call (create_a_diligent_robot_task_run_now)
    Runtime->>Truto: POST /proxy/robot_tasks/run
    Truto->>Diligent: POST /v1/orgs/{org_id}/robot_tasks/run
    Diligent-->>Truto: HTTP 429 Too Many Requests
    Truto-->>Runtime: 429 (ratelimit-reset: 60)
    
    Note over Runtime: Runtime intercepts 429<br>Initiates 60s backoff sleep
    Runtime->>Truto: POST /proxy/robot_tasks/run (Retry)
    Truto->>Diligent: POST /v1/orgs/{org_id}/robot_tasks/run
    Diligent-->>Truto: 200 OK (Job ID: 123)
    Truto-->>Runtime: Job ID: 123
    Runtime->>LLM: Provide tool result
```

Building an agent that successfully manages state, reasoning, and context window limits is a hard engineering problem. You should not compound that difficulty by forcing your developers to manually write JSON:API transformation layers, track ephemeral S3 redirect lifecycles, and maintain API specifications for GRC platforms. 

By leveraging Truto's `/tools` endpoint, you provide your agents with clean, deterministic functions, allowing your team to focus on workflow orchestration instead of integration maintenance.

> Stop writing boilerplate API wrappers for your AI agents. Let Truto handle the integration layer so you can focus on building intelligent workflows.
>
> [Talk to us](https://truto.one/book-a-demo/)
