Propertybase is not a standalone platform — it is a package of Salesforce custom objects installed in your Salesforce org. Connecting Bubble to Propertybase means connecting to the Salesforce REST API and running SOQL queries against objects with the pb__ prefix (pb__Listing__c, pb__Transaction__c, pb__Commission__c). OAuth token exchange runs in a Backend Workflow and credentials stay Private in the API Connector.
| Fact | Value |
|---|---|
| Tool | Propertybase |
| Category | Real Estate & Industry |
| Method | Bubble API Connector |
| Difficulty | Advanced |
| Time required | 3–5 hours |
| Last updated | July 2026 |
Propertybase + Bubble: The Salesforce-Based Real Estate CRM Integration
Many real estate brokerage developers search for 'Propertybase API' and expect to find a Propertybase developer portal with its own endpoints and credentials. The critical insight that saves hours of debugging: Propertybase does not have its own API. It is a Salesforce managed package — a collection of custom objects, fields, and business logic installed on top of a Salesforce org. All Propertybase data is stored in Salesforce's database as custom objects with the pb__ prefix.
This means 'connecting to Propertybase' is exactly the same as connecting to Salesforce's REST API. The Bubble integration uses Salesforce's OAuth 2.0 authentication, Salesforce's query endpoint, and SOQL — Salesforce's SQL-like query language. The only Propertybase-specific detail is knowing which object names to query: pb__Listing__c for property listings, pb__Transaction__c for deals, pb__Commission__c for commission records, and similar managed package objects.
In Bubble, the integration architecture is: 1. A Salesforce Connected App (created in your Salesforce org's setup) provides OAuth credentials 2. A Bubble Backend Workflow POSTs these credentials to Salesforce's token endpoint and stores the access_token in Bubble's database 3. The API Connector uses the stored token as a dynamic Bearer header in GET requests to Salesforce's query endpoint 4. SOQL query strings target pb__Listing__c and other Propertybase objects 5. A scheduled Backend Workflow refreshes the token before it expires
This integration is Advanced because it combines Salesforce OAuth, SOQL, and Backend Workflow scheduling in Bubble. But each individual piece is well-defined — follow the steps in order and the integration comes together predictably.
Note on Propertybase ownership: Propertybase was acquired by Lone Wolf Technologies. As of 2026, confirm with your Propertybase account that the platform is still actively supported and that your Salesforce org has the Propertybase managed package installed — the product landscape in this space has changed.
Integration method
Connect via Bubble's API Connector to the Salesforce REST API using OAuth 2.0 Bearer token. A Backend Workflow handles token exchange (POSTing to Salesforce's token endpoint with Connected App credentials) and stores the token for use in API calls. SOQL queries target Propertybase custom objects: pb__Listing__c, pb__Transaction__c, pb__Commission__c.
Prerequisites
- A Salesforce org with the Propertybase managed package installed and active data in pb__Listing__c and related objects
- Salesforce System Administrator access to create a Connected App at setup.salesforce.com
- Your Salesforce user's username, password, and security token (for the password grant OAuth flow)
- A Bubble app on a paid plan (Starter or above) — required for Backend Workflows used in token exchange and scheduled token refresh
- Basic familiarity with Bubble's API Connector, Backend Workflows, and the Workflow editor
Step-by-step guide
Step 1: Create a Salesforce Connected App
Log in to your Salesforce org with System Administrator credentials. In the top-right corner, click the gear icon → **Setup**. In Setup, use the Quick Find search bar to search for 'App Manager'. Click **App Manager** → **New Connected App** in the top-right. Fill in the Connected App form: - **Connected App Name**: Bubble Integration (or any descriptive name) - **API Name**: Bubble_Integration (auto-fills, adjust if needed) - **Contact Email**: your email address In the **API (Enable OAuth Settings)** section: - Check **Enable OAuth Settings** - **Callback URL**: https://[your-bubble-app].bubbleapps.io/oauth_callback (Bubble's URL; for now you can use a placeholder — for the password grant flow this URL is not actively used) - **Selected OAuth Scopes**: Add these scopes: - Access and manage your data (api) - Perform requests on your behalf at any time (refresh_token, offline_access) Click **Save**. Salesforce takes 2-10 minutes to provision the Connected App. After saving, click **Manage Consumer Details** (you may need to verify your identity). Copy the **Consumer Key** (client_id) and **Consumer Secret** (client_secret). Store these securely — you will paste them into Bubble's Backend Workflow in the next step. Also obtain your Salesforce **security token**: go to your Salesforce user profile → Settings → Reset My Security Token. Salesforce emails the new token to your email address. The full password for the OAuth flow is your Salesforce password + security token concatenated (e.g., if password is 'abc123' and token is 'xyz', use 'abc123xyz').
Pro tip: The Connected App takes 2-10 minutes to become active after saving in Salesforce. If your first token exchange attempt fails with 'invalid_client', wait a few minutes and try again — the app may not be fully provisioned yet.
Expected result: You have a Salesforce Connected App with Consumer Key and Consumer Secret. You have your Salesforce username, password+security_token, and the org's login URL (typically https://login.salesforce.com).
Step 2: Build the Backend Workflow for OAuth Token Exchange
The Salesforce access token must be obtained server-side — the Consumer Secret cannot appear in any client-side Bubble action. A Backend Workflow handles this. **First, create a data type to store the token:** Go to Data tab → Data types → New type → name it 'SalesforceToken'. Add fields: - access_token (text) - instance_url (text) — Salesforce returns a unique instance URL per org; you must use this URL for all subsequent API calls, not a hardcoded base URL - issued_at (date) — to track when the token was issued **Enable Backend Workflows:** Go to **Settings** (gear icon in editor) → **API** tab → check **'This app exposes a Workflow API'**. This requires a paid Bubble plan. **Create the Backend Workflow:** Click **Backend workflows** in the left panel → **New API workflow**. Name it 'GetSalesforceToken'. Set it to be triggered by API call (not exposed publicly — this is an internal workflow). Inside the workflow, add the action **Plugins → API Connector → POST Salesforce Token** (you'll create this API Connector call in a moment, then come back). For now, proceed to configure the API Connector call first. **Configure the token endpoint in the API Connector:** Go to Plugins → API Connector → Add another API → name it 'Salesforce'. Set base URL to https://login.salesforce.com. Click **New call**. Configure: - Name: Get Access Token - Method: POST - Endpoint: /services/oauth2/token - Body type: Form parameters URL-encoded - Body parameters (all Private): - grant_type: password - client_id: [your Consumer Key] — mark Private - client_secret: [your Consumer Secret] — mark Private - username: [your Salesforce username] — mark Private - password: [your Salesforce password + security token concatenated] — mark Private Set **Use as**: Action (not Data — the response structure is a single object, not a list). Click **Initialize call**. Bubble will execute a real token exchange with Salesforce. On success, Bubble detects the response fields: access_token, instance_url, token_type, issued_at, id. These are the fields you'll store in the SalesforceToken data type. Now return to the Backend Workflow and add the workflow steps: 1. Call the 'Get Access Token' API call 2. 'Create a new SalesforceToken' with: - access_token = Result of Step 1's access_token - instance_url = Result of Step 1's instance_url - issued_at = Current date/time 3. (Optional) Delete old SalesforceToken records to prevent accumulation Trigger this Backend Workflow once manually to create the first token. The SalesforceToken record now exists in Bubble's database, ready for use.
1{2 "call_name": "Get Access Token",3 "method": "POST",4 "url": "https://login.salesforce.com/services/oauth2/token",5 "body_type": "Form URL-encoded",6 "body": {7 "grant_type": "password",8 "client_id": "<consumer_key_private>",9 "client_secret": "<consumer_secret_private>",10 "username": "<sf_username_private>",11 "password": "<sf_password_plus_token_private>"12 },13 "use_as": "Action"14}Pro tip: The instance_url in the Salesforce token response is critical — it looks like https://yourorg.my.salesforce.com and changes per auth. Every subsequent API call must use this URL, not a hardcoded base URL. Store it in the SalesforceToken data type and reference it dynamically.
Expected result: The Backend Workflow successfully exchanges credentials for a Salesforce access token. A SalesforceToken record appears in Bubble's database with access_token, instance_url, and issued_at populated.
Step 3: Configure the API Connector for Salesforce REST Queries
With a valid access token stored in Bubble's database, configure the API Connector for actual data queries against Propertybase objects. In the API Connector, within the 'Salesforce' entry, click **New call**. Configure: - Name: SOQL Query - Method: GET - Endpoint: leave this blank — you'll use a dynamic URL built from the stored instance_url Actually, for dynamic base URLs, create a separate API Connector entry: click **Add another API** → name it 'Salesforce Data'. In the **API Root URL** field, enter a placeholder — you will override this per call with the dynamic instance_url. Alternatively, structure the call URL as a dynamic parameter. The most reliable pattern for dynamic Salesforce instance URLs in Bubble: add the full URL (including instance_url prefix) as a dynamic variable in the endpoint field: - Endpoint path: /services/data/v59.0/query - Query parameter: q (dynamic SOQL string) For the Authorization header, click **Add shared headers or parameters**: - Name: Authorization - Value: Bearer [reference to SalesforceToken's access_token field from Bubble DB] - Private: checked To make the Authorization header dynamic (pulling the token from the database), you must reference it from the workflow context, not as a fixed string. In the API Connector shared header, set the value to a Bubble dynamic expression: 'Do a search for SalesforceToken sort by issued_at descending first item's access_token'. This pulls the most recent valid token. Click **New call** → name it 'Query Propertybase Listings'. Set: - Method: GET - Use as: Data - Endpoint: /services/data/v59.0/query - Query parameter q (dynamic): will be set from workflows For the Initialize call, enter a test SOQL query to confirm the connection. Example: `SELECT Id, pb__Address__c, pb__ListPrice__c, pb__Status__c FROM pb__Listing__c WHERE pb__Status__c = 'Active' LIMIT 10` URL-encode this string for the q parameter in the Initialize call test. Bubble typically handles URL encoding automatically for query parameters. If the Initialize call succeeds, Bubble detects the Salesforce response structure: totalSize, done, records[] with each record containing Id and the requested fields. This is the data structure you'll bind to Bubble UI elements.
1{2 "call_name": "Query Propertybase Listings",3 "method": "GET",4 "url": "https://[instance_url_from_db]/services/data/v59.0/query",5 "headers": {6 "Authorization": "Bearer <access_token_from_db_private>"7 },8 "params": {9 "q": "SELECT Id, pb__Address__c, pb__ListPrice__c, pb__Status__c, pb__Bedrooms__c, pb__Bathrooms__c FROM pb__Listing__c WHERE pb__Status__c = 'Active' LIMIT 100"10 },11 "use_as": "Data"12}Pro tip: If the Initialize call returns a 401 INVALID_SESSION_ID error, the access token in the database has expired. Re-run the GetSalesforceToken Backend Workflow to refresh it, then retry the Initialize call. This is normal — tokens expire and must be refreshed.
Expected result: The SOQL query call initializes successfully. Bubble detects the Salesforce response structure with totalSize, done, and records[] fields. The records array contains Propertybase listing objects with pb__ prefixed field names.
Step 4: Verify Propertybase Object and Field API Names
Propertybase field API names vary by org configuration. The pb__ prefix is standard for the managed package, but specific field names (like pb__ListPrice__c vs pb__List_Price__c) depend on how Propertybase was installed and customized in your Salesforce org. You must verify the exact names in Salesforce Object Manager before building Bubble workflows. In Salesforce Setup, search for **Object Manager** in Quick Find. Click **Object Manager**. In the search box, type 'pb__' to filter for Propertybase objects. You will see: - pb__Listing__c — property listings - pb__Transaction__c — deals and closings - pb__Commission__c — commission records - Other pb__ objects depending on your Propertybase version Click on **pb__Listing__c** → click **Fields & Relationships** in the left panel. This shows every field on the Listing object with its **Field Label** (human-readable) and **Field Name** (API name, the one you use in SOQL queries). Common fields: - pb__Address__c — property address - pb__ListPrice__c — list price - pb__Status__c — listing status - pb__Bedrooms__c — bedroom count - pb__Listing_Agent__c — assigned agent (lookup to User) - pb__CloseDate__c — close date (on Transaction) Make a list of the exact API names for every field you plan to display in Bubble. Any mismatch between what you write in a SOQL query and the actual field API name results in a Salesforce error: 'No such column 'fieldname' on entity 'pb__Listing__c'. For status values: click on pb__Status__c's field label to see its picklist values. These are the exact strings you'll use in SOQL WHERE clauses (e.g., WHERE pb__Status__c = 'Active' — the value must match the picklist entry exactly, including capitalization). Write down your verified SOQL query: ``` SELECT Id, pb__Address__c, pb__ListPrice__c, pb__Status__c, pb__Bedrooms__c FROM pb__Listing__c WHERE pb__Status__c = 'Active' ORDER BY pb__ListPrice__c ASC LIMIT 100 ``` Test this query in Salesforce's **Developer Console** (Setup → Developer Console → Query Editor tab) before putting it in Bubble. If it works in Developer Console, it will work in Bubble's API call.
1-- Test in Salesforce Developer Console (Query Editor tab)2-- Replace field names with your org's actual API names3SELECT 4 Id,5 pb__Address__c,6 pb__ListPrice__c,7 pb__Status__c,8 pb__Bedrooms__c,9 pb__Bathrooms__c,10 pb__Listing_Agent__r.Name11FROM pb__Listing__c12WHERE pb__Status__c = 'Active'13ORDER BY pb__ListPrice__c ASC14LIMIT 100Pro tip: Use Salesforce's Developer Console (Setup → Developer Console → Query Editor) to test SOQL queries against your real Propertybase data before building Bubble workflows. This saves many round-trips of debugging API Connector calls.
Expected result: You have a verified SOQL query with exact Propertybase field API names that returns active listing records in Salesforce's Developer Console. These same field names will be used in Bubble's API Connector call.
Step 5: Build the Listing Dashboard in Bubble
With the API Connector configured and field names verified, build the Propertybase listing dashboard. **Create Bubble data types for caching:** Go to Data tab → New type → 'PropertybaseListing'. Add fields matching your verified SOQL fields: - sf_id (text) — Salesforce Id - address (text) — pb__Address__c value - list_price (number) — pb__ListPrice__c value - status (text) — pb__Status__c value - bedrooms (number) — pb__Bedrooms__c value - bathrooms (number) — pb__Bathrooms__c value - last_synced (date) **Create a sync workflow:** In the Workflow editor, add a workflow triggered by a 'Sync Listings' button: 1. Call the SOQL Query API call with the verified Propertybase query 2. For each record in Result's records list: - Search for existing PropertybaseListing where sf_id = record's Id - If found: Make changes to update fields - If not found: Create new PropertybaseListing 3. Update the sync timestamp displayed on the page Note: Bubble's native 'For each record' looping is available via a recursive Backend Workflow (paid plan) or via the API Connector's list handling. For smaller datasets (under 100 records), use Bubble's 'create/modify a list of things' approach. **Build the repeating group:** Add a Repeating Group: - Type of content: PropertybaseListing - Data source: Do a search for PropertybaseListing (with optional status filter) - Layout: list, 1 column for a dashboard style Inside the cell: - Text for address: Current cell's PropertybaseListing's address - Text for price: '$' + Current cell's list_price formatted as dollar amount - Text for bedrooms: Current cell's bedrooms + ' beds' - A status badge: text showing Current cell's status, conditionally styled (green background when 'Active', grey when 'Pending') - A 'View in Salesforce' link: https://[your org].lightning.force.com/[current cell's sf_id] **Add privacy rules:** Go to Data → Privacy → PropertybaseListing → add rule: 'When Current User is logged in and Current User's role = Agent or Manager → all fields visible'. Unauthenticated users should not read listing data.
Pro tip: Store Propertybase data in Bubble's database (not just in page custom state) so the dashboard loads instantly on return visits. The Salesforce sync only needs to run when data is stale — not on every page load. A 'last synced' display with a manual refresh button gives users control without burning Salesforce API calls.
Expected result: The listing dashboard shows active Propertybase listings from the synced Bubble database. Filters by status and agent work using Bubble's native 'Do a search for' constraints. The 'Sync Listings' button refreshes data from Salesforce.
Step 6: Schedule Token Refresh and Handle SOQL Pagination
**Schedule the token refresh:** Salesforce access tokens from the password grant flow typically expire within 2 hours. To keep the integration running without manual intervention, create a scheduled Backend Workflow that refreshes the token automatically. In Backend Workflows, create a new workflow named 'RefreshSalesforceToken'. Add the same steps as the GetSalesforceToken workflow: POST to the Salesforce token endpoint and update the SalesforceToken record in Bubble's database. To schedule it: in the Backend Workflows panel, click the clock icon next to RefreshSalesforceToken → **Schedule recurring** → set interval to every 90 minutes (giving a 30-minute buffer before the 2-hour expiry). This requires a paid Bubble plan. On the free plan, you would need to manually trigger token refresh — which is not viable for a production integration. RapidDev's team has built Salesforce-connected Bubble apps for real estate brokerages integrating with Propertybase, Salesforce CRM, and custom SF objects — if you need help with the SOQL data model or token refresh architecture, book a free scoping call at rapidevelopers.com/contact. **Handle SOQL pagination for large portfolios:** Salesforce limits SOQL results to 2,000 records per query. For brokerages with large listing databases, implement offset-based pagination: ```sql SELECT Id, pb__Address__c, pb__ListPrice__c, pb__Status__c FROM pb__Listing__c WHERE pb__Status__c = 'Active' ORDER BY Id ASC LIMIT 2000 OFFSET 0 ``` Increment the OFFSET by 2000 in each iteration of a recursive Backend Workflow until totalSize is reached. Store each page of results into Bubble's database during the sync, then query the Bubble database (not Salesforce directly) for display — this keeps the UI fast and avoids repeated Salesforce API calls. Salesforce API call limits apply at the edition level (Developer: 15,000/day; Enterprise: 150,000/day — verify current limits). For large syncs, consider running the full sync nightly via a scheduled Backend Workflow and only fetching changes (records modified in the last 24 hours) during daytime refresh cycles using a SOQL WHERE clause like: `WHERE LastModifiedDate >= [24 hours ago]`.
1-- Incremental sync: only fetch recently modified records2-- Run this on hourly scheduled Backend Workflow3SELECT 4 Id,5 pb__Address__c,6 pb__ListPrice__c, 7 pb__Status__c,8 pb__Bedrooms__c,9 LastModifiedDate10FROM pb__Listing__c11WHERE LastModifiedDate >= LAST_N_HOURS:2412ORDER BY LastModifiedDate DESC13LIMIT 2000Pro tip: Use LAST_N_HOURS:24 or LAST_N_DAYS:1 in SOQL WHERE clauses for incremental syncs. These are Salesforce date literals that avoid the complexity of converting Bubble date values to Salesforce's ISO 8601 format in workflow logic.
Expected result: A scheduled Backend Workflow refreshes the Salesforce token every 90 minutes without manual intervention. Large listing portfolios sync incrementally using LastModifiedDate filtering, keeping Salesforce API call usage within edition limits.
Common use cases
Brokerage Listing Dashboard
Build a Bubble-powered internal dashboard that pulls active listings from Propertybase (pb__Listing__c WHERE pb__Status__c = 'Active') and displays them to agents with address, list price, status, and assigned agent. Agents get a branded interface without needing Salesforce licenses for read-only reporting tasks.
Copy this prompt to try it in Bubble
Transaction Pipeline Tracker
Create a deal pipeline view that reads Propertybase transaction records (pb__Transaction__c) and shows each deal's stage, closing date, and commission amount. Filter by agent to give individual agents a personal pipeline view. Update deal stage from Bubble by writing back to Salesforce via the Composite API.
Copy this prompt to try it in Bubble
Agent Performance Report
Build a reporting page that pulls commission records (pb__Commission__c) and closed transaction counts per agent for the current quarter. Aggregate in SOQL using GROUP BY and display results in Bubble charts — giving brokerage managers a custom performance dashboard without paying for Salesforce reports and dashboards licenses.
Copy this prompt to try it in Bubble
Troubleshooting
Token exchange returns 'invalid_client_credentials' or 'authentication failure'
Cause: The Consumer Key, Consumer Secret, username, or password+security_token combination is incorrect. A common mistake is using just the password without the security token appended — the Salesforce password grant flow requires password concatenated with the security token (no separator).
Solution: Verify each credential: (1) Consumer Key and Consumer Secret from the Connected App's 'Manage Consumer Details' page — these are long strings, easy to copy incompletely. (2) Confirm your Salesforce username is the full email-format username, not a display name. (3) Reset your security token (Salesforce user profile → Settings → Reset Security Token) and use the newly emailed token. The combined password field must be: yourPassword123securityTokenXYZ — no space, no separator.
SOQL query returns 'No such column pb__ListPrice__c on entity pb__Listing__c'
Cause: The field API name used in the SOQL query doesn't exist on the Propertybase object in this specific Salesforce org. Field names can differ between Propertybase versions and org customizations.
Solution: Go to Salesforce Setup → Object Manager → search 'pb__' → click pb__Listing__c → Fields & Relationships. Find the price field and note its exact Field Name (the API name column, ending in __c). Update your SOQL query to use the exact API name shown. Test the corrected query in Salesforce Developer Console before updating Bubble.
1-- Find correct field names in Salesforce Developer Console:2DESCRIBE pb__Listing__cAPI calls return 401 INVALID_SESSION_ID after the integration was working
Cause: The Salesforce access token stored in Bubble's database has expired. Password grant tokens expire within 2 hours by default.
Solution: Manually trigger the GetSalesforceToken Backend Workflow to generate a fresh token and update the SalesforceToken record. Then set up the scheduled token refresh Backend Workflow (Step 6) to prevent this from happening again. On Bubble's free plan, you cannot schedule Backend Workflows — upgrade to a paid plan for production use.
The Initialize call in the API Connector shows 'There was an issue setting up your call' for the SOQL query endpoint
Cause: The instance_url in the API Connector endpoint is not correct, the access token is expired, or the Bubble API Connector cannot resolve the dynamic base URL reference during the Initialize step.
Solution: During the Initialize call, enter the actual instance_url value directly (e.g., https://myorg.my.salesforce.com) rather than a dynamic Bubble reference. Copy the instance_url from the SalesforceToken record in Bubble's Data tab and paste it as the base URL temporarily for initialization. After initialization, switch back to the dynamic reference for production use.
Backend Workflow for token refresh shows 'Workflow API is not enabled'
Cause: Backend Workflows (API Workflows) require a paid Bubble plan. The free tier does not support this feature.
Solution: Upgrade to Bubble's Starter plan or above to enable Backend Workflows. In Bubble Settings → API tab → check 'This app exposes a Workflow API'. This is required for both the token exchange workflow (Step 2) and the scheduled token refresh (Step 6). Without a paid plan, this Propertybase integration cannot run in production.
SOQL query returns 0 records even though listings exist in Propertybase
Cause: The WHERE clause uses an incorrect picklist value that doesn't match Propertybase's status field values in this org, or the Connected App user doesn't have permission to read pb__Listing__c records.
Solution: Check the exact picklist values: in Salesforce Setup → Object Manager → pb__Listing__c → Fields → pb__Status__c → click the field → scroll to 'Values' to see the exact status strings used. Also verify in Salesforce Developer Console that the query returns records when run as the same user whose credentials the Connected App uses. Check that the user's Salesforce Profile has read access to pb__Listing__c and its relevant fields.
1-- Test in Salesforce Developer Console with no WHERE filter:2SELECT Id, pb__Status__c FROM pb__Listing__c LIMIT 103-- See what actual status values appear in your dataBest practices
- Always use the Salesforce instance_url returned in the token response as the base URL for all data API calls — never hardcode a Salesforce org URL. The instance_url is org-specific and can change (e.g., during Salesforce infrastructure migrations). Store it in the SalesforceToken data type alongside the access token.
- Verify Propertybase field API names in Salesforce Object Manager before writing any SOQL query. The pb__ prefix is standard, but field names vary by org. A SOQL query with a wrong field name fails immediately with a clear error — but only after you deploy and try to use it.
- Test all SOQL queries in Salesforce Developer Console (Setup → Developer Console → Query Editor) before adding them to Bubble workflows. The Developer Console gives instant results, shows exact error messages, and lets you iterate quickly without Bubble workflow round-trips.
- Store Propertybase data in Bubble's database and sync on a schedule or on-demand button rather than fetching from Salesforce on every page load. Salesforce API calls count against your org's daily API limit (varies by edition). Repeated page loads hitting the API can exhaust limits on editions with lower call quotas.
- Configure Bubble privacy rules on all data types that store Propertybase/Salesforce data before going live. Listings, transactions, and commission data are commercially sensitive — restrict visibility to authenticated, authorized users by role.
- Schedule the token refresh Backend Workflow at a shorter interval than the token's expiry time — if the token expires in 2 hours, refresh every 90 minutes. A buffer prevents edge cases where the refresh runs slightly late and the token has already expired when an API call is made.
- Use SOQL date literals (LAST_N_HOURS:24, THIS_MONTH, LAST_QUARTER) for incremental sync queries instead of converting Bubble date values to Salesforce's ISO 8601 format. This avoids timezone-related conversion bugs and keeps the SOQL query readable.
Alternatives
If you're accessing Salesforce standard objects (Contacts, Accounts, Opportunities) rather than Propertybase custom objects, the Bubble-to-Salesforce integration is the same — the only difference is the object names in SOQL (standard names instead of pb__ prefixed ones). All the OAuth, token storage, and API Connector patterns are identical.
Buildium is a standalone property management REST API for residential operators with self-serve key generation and no Salesforce complexity. If your use case is tenant and maintenance management rather than brokerage CRM, Buildium is significantly simpler to integrate — no OAuth flow, no SOQL, no token scheduling.
CoStar provides commercial real estate market data (listings, comparables, analytics) rather than brokerage CRM functionality. If your Bubble app needs market data rather than deal pipeline tracking, CoStar is the enterprise data alternative — though it also requires enterprise contract approval.
Frequently asked questions
Does Propertybase have its own API separate from Salesforce?
No. Propertybase is a Salesforce managed package — it installs custom objects, fields, and business logic into a Salesforce org. There is no separate Propertybase API endpoint or developer portal. All Propertybase data is accessed through Salesforce's standard REST API, with Propertybase data living in objects prefixed with pb__. This is the most important thing to understand before starting the integration.
What Salesforce objects does Propertybase add that I can query from Bubble?
The core Propertybase objects are pb__Listing__c (property listings with address, price, status, and listing details), pb__Transaction__c (deal records with stages, close dates, and parties), pb__Commission__c (commission amounts and splits), and pb__Contact__c or standard Salesforce Contact with Propertybase fields. The exact fields on each object depend on your org's Propertybase version and customization — always verify in Salesforce Object Manager.
Do I need a Salesforce developer license or just the admin credentials?
For creating the Connected App, you need Salesforce System Administrator access. For the OAuth password grant flow, you need the credentials of a Salesforce user whose profile has read (and write, if needed) access to pb__Listing__c and related objects. This can be a dedicated integration user profile with minimal permissions — you don't need to use admin credentials in production.
What is SOQL and how is it different from SQL?
SOQL (Salesforce Object Query Language) is Salesforce's SQL-like query language. It looks similar to SQL but with important differences: there are no JOINs (use relationship notation like pb__Transaction__r.pb__Listing__c instead), the FROM clause references Salesforce object API names (not table names), date comparisons use Salesforce date literals like THIS_MONTH or LAST_N_DAYS:30, and the maximum records per query is 2,000 (use OFFSET and LIMIT for pagination). Test SOQL in Salesforce Developer Console before building Bubble workflows.
Do I need a paid Bubble plan to integrate with Propertybase?
Yes. A paid Bubble plan (Starter or above) is required for two reasons: (1) the OAuth token exchange must happen in a Backend Workflow, not a client-side action, and Backend Workflows require a paid plan; (2) the scheduled token refresh workflow also requires a paid plan. Without Backend Workflows, you cannot keep Salesforce credentials server-side and cannot refresh tokens automatically.
How do I handle Propertybase field names that differ from documentation?
Propertybase field API names are set per-org and can be customized. Always verify in Salesforce Object Manager: Setup → Object Manager → search 'pb__' → click the object → Fields & Relationships → note the Field Name column (ending in __c). These exact names are what you use in SOQL queries and in Bubble's API Connector response field mapping. Documentation and online examples may use generic names that don't match your specific installation.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation