Connect Bubble to OpenAI GPT using the API Connector with your OpenAI API key as a Private Bearer token — no external proxy needed because Bubble's API Connector runs server-side, keeping your key out of browser DevTools entirely. Build context-aware AI features that inject live Bubble database data into GPT prompts for truly personalized responses.
| Fact | Value |
|---|---|
| Tool | OpenAI GPT |
| Category | AI & ML |
| Method | Bubble API Connector |
| Difficulty | Beginner |
| Time required | 45–90 minutes |
| Last updated | July 2026 |
No proxy needed — Bubble's server-side API Connector is OpenAI's ideal integration partner
A common misconception from developers who have used FlutterFlow or Bolt.new is that AI API keys must be hidden behind a server-side proxy function. This is correct for those tools — their API calls originate from the user's browser, making any key placed in a header visible in browser DevTools. Bubble works differently.
Bubble's API Connector runs on Bubble's servers. When a user clicks a button that triggers an OpenAI API call, the HTTP request goes from Bubble's infrastructure to OpenAI's servers — not from the user's browser. The 'Private' checkbox in the API Connector header settings tells Bubble to keep that header value server-side and never send it to the browser as part of the Bubble app bundle. This is exactly the protection a Cloud Function proxy provides in other tools — Bubble provides it natively.
The practical result: you configure OpenAI in Bubble's API Connector with `Authorization: Bearer sk-...your-key...` marked Private, and you are done. No Cloud Function, no extra backend, no Lambda. The key never reaches the browser.
The primary use case is **context-aware AI features**: Bubble stores your users' data, product records, conversation histories, and preferences. Using Bubble's dynamic text expressions (`<>`), you inject this live data into the GPT system prompt or user message before the API call fires. OpenAI then generates responses that reference real user-specific context — making the AI feel genuinely personalized rather than generic. This is the pattern that separates excellent Bubble AI apps from generic chatbot demos.
Integration method
Bubble API Connector with OpenAI API key as a Bearer token in the Authorization header marked Private — no external proxy or server required because Bubble's API Connector executes all calls server-side on Bubble's infrastructure.
Prerequisites
- An OpenAI account at platform.openai.com — sign up and add a payment method to access API usage beyond the free tier
- An OpenAI API key (starts with sk-...) from platform.openai.com → API Keys → Create new secret key — copy it immediately, it is shown only once
- The API Connector plugin installed in your Bubble app (Plugins tab → Add plugins → search 'API Connector' by Bubble → Install)
- Optional: OpenAI organization ID if your account belongs to an organization with multiple projects (found in platform.openai.com → Settings → Organization)
Step-by-step guide
Get your OpenAI API key and understand rate limits
Go to platform.openai.com and sign in. Click 'API Keys' in the left sidebar (or navigate to platform.openai.com/api-keys). Click 'Create new secret key.' Give it a name like 'Bubble App' so you can identify it later and set any usage limits if available. Click 'Create secret key.' The API key is shown **exactly once** — copy it immediately and store it in a password manager. If you lose it, you must generate a new one (old keys can be revoked from the dashboard). The key starts with `sk-` followed by a long alphanumeric string. This is the value you will paste into Bubble's API Connector Authorization header. **Understanding rate limits:** OpenAI's rate limits depend on your account tier. New accounts start at Tier 1: - GPT-4o: ~500 requests per minute (RPM), 30,000 tokens per minute (TPM) - GPT-3.5-turbo: higher limits For most Bubble apps in early stages, Tier 1 limits are sufficient. As your app grows and you spend more on the OpenAI API over time, your tier automatically increases. Monitor your usage at platform.openai.com → Usage. **Cost awareness:** GPT-4o charges per token (verify current rates at openai.com/pricing). Setting `max_tokens` in your API call limits the maximum output size and caps per-call cost. Without a `max_tokens` limit, GPT can generate very long responses that cost more than expected.
1// OpenAI API key format:2// sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx34// OpenAI API base URL:5https://api.openai.com/v167// Chat Completions endpoint:8POST https://api.openai.com/v1/chat/completions910// Required headers:11// Authorization: Bearer sk-your-key-here (mark Private in Bubble)12// Content-Type: application/json1314// Recommended models for Bubble apps:15// gpt-4o — best quality, higher cost16// gpt-4o-mini — fast, cost-efficient, great for most use cases17// gpt-3.5-turbo — legacy, cheapestPro tip: Create a separate OpenAI API key for each Bubble app or project you build. This lets you set individual usage limits per key and identify which app is consuming tokens if you need to debug unexpected costs. You can create multiple keys in platform.openai.com → API Keys.
Expected result: You have an OpenAI API key copied and stored securely. You understand which model you will use and have checked the current pricing at openai.com/pricing.
Configure the Bubble API Connector for OpenAI Chat Completions
In your Bubble editor, click Plugins in the left sidebar. Find the API Connector plugin and click 'Add another API.' Name it 'OpenAI.' At the API group level, add a shared header: - Name: `Authorization` - Value: `Bearer sk-your-openai-api-key-here` - Check the **Private** checkbox — this is the critical step that keeps your API key server-side Add another shared header: - Name: `Content-Type` - Value: `application/json` Now add the main call. Click 'Add another call' and name it 'Chat Completion.' Set: - Method: POST - URL: `https://api.openai.com/v1/chat/completions` - Use as: Action For the JSON body, add parameters: - `model` (text, default `gpt-4o-mini`) — the model name - `messages` (JSON array) — the conversation messages array - `max_tokens` (number, default 500) — limits response length and cost - `temperature` (number, default 0.7) — controls creativity (0=deterministic, 1=creative) The messages parameter is the key field. In Bubble's body editor, set it to a JSON array containing at minimum a system message and a user message: ```json [ {"role": "system", "content": "<dynamic_system_prompt>"}, {"role": "user", "content": "<dynamic_user_message>"} ] ``` Mark `system_prompt` and `user_message` as dynamic parameters. **Initialize call:** Click 'Initialize call.' For the system prompt, enter something like 'You are a helpful assistant.' For the user message, enter 'Say hello in one sentence.' Click 'Send.' OpenAI returns a JSON response with a `choices` array — Bubble detects the structure. The AI response text is at `choices[0].message.content`.
1// API Connector: OpenAI → Chat Completion2// Method: POST3// URL: https://api.openai.com/v1/chat/completions4//5// Shared headers:6// Authorization: Bearer sk-your-key // mark Private7// Content-Type: application/json8//9// JSON body:10{11 "model": "gpt-4o-mini",12 "messages": [13 {"role": "system", "content": "<dynamic_system_prompt>"},14 {"role": "user", "content": "<dynamic_user_message>"}15 ],16 "max_tokens": 500,17 "temperature": 0.718}1920// Response structure:21// {22// "id": "chatcmpl-abc123",23// "object": "chat.completion",24// "model": "gpt-4o-mini-2024-07-18",25// "choices": [26// {27// "index": 0,28// "message": {29// "role": "assistant",30// "content": "Hello! How can I help you today?"31// },32// "finish_reason": "stop"33// }34// ],35// "usage": {36// "prompt_tokens": 12,37// "completion_tokens": 9,38// "total_tokens": 2139// }40// }4142// AI response text path:43// choices[0].message.contentPro tip: Always perform the Initialize call with a real test request that returns a valid response. Bubble's Initialize call must detect the `choices` array to make the response fields available in workflows. If you leave the body parameters empty or send an invalid request, Bubble cannot detect the schema and the response fields will not appear in the workflow editor.
Expected result: The OpenAI API Connector call initializes successfully. Bubble detects the choices array in the response. The `choices[0].message.content` path is visible in the workflow editor for binding the AI response to Bubble elements.
Build a simple AI assistant with dynamic context injection
Now build the core AI interaction. The pattern that sets Bubble AI apps apart is injecting live database data into the prompt before the call fires — creating responses that reference the actual user's situation. On a Bubble page, add: - A Text Input labeled 'Your question' - A Button labeled 'Ask AI' - A Text element to display the AI response (initially hidden) - A loading indicator (an icon or text element visible only during processing) In the workflow editor, create a workflow triggered by 'Button Ask AI is clicked.' **Action 1:** Show the loading indicator. Use 'Show element' or a Conditional on visibility. **Action 2:** Call the OpenAI Chat Completion API Connector action. Fill in the parameters: - `system_prompt`: Build a dynamic string using Bubble's text concatenation. Example: `'You are a helpful assistant for ' + Current User's company name + '. The user is on the ' + Current User's plan + ' plan. Be concise and helpful.'` - `user_message`: `Question Input's value` - `max_tokens`: 500 - `temperature`: 0.7 **Action 3:** Set a Custom State (or Page State) to the API result's `choices[0].message.content` value. **Action 4:** Hide the loading indicator. Make the response Text element visible (or set it to display the Custom State value). The response Text element's content: bind to the Custom State containing the AI response. This updates immediately when the state changes after the API call completes. Note: Bubble's API Connector does NOT support streaming (SSE). The response arrives as a single JSON object after GPT finishes generating — users see a loading state until the complete response arrives, then it appears all at once. For most use cases, this is acceptable. Communicate this with a clear 'Generating your answer...' loading message.
1// Bubble workflow: 'Ask AI' button clicked2//3// Action 1: Show element 'Loading Spinner'4//5// Action 2: Plugins → OpenAI → Chat Completion6// model: gpt-4o-mini7// system_prompt: 'You are a helpful assistant for '8// + Current User's company + '. '9// + 'User is on the ' + Current User's plan + ' plan. '10// + 'Answer concisely in 2-3 sentences.'11// user_message: Question Input's value12// max_tokens: 50013// temperature: 0.714//15// Action 3: Set Custom State 'ai_response'16// Value: Result of step 2's choices[0].message.content17//18// Action 4: Hide element 'Loading Spinner'19// Action 5: Show element 'Response Text'20//21// Response Text content:22// [This Page's ai_response State]2324// System prompt template for personalizing AI responses:25// 'You are [App Name]'s AI assistant. The current user is [name] 26// working at [company]. Their account status is [plan]. 27// Their last action was [last_action_date]. 28// Keep responses under 150 words.'Pro tip: Keep your system prompt under 500 tokens to minimize input token costs. Focus on the most critical context — user name, plan, and one or two relevant data points — rather than dumping all user data into the prompt. GPT performs better with focused context than with an overwhelming amount of background information.
Expected result: When the user types a question and clicks 'Ask AI,' a loading indicator appears, the GPT API call fires server-side, and the AI response appears in the Text element after 2-5 seconds. The response references the user's dynamic context (name, plan, etc.) injected from Bubble's database.
Implement multi-turn conversation history
For a chatbot that maintains context across multiple messages, you need to store the conversation history and send it with every new GPT call. **Data model:** Create a 'Conversation' data type with fields: - `user` (User) - `created_at` (date) - `title` (text — optional, auto-generated from first message) Create a 'Message' data type with fields: - `conversation` (Conversation) - `role` (text — 'user' or 'assistant') - `content` (text) - `created_at` (date) **Chat UI:** Build a Repeating Group showing all Messages for the current Conversation, sorted by `created_at` ascending. Messages with role='user' display right-aligned, role='assistant' display left-aligned. **Sending a message workflow:** 1. Create a new Message record with role='user', content=Chat Input's value, conversation=current Conversation 2. Clear the Chat Input field 3. Build the messages array: do a search for all Messages in current Conversation sorted by created_at → format as the JSON messages array 4. Add a system message at the start of the array 5. Call OpenAI Chat Completion with the full messages array 6. Create a new Message record with role='assistant', content=API result's choices[0].message.content **Building the messages array in Bubble:** Bubble does not have a native 'join list of objects as JSON array' operator. Use a Repeating Group's source to feed individual message records, and build the JSON string manually: - System message string: `[{"role": "system", "content": "You are a helpful assistant."},` - For each message in history: `{"role": "` + message.role + `", "content": "` + message.content + `"},` - Current user message: `{"role": "user", "content": "` + user_input + `"}]` Alternatively, use the Toolbox plugin's 'List to JSON' or a similar approach to construct the array without manual string concatenation. For long conversations, limit the history: do a search for Messages sorted by created_at descending with a count limit of 10, then reverse — this keeps the last 10 messages as context, preventing the prompt from exceeding GPT's context window.
1// Bubble data types:2// Conversation: user (User), title (text), created_at (date)3// Message: conversation (Conversation), role (text), content (text), created_at (date)45// Messages array for GPT (JSON body 'messages' parameter):6// Build as a concatenated string in Bubble:7[8 {"role": "system", "content": "You are a helpful assistant. User: [Current User's name]"},9 {"role": "user", "content": "First user message from history"},10 {"role": "assistant", "content": "First AI response from history"},11 {"role": "user", "content": "Second user message from history"},12 {"role": "assistant", "content": "Second AI response from history"},13 {"role": "user", "content": "Current new user message"}14]1516// To avoid context window limits, limit history:17// Do a search for Messages18// where conversation = Current Conversation19// sorted by created_at descending20// count: 10 <- last 10 messages only21// Then reverse the list (oldest first) before building the array2223// Total token estimate for context management:24// System prompt: ~50-100 tokens25// Each message pair: ~50-200 tokens26// 10 messages ≈ 500-2000 tokens input27// Keep max_tokens to 500-1000 for responses28// Total per call: ~1000-3000 tokensPro tip: Escape double quotes and newlines in user-submitted content before including it in the JSON messages string. If a user types a message containing double quotes (e.g., 'She said "hello"'), the unescaped quotes will break the JSON body and return a 400 error. Use Bubble's `:converted to text` operator or add a sanitization step that replaces `"` with `\"` in user input before building the messages JSON.
Expected result: The chatbot maintains conversation context across multiple exchanges. Sending a new message includes the last 10 exchanges as history in the GPT call. GPT responds with awareness of earlier conversation points. Each message is stored in Bubble's database and visible in the chat Repeating Group.
Handle rate limits, errors, and add Bubble workflow error handling
Production AI features need robust error handling — GPT returns specific error codes that your Bubble workflows should handle gracefully. **Common OpenAI error codes:** - 401 — invalid API key (check the sk- key in your Private header) - 429 — rate limit exceeded (too many requests per minute or per day budget limit) - 500 — OpenAI server error (retry once after 5-10 seconds) - 400 — bad request (malformed JSON body, usually from unescaped quotes in dynamic content) **In Bubble, add error handling to the OpenAI API call action:** Click the action in the workflow editor → scroll to 'Only when' and add a fallback. Alternatively, in Bubble's 'Workflow' settings, look for the workflow error handling option. For 429 rate limit errors: add a workflow condition branch — if the API call returns an error, show a user-friendly message ('Our AI assistant is busy — please try again in a moment') and log the error to a Logs data type for monitoring. **Set max_tokens to avoid runaway costs:** Always include `max_tokens` in your API Connector body. Without it, GPT may generate very long responses — a 2000-token response costs 4x a 500-token response. For most use cases, 500-1000 tokens is sufficient. **Monitor usage:** Check platform.openai.com → Usage regularly during early deployment. Set a spending limit in platform.openai.com → Billing → Usage limits to cap monthly API spend automatically. **WU (Workload Unit) monitoring:** Each OpenAI API call from Bubble consumes Bubble Workload Units — one unit per API call action regardless of token count. If your app has many concurrent users each making AI calls, monitor Bubble's WU dashboard under Settings → Billing alongside your OpenAI token usage. RapidDev's team has built AI-powered Bubble apps across multiple industries — for complex AI workflow architecture or scaling guidance, reach out at rapidevelopers.com/contact.
1// OpenAI error response structure:2// {3// "error": {4// "message": "Rate limit exceeded for ...",5// "type": "requests",6// "param": null,7// "code": "rate_limit_exceeded"8// }9// }1011// Bubble workflow error handling pattern:12// After OpenAI API call action:13// → Add 'Only when' condition: This step returned no error14// YES path: set Custom State to response content15// NO path: show error message to user1617// Error message mapping:18// HTTP 401 → 'Configuration error — contact support'19// HTTP 429 → 'AI assistant is temporarily busy — try again in a moment'20// HTTP 500 → 'OpenAI service error — try again in a few seconds'21// HTTP 400 → 'Invalid request — check for special characters in your input'2223// Rate limit mitigation:24// - Add a 'debounce' — disable the Ask AI button for 2 seconds after click25// - Set per-user daily limits using a counter field on the User data type26// - Use gpt-4o-mini instead of gpt-4o for non-critical features (10x cheaper)Pro tip: Add a simple daily usage counter per user: increment a `ai_calls_today` counter field on each GPT call, and reset it daily via a Bubble 'recurring event' Backend Workflow. Show a message 'You've reached your daily AI limit' when the counter hits your threshold. This prevents a single user from exhausting your entire OpenAI tier's rate limits.
Expected result: Your Bubble app handles OpenAI errors gracefully — users see friendly messages instead of raw error codes. Rate limit errors are caught and communicated clearly. The `max_tokens` limit prevents unexpectedly large OpenAI bills. Bubble Logs tab shows successful 200 responses for normal API calls.
Secure your integration and validate the complete flow
Before going live, verify these critical security and quality checkpoints: **1. Privacy verification — the most important step:** Open your deployed Bubble app in a browser (not the editor preview). Open browser DevTools (F12 → Network tab). Trigger an AI call by clicking 'Ask AI.' Filter network requests by 'openai.com.' You should see **zero requests** going directly to api.openai.com from the browser. All OpenAI calls should go through Bubble's server infrastructure. If you see a direct request to api.openai.com in the browser network tab, your API key is exposed — check that the Authorization header has the Private checkbox enabled and that the call is not being made from a client-side JavaScript 'Run JavaScript' action. **2. Confirm the API key is Private in the Connector:** In Bubble's API Connector, open the OpenAI group → Chat Completion call → look at the Authorization shared header. The Private checkbox (🔒 or checkmark) must be enabled. If it is not checked, check it and re-deploy your app. **3. Test with real user data:** Log in as a test user with realistic data (name, plan, recent activity). Submit a question and verify the AI response correctly references the user's dynamic context from the system prompt. Check that the response text appears in the correct UI element. **4. Streaming awareness:** Bubble does not support SSE/streaming responses. The full GPT response arrives as a single JSON object after generation completes — which can take 3-10 seconds for longer responses. Show a clear loading state ('AI is generating your answer...') during this wait to avoid users thinking the app is frozen. **5. Add privacy rules to stored conversations:** If you store Message records in Bubble's database (recommended for conversation history), go to Data tab → Message type → Privacy → add rule: 'This Thing is visible to Current User when Message's conversation's user = Current User.' This prevents one user from reading another user's conversation history.
1// Privacy validation — open deployed app in browser:2// DevTools → Network tab → filter: openai.com3// Expected: 0 results (no direct browser-to-OpenAI requests)4// If you see requests here: Authorization header is NOT marked Private5//6// To fix: Plugins → API Connector → OpenAI → Chat Completion7// → Authorization header → check 'Private' checkbox8// → Deploy changes910// Bubble privacy rules for conversation data:11// Data tab → Message type → Privacy12// Add rule:13// 'This Thing is visible to Current User'14// When: Message's conversation's user = Current User15//16// Data tab → Conversation type → Privacy17// Add rule:18// 'This Thing is visible to Current User'19// When: Conversation's user = Current User2021// Quick test: loading state workflow22// Show 'AI is generating your answer...' spinner:23// Action 1: Set element visible (loading state)24// Action 2: API call (OpenAI) ← blocks until complete25// Action 3: Set Custom State to result26// Action 4: Hide loading state27// Action 5: Show response textPro tip: After deploying any change to your API Connector (marking headers Private, changing model, updating endpoint), always re-test the browser network tab privacy check. Bubble sometimes requires a full app re-deployment for Private header changes to take effect — not just saving in the editor.
Expected result: No OpenAI API calls appear in the browser network tab — all requests go server-side. The OpenAI API key is not visible anywhere in browser DevTools. AI responses display correctly with dynamic user context. Conversation records in Bubble's database are accessible only to the user who created them.
Common use cases
Personalized AI assistant with database context
Inject the current user's name, subscription plan, recent orders, and preferences into the GPT system prompt dynamically. The assistant responds with context-aware answers — 'Your Pro plan includes unlimited reports, and I see your last order was placed on July 5th' — without requiring the user to provide this information themselves.
System message: 'You are a helpful assistant for YourApp. The current user is [Current User's name] on the [Current User's plan] plan. Their last activity was [Current User's last_action]. Answer questions about their account and your product concisely.' User message: [Chat Input's value]
Copy this prompt to try it in Bubble
AI-powered content generation for product listings
Founders building marketplaces or e-commerce Bubble apps can generate professional product descriptions on demand. A seller selects a product category, enters key attributes, and clicks 'Generate Description.' GPT returns a polished product description that Bubble inserts directly into the listing form — reducing the effort of writing copy from scratch.
System message: 'You are an e-commerce copywriter. Write compelling, SEO-friendly product descriptions of 80-120 words.' User message: 'Category: [Dropdown's value]. Key features: [Text Input's value]. Tone: [Tone Dropdown's value]. Write a product description for this item.'
Copy this prompt to try it in Bubble
Multi-turn chatbot with conversation history
Build a full conversational AI feature in Bubble where GPT remembers the entire conversation context. Each message exchange is stored in a Bubble 'Message' data type, and the full history is sent as the messages array on every GPT call — creating genuine multi-turn dialogue where the AI references earlier parts of the conversation naturally.
Before each GPT call, load all Message records for the current conversation sorted by created_at. Build the messages array: [{role: 'system', content: system_prompt}, {role: 'user', content: msg1}, {role: 'assistant', content: reply1}, ...current user message]. Send this array in the GPT call to maintain conversation context.
Copy this prompt to try it in Bubble
Troubleshooting
OpenAI API call returns 401 Unauthorized
Cause: The API key in the Authorization header is incorrect, expired, or was deleted from the OpenAI dashboard. A common mistake is leaving a placeholder like 'sk-your-key-here' in the header instead of the actual key, or the key was revoked after a team member left.
Solution: Go to platform.openai.com → API Keys and verify the key is active (shows as 'Active' not 'Revoked'). If the key is revoked or missing, create a new one. In Bubble's API Connector, update the Authorization header value to `Bearer sk-[your-new-key]` and ensure the Private checkbox is checked. Re-run the Initialize call to confirm the connection works.
Initialize call fails with 'There was an issue setting up your call'
Cause: Bubble's Initialize call needs a valid JSON body to send to OpenAI. If the messages array is empty or malformed, OpenAI returns 400 and Bubble cannot detect the response schema. A common mistake is leaving dynamic parameters unfilled during initialization.
Solution: During Initialize call, fill in ALL dynamic parameters with real test values: for `system_prompt` enter 'You are a helpful assistant', for `user_message` enter 'Say hello', for `max_tokens` enter 100. Click Send — OpenAI must return a 200 response with a choices array for Bubble to detect the schema. If you see a 400 error, check the JSON body format in the Initialize call response details.
GPT response truncates mid-sentence
Cause: `max_tokens` is set too low for the expected response length. When GPT reaches the max_tokens limit, it stops generating — sometimes mid-sentence. The response `finish_reason` field will show 'length' instead of 'stop' to indicate this.
Solution: Increase the `max_tokens` parameter in your API Connector call. For conversational responses, 500 tokens is usually enough (roughly 375 words). For longer content generation (blog posts, product descriptions), set 1000-2000 tokens. Check the `finish_reason` field in the API response — if it shows 'length', increase max_tokens. Monitor your OpenAI usage at platform.openai.com to track token consumption after increasing the limit.
OpenAI API call returns 429 Too Many Requests
Cause: The app is exceeding OpenAI's rate limits for your account tier — either requests per minute (RPM) or tokens per minute (TPM). This is common during load testing or when multiple users simultaneously trigger AI calls.
Solution: Add error handling to your Bubble workflow that catches 429 errors and shows a user-friendly message. For high-traffic apps, implement a queuing pattern using Bubble's 'Schedule API Workflow' to stagger OpenAI calls over time rather than firing them simultaneously. Consider upgrading your OpenAI tier by spending more on the API — OpenAI automatically increases limits as your spending history grows.
OpenAI API key appears in browser DevTools network requests
Cause: The Authorization header in the API Connector does not have the Private checkbox enabled, or the OpenAI call is being made from a client-side JavaScript action (Run JavaScript using Toolbox plugin) rather than from a Bubble API Connector call.
Solution: In Plugins → API Connector → OpenAI → click the Authorization shared header → check the 'Private' checkbox. Re-deploy your Bubble app. If the call is in a Run JavaScript action, move it to a proper API Connector call in a Backend Workflow instead. After fixing, open the deployed app in a browser → DevTools → Network tab and confirm no requests to api.openai.com appear from the browser.
Best practices
- Always check the Private checkbox on the Authorization header in Bubble's API Connector — this single setting is what prevents your OpenAI API key from being exposed in browser DevTools. Verify it with a DevTools network inspection after every deployment.
- Set an explicit `max_tokens` limit in every OpenAI API call — without it, GPT can generate very long responses that accumulate token costs faster than expected. 500 tokens (≈375 words) is suitable for most conversational use cases.
- Inject dynamic Bubble data into the GPT system prompt to create personalized AI responses — user name, plan, recent history, and relevant context make AI responses feel genuinely useful rather than generic.
- Limit conversation history to the last 10-15 message pairs before sending to GPT — beyond that, the input token count climbs rapidly, increasing cost per call without meaningfully improving response quality.
- Use `gpt-4o-mini` for most features and reserve `gpt-4o` only for use cases that require deep reasoning — gpt-4o-mini delivers excellent quality at a fraction of the cost, making it the right default for Bubble apps with budget constraints.
- Add Bubble Privacy rules to any Message or Conversation data types you create — ensure users cannot read each other's conversation histories by filtering records to the Current User who created them.
- Monitor both your OpenAI usage dashboard (platform.openai.com → Usage) and your Bubble Workload Units — AI API calls consume both OpenAI tokens and Bubble WUs simultaneously, and costs can compound quickly in high-traffic apps.
Alternatives
Google Cloud AI Platform (Vertex AI) hosts your custom-trained ML models rather than providing off-the-shelf LLMs. Vertex AI requires a JWT-signing proxy (Cloud Function) to authenticate — significantly more complex than OpenAI's persistent API key. Choose Vertex AI when you need to run your own trained models (computer vision, tabular ML) that cannot be handled by a general-purpose LLM like GPT.
IBM Watson targets structured enterprise NLP tasks (sentiment analysis, entity extraction, document classification) with time-limited IAM tokens requiring a two-step auth exchange. OpenAI GPT is better for general-purpose text generation and multi-turn conversation. Choose Watson if your use case involves structured NLP on enterprise documents in an IBM Cloud environment.
DeepAI offers simpler single-task AI endpoints (image generation, summarization, sentiment analysis) with a custom `api-key` header — no Bearer format, no OAuth. DeepAI is easier to configure for specific tasks but lacks OpenAI's conversational capabilities and context handling. Choose DeepAI for straightforward image generation or one-shot text tasks without needing multi-turn conversation context.
Frequently asked questions
Do I need a proxy or Cloud Function to keep my OpenAI API key safe in Bubble?
No. Unlike FlutterFlow or Bolt.new where API calls originate from the user's browser, Bubble's API Connector runs on Bubble's servers. With the 'Private' checkbox enabled on the Authorization header, your OpenAI API key is kept server-side and never sent to the browser. You can verify this by opening browser DevTools → Network tab on your deployed app and confirming no requests to api.openai.com appear from the browser.
Does Bubble support OpenAI streaming (word-by-word response display)?
No. Bubble's API Connector does not support Server-Sent Events (SSE) or streaming responses. The full GPT response arrives as a complete JSON object after generation finishes. For users, this means a 2-10 second loading state followed by the complete response appearing at once. Design your UI with a clear loading indicator to communicate that the AI is processing — this expectation-setting prevents users from thinking the app is frozen.
What model should I use for my Bubble app — GPT-4o or GPT-4o-mini?
Start with gpt-4o-mini for most features. It delivers excellent response quality at roughly 10x lower cost than gpt-4o, handles most conversational and content generation tasks very well, and has higher rate limits for new accounts. Reserve gpt-4o for specific features that require deep reasoning, complex analysis, or where response quality is critical enough to justify the higher cost.
How do I pass Bubble database data into the GPT prompt?
Use Bubble's dynamic text expressions (the `<>` operator) inside the API Connector body parameters. In the system_prompt dynamic parameter, you can include expressions like `Current User's name`, `Current User's plan`, or results from a Bubble database search — all resolved server-side before the API call fires. This lets you build personalized prompts without any extra steps.
Can I use functions/tools (function calling) with OpenAI in Bubble?
You can include the `tools` parameter in your API Connector call body, but Bubble has no native way to execute the function call that GPT returns — Bubble would need to parse the tool_call from the response, execute the corresponding action, and make a follow-up GPT call with the result. This is possible using Bubble's workflow conditionals and nested Backend Workflows but requires careful orchestration. For simple tool use (like web search), consider using a backend API that pre-runs the tool and passes results as context in the user message instead.
How much does it cost to add OpenAI to my Bubble app?
Costs depend on the model and usage volume. GPT-4o-mini is very affordable for typical Bubble app usage. A user sending 10 messages per session at 200 tokens each costs well under a cent per session at current pricing. For exact current rates, check openai.com/pricing. Set a monthly spending limit in platform.openai.com → Billing → Usage limits to cap costs automatically, and monitor the Usage dashboard to track consumption as your app grows.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation