Skip to content

Connect GoCardless to AI Agents: Handle Billing and Outbound Flows

Learn how to connect GoCardless to AI agents using Truto's /tools endpoint. Build autonomous workflows to handle Direct Debits, retries, and outbound payments.

Sidharth Verma Sidharth Verma · · 11 min read
Connect GoCardless to AI Agents: Handle Billing and Outbound Flows

You want to connect GoCardless to an AI agent so your system can independently recover failed payments, generate new direct debit mandates, issue refunds, and initiate outbound payouts based on historical billing context. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to build and maintain a custom GoCardless integration from scratch.

Giving a Large Language Model (LLM) read and write access to a complex financial API like GoCardless is an engineering minefield. You either spend months building strict schema validations, state machine handlers, and rate limit logic, or you use a managed infrastructure layer that handles the translation for you. If your team uses ChatGPT, check out our guide on connecting GoCardless to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting GoCardless to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for GoCardless, bind them natively to an LLM using frameworks like LangChain, LangGraph, CrewAI, or the Vercel AI SDK, and execute complex revenue operations 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 Financial Agents

Before writing a line of integration code, you must decide how your agent will interact with external APIs. When dealing with payments, direct debits, and bank mandates, the stakes are exceptionally high. An agent hallucinating a parameter in a CRM update is an annoyance; an agent hallucinating an amount or currency in a billing request is a critical incident.

Directly wrapping raw GoCardless endpoints as tools exposes your LLM to the full complexity of the underlying API. The model has to memorize exact JSON structures, understand which fields are required based on the scheme (e.g., Bacs vs SEPA vs ACH), and manage intricate error formats.

Using a managed proxy layer like Truto's /tools endpoint collapses these complexities. The agent interacts with strictly typed schemas generated from Truto's internal Proxy APIs. This provides immediate architectural benefits:

  1. Deterministic input validation. Every tool is strictly bounded by a JSON schema. If the LLM attempts to send a string instead of an integer for an amount, or hallucinates an unsupported currency code, the tool call fails locally before a malformed request ever hits the GoCardless API.
  2. Elimination of pagination logic. LLMs are notoriously bad at handling cursor-based pagination. Truto abstracts pagination away at the proxy layer, allowing the agent to request data naturally without managing after or before tokens in its context window.
  3. Framework agnosticism. Because Truto returns standard OpenAPI-style schemas via an API endpoint, your integration layer is decoupled from your agent framework. You can swap LangChain for LangGraph or CrewAI without rewriting your GoCardless tool definitions.

The Engineering Reality of the GoCardless API

Giving an LLM access to external financial data sounds simple until you actually read the API documentation. GoCardless introduces several specific integration challenges that break standard REST assumptions. If you hardcode these interactions into your agent's prompt, you will spend your sprints writing defensive integration code instead of improving your model's reasoning.

The Asynchronous State Machine Trap

Most LLMs are trained to expect synchronous results. If an agent calls a POST endpoint to create a user, it expects the user to be active immediately. GoCardless does not work this way. Direct Debit is fundamentally asynchronous.

When an agent creates a payment against an active mandate, GoCardless returns the payment object with a status of pending_submission. It takes days for the payment to clear the banking networks and transition to confirmed, or fail and become failed. If your agent attempts to execute logic based on the assumption that a just-created payment is already successful, it will fail catastrophically. The agent must be given tools to either poll for status updates or query the list_all_go_cardless_events endpoint to understand state transitions.

Billing Requests vs Legacy Endpoints

The GoCardless API is currently in a transitional phase. Older integrations relied heavily on the legacy Redirect Flows and direct Mandate creation endpoints. GoCardless now strongly pushes integrators toward the Billing Requests API.

The Billing Requests API is a complex, multi-step state machine. You do not just "create a mandate." You create a billing_request, then attach customer details, then attach bank details, then generate an authorization flow, and finally fulfil the request. Expecting an LLM to navigate this raw multi-step dependency tree without strict tool boundaries will result in hallucinated transitions. Your tool layer must clearly describe which step requires the output ID of the previous step.

Rate Limits and the Agent Loop

Financial APIs enforce strict rate limiting to prevent abuse. Truto does not retry, throttle, or apply backoff on rate limit errors. This is a critical architectural fact. When the GoCardless API returns an HTTP 429, Truto passes that error directly back to the caller.

However, Truto normalizes the upstream rate limit information into standardized IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). This means your agent's execution loop must explicitly catch HTTP 429 errors from the tool call, read the ratelimit-reset timestamp, and pause execution. Do not assume the integration layer will magically absorb traffic spikes caused by a looping LLM.

Hero Tools for GoCardless Agents

Truto exposes the entirety of the GoCardless API through the /tools endpoint. However, when building an agent, you should only provide the specific tools necessary for the job to avoid overwhelming the model's context. Here are the highest-leverage tools for automating GoCardless workflows.

Create a Billing Request

Tool Name: create_a_go_cardless_billing_request

This is the modern entry point for collecting payments and setting up mandates. It replaces legacy endpoints and allows your agent to define what needs to be collected (a payment, a mandate, or both) in a single request.

Usage Note: The agent must provide either a payment_request, a mandate_request, or both. The resulting ID (beginning with BRQ) is required for all subsequent actions in the flow.

"Generate a new billing request to set up a GBP mandate for a new enterprise customer. We don't need an immediate payment, just the mandate authorization."

List Mandates

Tool Name: list_all_go_cardless_mandates

Crucial for checking the status of existing authorizations. Before an agent attempts to charge a customer, it should verify that an active mandate exists.

Usage Note: Agents can use this to audit the system, finding mandates that have expired, failed, or been cancelled by the customer at their bank.

"Find all GoCardless mandates for the customer ID CU123456 and tell me if any of them are currently in an active state."

Create a Subscription

Tool Name: create_a_go_cardless_subscription

This tool allows the agent to schedule recurring payments against an active mandate automatically.

Usage Note: Requires a valid mandate ID, the amount in the lowest denomination (e.g., pence or cents), the currency, and the interval (e.g., monthly). The API enforces strict recurrence rules (like valid days of the month), which the tool schema enforces.

"Set up a new monthly subscription for £150 against mandate MD987654. The subscription should charge on the 1st of every month."

Retry a Failed Payment

Tool Name: go_cardless_payments_retry

An essential tool for autonomous revenue recovery operations. If a payment fails due to insufficient funds, the agent can retry it without human intervention.

Usage Note: This tool will fail with a retry_failed error if the payment is not actually in a failed state, or if it has exceeded the maximum of 3 retries per payment. The underlying mandate must still be active.

"Payment PM112233 failed yesterday due to insufficient funds. The customer just emailed saying they topped up their account. Please retry the payment now."

Create an Outbound Payment

Tool Name: create_a_go_cardless_outbound_payment

GoCardless isn't just for collecting money; it can also send it. This tool is vital for AP automation workflows or issuing refunds outside of the standard refund window.

Usage Note: The agent must supply the amount, scheme, description, and links to the creditor and recipient bank account. Outbound payments enter a pending_approval state and must be explicitly approved unless auto-approval is configured.

"We need to issue a manual £50 payout to vendor ID VN445566 for an SLA breach. Create an outbound payment using our primary creditor account."

List All Events

Tool Name: list_all_go_cardless_events

Because GoCardless is heavily asynchronous, events are the source of truth. This tool allows the agent to query the audit trail of what actually happened to a resource.

Usage Note: The agent can filter by resource_type (e.g., payments, mandates) and action (e.g., failed, cancelled) to independently verify state transitions without waiting for webhooks.

"Check the recent events for payment PM998877. Has it transitioned to confirmed yet, or did it fail at the bank level?"

To view the complete inventory of available proxy endpoints and their JSON schemas, visit the GoCardless integration page.

Workflows in Action

Exposing tools is only half the battle. The true value of an AI agent lies in its ability to chain these tools together to execute complex, multi-step workflows. Here is how specific personas use these tools in production.

Scenario 1: Autonomous Failed Payment Recovery (RevOps)

Revenue Operations teams spend hours chasing down failed payments. An AI agent can handle the initial tier of this process entirely autonomously.

"Check for any payments that failed yesterday. If the failure reason was insufficient funds, check if the underlying mandate is still active. If it is active, retry the payment automatically. If the mandate is cancelled, draft an email to the customer."

Step-by-step execution:

  1. The agent calls list_all_go_cardless_events filtering for resource_type=payments and action=failed within the last 24 hours.
  2. For each failed payment returned, the agent calls get_single_go_cardless_payment_by_id to retrieve the associated links.mandate.
  3. The agent calls get_single_go_cardless_mandate_by_id to check the status.
  4. If the status is active, the agent calls go_cardless_payments_retry passing the payment ID.
  5. The agent parses the result to ensure the retry entered the pending_submission state.

Scenario 2: Automated Outbound Vendor Payouts (Finance/AP)

Finance teams need to issue payouts to suppliers or contractors. Instead of logging into a banking portal, they can instruct an agent via Slack or a custom UI.

"We need to pay our contractor 'Acme Corp' their monthly retainer of €2,000. Find their verified bank account in our system and initiate the outbound payment for tomorrow."

Step-by-step execution:

  1. The agent calls list_all_go_cardless_creditor_bank_accounts (or relies on CRM context if integrated elsewhere) to locate the correct recipient bank account ID for 'Acme Corp'.
  2. The agent verifies the account is enabled.
  3. The agent calls create_a_go_cardless_outbound_payment with the amount 200000 (in cents), currency EUR, and the associated links.
  4. The agent returns a summary confirming the payment ID and noting that it is currently in pending_approval status.

Scenario 3: Investigating a Stuck Onboarding Flow (Support)

Customer support often receives tickets like "I tried to sign up but it didn't work." The agent can investigate the underlying Billing Request state machine.

"Customer cu_889900 says they couldn't complete their direct debit setup. Can you check their billing requests and tell me where they got stuck?"

Step-by-step execution:

  1. The agent calls list_all_go_cardless_billing_requests filtering by the customer ID.
  2. It identifies the most recent request and calls get_single_go_cardless_billing_request_by_id.
  3. The agent analyzes the actions array in the response to see which steps are complete (e.g., collect_customer_details is done, but collect_bank_account is pending).
  4. The agent responds to the support rep explaining that the customer dropped off before entering their bank details and provides the authorisation_url to send back to the user.

Building Multi-Step Workflows

To build these workflows, you need a programmatic way to fetch Truto's tools and bind them to your LLM. While direct API calls work, using an SDK like the truto-langchainjs-toolset handles the boilerplate of schema conversion.

Below is a framework-agnostic architectural view of how this integration operates in production.

sequenceDiagram
    participant Agent as LangChain Agent
    participant Truto as Truto /tools API
    participant GC as GoCardless API

    Note over Agent, Truto: Initialization Phase
    Agent->>Truto: GET /integrated-account/<id>/tools?methods[0]=write
    Truto-->>Agent: Returns JSON schemas for tools
    Agent->>Agent: .bindTools() to LLM

    Note over Agent, GC: Execution Phase
    Agent->>Truto: Call go_cardless_payments_retry(payment_id)
    Truto->>GC: POST /payments/<id>/retry
    
    alt Rate Limit Exceeded
        GC-->>Truto: 429 Too Many Requests
        Truto-->>Agent: 429 Error + ratelimit-reset header
        Agent->>Agent: Sleep until ratelimit-reset
        Agent->>Truto: Retry tool call
        Truto->>GC: POST /payments/<id>/retry
        GC-->>Truto: 201 Created (Success)
    else Success
        GC-->>Truto: 201 Created
    end
    
    Truto-->>Agent: Standardized JSON response
    Agent->>Agent: Parse result and continue reasoning

Example: Binding Tools in TypeScript

Here is how you actually write the code to fetch these tools and handle the execution loop. This example uses LangChain, but the core logic - fetching schemas, executing the LLM, and handling rate limits - applies to any agent framework.

import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
import { HumanMessage } from "@langchain/core/messages";
 
async function runGoCardlessAgent() {
  // 1. Initialize the LLM
  const model = new ChatOpenAI({
    modelName: "gpt-4o",
    temperature: 0,
  });
 
  // 2. Initialize the Truto Tool Manager
  // Ensure your TRUTO_API_KEY is set in your environment variables
  const toolManager = new TrutoToolManager({
    integratedAccountId: process.env.GOCARDLESS_INTEGRATED_ACCOUNT_ID!,
  });
 
  // 3. Fetch tools from Truto's API
  // We filter to grab both read and write tools needed for payment recovery
  await toolManager.initialize({
    methods: ["read", "write", "custom"]
  });
 
  const tools = toolManager.getTools();
  console.log(`Loaded ${tools.length} GoCardless tools via Truto.`);
 
  // 4. Bind the tools to the LLM
  const modelWithTools = model.bindTools(tools);
 
  // 5. Provide the prompt
  const messages = [
    new HumanMessage("Check if payment PM12345 failed. If it did, and the mandate is still active, retry the payment.")
  ];
 
  // 6. Basic Agent Execution Loop
  // Note: In production, use LangGraph or a robust state machine for execution.
  while (true) {
    const response = await modelWithTools.invoke(messages);
    messages.push(response);
 
    if (response.tool_calls && response.tool_calls.length > 0) {
      for (const toolCall of response.tool_calls) {
        console.log(`Executing 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: result,
            });
          } catch (error: any) {
            // CRITICAL: Handle Rate Limits
            // Truto passes upstream 429s directly to you. You must handle backoff.
            if (error?.response?.status === 429) {
              const resetTime = error.response.headers.get('ratelimit-reset');
              console.warn(`Rate limited. Reset at: ${resetTime}. Agent should backoff.`);
              // Implement your backoff strategy here before continuing the loop
            }
            messages.push({
              role: "tool",
              tool_call_id: toolCall.id,
              content: `Error executing tool: ${error.message}`,
            });
          }
        }
      }
    } else {
      // The model has finished its reasoning
      console.log("Agent finished:", response.content);
      break;
    }
  }
}
 
runGoCardlessAgent().catch(console.error);

When you use this approach, you are no longer responsible for writing the underlying HTTP request logic, parsing specific GoCardless error XML/JSON formats, or normalizing the authentication headers. Truto handles the transport layer, allowing you to focus entirely on the agent's system prompt and workflow logic.

Moving from Prototyping to Production

Giving AI agents access to financial infrastructure is the ultimate test of your integration architecture. If you rely on point-to-point scripts or unmanaged API wrappers, your agent will inevitably hallucinate invalid bank structures, trigger infinite retry loops against rate limits, or fail to comprehend asynchronous payment states.

By routing your agent's interactions through a strict, schema-validated tool layer, you fundamentally alter the attack surface for hallucination. Your agent operates within safe, deterministic boundaries, interacting with GoCardless the way it was designed to be used.

Stop writing defensive integration code and start building autonomous financial operations.

FAQ

How do AI agents handle asynchronous GoCardless payments?
Agents cannot rely on a single synchronous API call to confirm a Direct Debit. Instead, you provide the agent with tools to check GoCardless events or poll the payment status, allowing it to verify if a payment has transitioned from pending to confirmed or failed.
Does Truto automatically retry rate-limited GoCardless API calls?
No. When the GoCardless API returns an HTTP 429, Truto passes that error directly to your agent, along with standardized IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Your agent framework is responsible for implementing retry and backoff logic.
Which frameworks can I use to bind GoCardless tools?
Truto's /tools endpoint returns standard JSON schemas that can be parsed and bound to any major framework, including LangChain, LangGraph, CrewAI, and the Vercel AI SDK.
Can I restrict my agent to only read data from GoCardless?
Yes. When querying the Truto /tools endpoint, you can filter by methods (e.g., methods[0]=read) to only expose safe, read-only GoCardless endpoints to your LLM.

More from our Blog