# MongoDB Atlas

- Tool: Bubble
- Difficulty: Advanced
- Time required: 2 hours
- Last updated: July 2026

## TL;DR

Connect Bubble to MongoDB Atlas using a REST proxy that exposes CRUD endpoints, Atlas Search queries, and Atlas Trigger webhooks. The Atlas Data API was retired in September 2025 — you need a Node.js proxy on Render or Atlas App Services custom HTTPS endpoints. Atlas-specific features like full-text search, vector search, and database event triggers make this integration particularly powerful for Bubble apps that need intelligent search or real-time data sync.

## Atlas-specific features that go beyond basic MongoDB CRUD for Bubble

The `mongodb` brief covers connecting Bubble to a MongoDB database in general — basic CRUD via a proxy. This brief covers MongoDB Atlas's managed platform features that make Atlas distinct from a self-hosted MongoDB instance:

**Atlas Search** is a full-text search engine built into your Atlas cluster using Apache Lucene indexes. It supports fuzzy matching, autocomplete, phrase search, and faceted search over any MongoDB collection. From Bubble, you send a search term to your proxy, the proxy runs a `$search` aggregation stage, and the results come back as an ordered list of matching documents — ready to populate a Bubble Repeating Group with ranked search results.

**Atlas Triggers** fire server-side when documents are inserted, updated, or deleted in a collection. You configure a trigger in Atlas App Services that sends an HTTPS POST to a Bubble Backend Workflow URL when the event occurs. This enables real-time reactions in Bubble without polling — when a new order arrives in MongoDB, Atlas fires a trigger that hits Bubble, which sends a notification to the relevant user.

**Atlas Vector Search** adds semantic similarity search using stored vector embeddings. Your proxy receives a query text, generates an embedding using an AI API, and runs a `$vectorSearch` aggregation stage to find semantically similar documents. Available on M10+ dedicated clusters.

The Atlas M0 free cluster (512MB shared) supports Atlas Search and Triggers. Dedicated M10 clusters add vector search and higher query throughput — verify current pricing and tier availability at atlas.mongodb.com.

The Atlas Data API (`data.mongodb-api.com`) was retired in September 2025. Any Bubble integration referencing that URL will fail with 404/410 errors. The architecture described in this guide is the correct 2026 approach.

## Before you start

- A MongoDB Atlas account with an M0 free cluster (for Atlas Search and Triggers) or M10+ dedicated cluster (for vector search) at atlas.mongodb.com
- A Render account (render.com) for the Node.js proxy, or familiarity with Atlas App Services custom HTTPS endpoints
- A Bubble app on any plan for basic API Connector usage; paid Bubble plan (Starter or above) required for API Workflows / Backend Workflows (needed for Atlas Triggers)
- The API Connector plugin installed in your Bubble app (Plugins tab → Add plugins → search 'API Connector' by Bubble → Install)

## Step-by-step guide

### 1. Set up your Atlas cluster, database user, and Atlas Search index

Log into atlas.mongodb.com and sign in or create a free account. Create a free M0 cluster (click 'Build a Database' → choose M0 free tier → select cloud provider and region). Once the cluster is provisioned, go to 'Database Access' and add a database user with a username like `bubble-proxy` and a generated password — copy this password. Set the role to 'Read and Write to Any Database' for development. Under 'Network Access', add `0.0.0.0/0` (allow all) since Render does not provide a static outbound IP on the free tier. Click 'Connect' → 'Connect your application' and copy the `mongodb+srv://` connection string, replacing `<password>` with your user's password. To create an Atlas Search index: in the Atlas dashboard, click 'Atlas Search' in the left sidebar → 'Create Search Index'. Choose the 'Visual Editor' and select your database and collection. The default index configuration (`index: 'default'`) indexes all string fields and supports fuzzy text search. Name it `default` and create it — index building may take a minute. You can create additional search indexes for specific field sets or for autocomplete if needed.

**Expected result:** Your Atlas M0 cluster is running with a database user and Atlas Search index on your target collection. The search index status is 'Active'. You have the connection string ready for the proxy environment variable.

### 2. Deploy a Node.js proxy with CRUD and Atlas Search endpoints on Render

Create a GitHub repository with `package.json` (dependencies: `express`, `mongodb`) and `server.js`. The proxy validates `X-API-Key`, connects to MongoDB via the connection string in environment variables, and exposes endpoints for: `/find` (CRUD document queries with filter, limit, skip), `/insertOne` (insert a document), `/updateOne` (update by _id), and `/search` (Atlas Search using the `$search` aggregation stage). The search endpoint accepts a `query` string and `collection` name, runs the `$search` aggregation with fuzzy text matching, and returns ranked results. Convert `_id` ObjectID to a plain string in all responses. On Render: create a Web Service, connect the GitHub repo, set environment variables (`MONGO_URI`, `API_KEY`), and deploy. The proxy HTTPS URL from Render becomes your Bubble API Connector root URL.

```
// server.js — MongoDB Atlas proxy with Atlas Search for Bubble
const express = require('express');
const { MongoClient, ObjectId } = require('mongodb');
const app = express();
app.use(express.json());

const client = new MongoClient(process.env.MONGO_URI);
let db;
async function connect() {
  await client.connect();
  db = client.db();
  console.log('Atlas connected');
}
connect();

function auth(req, res, next) {
  if (req.headers['x-api-key'] !== process.env.API_KEY) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  next();
}

function serialize(docs) {
  return docs.map(d => ({ ...d, _id: d._id ? d._id.toString() : undefined }));
}

// CRUD: find documents
app.post('/find', auth, async (req, res) => {
  const { collection, filter = {}, limit = 25, skip = 0 } = req.body;
  const docs = await db.collection(collection)
    .find(filter).limit(limit).skip(skip).toArray();
  res.json({ documents: serialize(docs) });
});

// CRUD: insert one document
app.post('/insertOne', auth, async (req, res) => {
  const { collection, document } = req.body;
  const result = await db.collection(collection).insertOne(document);
  res.json({ insertedId: result.insertedId.toString() });
});

// CRUD: update one document by _id string
app.post('/updateOne', auth, async (req, res) => {
  const { collection, id, updates } = req.body;
  await db.collection(collection)
    .updateOne({ _id: new ObjectId(id) }, { $set: updates });
  res.json({ success: true });
});

// Atlas Search: full-text fuzzy search
app.post('/search', auth, async (req, res) => {
  const { collection, query, limit = 10 } = req.body;
  const docs = await db.collection(collection).aggregate([
    {
      $search: {
        index: 'default',
        text: {
          query: query,
          path: { wildcard: '*' },
          fuzzy: { maxEdits: 1 }
        }
      }
    },
    { $limit: limit },
    {
      $project: {
        _id: { $toString: '$_id' },
        score: { $meta: 'searchScore' },
        name: 1,
        description: 1
      }
    }
  ]).toArray();
  res.json({ documents: docs });
});

app.listen(process.env.PORT || 3000);
```

**Expected result:** Your Render proxy is live. Test `/search` with a POST body of `{"collection":"products","query":"widget"}` and confirm you receive matching documents with relevance scores. Test `/find` to confirm basic CRUD also works through the same proxy.

### 3. Configure Bubble's API Connector with two API groups: CRUD and Search

In your Bubble editor, go to Plugins tab → API Connector (install if not present). Click 'Add another API'. Name it 'Atlas Proxy'. Root URL: your Render proxy HTTPS URL. Shared headers: `X-API-Key` (value: your proxy API key, Private checkbox checked) and `Content-Type: application/json` (not private). This one API group handles both CRUD calls and the search call since they all go to the same proxy. Optionally, if you also want to use the Atlas Administration API (for creating indexes or viewing cluster metrics), create a separate API group named 'Atlas Admin API' with Root URL `https://cloud.mongodb.com/api/atlas/v2` and Digest Auth headers (Atlas Admin API uses HTTP Digest authentication with a public key and private key, not Bearer). The CRUD/search proxy and the Admin API are separate and use different credentials — keep them in separate Bubble API Connector groups to avoid confusion.

```
// Atlas Proxy API group
{
  "name": "Atlas Proxy",
  "root_url": "https://your-atlas-proxy.onrender.com",
  "shared_headers": [
    { "key": "X-API-Key", "value": "<proxy-api-key>", "private": true },
    { "key": "Content-Type", "value": "application/json", "private": false }
  ]
}
```

**Expected result:** The 'Atlas Proxy' API group is configured in Bubble with the Render URL and X-API-Key header marked Private. Ready to add individual endpoint calls.

### 4. Create CRUD calls and the Atlas Search call — initialize each for correct data type detection

Add a 'FindDocuments' call (POST `/find`, body: `collection`, `filter`, `limit`, `skip`). Initialize with a real collection and sample filter — confirm `documents` array in response. Set 'Use as Data'. Name the detected type after your collection. Add 'InsertDocument' (POST `/insertOne`) and 'UpdateDocument' (POST `/updateOne`) — both set to 'Action'. Add a 'SearchDocuments' call (POST `/search`, body: `collection`, `query`, `limit`). Initialize with a real query term that has matching documents in your collection — confirm the response shows `documents` with a `score` field. Set 'Use as Data'. The detected type will include the `score` field alongside your document fields. In your Bubble Repeating Group bound to the search call, you can display the score for debugging or hide it in production. Note: if your Atlas Search index was not yet 'Active' when you initialized the call, the `documents` array will be empty — wait for the index to build and re-initialize once it is Active.

```
// SearchDocuments call body
{
  "collection": "products",
  "query": "{{searchTerm}}",
  "limit": 10
}

// Atlas Search response from proxy
{
  "documents": [
    {
      "_id": "64f8a2b3c1d2e3f4a5b6c7d8",
      "name": "Widget Pro",
      "description": "A professional-grade widget for industrial use",
      "score": 1.823
    },
    {
      "_id": "64f8a2b3c1d2e3f4a5b6c7d9",
      "name": "Widget Basic",
      "description": "Entry-level widget for home projects",
      "score": 1.241
    }
  ]
}
```

**Expected result:** You have four calls: FindDocuments (Data), InsertDocument (Action), UpdateDocument (Action), SearchDocuments (Data). The search call returns documents with relevance scores sorted by Atlas Search ranking. All calls initialize without errors.

### 5. Configure an Atlas Trigger to push events to a Bubble Backend Workflow

Atlas Triggers allow MongoDB document events to push data to Bubble in real time. This requires a paid Bubble plan for the Backend Workflow feature. In your Bubble editor: Settings → API → enable 'This app exposes a Workflow API'. Go to the Backend Workflows section and create a new API workflow. Name it `on_new_order` (or appropriate for your use case). Enable 'Ignore privacy rules when triggered via API'. Click 'Detect request data' and note the workflow's endpoint URL — it looks like `https://yourapp.bubbleapps.io/api/1.1/wf/on_new_order`. Now go to your Atlas cluster → App Services → Create App (or use an existing one) → Triggers → Add Trigger. Type: Database. Select your cluster, database, and collection. Event types: check 'Insert Document'. Under 'Event Type' → 'Select an event type', choose 'Send Event' with a custom HTTP request. Paste your Bubble Backend Workflow URL. Set the request method to POST and the Content-Type to application/json. In the 'Body' section, use `%%doc%%` or `fullDocument` to include the inserted document. Save the trigger. When the next document is inserted in the collection, Atlas sends a POST to your Bubble workflow URL automatically.

```
// Atlas Trigger configuration (in Atlas App Services UI)
// Event type: Database → Insert
// Action: HTTP Request to Bubble Backend Workflow URL

// Sample payload sent by Atlas Trigger to Bubble
{
  "fullDocument": {
    "_id": { "$oid": "64f8a2b3c1d2e3f4a5b6c7d8" },
    "customerId": "cust_abc123",
    "orderTotal": 149.99,
    "items": ["item_001", "item_002"],
    "createdAt": "2026-03-15T10:30:00Z"
  },
  "operationType": "insert",
  "ns": { "db": "myapp", "coll": "orders" }
}

// Bubble Backend Workflow: detect request data fields:
// fullDocument_customerId (text)
// fullDocument_orderTotal (number)
// fullDocument_createdAt (text)
```

**Expected result:** The Atlas Trigger is active and sends document data to your Bubble Backend Workflow URL on every Insert event in the target collection. Test by inserting a document in Atlas → the Bubble workflow runs automatically. You can verify in Bubble's Logs tab under Backend Workflows.

### 6. Build Bubble search UI and wire Atlas Search to a live search input

Add a text input element named 'SearchInput' to your Bubble page and a Repeating Group named 'SearchResults' below it. Set the Repeating Group's data source to 'Get data from external API' → SearchDocuments. Pass `collection` as your collection name, `query` as `SearchInput's value`, and `limit` as `10`. The Repeating Group automatically re-fetches whenever the SearchInput value changes (Bubble re-runs the data source query on element state changes). Access search result fields on each cell: `current cell's AtlasProduct's name`, `current cell's AtlasProduct's description`. Add a 'No results' conditional: show a 'No results found' text element when `SearchResults's list of AtlasProduct is empty`. For the Bubble CRUD interface (separate from search): use a second Repeating Group bound to FindDocuments with a `filter` parameter that shows all documents or a fixed filter. The RapidDev team has built Atlas Search integrations in Bubble for clients across multiple industries — if you want a fuzzy search implementation reviewed or customized, book a free call at rapidevelopers.com/contact. Set up Privacy rules under Data tab → Privacy for any data types created from Atlas responses to ensure users only see records they are authorized to access.

**Expected result:** Typing in the Bubble SearchInput populates the SearchResults Repeating Group with Atlas Search results ranked by relevance. Fuzzy matching returns results for minor misspellings. An empty query shows no results (or can be configured to show all documents by falling back to the FindDocuments call).

## Best practices

- Always mark the proxy API key as Private in Bubble's API Connector shared header. This credential protects access to your entire MongoDB Atlas database, including write operations.
- Convert MongoDB `_id` ObjectID to a plain string in your proxy before returning JSON to Bubble. Returning `{"$oid":"..."}` objects to Bubble creates complex nested types that break filtering and update workflows. The proxy code in Step 2 handles this correctly.
- Create Atlas Search indexes in the Atlas UI before initializing the SearchDocuments call in Bubble. Initializing with an inactive index returns an empty `documents` array, causing Bubble to create an empty data type with no fields.
- Use the `$project` aggregation stage in Atlas Search queries to return only the fields your Bubble UI needs, plus `_id` (as string) and `score`. Returning full documents with large text fields increases response size and slows Repeating Group rendering.
- For Atlas Triggers sending events to Bubble Backend Workflows: verify the Bubble workflow URL does not include the `/initialize` suffix used during 'Detect request data'. The production Atlas Trigger URL must be the base workflow URL without `/initialize`.
- Add `limit` and `skip` parameters to all `/find` CRUD calls in Bubble. Without limits, a growing MongoDB collection can return thousands of documents, exceeding Bubble's 30-second workflow timeout and response size limits.
- Set up Data tab → Privacy rules in Bubble for all data types created from MongoDB Atlas responses. Without privacy rules, Bubble's built-in search exposes records across users. Atlas-specific security (Atlas authentication, network access restrictions) protects the database layer; Bubble Privacy rules protect the application layer.
- Test Atlas Triggers by inserting documents directly in the Atlas Data Explorer (cluster → Browse Collections → Insert Document) rather than via Bubble. This isolates Atlas Trigger behavior from Bubble proxy behavior when debugging.

## Use cases

### Fuzzy product search with Atlas Search in a Bubble marketplace

A Bubble marketplace app needs a search bar that returns relevant products even when users misspell product names or use partial terms. Atlas Search's `$search` aggregation with `fuzzy` option handles this natively. Your proxy exposes a `/search` endpoint that accepts a query string, runs the Atlas Search aggregation, and returns ranked matching documents. Wire the Bubble search input to this endpoint — results update as the user types (debounced) in a Repeating Group.

Prompt example:

```
Add a search input to a Bubble page that, when the user stops typing for 500ms, calls the MongoDB Atlas proxy /search endpoint with the input value. The endpoint runs an Atlas Search fuzzy query on the product name and description fields. Display the top 10 results in a Repeating Group sorted by Atlas Search relevance score.
```

### Real-time Bubble notifications via Atlas Triggers

When a new customer order is inserted into a MongoDB Atlas collection, an Atlas Trigger fires immediately and sends the document data to a Bubble Backend Workflow URL via HTTPS POST. The Bubble workflow creates a notification record, sends an email via SendGrid, and marks the order as 'received' in Bubble's own database. No polling, no scheduled checks — Bubble reacts the moment the MongoDB document is created.

Prompt example:

```
Configure an Atlas Trigger on the 'orders' collection that fires on INSERT events and POSTs the new order document to a Bubble Backend Workflow URL. The Bubble workflow should extract the customer ID from the document, find the matching Bubble user, and create a notification record in Bubble's database that appears in the user's in-app notification center.
```

### AI-powered semantic document search with Atlas Vector Search

A Bubble knowledge base or document management app needs to surface semantically relevant articles when a user describes what they are looking for, not just keyword matches. Your proxy accepts a query text, calls an OpenAI embeddings API to generate a vector, runs a MongoDB `$vectorSearch` aggregation to find documents with similar embeddings, and returns ranked semantically relevant results. Bubble displays these results in a Repeating Group with relevance scores.

Prompt example:

```
Build a Bubble search page where users describe their problem in natural language. The proxy generates an embedding from the input text using OpenAI's text-embedding-3-small model and runs $vectorSearch over the knowledge base collection. Return the top 5 semantically similar articles to Bubble, which displays them with a brief excerpt in a Repeating Group.
```

## Troubleshooting

### Atlas Search returns an empty documents array even though the collection has documents

Cause: The Atlas Search index is still building (not yet 'Active'), the index name in the proxy's `$search` query does not match the created index name, or the search query term has no fuzzy matches in the indexed fields.

Solution: Check the Atlas Search dashboard and confirm the index status is 'Active' (green). Verify the index name in your proxy's `$search` stage matches exactly what is shown in Atlas — the default index is named `default`. Test the search query directly in the Atlas console using the 'Search Tester' tool before blaming the Bubble integration.

### Atlas Trigger is not firing when documents are inserted into the collection

Cause: The trigger may be paused or in an error state. The collection or database selected in the trigger configuration may not match where Bubble's InsertDocument call is writing. The Atlas App Services app may not be linked to the correct cluster.

Solution: Go to Atlas App Services → Triggers → find your trigger → check its Status (Active vs Paused). Click 'Edit' and verify the cluster, database, and collection exactly match where your documents are being inserted. In the Trigger logs (Atlas → App Services → Logs), check if the trigger is firing but failing to reach the Bubble URL. Common cause: the Bubble Backend Workflow URL changed after the trigger was set up — re-copy the URL from Bubble's Settings → API → Backend Workflows.

### 'Workflow API is not enabled' when trying to set up Bubble Backend Workflows for Atlas Triggers

Cause: Bubble's Backend Workflows (API Workflows) are only available on paid plans. The Free plan does not include this feature.

Solution: Upgrade to at least the Bubble Starter plan ($32/mo). Once upgraded, go to Settings → API → enable 'This app exposes a Workflow API'. The Backend Workflows section becomes available. Create your workflow, detect the request data from a test Atlas Trigger POST, and save. Note: the `/initialize` suffix on the detection URL must be dropped when registering the production webhook in Atlas — use the base workflow URL without `/initialize`.

### Proxy initialize call returns 'There was an issue setting up your call' or 404

Cause: The Render proxy may be cold-starting (spins down after 15 minutes on free tier), the X-API-Key header does not match the Render API_KEY environment variable, or the root URL has a trailing slash.

Solution: Wait 30 seconds and retry initialization — Render free tier cold starts take 15-30 seconds. Check Render logs to confirm the service started. Verify X-API-Key in Bubble matches API_KEY in Render exactly (case-sensitive). Confirm the root URL ends without a trailing slash.

### Atlas App Services HTTPS endpoints are not available on the free M0 cluster

Cause: Atlas App Services custom HTTPS endpoints (Functions) feature availability on M0 free tier can change. MongoDB may limit this feature to paid tiers.

Solution: Verify current Atlas App Services feature availability for M0 at docs.atlas.mongodb.com. If not available on M0, use the Render Node.js proxy approach (Step 2) instead — it provides identical functionality without depending on Atlas App Services tier availability. The proxy approach is fully compatible with M0 clusters.

## Frequently asked questions

### Is the Atlas Data API coming back, or do I need a proxy permanently?

The Atlas Data API was retired by MongoDB in September 2025. There are no announced plans to reinstate it. The supported paths for Bubble + MongoDB Atlas in 2026 are: a custom REST proxy (the approach in this guide), or MongoDB Atlas App Services custom HTTPS endpoints. Both are stable, production-ready architectures. The custom proxy gives you more control over endpoint design and query logic. Atlas App Services eliminates the need to manage separate proxy infrastructure.

### Does Atlas Search work on the free M0 cluster?

Yes. MongoDB Atlas Search (full-text and fuzzy search) is available on the M0 free cluster (512MB shared). Atlas Triggers are also available on M0. What is NOT available on M0 is Atlas Vector Search ($vectorSearch aggregation stage) — that requires a dedicated M10 or higher cluster. If you only need full-text fuzzy search and database triggers, the free M0 tier is sufficient for production use cases.

### Do I need a paid Bubble plan to receive Atlas Triggers in Bubble?

Yes. Atlas Triggers deliver events to Bubble via POST requests to Bubble Backend Workflow URLs. Backend Workflows (API Workflows) in Bubble require a paid plan — at minimum the Starter plan ($32/mo). The Free plan does not include Backend Workflows. If you are on the Free plan and need event-driven Bubble reactions, a workaround is to poll MongoDB periodically using a scheduled client-side workflow — but this consumes Bubble Workload Units and is significantly less efficient than a trigger-based approach.

### How is Atlas Search different from just filtering MongoDB documents in the proxy?

A regular MongoDB `find` with a `$regex` filter does a text scan over the collection — slow on large collections, case-sensitive by default, no ranking, no fuzzy matching. Atlas Search uses Apache Lucene indexes built alongside your collection: it supports fuzzy matching (1-2 character typos), relevance scoring (best matches first), phrase search, autocomplete, and faceted filters. For a search box in a Bubble UI where users type natural language queries, Atlas Search returns significantly better results than a proxy-based filter.

### Can I use Atlas Vector Search to build an AI-powered search in Bubble?

Yes, on M10+ dedicated clusters (verify current tier availability at atlas.mongodb.com). The pattern is: (1) store vector embeddings alongside your documents in MongoDB Atlas (generate embeddings when inserting documents via the proxy's insertOne endpoint); (2) add a `/vectorSearch` endpoint to the proxy that accepts query text, calls an embeddings API to generate a query vector, and runs `$vectorSearch` to find similar documents; (3) add a VectorSearch call to Bubble's API Connector pointing to this endpoint. Bubble passes the user's search text; the proxy handles embedding generation and the vector search, returning semantically similar documents.

### What is the difference between the mongodb and mongodb-atlas Bubble integration briefs?

The `mongodb` page covers connecting Bubble to MongoDB in general — basic CRUD operations via a REST proxy, applicable to both self-hosted MongoDB and MongoDB Atlas. That brief focuses on getting documents in and out of a MongoDB collection from Bubble. This `mongodb-atlas` page focuses on Atlas-specific platform features: Atlas Search for full-text and fuzzy search, Atlas Triggers for event-driven Bubble workflows, Atlas Vector Search for semantic similarity, and the Atlas Administration API. Same database engine, different value proposition. Start with the `mongodb` brief if you only need CRUD; come to this brief when you need search or real-time triggers.

---

Source: https://www.rapidevelopers.com/bubble-integrations/mongodb-atlas
© RapidDev — https://www.rapidevelopers.com/bubble-integrations/mongodb-atlas
