Khan Academy's full REST API was officially deprecated — there are no API keys to configure. Instead, build your own data layer in Bubble: store curated Khan Academy video URLs in a custom database, call the public oEmbed endpoint to fetch embed HTML server-side, cache it in a Bubble field, and render it in an HTML element. Progress tracking lives entirely in Bubble's built-in database, not fetched from Khan Academy.
| Fact | Value |
|---|---|
| Tool | Khan Academy API |
| Category | Education |
| Method | Bubble API Connector |
| Difficulty | Intermediate |
| Time required | 3–4 hours |
| Last updated | July 2026 |
Khan Academy in Bubble: own your data layer
Most developers searching 'Khan Academy API integration' expect to find an API key, endpoints for course catalogs, and a way to sync student progress. Unfortunately, that API no longer exists — Khan Academy officially deprecated its REST API (api.khanacademy.org), and independent developers cannot obtain credentials for it. Requests to that domain return 403 errors.
The good news is that Bubble is exceptionally well-suited for the most practical alternative: building your own content curation and progress tracking layer on top of Khan Academy's free video library. You manually curate a list of Khan Academy video URLs in Bubble's database, call the oEmbed endpoint to fetch the embeddable iframe HTML for each video, cache that HTML in a Bubble field to avoid re-fetching on every page load, and render it using Bubble's HTML element. Student progress — completions, scores, streaks — lives entirely in Bubble's built-in database, giving you full control over the data model.
This pattern is powerful because it lets you build a fully branded learning portal: custom onboarding flows, personalized learning paths, completion certificates, and role-based access — none of which are available if you were using an official Khan Academy API anyway.
Integration method
Call the Khan Academy oEmbed endpoint (unauthenticated) via Bubble API Connector to retrieve embeddable iframe HTML for video pages.
Prerequisites
- A Bubble account on the Starter plan or higher (Backend Workflows required for the oEmbed caching workflow; not available on Free)
- Familiarity with Bubble's Data tab for creating custom Data Types and fields
- A list of Khan Academy video URLs you want to include — each must contain '/v/' in the path (not exercise or article pages)
- The API Connector plugin installed in your Bubble app (Plugins tab → Add plugins → search 'API Connector' by Bubble)
Step-by-step guide
Design your Data Types in Bubble
Before touching the API Connector, set up the data model that will power the entire integration. Go to the Data tab in your Bubble editor. Create a Data Type called **KhanContent** with these fields: - `title` (text) — the human-readable video title you write yourself - `khan_url` (text) — the full Khan Academy video URL (e.g., https://www.khanacademy.org/math/algebra/x2f8bb11595b61c86:expressions-with-exponents/x2f8bb11595b61c86:intro-to-exponents/v/introduction-to-exponents) - `embed_html` (text) — will store the iframe HTML returned by oEmbed (start empty; populated by the Backend Workflow) - `subject` (text) — e.g., Math, Science, Computing - `grade_level` (text) — e.g., Grade 6, High School - `created_date` (date) — auto-populated on creation Create a second Data Type called **Completion** with these fields: - `user_ref` (User) — the Bubble user who completed the video - `content_ref` (KhanContent) — the video that was completed - `completed_at` (date) — timestamp of completion Now set Privacy Rules. Click the Privacy tab for the **Completion** Data Type. Add a rule: **'This Completion is visible when: Current User is user_ref'**. This ensures users can only see their own completion records — never all completions in the database. Do the same for KhanContent if you want to restrict visibility to logged-in users only.
Pro tip: Add an 'is_oembed_fetched' (yes/no) field to KhanContent — it lets you easily filter for videos whose embed_html hasn't been populated yet and run bulk fetch workflows from the admin panel.
Expected result: You have two Data Types — KhanContent and Completion — with all required fields and privacy rules configured. The Data tab shows both types listed.
Configure the API Connector for the oEmbed endpoint
Go to **Plugins tab → Add plugins**, search for 'API Connector' (by Bubble), and install it. Then open the API Connector plugin settings. Click **Add another API** and name it **Khan Academy oEmbed**. Under this API group, click **Add another call** and configure it as follows: - **Name:** Get oEmbed - **Method:** GET - **URL:** `https://www.khanacademy.org/api/labs/shorten/oembed` - **URL Parameters:** - `url` — set value to a test Khan Academy video URL for initialization (e.g., `https://www.khanacademy.org/math/algebra/x2f8bb11595b61c86:expressions-with-exponents/x2f8bb11595b61c86:intro-to-exponents/v/introduction-to-exponents`), check **Allow blank** OFF, check **Private** OFF (this parameter will be dynamic, not secret) - `format` — set value to `json`, check **Allow blank** OFF - **Use as:** Data (not Action) — this tells Bubble the call returns structured data you can bind to elements - Do NOT add any Authorization header — the oEmbed endpoint requires no authentication Leave **Headers** empty. The call configuration looks like this: ```json { "method": "GET", "url": "https://www.khanacademy.org/api/labs/shorten/oembed", "params": { "url": "<khan_video_url>", "format": "json" } } ``` Click **Initialize call**. Bubble will run the call with your test URL and auto-detect the response fields — you should see fields like `html`, `title`, `width`, `height`, `type`, `version`. If you see an error instead, double-check that your test URL contains `/v/` in the path. Article and exercise URLs will return an error from the oEmbed endpoint.
1{2 "method": "GET",3 "url": "https://www.khanacademy.org/api/labs/shorten/oembed",4 "params": {5 "url": "<khan_video_url>",6 "format": "json"7 }8}Pro tip: If Initialize call returns 'There was an issue setting up your call', the most common cause is that the test URL is for a Khan Academy exercise or article page rather than a video. Check that the URL contains '/v/' before the video slug.
Expected result: The Initialize call succeeds and Bubble auto-detects response fields including 'html', 'title', 'width', and 'height'. You see these listed as available data fields in the API Connector.
Build a Backend Workflow to fetch and cache oEmbed HTML
Rather than fetching oEmbed HTML on every page load (which costs Workload Units and slows down the viewer page), you'll build a Backend Workflow that fetches the oEmbed HTML once and caches it in the KhanContent record. Navigate to **Settings → API** and enable **'This app exposes a Workflow API'** — this unlocks the Backend Workflows section. Note: this feature requires a paid Bubble plan (Starter $32/mo or higher). Go to the **Backend Workflows** tab (in the left sidebar after enabling). Click **New API Workflow** and name it `FetchOembedAndCache`. Add a parameter: `content_id` (text) — this will receive the Bubble ID of the KhanContent record to process. Inside the workflow, add these actions: **Step 1 — Look up the KhanContent record:** Add action: **Database → Make changes to a Thing** (configure a search first). Actually, use a **Custom Event** pattern: the workflow receives `content_id`, searches for the KhanContent with matching `_id`, then proceeds. **Step 2 — Call oEmbed:** Add action: **Plugins → Khan Academy oEmbed - Get oEmbed** Set the `url` parameter to: the `khan_url` field of the KhanContent record found in Step 1. **Step 3 — Save embed HTML:** Add action: **Database → Make changes to a Thing** - Thing: the KhanContent record from Step 1 - Field: `embed_html` → set to `Result of Step 2's html` - Field: `is_oembed_fetched` → set to `yes` On your admin panel page, add a button **'Fetch Embed'** that triggers a workflow: **Backend Workflows → Schedule API Workflow → FetchOembedAndCache** with `content_id` set to `Current KhanContent's _id`. Administrators can click this after adding a new video URL to populate the cached embed HTML.
Pro tip: You can bulk-fetch oEmbed for all unfetched videos by using Bubble's 'Schedule API Workflow on a List' action — search for KhanContent where is_oembed_fetched = no and schedule FetchOembedAndCache for each, with a 500ms delay between runs to be respectful to Khan Academy's servers.
Expected result: The FetchOembedAndCache Backend Workflow exists and is callable. After running it for a KhanContent record, the record's embed_html field is populated with an iframe HTML string and is_oembed_fetched is yes.
Build the video viewer page
Create a new page in your Bubble app called `video-viewer`. Set the page's Content Type to **KhanContent** so it receives a specific video record via URL parameter. Add these elements to the page: **Video title:** Add a Text element. Set its content to `Current Page KhanContent's title`. **Video embed:** Add an **HTML element** from the Visual Elements panel. Set its HTML content (in the property editor) to the dynamic expression: `Current Page KhanContent's embed_html` IMPORTANT: Bubble's HTML element passes through `<iframe>` tags safely — the oEmbed `html` field contains an iframe with `allowfullscreen` which renders correctly. Bubble does strip `<script>` tags, but the oEmbed response contains no scripts. **Subject and grade tags:** Add two text elements displaying `Current Page KhanContent's subject` and `Current Page KhanContent's grade_level`. **Mark Complete button:** Add a Button labeled 'Mark Complete'. Set a conditional: hide the button if a Completion record exists where `content_ref = Current Page KhanContent AND user_ref = Current User`. This prevents double-completions. Add a Workflow to the button: - Event: When button is clicked - Action 1: **Database → Create a new Completion** - `user_ref` → Current User - `content_ref` → Current Page KhanContent - `completed_at` → Current date/time - Action 2: Show an alert or change button state to 'Completed ✓' Add a Completion count text: `Search for Completions where user_ref = Current User: count` to show the user's overall progress across all videos.
Pro tip: If the embedded video appears broken after publishing your app, check Bubble's Content Security Policy settings. Some Bubble plans allow you to customize the CSP header — add 'khanacademy.org' and 'youtube.com' to the frame-src directive, since many Khan Academy videos are served via YouTube's embed player.
Expected result: The video viewer page displays the video title, renders the embedded iframe video from cached oEmbed HTML, shows subject and grade level, and the Mark Complete button creates a Completion record when clicked — disappearing after completion.
Build the course library and admin panel
Create a **course-library** page that displays the full catalog of curated KhanContent records using a Repeating Group. **Public catalog page:** Add a Repeating Group with Type 'KhanContent' and Data Source 'Search for KhanContent'. Add filter dropdowns for Subject and Grade Level using Option Sets or hardcoded values in a Dropdown element — filter the Repeating Group's data source based on the dropdown's value. Each cell should show: the video title, subject tag, a completion checkmark (conditional on searching for a Completion where content_ref = Current cell's KhanContent AND user_ref = Current User), and a 'Watch' button that navigates to the video-viewer page with the current cell's KhanContent as the page data. **Admin panel (restricted page):** Create a page `admin-content` and add a condition: if Current User's email is not in your admin list, redirect to the index page. Add a Form to create new KhanContent records: - Input fields: title, khan_url, subject, grade_level - A 'Add Video' button workflow: Create a new KhanContent with all field values, then schedule the FetchOembedAndCache Backend Workflow for the new record's `_id` Add a Repeating Group showing all KhanContent records. Include a 'Fetch Embed' button per row (for re-fetching if the oEmbed HTML is stale) and a 'Delete' button that removes the record.
Pro tip: RapidDev's team has built hundreds of Bubble apps with custom content architectures like this — if you need help designing the data model or the admin curation flow for your specific use case, book a free scoping call at rapidevelopers.com/contact.
Expected result: The course library page shows a filterable grid of Khan Academy videos with completion indicators. The admin panel allows adding new video URLs and triggering oEmbed fetch. The full content management flow works without leaving the Bubble editor.
Test, validate, and launch
Before going live, run through this checklist: **Test oEmbed fetching:** Add a KhanContent record with a valid video URL (must contain '/v/' in the path). Click 'Fetch Embed' from the admin panel. Open the record and confirm embed_html is populated. Navigate to the video-viewer page for that record and verify the video plays. **Test invalid URL handling:** Add a KhanContent record with a Khan Academy exercise URL (containing '/e/' or '/a/' instead of '/v/'). Run FetchOembedAndCache — the oEmbed call will fail. Verify that your workflow handles this gracefully (the embed_html remains empty and is_oembed_fetched remains no) rather than crashing. **Test privacy rules:** Log in as User A and complete a video. Log out. Log in as User B. Confirm User B cannot see User A's completion records — search for Completions from User B's session should return zero results for User A's videos. **Test content rendering:** Publish the app (click Publish → Update). Open the video viewer page in a fresh browser session. Confirm the iframe renders and the video plays. If the video appears as a broken frame, check the Content Security Policy and ensure khanacademy.org and youtube.com are not blocked. **Check WU usage:** After your first batch of oEmbed fetches, open Logs → WU usage in the Bubble editor. Each Backend Workflow run consumes WU — confirm the usage is within your plan's allocation before launching to many users.
Pro tip: Consider adding a 'Report broken video' button on the video viewer page that sets is_oembed_fetched back to 'no' — this lets users flag videos whose embed HTML has become stale (Khan Academy occasionally changes video URLs), triggering an admin re-fetch.
Expected result: The app is live with a working video library, oEmbed fetching runs cleanly from the admin panel, completion tracking works per user, and privacy rules prevent cross-user data exposure.
Common use cases
Branded nonprofit learning portal
A nonprofit builds a custom-branded educational portal for their community, embedding curated Khan Academy math and science videos alongside their own content. Students log in via Bubble Auth, watch videos, and their completion status is stored in Bubble's database — enabling progress reports and certificate generation entirely within the Bubble app.
Build a Bubble app where nonprofit staff can add Khan Academy video URLs to a curated course library, and students can watch embedded videos and mark them complete. Show each student's overall completion percentage on their dashboard.
Copy this prompt to try it in Bubble
School supplemental homework tracker
A school district's Bubble app allows teachers to assign specific Khan Academy videos as homework by adding video URLs to assignment records. Students open the app, watch the embedded video, and click 'Done' to log a completion record. Teachers see a class-level completion report filtered by subject and grade level.
Create a Bubble app where teachers can assign Khan Academy videos by URL. Students see their assignments, watch embedded videos, and mark them done. The teacher dashboard shows which students completed each assignment and when.
Copy this prompt to try it in Bubble
Corporate microlearning library
A company uses Bubble to curate Khan Academy programming and data analysis videos for employee upskilling. HR managers tag each video with skill categories and required roles. Employees receive a personalized playlist based on their job function and can track which videos they have watched, creating an internal learning record without a dedicated LMS license.
Build a corporate learning portal in Bubble that lets HR admins curate Khan Academy videos by skill category. Employees see videos recommended for their role, can play them embedded in the app, and their watch completions are recorded per user.
Copy this prompt to try it in Bubble
Troubleshooting
The Initialize call in API Connector returns 'There was an issue setting up your call'
Cause: The test URL used for initialization points to a Khan Academy exercise or article page, not a video page. The oEmbed endpoint only accepts video URLs containing '/v/' in the path.
Solution: Replace the test URL with a valid Khan Academy video URL. Navigate to any Khan Academy video in your browser — the URL must contain '/v/' before the video slug, for example: https://www.khanacademy.org/math/algebra/x2f8bb11595b61c86:expressions-with-exponents/x2f8bb11595b61c86:intro-to-exponents/v/introduction-to-exponents. Use this URL as the initialization value.
The API Connector call returns a 403 or empty response when targeting api.khanacademy.org
Cause: The Khan Academy REST API at api.khanacademy.org is officially deprecated and inaccessible to independent developers. Any credentials or integration targeting that domain will fail permanently.
Solution: Do not use api.khanacademy.org. The only supported integration path is the oEmbed endpoint at https://www.khanacademy.org/api/labs/shorten/oembed — which requires no API key. Rebuild your API Connector call to target this endpoint only.
Embedded video appears as a broken or blank frame on the published app
Cause: The Bubble app's Content Security Policy is blocking iframes from khanacademy.org or youtube.com. Many Khan Academy videos are delivered through YouTube's embed player, which the iframe points to.
Solution: On your Bubble app's Settings → General page, look for the Content Security Policy (CSP) option if your plan includes it. Add 'khanacademy.org' and '*.youtube.com' to the frame-src directive. If CSP settings are not available on your plan, contact Bubble support or upgrade. As an alternative, test in a private browser window — browser extensions like ad blockers sometimes block Khan Academy or YouTube iframes independently of Bubble's CSP.
'Schedule API Workflow' action is missing or greyed out in the workflow editor
Cause: Backend Workflows (and the ability to schedule them) are not available on Bubble's Free plan. The FetchOembedAndCache workflow requires a paid plan.
Solution: Upgrade to Bubble's Starter plan ($32/month) or higher. After upgrading, go to Settings → API and enable 'This app exposes a Workflow API'. The Backend Workflows tab will appear in the left sidebar, and the 'Schedule API Workflow' action will become available in the workflow editor.
Users can see other users' completion records in search results
Cause: Privacy rules on the Completion Data Type are either not set or set incorrectly. Without a privacy rule, Bubble returns all Completion records to all logged-in users.
Solution: Go to Data tab → Completion → Privacy. Delete any existing rules. Add a new rule: set condition to 'Current User is user_ref'. Under 'This user can find this in searches', ensure 'yes' is selected. This restricts Completion records to only be visible to the user who created them.
Best practices
- Cache oEmbed HTML in your Bubble database immediately after adding a video URL — never fetch oEmbed on every page load, as each API call consumes Workload Units and adds latency to the user experience.
- Validate Khan Academy video URLs before attempting oEmbed fetches: check that the URL contains '/v/' in the path. Exercise and article pages return errors from the oEmbed endpoint, so add a URL format check in your admin panel before saving a new KhanContent record.
- Set strict privacy rules on the Completion Data Type from day one — restrict visibility so each user can only read and write their own completion records. Retrofitting privacy rules after data accumulates is error-prone and risky.
- Use Bubble's 'Schedule API Workflow on a List' with a delay parameter (at least 200ms between runs) when bulk-fetching oEmbed HTML for many videos. Sending dozens of concurrent requests to the Khan Academy oEmbed endpoint in a tight loop risks rate-limiting even on an unauthenticated endpoint.
- Store the Khan Academy video URL separately from the embed_html in your KhanContent Data Type. If a video's embed HTML becomes stale (Khan Academy changes the URL structure), you need the original URL to re-fetch fresh oEmbed data.
- Monitor WU usage in Bubble's Logs tab after launching. Each Backend Workflow run for oEmbed fetching counts against your plan's WU allocation. For large content libraries (100+ videos), plan your bulk-fetch schedule to spread WU consumption across off-peak hours.
- Consider offering YouTube as a fallback for Khan Academy videos. Most Khan Academy videos are also published on their YouTube channel — if a video URL fails oEmbed validation, you can link to the YouTube equivalent, which may be easier to embed via YouTube's own API.
Alternatives
Many Khan Academy videos are also available on Khan Academy's YouTube channel. YouTube's Data API v3 provides a full-featured video catalog, search, and embed system with proper API keys and quota management — a more robust integration path than the Khan Academy oEmbed workaround.
If you need to host your own educational video content (rather than linking to Khan Academy), Vimeo for Business offers a proper API with upload, embed, and analytics endpoints. It eliminates dependence on third-party video URLs and gives you full control over the content library.
If you need a full Learning Management System API — with real course enrollment, grade tracking, user management, and quiz results — Moodle offers a complete Web Services API with token authentication. Khan Academy has no such live API; Moodle is the right choice when you need writable LMS data.
Frequently asked questions
Does Khan Academy's oEmbed endpoint require an API key?
No. The oEmbed endpoint at https://www.khanacademy.org/api/labs/shorten/oembed is completely public and unauthenticated. You do not need to register for any credentials, configure any headers, or create a developer account. Simply pass the video URL and format=json as query parameters.
Can I use the Khan Academy REST API (api.khanacademy.org) in Bubble?
No. The Khan Academy REST API at api.khanacademy.org has been officially deprecated and is no longer accessible to independent developers. Requests to that domain return 403 errors. The only remaining programmatic integration point is the public oEmbed endpoint, which only works for video pages.
Can I track what videos each student has watched from Khan Academy's side?
No. Because you are embedding videos from Khan Academy rather than integrating with a live API, Khan Academy has no way to report watch data back to your Bubble app. All progress tracking must be self-reported by the user (clicking 'Mark Complete') or inferred from your Bubble database. There is no way to verify whether a student actually watched a video to completion.
Why do I need the Starter plan just to use the oEmbed endpoint?
The oEmbed API Connector call itself can technically run as a client-side call on the Free plan. However, the recommended pattern caches oEmbed HTML via a Backend Workflow (to avoid re-fetching on every page load), and Backend Workflows require a paid Bubble plan (Starter $32/month or higher). If you are on the Free plan, you can run the oEmbed call directly from a page workflow, but this increases page load time and WU consumption.
What happens if Khan Academy changes a video's URL after I've cached the embed HTML?
The cached embed_html in your Bubble database will become stale — the iframe src URL may break, showing an error in the video player. To handle this, add a 'Report broken video' button on your viewer page that resets is_oembed_fetched to 'no'. Admins can then re-run the FetchOembedAndCache workflow with the updated URL.
Can I search the Khan Academy course catalog from Bubble to let users browse topics?
Not via an API — the catalog search endpoints were part of the deprecated REST API. The practical approach is to manually curate your content library in Bubble's database, adding Khan Academy video URLs and metadata (title, subject, grade level) directly. For a larger catalog, you can build a CSV import workflow in Bubble that reads a spreadsheet of Khan Academy URLs and bulk-creates KhanContent records.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation