Skip to content

Connect dotloop to ChatGPT: Manage Transaction Loops and Documents

Learn how to connect dotloop to ChatGPT using Truto's managed MCP server. Execute Loop-It workflows, update financials, and manage closing documents.

Yuvraj Muley Yuvraj Muley · · 10 min read
Connect dotloop to ChatGPT: Manage Transaction Loops and Documents

If you are building AI agents to manage real estate transactions, automate closing coordination, or extract data from closing disclosures, you need a Model Context Protocol (MCP) server. This architecture acts as the translation layer between ChatGPT's function calls and dotloop's proprietary REST API. You can either spend weeks writing custom integration code and managing OAuth lifecycles, or you can use a managed platform like Truto to dynamically generate a secure, authenticated MCP server URL.

If your team uses Claude, check out our guide on connecting dotloop to Claude or explore our broader architectural overview on connecting dotloop to AI Agents.

Giving a Large Language Model (LLM) read and write access to a transaction management system like dotloop introduces unique engineering hurdles. Real estate APIs are rarely straightforward CRUD. You have to handle complex profile routing, multipart binary uploads for PDFs, and deeply nested, non-standard field names.

This guide details how to use Truto to generate a secure MCP server for dotloop, connect it natively to ChatGPT, and execute multi-step transaction workflows using natural language.

The Engineering Reality of the dotloop API

A custom MCP server is essentially a self-hosted API gateway for your AI agent. While MCP provides a predictable JSON-RPC standard for models to discover tools, mapping that standard to dotloop's highly specific data model is painful.

If you build this layer yourself, you own the entire integration lifecycle. Here are the specific challenges you will encounter when working with the dotloop API:

Profile-Centric Routing

Unlike a standard SaaS platform where a tenant has a single global context, dotloop organizes data strictly around profile_id. A single user account can have multiple profiles (e.g., acting as an agent in one brokerage and a transaction coordinator in another). Loops work on individual profiles exclusively. If your LLM attempts to create or query a loop without understanding this context, the API will reject the request. Your MCP server must inject and enforce profile_id routing logic so the agent does not cross-contaminate data across a user's disparate roles.

The "Loop-It" Complexity vs Standard CRUD

Creating a transaction in dotloop is not as simple as POST /loops. The platform uses a specialized "Loop-It" endpoint that handles the property creation, participant assignments (and contact directory insertion), and template application in a single complex payload. Mapping a standard REST mindset to this endpoint fails. Your MCP tool definitions must explicitly guide the LLM to provide the correct nested payload (transactionType, status, name, participants, template) to avoid validation errors.

301 Redirects on Merged Loops

Real estate agents merge duplicate loops frequently. When an LLM asks for details on a specific loop ID that has been merged into another, dotloop does not return standard JSON data - it returns an HTTP 301 Redirect with the new loop's path in the Location header. Naive HTTP clients (and basic custom MCP servers) will drop this payload, causing the agent to hallucinate a failure. Truto's proxy layer handles this natively, following the redirect and returning the target loop's data without confusing the model.

Spaced Field Names and Nested Updates

Dotloop organizes loop details in deeply nested structures with human-readable keys. Instead of standard camelCase or snake_case, you will encounter sections like "Property Address" containing fields like "Street Name". When doing a bulk update (dotloop_loop_details_bulk_update), the payload must match this exact spacing and casing. If you build a custom MCP server, you have to write schema mappers. Truto passes these schemas directly to ChatGPT, ensuring the LLM formats its JSON payload precisely as dotloop expects.

Connect dotloop to ChatGPT: Quickstart Guide

To bypass these API quirks, we will use Truto to generate a dotloop MCP server. You can then plug this server directly into ChatGPT.

Step 1: Authenticate the dotloop Account

Before generating tools, you need an authenticated connection. In Truto, navigate to Integrated Accounts -> New Integrated Account, select dotloop, and complete the OAuth flow. Truto securely stores the refresh token and automatically handles access token rotation. Your AI agent will never encounter an expired token error.

Once connected, note your integrated_account_id.

Step 2: Generate the dotloop MCP Server

Truto dynamically generates MCP tools based on the resources available in the dotloop integration. You can create this server via the dashboard or the API.

Method A: Via the Truto UI

  1. Navigate to the integrated account page for your dotloop connection.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Select your desired configuration (e.g., read-only, specific tags, expiration date).
  5. Click Save and copy the generated MCP server URL (e.g., https://api.truto.one/mcp/a1b2c3d4e5f6...).

Method B: Via the API Alternatively, you can generate the server programmatically by sending a POST request to Truto. This is useful for multi-tenant applications dynamically spinning up agents for users.

curl -X POST https://api.truto.one/integrated-account/<INTEGRATED_ACCOUNT_ID>/mcp \
  -H "Authorization: Bearer $TRUTO_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dotloop Closing Agent",
    "config": {
      "methods": ["read", "write", "custom"],
      "tags": ["loops", "documents", "participants"]
    }
  }'

The response contains a url field. This single URL handles all JSON-RPC routing and OAuth token injection. Treat it as a sensitive secret.

Step 3: Connect the Server to ChatGPT

You can connect this MCP server to ChatGPT using either the desktop application UI or a manual configuration file.

Method A: Via the ChatGPT UI

  1. Open the ChatGPT Desktop app.
  2. Navigate to Settings -> Apps -> Advanced settings.
  3. Enable Developer mode.
  4. Under MCP servers / Custom connectors, click add.
  5. Name the connector (e.g., "dotloop (Truto)") and paste the MCP server URL you copied in Step 2.
  6. Save and exit. ChatGPT will immediately initialize the connection and discover the dotloop tools.

Method B: Via Manual Config File If you are managing agents via CLI or custom wrappers, you can use the standard MCP configuration format to connect over Server-Sent Events (SSE). Add the following to your MCP config file:

{
  "mcpServers": {
    "dotloop_truto": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/<YOUR_SECURE_TOKEN>"
      ]
    }
  }
}

Step 4: Understanding Rate Limits

It is critical to understand how rate limits function when connecting AI agents to external APIs. Truto does not retry, throttle, or apply backoff on rate limit errors.

When the upstream dotloop API returns an HTTP 429 Too Many Requests, Truto passes that error directly back to the caller (ChatGPT). Truto automatically normalizes the upstream rate limit information into standardized IETF headers:

  • ratelimit-limit
  • ratelimit-remaining
  • ratelimit-reset

Your agent logic or prompt instructions must be capable of catching tool execution failures and handling the necessary wait state based on the ratelimit-reset window.

Hero Tools for dotloop Workflows

When ChatGPT connects to the Truto MCP server, it parses the JSON schemas for every available dotloop endpoint. Here are the highest-leverage tools your agent can use to orchestrate real estate transactions.

create_a_dotloop_loop_it

This is the most powerful tool for transaction initiation. Instead of making separate calls to create a loop, add a property, invite buyers, and attach a template, this tool executes the "Loop-It" workflow in a single request.

Contextual Usage: Requires profile_id if the account has multiple profiles. The response includes a loopUrl that the agent can hand back to the user to open the loop natively in dotloop.

"I just got a new listing at 742 Evergreen Terrace. Create a new loop for this property using the 'Standard Listing Template', set the status to 'Active', and add John Doe (john@example.com) as the Seller."

get_single_dotloop_loop_detail_by_id

Retrieves the comprehensive details of a specific loop. This tool returns the data grouped by sections (e.g., Financials, Property Address) using dotloop's exact human-readable field names.

Contextual Usage: Essential for auditing disclosures. If a loop was merged, Truto automatically follows the 301 redirect and fetches the active loop's details.

"Pull the complete details for loop ID 987654. What is the current 'Purchase Sale Price' listed under the Financials section?"

dotloop_loop_details_bulk_update

Updates loop details without requiring a standard batch array. You pass a single JSON object containing only the sections and fields you want to change.

Contextual Usage: ChatGPT must respect the spaced field naming convention. Because Truto provided the schema during initialization, the model knows exactly how to nest the JSON.

"Update the loop details for ID 987654. Change the 'Purchase Sale Price' in the 'Financials' section to 450000, and update the 'Street Name' in the 'Property Address' section to 742 Evergreen Terrace."

list_all_dotloop_loop_documents

Lists all documents inside a specific loop.

Contextual Usage: Requires folder_id. If you do not know the folder ID, you must first call list_all_dotloop_loop_folders. This returns metadata, not the binary file itself.

"List all the documents inside the 'Closing Docs' folder for the Evergreen Terrace loop. Have the signed disclosures been uploaded yet?"

create_a_dotloop_loop_document

Uploads an individual document to a specific loop folder via multipart form post.

Contextual Usage: The AI agent must format the payload as multipart/form-data. The file name of the part becomes the document name in dotloop. This is critical for agents generating addendums or fetching external PDFs and pushing them to the transaction.

"Upload the attached lead paint disclosure PDF into the 'Disclosures' folder for the Evergreen Terrace loop."

list_all_dotloop_contacts

Retrieves the global contact directory for the user's profile.

Contextual Usage: Truto handles pagination natively via batch_size and batch_number. The agent can control the batch size using the limit argument (maximum 100).

"Search my dotloop contacts for anyone with the email domain @titlecompany.com so we can add an escrow officer to the new loop."

For a complete list of tools - including endpoints for tasks, webhook event subscriptions, and activity logs - see the full dotloop integration page.

Workflows in Action

Connecting tools is only half the battle. Here is how ChatGPT orchestrates multi-step workflows using the MCP server.

Scenario 1: The Transaction Coordinator Setup

The Persona: A busy Transaction Coordinator handling 40+ escrows a month needs to spin up a new buyer file instantly from an email summary.

User Prompt: "My buyer, Sarah Connor (sarah@example.com), just went into contract on 100 Cyberdyne Way. Please set up the loop using the 'Buyer File' template, make sure her contact info is in the directory, and add her to the loop as the Buyer."

Execution Steps:

  1. list_all_dotloop_contacts: ChatGPT checks if Sarah Connor already exists in the profile's global contact directory to avoid duplicates.
  2. create_a_dotloop_contact: If she does not exist, the agent creates her contact record.
  3. create_a_dotloop_loop_it: ChatGPT fires the Loop-It payload, passing the property address, Sarah's contact details, her role ('Buyer'), and the requested template.
  4. Response: ChatGPT returns: "Loop created successfully! You can view the new transaction for 100 Cyberdyne Way here: [dotloop URL]. Sarah has been added as the Buyer."
sequenceDiagram
    participant User
    participant Agent as ChatGPT
    participant Truto as Truto MCP
    participant API as dotloop API
    
    User->>Agent: Create loop for Sarah Connor at Cyberdyne Way
    Agent->>Truto: Call list_all_dotloop_contacts(email: sarah@...)
    Truto->>API: GET /contacts
    API-->>Truto: { data: [] }
    Truto-->>Agent: No results found
    
    Agent->>Truto: Call create_a_dotloop_contact(name, email)
    Truto->>API: POST /contacts
    API-->>Truto: 201 Created (contact_id)
    Truto-->>Agent: Contact generated
    
    Agent->>Truto: Call create_a_dotloop_loop_it(property, participant, template)
    Truto->>API: POST /loop-it
    API-->>Truto: 201 Created (loopUrl)
    Truto-->>Agent: Loop-It successful
    Agent-->>User: Loop ready at [URL]

Scenario 2: Escrow Financials Audit

The Persona: A broker reviewing files prior to closing to ensure the system of record matches the final settlement statement.

User Prompt: "Check the Evergreen Terrace loop. Ensure the purchase price is exactly $500,000 and the earnest money is updated to $15,000. If it doesn't match, update it."

Execution Steps:

  1. list_all_dotloop_loops: ChatGPT searches for a loop matching "Evergreen Terrace" and extracts the loop_id and profile_id.
  2. get_single_dotloop_loop_detail_by_id: The agent fetches the deeply nested loop details and inspects the Financials section.
  3. Decision Logic: The LLM compares the requested figures ($500,000 and $15,000) against the returned API data.
  4. dotloop_loop_details_bulk_update: If the numbers do not match, the agent constructs a patch payload. It formats the JSON properly (e.g., {"Financials": {"purchase_sale_price": "500000", "earnest_money": "15000"}}) and submits the update.
  5. Response: ChatGPT returns: "I checked the loop. The purchase price was already $500k, but the earnest money was blank. I have updated the earnest money field to $15,000."

Security and Access Control

Granting an AI agent write access to active real estate transactions requires strict governance. Truto MCP servers provide multiple layers of access control out of the box:

  • Method Filtering: If you only want ChatGPT to read loop data and never alter closing documents, you can pass config.methods = ["read"] during server creation. Truto will simply not generate any write, create, update, or delete tools.
  • Tag Filtering: Limit the agent's scope to specific domains. Passing config.tags = ["loops", "folders"] ensures the agent cannot touch the global contact directory or webhook subscriptions.
  • Extra Authentication (require_api_token_auth): By default, the MCP URL carries its own auth. By enabling this flag, you force the client to also provide a valid Truto API token in the headers. This prevents unauthorized execution even if the URL leaks in a Slack channel.
  • Ephemeral Servers (expires_at): For temporary auditing workflows, you can set an ISO datetime. Truto will automatically destroy the MCP server and revoke its KV tokens at the exact scheduled time.

Wrap Up

Connecting ChatGPT to dotloop via a custom MCP server turns a static chat interface into a capable real estate transaction coordinator. Instead of clicking through dozens of folders and nested menus, agents and brokers can orchestrate loops, update financials, and audit closing documents using conversational prompts.

By leveraging Truto's dynamic tool generation, you bypass the complexity of profile routing, Loop-It endpoints, and 301 redirects, giving your LLM clean, reliable access to the dotloop API in minutes.

FAQ

How does Truto handle dotloop API rate limits?
Truto does not retry, throttle, or apply backoff on rate limit errors. If dotloop returns an HTTP 429, Truto passes the error directly to ChatGPT. Truto normalizes the upstream rate limit information into standard headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec, so your client logic can handle the backoff.
Can I restrict ChatGPT to only read data from dotloop?
Yes. When generating your dotloop MCP server via Truto, you can pass config.methods = ['read']. This strips out all write, create, update, and delete tools, ensuring the AI agent can only query loops and documents.
How do I handle dotloop's spaced field names in ChatGPT?
Truto automatically maps and exposes dotloop's native nested structures. ChatGPT will receive the exact schema required, meaning it will correctly format JSON payloads like {"Property Address": {"Street Name": "123 Main"}} when invoking the bulk update tool.

More from our Blog