---
title: "Connect DualEntry to AI Agents: Orchestrate AP/AR & Bank Matching"
slug: connect-dualentry-to-ai-agents-orchestrate-ap-ar-bank-matching
date: 2026-09-13
author: Sidharth Verma
categories: ["AI & Agents"]
excerpt: Learn how to connect DualEntry to AI agents using Truto's tools endpoint. Build autonomous AP/AR and bank reconciliation workflows using standard LLM frameworks.
tldr: "Connect DualEntry to AI agents safely using Truto's proxy API tools. This guide covers bypassing complex ledger validations, executing asynchronous bank-matching pipelines, handling standard rate limit headers, and binding deterministic schemas to LangChain or CrewAI."
canonical: https://truto.one/blog/connect-dualentry-to-ai-agents-orchestrate-ap-ar-bank-matching/
---

# Connect DualEntry to AI Agents: Orchestrate AP/AR & Bank Matching


You want to connect DualEntry to an AI agent so your system can autonomously ingest vendor bills, execute complex journal entries, and orchestrate the bank matching pipeline. Here is exactly how to do it using Truto's `/tools` endpoint and SDK, bypassing the need to build and maintain a custom DualEntry integration from scratch.

Financial systems are inherently stateful, highly relational, and deeply unforgiving. If your team uses ChatGPT, check out our guide on [connecting DualEntry to ChatGPT](https://truto.one/connect-dualentry-to-chatgpt-manage-general-ledger-multi-entity/), or if you are building on Anthropic's models, read our guide on [connecting DualEntry to Claude](https://truto.one/connect-dualentry-to-claude-automate-revenue-rec-fixed-assets/). For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them natively to your agent framework.

Building an AI agent is an exercise in prompt orchestration and state management. Giving that agent reliable access to external accounting APIs is where projects fall apart. If you decide to build a custom connector, you own the entire API lifecycle. You must write the JSON schemas for the LLM to understand the endpoints, handle the authentication lifecycle, normalize pagination, and parse highly specific error payloads.

This guide breaks down exactly how to fetch AI-ready tools for DualEntry, [bind them to an LLM](https://truto.one/best-unified-api-for-llm-function-calling-ai-agent-tools-2026/) using frameworks like LangChain, LangGraph, CrewAI, or the Vercel AI SDK, and safely execute complex financial operations. For a broader look at this architectural pattern, read our research 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 DualEntry API

Giving an LLM access to external data sounds trivial in a rapid prototype. You write a fetch request and wrap it in a tool decorator. In production, against a strict financial ledger like DualEntry, standard REST assumptions collapse.

DualEntry is not a simple CRUD database. It is a double-entry accounting system bound by strict financial compliance rules, period locks, and asynchronous pipelines. If you hardcode these interactions into your agent without a rigid abstraction layer, you will spend your sprints writing defensive integration code instead of improving your model's reasoning.

### The Draft vs. Posted Validation Trap

When a standard API creates a record, it usually accepts whatever fields you provide as long as the types match. DualEntry enforces intense business logic at the point of creation. By default, when you submit a `POST` request to create an Invoice or a Bill, DualEntry attempts to create it with a `record_status` of `posted`. 

Posting a record triggers a cascade of validations: line item totals must balance, exchange rates must be provided if multi-currency is enabled, and the financial period must not be locked. An LLM generating an invoice from a messy email will frequently hallucinate or omit a required tax code. DualEntry will reject the payload immediately. 

Your agent needs to know that it should explicitly set `record_status: draft` when generating records from unstructured data. Drafts skip the strict validation rules, allowing the agent to save incomplete work for a human accountant to review and approve.

### Asynchronous Bank Matching Pipelines

Reconciling a bank feed against an accounting ledger is rarely a one-to-one mapping. DualEntry abstracts this behind a multi-step, asynchronous bank matching pipeline. 

An LLM cannot simply "match a transaction." It must first trigger the pipeline to populate suggestions. Then, it must poll the status counts to ensure the AI engine and deterministic rules have finished processing. Only then can it fetch the suggested pairings and explicitly confirm them via a match group ID. Exposing this raw async complexity to an LLM drastically increases the risk of hallucination. The agent loses track of where it is in the state machine, attempting to confirm matches before the pipeline completes.

### Intercompany Journal Constraints

Creating a journal entry in DualEntry requires deep relational awareness. If an agent attempts to create an intercompany journal entry, the API enforces that the line items must span at least two distinct `company_id`s, and the total debits must equal the total credits down to the exact decimal, calculated against specific currency exchange rates. An LLM guessing at an ID or rounding a float will result in a 422 Unprocessable Entity.

## Why a Unified Tool Layer Matters for Agent Safety

Before writing integration code, decide what layer your agent interacts with. Direct API tools - one tool per raw DualEntry endpoint - push provider-specific quirks into the LLM's context window. 

A [unified tool layer](https://truto.one/the-best-unified-accounting-api-for-b2b-saas-and-ai-agents-2026/) collapses these complexities behind a stable schema. Your agent sees standard methods bound to resources. This provides three concrete safety wins:

1.  **Deterministic Input Validation:** Every tool is backed by a strict JSON schema. If the LLM attempts to send a string instead of an array of line items, the tool framework rejects the call before it ever hits the DualEntry API, preventing unnecessary network overhead and saving token costs on messy error responses.
2.  **Smaller Attack Surface:** The LLM does not need to memorize the exact structure of DualEntry's tax components or multi-book depreciation schedules unless explicitly required by the tool schema.
3.  **Standardized Rate Limit Handling:** When an agent executes a loop of heavy financial operations, it will hit rate limits. Truto normalizes DualEntry's rate limit information into standardized IETF headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`). 

```mermaid
sequenceDiagram
    participant LLM as Agent Framework
    participant Truto as Truto Proxy
    participant DE as DualEntry API
    LLM->>Truto: Call DualEntry Tool
    Truto->>DE: Transform Request
    DE-->>Truto: Return HTTP 429
    Truto-->>LLM: Pass HTTP 429 with ratelimit headers
    Note over LLM: Agent initiates backoff based on ratelimit-reset
    LLM->>Truto: Retry Tool Call
    Truto->>DE: Transform Request
    DE-->>Truto: Return 200 OK
    Truto-->>LLM: Return normalized JSON
```

*Note on Rate Limits:* Truto does not retry, throttle, or apply backoff on rate limit errors. When DualEntry returns an HTTP 429, Truto passes that error directly to the caller with the normalized headers attached. The caller (your agent framework) is fully responsible for reading the reset window and executing the retry backoff.

## DualEntry Hero Tools for AI Agents

Truto exposes DualEntry endpoints as Proxy APIs, transforming them into [LLM-ready tools](https://truto.one/best-unified-api-for-llm-function-calling-ai-agent-tools-2026/). The `/tools` endpoint serves these definitions automatically. Here are the highest-leverage tools for AP/AR and bank matching workflows.

### 1. create_a_dual_entry_public_invoice

This tool allows the agent to generate Accounts Receivable records. Because it requires nested item lines and specific exchange rates for posted records, it is highly recommended to instruct the agent to use the draft status.

> "Extract the billing items from this attached PDF contract. Create a new invoice for customer ID 'cust_8923'. Set the currency to USD and the record status to draft so the finance team can review the deferred revenue schedules before posting."

### 2. create_a_dual_entry_public_bill

This tool handles Accounts Payable ingestion. The agent can take raw vendor data, map it to the `vendor_id`, and populate the expense lines. Draft bills default to an empty memo, an exchange rate of 1.0, and USD.

> "Read the parsed text from this AWS hosting receipt. Create a bill in DualEntry under vendor ID 'vend_104'. Map the total to expense account 'acc_501' and set the supply date to yesterday."

### 3. create_a_dual_entry_bank_match_populate

This tool is the trigger for DualEntry's async bank-match suggestion pipeline. It runs immediately and returns a 202 Accepted. The agent must understand that calling this tool begins a background process, and it must wait before querying results.

> "Trigger the DualEntry bank match pipeline to evaluate the latest imported bank feed rows against our open ledgers. Let me know when the pipeline has started successfully."

### 4. list_all_dual_entry_bank_match_suggestions

After the pipeline processes, this tool retrieves the AI-driven pairings between a bank-feed row and an accounting transaction. The response includes a `confidence_score` and a `suggestion_type` (indicating if it matches an existing record or requires drafting a new one).

> "Fetch the latest bank match suggestions from DualEntry. Filter the results in memory to only include suggestions with a confidence score higher than 95, and list the financial transaction IDs."

### 5. create_a_dual_entry_bank_match_match

This tool executes the actual reconciliation. The agent passes the `financial_transaction_ids` alongside the corresponding accounting `transaction_ids`. The amounts must reconcile perfectly in a single currency, and all rows must share the same sign.

> "Confirm the bank match for financial transaction ID 'ft_991' against transaction ID 'tx_442'. Ensure you handle the response and confirm the matching status flipped to 'matched'."

### 6. create_a_dual_entry_public_journal_entry

For complex accounting maneuvers, this tool creates direct journal entries. It requires exact balancing of debits and credits across all provided line items. It supports intercompany entries if the lines span multiple company IDs.

> "Create a draft journal entry to record depreciation for the month. Debit account 'acc_700' for $450 and credit accumulated depreciation account 'acc_150' for $450. Set the memo to 'Monthly Server Depreciation'."

To view the complete inventory of DualEntry tools, including endpoints for contracts, fixed assets, and custom fields, visit the [DualEntry integration page](https://truto.one/integrations/detail/dualentry).

## Workflows in Action

Individual tools are useful, but AI agents deliver real value when they chain these tools together to orchestrate multi-step business processes autonomously. Here is how specific personas use these workflows in production.

### Scenario 1: Autonomous AP Ingestion and Payment Preparation

A finance operations manager receives dozens of vendor invoices daily via email. The agent monitors the inbox, extracts the data, and prepares the payments in DualEntry without human data entry.

> "I just forwarded an invoice from Acme Corp for $1,200. Create a bill in DualEntry. Check if the vendor requires prepayment. If not, draft the bill, and prepare a vendor payment record linked to the bill ID. Leave everything in draft status."

**Agent Execution Steps:**
1.  The agent calls `create_a_dual_entry_public_bill` using the extracted text, mapping Acme Corp to the correct vendor ID and setting `record_status` to `draft`.
2.  The agent calls `list_all_dual_entry_public_vendor_prepayments` to check for existing open prepayments for that vendor.
3.  Seeing no prepayments, the agent calls `create_a_dual_entry_public_vendor_payment`, passing the newly created bill ID and setting the payment method to standard ACH draft.

**Result:** The finance team logs into DualEntry to find the bill accurately drafted and the payment staged for approval, eliminating manual data entry.

### Scenario 2: End-to-End Bank Reconciliation

A controller wants to close the books faster at the end of the month by automating the rote task of matching clear-cut bank transactions to open invoices.

> "Run the bank match pipeline for the main operating account. Wait for it to finish, then retrieve all suggestions. Automatically match any suggestion that has a confidence score over 98 and involves a single invoice."

**Agent Execution Steps:**
1.  The agent calls `create_a_dual_entry_bank_match_populate` to initiate the background engine.
2.  The agent loops a call to `list_all_dual_entry_bank_match_status_counts` to check the `unprocessed` and `ai_in_progress` fields, waiting until they hit zero.
3.  The agent calls `list_all_dual_entry_bank_match_suggestions` to retrieve the output.
4.  The agent evaluates the JSON response, filtering for `confidence_score > 98`.
5.  For the high-confidence results, the agent iterates through and calls `create_a_dual_entry_bank_match_match` to lock in the reconciliation.

**Result:** The ledger is instantly reconciled for all deterministic and high-confidence AI matches. The human controller only needs to review the exceptions.

## Building Multi-Step Workflows

To build these autonomous workflows, you must fetch the tools from Truto and bind them to your agent. This approach works natively across any framework that supports OpenAI-compatible function calling, including LangChain, CrewAI, or the Vercel AI SDK.

Here is how you initialize the agent, bind the DualEntry tools, and handle the execution loop using LangChain.js and the Truto SDK.

```typescript
import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIToolsAgent } from "langchain/agents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { TrutoToolManager } from "truto-langchainjs-toolset";

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

  // 2. Fetch DualEntry Tools from Truto
  // Ensure you have TRUTO_API_KEY set in your environment
  const toolManager = new TrutoToolManager({
    integratedAccountId: "your_dualentry_account_id"
  });
  
  // Optionally filter to just write methods to limit context size
  const dualEntryTools = await toolManager.getTools();

  // 3. Bind tools to the prompt
  const prompt = ChatPromptTemplate.fromMessages([
    ["system", "You are a senior accountant. You create bills and execute bank reconciliations in DualEntry. Always set new bills to draft status to prevent posting errors. If a tool fails due to a rate limit, instruct the system to back off and try again."],
    ["human", "{input}"],
    ["placeholder", "{agent_scratchpad}"],
  ]);

  // 4. Create and execute the agent
  const agent = await createOpenAIToolsAgent({
    llm,
    tools: dualEntryTools,
    prompt,
  });

  const agentExecutor = new AgentExecutor({
    agent,
    tools: dualEntryTools,
    maxIterations: 10,
  });

  const result = await agentExecutor.invoke({
    input: "We just received an AWS bill for $4,500. Create a draft bill in DualEntry.",
  });

  console.log(result.output);
}

runDualEntryAgent().catch(console.error);
```

### Handling Rate Limits and Error States

When executing loops - like iterating through bank match suggestions - you will inevitably encounter API rate limits. 

DualEntry enforces rate limits on high-volume requests. Truto respects this by passing the HTTP 429 status code straight through to your agent, alongside the normalized `ratelimit-limit`, `ratelimit-remaining`, and `ratelimit-reset` headers.

Because Truto acts as a pass-through layer, it does not magically absorb the 429 or sit in an arbitrary `sleep()` loop, which could lock up your application threads. Your agent framework must catch the `ToolExecutionError`, read the `ratelimit-reset` timestamp from the headers, and initiate a backoff mechanism before retrying the tool call. Modern frameworks like LangGraph make this straightforward by allowing you to define a retry state node in your execution graph.

## Moving from Integration Boilerplate to Agentic Workflows

Giving AI agents read and write access to a financial ledger is a massive technical responsibility. You cannot afford schema hallucinations, unbalanced journal entries, or silent failures in the bank reconciliation pipeline. 

By routing your agent through a unified tool layer, you trade brittle point-to-point code for deterministic schemas and standardized error handling. Your engineering team stops writing defensive API validation logic and starts focusing on building complex, multi-step financial reasoning loops.

> Ready to connect DualEntry and 100+ other SaaS applications to your AI agents? Get a demo of Truto's [unified tools layer](https://truto.one/the-best-unified-accounting-api-for-b2b-saas-and-ai-agents-2026/) today.
>
> [Talk to us](https://truto.one/book-a-demo/)
