Skip to main content
RapidDev - Software Development Agency
replit-integrationsStandard API Integration

How to Integrate Replit with Propertybase

To integrate Replit with Propertybase, obtain Salesforce API credentials (Propertybase is built on Salesforce), store them in Replit Secrets (lock icon 🔒), and use the Salesforce REST API or SOQL to query listings, contacts, and transaction records. All Propertybase data lives in Salesforce custom objects. Use JSForce (Node.js) or simple-salesforce (Python) to handle OAuth 2.0 and the Salesforce API.

What you'll learn

  • How to create a Salesforce Connected App for Propertybase API access
  • How to authenticate Replit with Salesforce OAuth 2.0 using username-password flow
  • How to query Propertybase listings, contacts, and transactions using SOQL from Node.js and Python
  • How to navigate Salesforce custom objects to find Propertybase-specific data
  • Differences between Propertybase API access and standalone CRM APIs like HubSpot
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate13 min read30 minutesOtherMarch 2026RapidDev Engineering Team
TL;DR

To integrate Replit with Propertybase, obtain Salesforce API credentials (Propertybase is built on Salesforce), store them in Replit Secrets (lock icon 🔒), and use the Salesforce REST API or SOQL to query listings, contacts, and transaction records. All Propertybase data lives in Salesforce custom objects. Use JSForce (Node.js) or simple-salesforce (Python) to handle OAuth 2.0 and the Salesforce API.

Propertybase API Integration via Salesforce from Replit

Propertybase is one of the most widely used real estate CRMs in North America and Europe, built entirely on the Salesforce platform. This means there is no separate Propertybase API — all Propertybase data (listings, leads, contacts, transactions, commissions) is stored in Salesforce objects, accessible through the Salesforce REST API. For Replit developers integrating with Propertybase, the task is learning Salesforce's API and Propertybase's object schema.

Salesforce uses a powerful query language called SOQL (Salesforce Object Query Language) that resembles SQL. You write queries like SELECT Id, Name, MLS_Number__c FROM pb__Listing__c WHERE Status__c = 'Active' to retrieve Propertybase listings. Custom objects in Salesforce (including Propertybase's) have an __c suffix on both the object name and custom field names. Propertybase's custom objects typically have a pb__ namespace prefix.

The Salesforce connected app authentication model requires creating a Connected App in your Salesforce org that acts as the OAuth client. The Connected App has a consumer key (client ID) and consumer secret. For server-side integrations, Salesforce's username-password OAuth flow allows your Replit server to authenticate directly without browser-based OAuth redirects, making it ideal for background integrations and reporting pipelines.

Integration method

Standard API Integration

Propertybase is a Salesforce-native application — all Propertybase data is stored in Salesforce standard and custom objects. To integrate Replit with Propertybase, you connect to Salesforce using OAuth 2.0 Connected App credentials and query Propertybase data using SOQL (Salesforce Object Query Language) via the Salesforce REST API. JSForce (Node.js) and simple-salesforce (Python) are libraries that abstract the Salesforce authentication and API calls.

Prerequisites

  • A Replit account with a Node.js or Python Repl ready
  • A Salesforce org with Propertybase installed and active
  • Salesforce System Administrator access to create a Connected App
  • A Salesforce user account that will be used for API authentication

Step-by-step guide

1

Create a Salesforce Connected App

Log into your Salesforce org as an administrator. Navigate to Setup (gear icon → Setup) → Apps → App Manager → New Connected App. Fill in the required fields: Connected App Name (e.g., Replit Integration), API Name (auto-populated), and Contact Email. Under API (Enable OAuth Settings), check 'Enable OAuth Settings'. Set the Callback URL to https://localhost for server-side integrations using the username-password flow (you will not actually use this URL for callbacks). Under Selected OAuth Scopes, add at minimum: 'Access and manage your data (api)' and 'Perform requests on your behalf at any time (refresh_token, offline_access)'. Save the Connected App. Salesforce takes a few minutes to provision it. After saving, navigate back to the Connected App to find the Consumer Key (client ID) and Consumer Secret. Click 'Click to reveal' next to Consumer Secret to see the full value. Also ensure your org's password policy allows API access. Go to Setup → Security → Session Settings and verify that 'Lock sessions to the IP address from which they originated' is NOT checked for your API user — Replit's dynamic IPs mean each session might come from a different IP. For the username-password OAuth flow, you also need the user's Security Token. The Salesforce API requires appending the security token to the password for login from untrusted IP addresses. Navigate to your user settings → Reset My Security Token to generate a new token. It will be emailed to you. Note: Propertybase's custom object namespace is typically pb__. Run a SOQL query in Salesforce Developer Console (Setup → Developer Console) to explore available objects: SELECT QualifiedApiName FROM EntityDefinition WHERE QualifiedApiName LIKE 'pb__%' to list Propertybase objects.

Pro tip: After creating the Connected App, Salesforce often requires a 10-minute wait before the OAuth credentials are active. If authentication fails immediately after creating the app, wait 10 minutes and try again.

Expected result: A Salesforce Connected App exists with Consumer Key and Consumer Secret. Your Salesforce user has a security token. API access is enabled.

2

Store Salesforce Credentials in Replit Secrets

Click the lock icon (🔒) in the left Replit sidebar to open the Secrets pane. Add the following secrets: SF_CLIENT_ID: your Salesforce Connected App's Consumer Key. SF_CLIENT_SECRET: your Salesforce Connected App's Consumer Secret. SF_USERNAME: the Salesforce username of the API user (email format, e.g., user@yourdomain.com). SF_PASSWORD: the API user's password with their security token appended as a single string (e.g., MyPassword3x7kQpLM where 3x7kQpLM is the security token). SF_LOGIN_URL: the Salesforce login URL. Use https://login.salesforce.com for production and https://test.salesforce.com for sandbox. These credentials provide full Salesforce API access as the authenticated user. Treat them with the same level of security as database admin credentials. Replit's Secret Scanner monitors code files for credential patterns.

check-salesforce-secrets.js
1// check-salesforce-secrets.js
2const required = ['SF_CLIENT_ID', 'SF_CLIENT_SECRET', 'SF_USERNAME', 'SF_PASSWORD', 'SF_LOGIN_URL'];
3for (const key of required) {
4 if (!process.env[key]) {
5 throw new Error(`Missing secret: ${key}. Set it in Replit Secrets (lock icon 🔒).`);
6 }
7}
8console.log('Salesforce secrets verified.');
9console.log('Login URL:', process.env.SF_LOGIN_URL);
10console.log('Username:', process.env.SF_USERNAME);

Pro tip: The SF_PASSWORD value must be the password concatenated with the security token as a single string — no space between them. If the password is 'MyPass123' and the security token is 'abc123xyz', the value is 'MyPass123abc123xyz'.

Expected result: All five Salesforce secrets appear in Replit Secrets. The check script prints login URL and username without errors.

3

Query Propertybase Data with JSForce (Node.js)

Install required packages in the Shell tab: npm install jsforce express. JSForce is a comprehensive JavaScript library for Salesforce that handles OAuth authentication, SOQL queries, DML operations, and Bulk API access. It takes care of token refresh and the Salesforce authentication flow automatically. Create a JSForce connection using the username-password OAuth flow. Call conn.login() with the username (and password+securityToken) — JSForce constructs the proper OAuth request. Once logged in, use conn.query() to execute SOQL queries and retrieve Propertybase data. Propertybase uses custom objects with the pb__ namespace prefix. Common objects to query: pb__Listing__c (property listings), pb__Lead__c or the standard Lead object (leads), Account (contacts/clients), Opportunity (transactions in Salesforce), pb__Transaction__c (Propertybase transaction records). Explore the exact field names by running a describe call: conn.sobject('pb__Listing__c').describe() returns all fields, their API names, and data types. This is essential since Propertybase's custom field names are not publicly documented and vary by configuration. For paginating large result sets, use SOQL's LIMIT and OFFSET, or use JSForce's conn.queryMore() to follow pagination cursors. Salesforce limits SOQL queries to 2000 records per query — for large datasets, use the Bulk API.

propertybase.js
1// propertybase.js — Propertybase/Salesforce API with JSForce for Node.js on Replit
2const jsforce = require('jsforce');
3const express = require('express');
4
5const app = express();
6app.use(express.json());
7
8const conn = new jsforce.Connection({
9 loginUrl: process.env.SF_LOGIN_URL // https://login.salesforce.com or https://test.salesforce.com
10});
11
12// Authenticate once and reuse the connection
13let isConnected = false;
14async function ensureConnected() {
15 if (!isConnected) {
16 await conn.login(process.env.SF_USERNAME, process.env.SF_PASSWORD);
17 isConnected = true;
18 console.log('Salesforce connected. Instance:', conn.instanceUrl);
19 }
20}
21
22// Get active Propertybase listings
23app.get('/api/listings', async (req, res) => {
24 try {
25 await ensureConnected();
26 const { status = 'Active', limit = 50 } = req.query;
27
28 // pb__Listing__c is Propertybase's listing object
29 // Field names vary by org — run describe() to find exact field names
30 const result = await conn.query(
31 `SELECT Id, Name, pb__Property_Address__c, pb__List_Price__c,
32 pb__Property_Type__c, pb__Status__c, pb__MLS_Number__c,
33 pb__Listing_Agent__r.Name
34 FROM pb__Listing__c
35 WHERE pb__Status__c = '${status}'
36 LIMIT ${parseInt(limit)}`
37 );
38
39 res.json({ listings: result.records, total: result.totalSize });
40 } catch (err) {
41 if (err.errorCode === 'INVALID_FIELD') {
42 return res.status(400).json({ error: 'Field name not found. Run GET /api/describe/pb__Listing__c to see available fields.', detail: err.message });
43 }
44 res.status(500).json({ error: err.message });
45 }
46});
47
48// Get contacts/leads from Salesforce (standard objects)
49app.get('/api/contacts', async (req, res) => {
50 try {
51 await ensureConnected();
52 const result = await conn.query(
53 `SELECT Id, FirstName, LastName, Email, Phone, LeadSource, CreatedDate
54 FROM Contact
55 ORDER BY CreatedDate DESC
56 LIMIT 100`
57 );
58 res.json({ contacts: result.records, total: result.totalSize });
59 } catch (err) {
60 res.status(500).json({ error: err.message });
61 }
62});
63
64// Describe a Salesforce object to find field names
65app.get('/api/describe/:objectName', async (req, res) => {
66 try {
67 await ensureConnected();
68 const metadata = await conn.sobject(req.params.objectName).describe();
69 const fields = metadata.fields.map(f => ({ name: f.name, label: f.label, type: f.type }));
70 res.json({ object: req.params.objectName, fields });
71 } catch (err) {
72 res.status(500).json({ error: err.message });
73 }
74});
75
76app.listen(3000, '0.0.0.0', () => console.log('Propertybase/Salesforce server running on port 3000'));

Pro tip: Before writing SOQL queries with hardcoded field names, call GET /api/describe/pb__Listing__c to see the actual field API names in your specific Propertybase configuration. Field names are customizable and vary between Propertybase installations.

Expected result: GET /api/listings returns Propertybase active listings. GET /api/contacts returns Salesforce contacts. GET /api/describe/pb__Listing__c returns the listing object's field names and types.

4

Python Integration with simple-salesforce

For Python Replit projects, install simple-salesforce and flask: pip install simple-salesforce flask. simple-salesforce is a thin wrapper around the Salesforce REST API that handles authentication and SOQL queries. Create a Salesforce instance with your credentials — simple-salesforce handles the username-password OAuth flow. Once authenticated, use the query() method for SOQL queries and iterate over the records in the result. The password+security_token pattern is the same as in Node.js — pass username and password separately, and simple-salesforce automatically appends the security token when it is provided as a separate parameter, which is cleaner than concatenating them yourself. For Propertybase-specific queries, the SOQL syntax is identical — just pass the query string to sf.query(). Access custom objects with their API names (pb__Listing__c, etc.) and custom fields with their __c-suffixed names. The result is a dictionary with a records key containing the matching rows. For write operations (creating or updating Propertybase records), use sf.pb__Listing__c.create({...}) or sf.pb__Listing__c.update('recordId', {...}). Salesforce DML operations through simple-salesforce follow the same object notation.

propertybase_api.py
1# propertybase_api.py Propertybase/Salesforce with simple-salesforce for Python on Replit
2import os
3from simple_salesforce import Salesforce
4from flask import Flask, request, jsonify
5
6app = Flask(__name__)
7
8# Connect to Salesforce / Propertybase
9# simple-salesforce appends security_token to password automatically
10sf = Salesforce(
11 username=os.environ['SF_USERNAME'],
12 password=os.environ['SF_PASSWORD'],
13 security_token='', # Set SF_SECURITY_TOKEN secret and use os.environ['SF_SECURITY_TOKEN']
14 domain='login' if os.environ.get('SF_LOGIN_URL', '').find('test') == -1 else 'test'
15)
16
17@app.route('/api/listings')
18def get_listings():
19 status = request.args.get('status', 'Active')
20 limit = min(int(request.args.get('limit', 50)), 200)
21 try:
22 result = sf.query(
23 f"SELECT Id, Name, pb__Property_Address__c, pb__List_Price__c, "
24 f"pb__Property_Type__c, pb__Status__c "
25 f"FROM pb__Listing__c "
26 f"WHERE pb__Status__c = '{status}' "
27 f"LIMIT {limit}"
28 )
29 return jsonify({'listings': result['records'], 'total': result['totalSize']})
30 except Exception as e:
31 return jsonify({'error': str(e)}), 500
32
33@app.route('/api/contacts')
34def get_contacts():
35 try:
36 result = sf.query(
37 "SELECT Id, FirstName, LastName, Email, Phone, LeadSource "
38 "FROM Contact ORDER BY CreatedDate DESC LIMIT 100"
39 )
40 return jsonify({'contacts': result['records'], 'total': result['totalSize']})
41 except Exception as e:
42 return jsonify({'error': str(e)}), 500
43
44@app.route('/api/describe/<object_name>')
45def describe_object(object_name):
46 try:
47 metadata = getattr(sf, object_name).describe()
48 fields = [{'name': f['name'], 'label': f['label'], 'type': f['type']}
49 for f in metadata['fields']]
50 return jsonify({'object': object_name, 'fieldCount': len(fields), 'fields': fields})
51 except Exception as e:
52 return jsonify({'error': str(e)}), 500
53
54if __name__ == '__main__':
55 app.run(host='0.0.0.0', port=3000)

Pro tip: Store the Salesforce security token separately as SF_SECURITY_TOKEN in Replit Secrets and pass it to simple-salesforce's security_token parameter. This is cleaner than concatenating it to the password and makes token rotation easier.

Expected result: GET /api/listings returns Propertybase listings from Salesforce. GET /api/describe/pb__Listing__c returns all field names for the listings object.

Common use cases

Listing Data Sync and Export

Pull active real estate listings from Propertybase and sync them to an external website, portal, or marketing tool. Query active listings with their addresses, prices, property types, and agent assignments. Push updates to listing portals or email marketing campaigns automatically when new listings are added or prices change.

Replit Prompt

Build an Express endpoint that fetches active Propertybase listings with address, price, property type, and listing agent from Salesforce, and returns them formatted for a website property search page.

Copy this prompt to try it in Replit

Lead Activity Dashboard

Create a custom reporting dashboard that shows lead flow through the Propertybase pipeline — leads by source, conversion rates by agent, and transaction velocity. Pull Propertybase contact and opportunity data from Salesforce to generate analytics that the standard Propertybase reporting does not provide.

Replit Prompt

Create a Python script that queries Propertybase leads from Salesforce, groups them by lead source and stage, calculates weekly conversion metrics, and returns a summary report.

Copy this prompt to try it in Replit

Transaction Commission Calculator

Pull transaction records from Propertybase and calculate commission splits, agent fees, and brokerage totals based on deal terms. Generate commission statements for agents by reading transaction data from Salesforce and applying the brokerage's commission structure rules.

Replit Prompt

Build a commission report endpoint that fetches closed Propertybase transactions from the last 30 days, calculates gross commission income and agent splits, and returns per-agent totals for payroll processing.

Copy this prompt to try it in Replit

Troubleshooting

INVALID_LOGIN: Invalid username, password, security token; or user locked out

Cause: The password in SF_PASSWORD does not include the security token, the token is incorrect, or the Salesforce user account is locked. Also occurs if the user has not been granted API access.

Solution: Verify SF_PASSWORD = password + security_token with no spaces. Reset your security token in Salesforce (profile settings → Reset My Security Token) and update the Secret. Check that the Salesforce user profile has API Enabled permission.

typescript
1// Test login with explicit error logging
2try {
3 await conn.login(process.env.SF_USERNAME, process.env.SF_PASSWORD);
4 console.log('Login OK. Instance:', conn.instanceUrl);
5} catch (err) {
6 console.error('Login error:', err.errorCode, err.message);
7}

INVALID_TYPE: sObject type 'pb__Listing__c' is not supported

Cause: Propertybase is not installed in this Salesforce org, or the object API name is different in this installation. Propertybase's namespace prefix may differ.

Solution: Run a describe query to list all custom objects: use conn.describeGlobal() in JSForce which returns all available object names. Filter for objects with 'pb' or 'propertybase' in the name to find the correct namespace prefix.

typescript
1// List all custom objects in the org
2const global = await conn.describeGlobal();
3const pbObjects = global.sobjects.filter(o => o.name.toLowerCase().includes('pb__'));
4console.log('Propertybase objects:', pbObjects.map(o => o.name));

INVALID_FIELD error when querying custom fields

Cause: The field API name is wrong — you are using the field label instead of the API name, or the field was renamed in this specific Propertybase configuration.

Solution: Use the /api/describe/{objectName} endpoint to list all fields with their correct API names. Custom fields always end in __c. Look for the field by label if you know what it represents but not its API name.

typescript
1// Get all fields for a Propertybase object
2const meta = await conn.sobject('pb__Listing__c').describe();
3meta.fields.forEach(f => console.log(`${f.label}: ${f.name} (${f.type})`));

Connected App not working — CONSUMER_KEY_MISMATCH or OAUTH error

Cause: Salesforce requires up to 10 minutes after Connected App creation before OAuth credentials activate. Or the Consumer Key/Secret was copied with extra whitespace.

Solution: Wait 10 minutes after creating the Connected App and try again. Verify SF_CLIENT_ID and SF_CLIENT_SECRET in Replit Secrets have no extra whitespace. Also check that the Connected App is not restricted to specific IP ranges that exclude Replit.

Best practices

  • Store SF_CLIENT_ID, SF_CLIENT_SECRET, SF_USERNAME, SF_PASSWORD, and SF_LOGIN_URL in Replit Secrets (lock icon 🔒) — these provide full Salesforce data access
  • Create a dedicated Salesforce Integration user with a read-only profile for reporting integrations rather than using an admin account
  • Use the /api/describe endpoint to explore object field names before hardcoding them in SOQL — field names vary by Propertybase configuration
  • Use SOQL LIMIT clauses on all queries — Salesforce has governor limits and large unfiltered queries can time out or return unexpected volumes of data
  • Store the Salesforce security token separately from the password in Secrets — this makes token rotation easier without changing the password value
  • Implement SOQL injection protection — never concatenate unvalidated user input directly into SOQL query strings
  • Cache Salesforce access tokens in your server's memory or a database — re-authenticating on every request is wasteful and subject to login limits
  • Deploy as Autoscale for on-demand reporting APIs; use Reserved VM for scheduled sync jobs that pull Propertybase data on a cron schedule

Alternatives

Frequently asked questions

How do I connect Replit to Propertybase?

Propertybase is built on Salesforce, so you connect through the Salesforce REST API. Create a Salesforce Connected App to get a Consumer Key and Secret, store those plus your Salesforce username and password+securityToken in Replit Secrets, and use JSForce (Node.js) or simple-salesforce (Python) to authenticate and run SOQL queries against Propertybase's custom objects.

Does Propertybase have its own API?

No. Propertybase is a Salesforce-native app — there is no separate Propertybase API. All Propertybase data is stored in Salesforce standard and custom objects (with the pb__ namespace prefix) and is accessible through the Salesforce REST API and SOQL. To integrate with Propertybase, you work with the Salesforce API.

What are the Propertybase object names in Salesforce?

Propertybase uses the pb__ namespace prefix. Common objects include pb__Listing__c (property listings), pb__Transaction__c (transaction records), and pb__Lead__c (leads). Standard Salesforce objects like Contact, Account, and Opportunity are also used. Run conn.describeGlobal() or sf.describe_global() to list all objects in your specific org — field names vary by configuration.

How do I store Salesforce credentials securely in Replit?

Click the lock icon (🔒) in the Replit sidebar and add SF_CLIENT_ID (Consumer Key), SF_CLIENT_SECRET, SF_USERNAME, SF_PASSWORD (password + security token concatenated), and SF_LOGIN_URL. Never put these in code files. For the username-password OAuth flow, the password must include the security token appended with no separator.

What Replit deployment type should I use for Propertybase integrations?

Use Autoscale for on-demand API endpoints where real estate data is fetched in response to user requests. Use Reserved VM for scheduled reporting jobs that sync Propertybase data to external systems on a regular schedule. Most Propertybase integrations are reporting or sync tools that run periodically, which suits Reserved VM for background jobs.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.