Skip to content

Connect Penneo to AI Agents: Manage Form Versions & Submissions

Learn how to connect Penneo to AI agents using Truto's /tools endpoint. Bypass custom API wrappers and automate form versions, submissions, and async casefiles.

Uday Gajavalli Uday Gajavalli · · 10 min read
Connect Penneo to AI Agents: Manage Form Versions & Submissions

You want to connect Penneo to an AI agent so your internal systems can independently generate casefiles, manage dynamic form versions, parse submission answers, and track asynchronous signature jobs. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to manually code dozens of API wrappers or manage complex polling logic.

Giving a Large Language Model (LLM) read and write access to your Penneo instance is an engineering challenge. You either spend weeks building, hosting, and maintaining a custom connector that understands the difference between draft and active form states, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting Penneo to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting Penneo 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 Penneo, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex document and signature operations. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.

The Engineering Reality of Custom Penneo Connectors

Building AI agents is easy. Connecting them to external SaaS APIs is hard. Giving an LLM access to external signature and document data sounds simple in a prototype. (While some developers are exploring building MCP servers for AI agents, using a managed toolset endpoint is often the fastest route to production.) You write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production, this approach collapses entirely, especially with a platform as structurally specific as Penneo.

If you decide to build a custom integration for Penneo yourself, you own the entire API lifecycle. The Penneo API introduces several highly specific integration challenges that break standard LLM assumptions.

The Asynchronous Casefile Trap

Standard CRUD APIs return the created object immediately. Penneo's casefile creation does not. When you create a Penneo casefile with documents and signers via a multipart/form-data POST request, the processing is asynchronous. The API returns a job reference, not a completed casefile.

LLMs are notoriously bad at handling asynchronous state. If an agent tries to create a casefile and immediately attempts to fetch the signing links, it will fail because the job is still processing. You must explicitly give the agent a polling tool and prompt instructions on how to use the job UUID and payload hash to check the status queue. If you hand-code this, you are responsible for maintaining the retry loops and state management.

Form Versioning State Machines

Penneo uses a strict state machine for form versioning. A form exists in a Draft, Active, or Archived state. If an AI agent wants to update a form, the API behavior changes based on the current state. If the form is a Draft, the API updates it directly. If the form is Active, the API creates an entirely new Draft version instead of modifying the live asset.

Stateless LLMs lack the historical context to know which version they are interacting with. Without well-defined tools that handle form version logic explicitly (e.g., specific tools for archiving a version vs publishing a version), the agent will repeatedly attempt to mutate active forms and fail or create uncontrolled sprawl of draft versions.

Dynamic Schemas in Form Answers

When an agent retrieves submission answers for a specific casefile or form request, standard REST conventions fail. The returned answer records do not have a predictable, static JSON schema. Instead, the fields are entirely specific to the casefile's underlying form question schema defined inside Penneo.

If an agent is instructed to "extract the client's phone number from the form submission," it cannot rely on a standard phone_number key. The agent must first retrieve the form definition to understand the dynamic schema, and then map those definitions to the arbitrary keys returned in the submission answer payload.

Handling Penneo Rate Limits

A critical note on infrastructure: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream Penneo API returns an HTTP 429, Truto passes that exact error to the caller. Truto normalizes the upstream rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. The caller - meaning your agent's orchestration loop - is responsible for handling the retry and backoff logic so the LLM can pause and resume execution.

Fetching Penneo Tools for Your AI Agent

Instead of manually wrapping Penneo endpoints, you can use Truto to expose Penneo's capabilities directly to your LLM. Truto acts as an integration proxy, translating the underlying Penneo REST endpoints into a standardized JSON array of tools that any modern LLM framework natively understands. This pass-through architecture ensures zero data retention, keeping your sensitive document metadata secure.

Every integration in Truto defines Resources (like forms or casefiles) and Methods (like list, create, or publish). When you connect a Penneo account through Truto, you immediately gain access to a /tools endpoint that outputs the complete schema for that specific tenant.

Here is how you fetch the tools via a standard cURL request:

curl -X GET "https://api.truto.one/integrated-account/{integrated_account_id}/tools" \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY"

The response is a ready-to-use array of tool definitions. Truto handles the OAuth 2.0 lifecycle, token refreshes, and pagination parsing. Your agent simply reads the descriptions, generates a tool call matching the schema, and executes it.

Integrating with LangChain and Vercel AI SDK

If you are using LangChain.js, the truto-langchainjs-toolset package completely abstracts the fetching process. You initialize the tool manager, fetch the tools, and bind them to your model.

import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
 
// 1. Initialize the Truto Tool Manager
const trutoManager = new TrutoToolManager({
  apiKey: process.env.TRUTO_API_KEY!,
});
 
// 2. Fetch all Penneo tools for a specific integrated account
const penneoTools = await trutoManager.getTools(
  process.env.PENNEO_INTEGRATED_ACCOUNT_ID!
);
 
// 3. Initialize your LLM and bind the tools
const llm = new ChatOpenAI({
  modelName: "gpt-4o",
  temperature: 0,
});
 
const agentWithPenneo = llm.bindTools(penneoTools);
 
// The agent is now capable of managing Penneo forms and casefiles autonomously.

Penneo Hero Tools for AI Agents

Penneo has a massive API surface. Exposing the entire API to an LLM at once can blow up the context window and cause decision paralysis. The best practice is to supply your agent with a curated set of "hero tools" - the high-leverage operations that unlock the most valuable workflows.

Here are the critical Penneo tools to bind to your agent.

list_all_penneo_forms

This tool allows the agent to discover existing forms within the Penneo instance, including filtering by status (Draft, Active, Archived) and retrieving the base signer configurations. Agents use this to locate the id required for subsequent updates or submissions.

"Find the active NDA form in our Penneo account and summarize its signer configuration requirements."

update_a_penneo_form_version_by_id

This tool handles the complex versioning state machine. The agent can submit sections and input fields to modify a form. If the agent targets an active form, this tool will automatically handle the underlying logic to generate a new draft version containing the updates.

"Update the draft version of the Employee Onboarding form by adding a new text input field for 'Emergency Contact Number'."

list_all_penneo_form_submissions

Agents use this tool to track when end-users have completed a specific form. It returns high-level metadata (like created_at identifiers). The agent can filter this list using ISO-8601 UTC datetimes to find recent submissions.

"Check if there are any new submissions for the Vendor Intake form completed after 08:00 UTC this morning."

list_all_penneo_form_submission_answers

Once a submission is located, this tool retrieves the actual answer data. Because the schema is dynamic and tied to the form definition, the agent must parse the returned object specifically to extract the needed business logic.

"Retrieve the answers for the latest Vendor Intake form submission and extract the submitted tax identification number."

create_a_penneo_casefile

This tool initiates the creation of a new Penneo case file containing documents and signers via a multipart/form-data POST request. The agent will receive an asynchronous job reference back, which it must use for status polling.

"Generate a new casefile for the provided employment contract PDF, setting the new hire as the primary signer. Acknowledge the job ID once initiated."

create_a_penneo_job_status

This is the critical polling tool. The agent uses the UUID and payload hash returned from the casefile creation to check if Penneo has finished processing the documents and generated the signing session.

"Take the job UUID from the casefile creation and check the queue status. If it is still processing, wait and check again until it returns a success result."

To view the complete inventory of available Penneo tools - including endpoints for OAuth token management, publishing form versions, restoring archives, and listing casefile files - visit the Penneo integration page.

Building Multi-Step Workflows

AI agents excel when they chain multiple tool calls together to complete an objective. Unlike traditional linear code scripts, an agent operates in a continuous loop: reasoning about the current state, selecting a tool, analyzing the response, and deciding on the next action.

When connecting an LLM to Penneo, the agent must handle API errors gracefully. If an agent hits an HTTP 429 rate limit, Truto passes the standardized ratelimit-reset header back. A well-designed agent loop will catch this error, read the reset time, sleep, and try again, rather than failing the entire workflow.

Here is how the control flow looks during an asynchronous casefile creation workflow:

sequenceDiagram
    participant App as Your App
    participant LLM as Agent (LLM)
    participant Truto as Truto API
    participant Penneo as Penneo API

    App->>LLM: "Create a casefile for this contract"
    LLM->>Truto: Tool Call: create_a_penneo_casefile
    Truto->>Penneo: POST /casefiles (multipart/form-data)
    Penneo-->>Truto: 202 Accepted (job_uuid: 1234)
    Truto-->>LLM: Tool Result: job_uuid 1234
    
    Note over LLM: Agent recognizes job is asynchronous.
    
    LLM->>Truto: Tool Call: create_a_penneo_job_status (uuid: 1234)
    Truto->>Penneo: GET /queue/1234
    Penneo-->>Truto: 200 OK (status: processing)
    Truto-->>LLM: Tool Result: status processing
    
    Note over LLM: Agent waits, then polls again.
    
    LLM->>Truto: Tool Call: create_a_penneo_job_status (uuid: 1234)
    Truto->>Penneo: GET /queue/1234
    Penneo-->>Truto: 200 OK (status: completed, casefile_id: 999)
    Truto-->>LLM: Tool Result: status completed
    
    LLM-->>App: "Casefile 999 created successfully."

To build this resilient loop in LangChain, you process the tool_calls returned by the model, invoke the corresponding Truto tools, and append the results back to the conversation history as tool_message objects. This allows the LLM to read the API responses (or error codes) and determine if it needs to adjust its parameters or wait for a rate limit window to clear.

Workflows in Action

By equipping an agent with Penneo tools, you shift from hardcoding endpoints to defining business outcomes. The LLM determines the execution path. Here are concrete examples of how this looks in production.

Use Case 1: Dynamic Form Versioning and Publishing

Compliance teams frequently update form requirements based on new regulations. Instead of manually editing forms in the UI, an agent can handle the versioning lifecycle automatically based on policy documents.

"We need to add a mandatory 'Data Processing Agreement' checkbox to our main GDPR consent form. Find the form in Penneo, update it with this new boolean field, and if everything looks correct, publish it as the active version."

Agent Execution Steps:

  1. Calls list_all_penneo_forms with a search filter to locate the ID for the "GDPR consent form".
  2. Calls update_a_penneo_form_version_by_id using the retrieved ID. Since the form is active, this tool creates a new Draft version containing the new boolean checkbox section.
  3. Calls create_a_penneo_form_version_publish targeting the new external ID and version number to finalize and publish the form.

Outcome: The agent autonomously drafts, modifies, and deploys a new compliance form without human intervention, maintaining a clean version history.

Use Case 2: Extracting Dynamic Employee Onboarding Data

When a new hire submits their onboarding documents, HR systems need that data structured and synced to the HRIS. Because Penneo's answer payloads are dynamic, custom scripting requires constant maintenance when forms change. Agents handle this gracefully.

"Fetch the latest submission for the 'Employee Onboarding 2026' form. Extract the employee's bank routing number and emergency contact details, and format them as a structured JSON object for our HRIS."

Agent Execution Steps:

  1. Calls list_all_penneo_forms to get the ID for the "Employee Onboarding 2026" form.
  2. Calls list_all_penneo_form_submissions to find the most recent submission ID.
  3. Calls list_all_penneo_form_submission_answers using the form and submission IDs.
  4. The LLM analyzes the dynamic JSON schema returned, semantically maps the arbitrary key names to "routing number" and "emergency contact", and generates the required structured output.

Outcome: The agent acts as a semantic ETL layer, dynamically understanding the form schema and extracting the correct fields regardless of how the form was internally structured.

Use Case 3: Automated Casefile Generation and Polling

Sales teams need contracts generated and sent without leaving their CRM. (See our guide on connecting AI agents to Salesforce and HubSpot for cross-platform workflows.) An agent orchestrates the entire asynchronous process.

"Take the attached MSA document and create a Penneo casefile for John Doe (john@example.com). Wait until the casefile is fully processed, then confirm it is ready for signature."

Agent Execution Steps:

  1. Calls create_a_penneo_casefile, formatting the primary signer data and submitting the MSA via the expected payload structure.
  2. Receives the asynchronous uuid and payloadHash.
  3. Calls create_a_penneo_job_status to poll the queue.
  4. If the status is "processing", the agent waits a few seconds and repeats step 3 until a "completed" status is returned.

Outcome: The agent successfully manages the asynchronous complexity of the Penneo platform, abstracting the polling loop away from the end-user and delivering a definitive success state.

Strategic Wrap-Up

Connecting AI agents to Penneo transforms electronic signature and document management from a series of manual UI tasks into an autonomous, programmatic capability. By utilizing Truto's /tools endpoint, you completely bypass the engineering overhead of building custom API wrappers, managing OAuth lifecycles, and writing brittle polling scripts for asynchronous tasks.

Instead of worrying about the difference between form drafts and active versions, or how to parse dynamic submission schemas, you can focus on building intelligent orchestration loops. Your agent receives standard JSON tools, handles rate limits natively via Truto's standardized headers, and executes complex document operations flawlessly across your infrastructure.

FAQ

Does Truto automatically handle Penneo API rate limits?
No. Truto does not retry, throttle, or apply backoff. When Penneo returns an HTTP 429, Truto passes the error back and normalizes the rate limit information into standard headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Your agent framework is responsible for handling the retry logic.
How do AI agents handle Penneo's asynchronous casefile creation?
Penneo processes casefiles asynchronously. The agent uses the `create_a_penneo_casefile` tool to get a job UUID, and must be prompted to use the `create_a_penneo_job_status` tool in a polling loop to check when the job is completed.
Why is extracting Penneo form submission data difficult for traditional code?
Penneo submission answers use dynamic schemas based on the specific form definition rather than standard REST objects. AI agents solve this by reading the dynamic JSON schema and semantically mapping the arbitrary fields to the required data.
What agent frameworks can use Truto's Penneo tools?
Truto's tools are framework-agnostic. They return standard JSON schemas that can be bound to any modern framework, including LangChain, LangGraph, CrewAI, and the Vercel AI SDK.

More from our Blog