# How to Integrate Retool with Yardi

- Tool: Retool
- Difficulty: Advanced
- Time required: 60 minutes
- Last updated: April 2026

## TL;DR

Connect Retool to Yardi using a REST API Resource configured for Yardi's SOAP or REST API endpoints. Yardi's API typically requires a partnership agreement and credentials provided by Yardi directly. Build property management operations panels that display resident records, track work orders, manage lease data, and monitor property performance across multi-family and commercial portfolios.

## Build a Yardi Property Management Operations Panel in Retool

Yardi Voyager and Yardi Breeze are the most widely deployed property management platforms in North America, used by operators managing everything from a few dozen units to portfolios of tens of thousands of apartments and commercial spaces. While Yardi's native interface is comprehensive, operations teams and asset managers frequently need custom dashboards that surface specific data views, combine property data with external sources, or provide simplified interfaces for field staff and regional managers.

A Retool integration with Yardi enables building purpose-built operations panels: a resident management dashboard that shows all current leases with expiration dates, renewal status, and outstanding balances; a maintenance tracking panel that lists open work orders by property, priority, and assigned vendor; and an asset performance dashboard that combines occupancy data from Yardi with financial reporting from a separate accounting system. These panels reduce the need for Yardi training for peripheral staff and give property managers faster access to the data they need most.

Yardi's API architecture is complex and varies significantly by product. Yardi Voyager — the enterprise flagship — uses a SOAP-based API that predates modern REST conventions, requiring XML-formatted requests and responses. Yardi Breeze — the newer SMB product — has a more modern REST API. Retool handles both patterns through its REST API Resource, with Yardi SOAP calls routed through standard POST requests using XML bodies. Because all requests proxy through Retool's server, Yardi credentials remain secure and CORS is not a concern.

## Before you start

- A Yardi Voyager, Yardi Breeze, or other Yardi product account with API access enabled — contact Yardi Support or your Account Manager to request API credentials (API access requires a paid licensing agreement)
- API credentials from Yardi: typically a username, password, server name, database name, and interface entity code for Voyager; or API key for Breeze
- Knowledge of your Yardi product version and deployment type (cloud-hosted vs on-premises), as this determines the API endpoint URL
- A Retool account with permission to create Resources and Configuration Variables
- Familiarity with SOAP/XML web services if using Yardi Voyager, or REST API concepts for Yardi Breeze

## Step-by-step guide

### 1. Obtain Yardi API access and understand your API type

Yardi API access is not self-service — it must be arranged through Yardi directly. Contact Yardi Support at your organization's support portal (support.yardi.com) or speak with your Yardi Account Manager to request API credentials. Specify that you are building a Retool integration and need API access for the Yardi products you use. Yardi will provide credentials and documentation specific to your product. Understanding which API you are working with is essential before configuring Retool. Yardi Voyager (enterprise) uses a SOAP-based web service — requests are XML-formatted POST calls to a SOAP endpoint. The Voyager API base URL follows the pattern https://{yardi-server}/Voyager/webservice/itfYardiGuestCard.asmx (endpoint names vary by integration type — resident data, work orders, and financial data each have separate WSDL endpoints). Yardi Breeze (SMB) uses a more modern REST API with JSON responses and API key authentication. RentCafe (the resident-facing portal platform) has its own API for marketing and leasing data. Your Yardi Account Manager will provide the specific endpoint URLs, WSDL files, and authentication parameters for your account. Store all Yardi credentials in Retool Settings → Configuration Variables: create YARDI_USERNAME, YARDI_PASSWORD, YARDI_SERVER_NAME, YARDI_DATABASE, and YARDI_ENTITY as separate secret variables. This structure matches the Voyager API's required parameters.

**Expected result:** You have Yardi API credentials, documentation, and the specific endpoint URL for your Yardi product, stored as configuration variables in Retool.

### 2. Create the Yardi REST API Resource in Retool

In Retool, click the Resources tab and Add Resource. Select REST API. Name it 'Yardi API'. For the Base URL, enter the base URL of your Yardi server. For Yardi Voyager (cloud-hosted), this is typically https://{your-yardi-server-name}.yardipcv.com — your Yardi Account Manager will confirm the exact hostname. For on-premises Voyager deployments, the URL is your internal server address (e.g., https://yardi.yourcompany.com). For Yardi Breeze, the API URL is typically https://api.yardibreeze.com or similar — confirm with Yardi documentation. For Voyager SOAP endpoints, the Authentication method depends on how your integration is configured. Many Voyager integrations embed credentials in the SOAP XML body rather than in HTTP headers. In the Retool resource, select 'No Auth' as the authentication type and include credentials in the query body. For Yardi Breeze REST API, select API Key authentication with the header name and value provided by Yardi. Add a Content-Type header: for SOAP requests, use text/xml; charset=utf-8; for REST/JSON, use application/json. Add an Accept header set to text/xml for SOAP or application/json for REST. Click Save Changes. Because Yardi Voyager's SOAP interface embeds authentication in every request body, you will configure credential substitution in each query using configuration variable references rather than resource-level authentication headers.

**Expected result:** A 'Yardi API' resource appears in the Retool Resources list with the correct base URL and content type headers for your Yardi product.

### 3. Build a Voyager SOAP query to retrieve resident data

Yardi Voyager's SOAP API uses XML request envelopes — each query is a POST request with an XML body following the specific WSDL schema for that operation. To retrieve resident (tenant) data, create a query in the Retool Code panel, select the Yardi API resource, set Method to POST, and set Path to the specific SOAP endpoint path (e.g., /Voyager/webservice/itfResidentData.asmx or the endpoint provided in your Yardi documentation). In the Body section, set Body Type to Raw and Body to an XML SOAP envelope. The SOAP envelope structure for Yardi Voyager embeds authentication credentials (server name, database, username, password, and entity) in the SOAP body within a 'Credentials' element — not in HTTP headers. Construct the SOAP body dynamically using Retool's {{ }} syntax to inject configuration variable values. In the Response Transformer (Advanced tab), write a JavaScript transformer to parse the XML response. Retool's REST API queries return XML responses as strings — parse them using the browser's DOMParser or a JSON transformation. Use the pattern: const parser = new DOMParser(); const xmlDoc = parser.parseFromString(data, 'text/xml') to access XML nodes. Extract resident records from the parsed XML and return a flat array of JavaScript objects for use in Retool Table components.

```
// Yardi Voyager SOAP Request body — configure as Raw Body
`<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetResidents xmlns="http://tempuri.org/">
      <UserName>{{ retoolContext.configVars.YARDI_USERNAME }}</UserName>
      <Password>{{ retoolContext.configVars.YARDI_PASSWORD }}</Password>
      <ServerName>{{ retoolContext.configVars.YARDI_SERVER_NAME }}</ServerName>
      <Database>{{ retoolContext.configVars.YARDI_DATABASE }}</Database>
      <PlatformType>SQL Server</PlatformType>
      <InterfaceEntity>{{ retoolContext.configVars.YARDI_ENTITY }}</InterfaceEntity>
      <YardiPropertyId>{{ propertySelect.value }}</YardiPropertyId>
    </GetResidents>
  </soap:Body>
</soap:Envelope>`
```

**Expected result:** The resident data query executes without SOAP fault errors and returns an XML response that the transformer parses into a flat array of resident records.

### 4. Parse Yardi XML responses and build the dashboard UI

Yardi Voyager returns data as XML, which requires parsing in Retool's JavaScript transformer. Create a transformer attached to your resident data query (in the query's Advanced tab, enable the transformer toggle). Write a parser that extracts resident elements from the SOAP response XML. The transformer receives the raw XML string in the 'data' variable. Use DOMParser to traverse the XML DOM and extract fields. Map each resident node's child elements to JavaScript object properties: tenant code, name, unit number, property code, lease start date, lease end date, market rent, actual charges, and resident status. With parsed data available, build the dashboard UI. Drag a Select component for property selection — populate it from a separate Yardi query that fetches all properties (/GetPropertyList equivalent). When the property selection changes, trigger the resident data query via event handler. Drag a Table component, bind its data to the resident query's transformer output ({{ getResidents.data }}), and configure columns: unit, tenant_name, lease_end, market_rent, status (with conditional formatting: 'Current' in green, 'Notice' in yellow, 'Past' in red). Add a search Text Input bound to the Table's search property. For work orders, create a separate SOAP query for the Yardi maintenance interface and display results in a second tab. For complex multi-property Yardi integrations with custom data transformations, RapidDev can help design the full query architecture and XML parsing layer.

```
// Transformer: parse Yardi Voyager XML resident response
// 'data' is the raw XML string from the SOAP response
try {
  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(data, 'text/xml');
  const residents = xmlDoc.getElementsByTagName('Resident');
  const result = [];

  for (let i = 0; i < residents.length; i++) {
    const r = residents[i];
    const getText = (tag) => r.getElementsByTagName(tag)[0]?.textContent || '';
    result.push({
      unit: getText('UnitCode'),
      tenant_code: getText('TenantCode'),
      tenant_name: getText('Name'),
      lease_start: getText('LeaseFrom'),
      lease_end: getText('LeaseTo'),
      market_rent: parseFloat(getText('MarketRent')) || 0,
      status: getText('Status'),
      property: getText('PropertyCode')
    });
  }
  return result;
} catch (e) {
  return [{ error: 'XML parse error: ' + e.message }];
}
```

**Expected result:** The property management dashboard displays resident records in a searchable Table with lease expiration date sorting and status-based conditional formatting.

### 5. Add work order management and property performance metrics

Extend the dashboard with maintenance and performance views. For work orders, create a second SOAP query targeting Yardi's work order or service request interface. The Yardi SOAP endpoint for work orders varies by Voyager module — common options are GetWorkOrders, GetServiceRequests, or similar depending on your Voyager configuration. Follow the same SOAP envelope pattern as the resident query, substituting the operation name and parameters. Work order data typically returns: work order number, unit code, description, priority (Emergency, Routine, Priority), status (New, Assigned, Completed), assigned vendor, date created, and scheduled date. Add a second tab to your dashboard's Tab Container labeled 'Maintenance'. Drag a Table component bound to the work order query data. Configure column formatting: priority 'Emergency' in red, 'Priority' in orange, 'Routine' in blue. Add days-open as a calculated column using a JavaScript transformer: const daysOpen = Math.floor((Date.now() - new Date(row.created_date).getTime()) / (1000 * 60 * 60 * 24)). For portfolio metrics, create a JavaScript transformer query that aggregates the resident data: calculates occupancy rate as (occupied units / total units * 100), total scheduled charges, delinquent balance, and expiring leases count. Display these in a Stats component row at the top of the dashboard. Add a Bar Chart component showing unit availability by property using the aggregated query output.

```
// Transformer: aggregate Yardi resident data into portfolio metrics
const residents = getResidents.data || [];
const total = residents.length;
const occupied = residents.filter(r => r.status === 'Current').length;
const expiringSoon = residents.filter(r => {
  if (!r.lease_end) return false;
  const daysLeft = Math.floor(
    (new Date(r.lease_end) - new Date()) / (1000 * 60 * 60 * 24)
  );
  return daysLeft >= 0 && daysLeft <= 60;
}).length;
const totalRent = residents
  .filter(r => r.status === 'Current')
  .reduce((sum, r) => sum + (r.market_rent || 0), 0);

return {
  occupancy_rate: total > 0 ? ((occupied / total) * 100).toFixed(1) + '%' : '0%',
  occupied_units: occupied,
  total_units: total,
  expiring_60_days: expiringSoon,
  total_scheduled_rent: `$${totalRent.toLocaleString()}`
};
```

**Expected result:** The dashboard shows portfolio metrics in stats cards at the top, resident records in the main tab, and work orders organized by priority in the maintenance tab.

## Best practices

- Store all Yardi credentials (username, password, server name, database, entity code) in Retool Configuration Variables marked as secret — Yardi SOAP requests embed credentials in XML bodies that would be visible if stored in plaintext query code
- Apply a minimum 5-minute query cache to all Yardi SOAP queries — Yardi Voyager's SOAP layer can be slow and is not designed for high-frequency polling; caching prevents both performance issues and accidental server overload
- Add property-level filtering to all Yardi queries from the start — queries without property filters can return tens of thousands of records for large portfolios, causing both slow responses and Retool's 100 MB result size limit to be reached
- Use Retool's query timeout setting (accessible in Advanced query settings) and set it to at least 30,000 ms (30 seconds) for Yardi SOAP calls, as large dataset queries regularly take 5-15 seconds to complete
- Build XML parsing transformers defensively with try/catch blocks and early fault detection — Yardi SOAP errors return valid HTTP 200 responses with SOAP fault XML bodies, not HTTP error codes
- For work order status updates and lease modifications, require manager-level access control using Retool's permission groups — property management write operations through the API bypass Yardi's native audit controls
- Document all WSDL endpoints and SOAP operation names used in your Retool integration — Yardi updates can change available operations, and having a reference makes troubleshooting API changes much faster

## Use cases

### Build a lease expiration and renewal tracking dashboard

Create a Retool property management panel that queries Yardi for all active leases across properties and highlights leases expiring within 30, 60, and 90 days. Display a filterable Table with resident name, unit, lease end date, monthly rent, and renewal status. Include a renewal action button that updates the lease status in Yardi and notifies the property manager via email or Slack.

Prompt example:

```
Build a Retool dashboard showing all active Yardi leases sorted by expiration date, with color-coded rows for leases expiring in under 30/60/90 days, a filter for property and unit type, and a button to mark leases as renewal-offered.
```

### Build a maintenance work order management panel

Create a Retool maintenance dashboard that displays all open work orders from Yardi, organized by property and priority. Show technician assignments, completion status, estimated vs actual completion times, and vendor costs. Include a form to create new work orders and update status, enabling field supervisors to manage maintenance without navigating Yardi's full interface.

Prompt example:

```
Build a Retool work order panel pulling open Yardi maintenance requests, organized by property and priority (Emergency/Routine), showing assigned technician, days open, and a status update form for field supervisors.
```

### Build a portfolio occupancy and financial performance dashboard

Create a Retool asset management dashboard that aggregates Yardi occupancy data across all properties in the portfolio. Show current occupancy rate, vacant units by property and unit type, average rent per square foot, and delinquency totals. Combine with historical occupancy data to show trends in Charts for quarterly portfolio reviews.

Prompt example:

```
Build a Retool portfolio dashboard aggregating Yardi occupancy across all properties — show current occupancy %, vacant units by bedroom count, delinquent balance totals, and a Line Chart of occupancy trend over 12 months.
```

## Troubleshooting

### SOAP request returns a SOAP Fault with 'Authentication failed' or 'Invalid credentials' message

Cause: Yardi Voyager SOAP authentication credentials are embedded in the XML request body — if any of the five required credential fields (UserName, Password, ServerName, Database, InterfaceEntity) are missing, incorrect, or in the wrong element names for your Yardi version, the server returns a SOAP fault.

Solution: Extract the fault message from the XML response using: xmlDoc.getElementsByTagName('faultstring')[0]?.textContent. Verify each credential field matches exactly what Yardi provided. The InterfaceEntity field is often overlooked — it corresponds to the Yardi entity code for your organization in Voyager. Confirm with your Yardi administrator or support team if unsure of any value.

```
// Extract SOAP fault message in transformer
if (data.includes('<faultstring>')) {
  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(data, 'text/xml');
  const fault = xmlDoc.getElementsByTagName('faultstring')[0]?.textContent;
  return [{ error: 'SOAP Fault: ' + fault }];
}
```

### Retool query times out before Yardi API returns a response

Cause: Yardi Voyager SOAP calls can be slow, particularly for queries that span large property portfolios or long date ranges. Default Retool query timeout of 10 seconds may be insufficient for large Yardi datasets.

Solution: In the query's Advanced settings, increase the query timeout — Retool allows up to 600,000 ms (10 minutes) on Cloud and configurable values on self-hosted. For large portfolios, add property filters to the SOAP request body to limit the result set. Alternatively, query data per property and use Retool's parallel query execution to fetch multiple properties concurrently.

### XML transformer returns empty array despite Yardi response appearing to contain data

Cause: Yardi SOAP responses often have XML namespaces on element tags (e.g., 'ns1:Resident' instead of 'Resident'). The getElementsByTagName() method is case-sensitive and namespace-sensitive — querying for 'Resident' will not find 'ns1:Resident'.

Solution: Use getElementsByTagNameNS('*', 'Resident') or inspect the raw response first using console.log(data.substring(0, 500)) in the transformer to see the actual element names including any namespace prefixes. Update your getElementsByTagName calls to match the actual element names returned by your Yardi installation.

```
// Namespace-aware element retrieval
const residents = xmlDoc.getElementsByTagNameNS('*', 'Resident');
// or using querySelector with local name:
const items = Array.from(xmlDoc.querySelectorAll('[localName="Resident"], Resident'));
```

### Yardi API is not accessible from Retool Cloud queries

Cause: On-premises Yardi deployments run on private networks without public IP addresses. Retool Cloud cannot reach servers that are not accessible from the public internet. Cloud Retool IP ranges also need to be whitelisted in Yardi's server firewall if using a publicly accessible Yardi cloud deployment.

Solution: For on-premises Yardi: deploy Retool self-hosted in your organization's network where it can reach the Yardi server directly. For cloud-hosted Yardi: whitelist Retool's published CIDR ranges (35.90.103.132/30 and 44.208.168.68/30 for US West) in Yardi's server firewall rules. Contact your network administrator and Yardi support to configure the appropriate access.

## Frequently asked questions

### How do I get API access to Yardi for a Retool integration?

Yardi API access is not self-service. Contact your Yardi Account Manager or Yardi Support (support.yardi.com) and request API credentials for integration. Yardi will ask about your intended use case, required data entities (residents, work orders, financials), and may require a separate API license or partner agreement depending on your current contract. The process typically takes 1-3 weeks to receive credentials and interface documentation.

### Does Retool support SOAP requests for Yardi Voyager?

Yes. Retool's REST API Resource can send SOAP requests by setting the HTTP method to POST, configuring the Content-Type header to 'text/xml; charset=utf-8', and using a Raw body with the XML SOAP envelope. Yardi Voyager's responses are also XML, which you parse in the query's JavaScript transformer using the DOMParser API. This approach works for all Yardi WSDL operations, though you must construct the correct XML envelope structure for each operation type.

### Can I write data back to Yardi from Retool?

Yes, Yardi's SOAP API supports write operations including creating work orders, updating resident information, and entering payment data. The same SOAP POST pattern applies — construct an XML request body for the appropriate write operation WSDL method. Yardi strongly recommends restricting write access to specific operations and user accounts through Yardi's native role configuration. Always test write operations in a Yardi test/staging environment before connecting to your production Yardi database.

### What is the difference between Yardi Voyager and Yardi Breeze API integration?

Yardi Voyager uses a SOAP/XML API with credentials embedded in request bodies — complex to configure but highly flexible for enterprise data. Yardi Breeze has a more modern REST API with JSON responses and API key authentication, making it significantly easier to configure in Retool. Both products require Yardi to provision API access, but Breeze integration follows standard REST patterns while Voyager requires XML parsing and SOAP envelope construction.

### How should I handle large portfolio queries that return thousands of Yardi records?

Filter all Yardi queries to a single property or small property set rather than pulling all records in one request. Add a property selector component in your Retool app that populates from a property list query, and pass the selected property ID as a parameter in every data query. For portfolio-wide analytics, consider building a Retool Workflow that runs nightly, queries Yardi property by property, and stores aggregated metrics in Retool Database — your dashboard then reads from the cached database rather than querying Yardi directly on demand.

---

Source: https://www.rapidevelopers.com/retool-integrations/yardi
© RapidDev — https://www.rapidevelopers.com/retool-integrations/yardi
