# IntelliJ IDEA

- Tool: Bubble
- Difficulty: Intermediate
- Time required: 45–60 minutes
- Last updated: July 2026

## TL;DR

IntelliJ IDEA is a JVM IDE with no hosted API of its own. Connect Bubble to your IntelliJ-built Java or Kotlin backend (Spring Boot or Ktor deployed on Railway or Render) using the API Connector, or use the JetBrains Space REST API to display code reviews, pipelines, and deployment status directly inside your Bubble app — no terminal required.

## Two ways to connect Bubble and IntelliJ IDEA

Before you start, it helps to understand what 'connecting Bubble to IntelliJ IDEA' actually means — because IntelliJ IDEA itself has no REST API. It is a desktop IDE that runs on your machine; there is nothing to call.

That said, IntelliJ IDEA users typically want one of two things inside Bubble:

**Path A — JetBrains Space dashboard.** JetBrains bundles Space, a hosted DevOps platform, with many of its tools. Space has a full REST API at `https://{org}.jetbrains.space/api/http` covering issues, code reviews, CI/CD pipelines, and deployment environments. If your team already uses Space for project tracking, you can pull that data into a Bubble internal dashboard or client portal without any custom backend.

**Path B — Custom Spring Boot or Ktor backend.** Many IntelliJ users write Java or Kotlin REST APIs with Spring Boot or Ktor and need a no-code front-end for clients or internal teams. Deploying that backend to Railway, Render, or AWS gives it a public HTTPS URL. Bubble's API Connector can then call it like any other REST API — and because Bubble's calls are server-side, secret credentials never leave Bubble's infrastructure.

This tutorial covers both paths. If you are a non-technical founder whose developers use IntelliJ and Space, start with Path A. If you are a developer who wants to expose your JVM backend to a Bubble front-end, jump to Path B in Step 5.

## Before you start

- A Bubble account (free plan works for outbound API Connector calls; paid plan required for inbound Backend Workflow webhooks)
- A JetBrains Space organisation at {yourorg}.jetbrains.space (free for up to 5 users) — OR — a deployed Spring Boot / Ktor backend with a public HTTPS URL
- Admin access to JetBrains Space to create a Service Application (for Path A)
- The 'API Connector' plugin by Bubble installed in your Bubble app (Plugins tab → Add plugins → search 'API Connector')

## Step-by-step guide

### 1. Step 1 — Decide which path to take (Space API or custom backend)

Open your Bubble app editor and, before touching the API Connector, answer one question: does your team use JetBrains Space? Go to `https://{yourorg}.jetbrains.space` — if you have an active organisation with issues, code reviews, or deployments tracked there, choose Path A. If your IntelliJ developers have built a Spring Boot or Ktor REST API and deployed it somewhere public, choose Path B.

This step matters because the two paths have different auth setups. Path A uses a JetBrains Space Service Application Bearer token obtained via an OAuth client_credentials exchange. Path B uses whatever auth your own API implements — JWT, API key, or Basic Auth.

If you are not sure, start with Path A — it requires no code changes to your IntelliJ projects, and you can always add Path B calls to the same Bubble app later. Write down your Space organisation subdomain (the part before `.jetbrains.space`) before proceeding; you will need it in every API URL.

**Expected result:** You know which path you are taking and have either your Space org subdomain or your backend's HTTPS base URL written down.

### 2. Step 2 — Create a JetBrains Space Service Application and copy the token (Path A)

In JetBrains Space, Service Applications are the correct credential type for server-to-server integrations — unlike user Personal Tokens, a Service Application token does not expire by default and can be scoped precisely.

Log in to your Space organisation and click **Administration** in the left sidebar (you need admin rights). Go to **Applications** → **New Application** → give it a name like `Bubble Dashboard`. Under **Authentication**, select the **Client Credentials** grant type — this is the OAuth flow where the application authenticates as itself without a user login.

Next, assign scopes. Click **Authorizations** → **Configure** → in the project scope picker, add:
- `Project.Issues.View` — read issues
- `Project.CodeReview.View` — read code reviews
- `Deployments.View` — read deployment environments

Grant these scopes to the specific projects you want visible in Bubble, or to all projects if this is an admin dashboard.

Copy the **Client ID** and **Client Secret** from the application's credentials screen. You will exchange these for a Bearer token in the next step via an API Connector call. Store them somewhere safe — you cannot view the Client Secret again after leaving this screen.

```
{
  "grant_type": "client_credentials",
  "client_id": "<your-client-id>",
  "client_secret": "<your-client-secret>"
}
```

**Expected result:** You have a Client ID and Client Secret for your Bubble Service Application in JetBrains Space, with the correct read scopes assigned.

### 3. Step 3 — Install the API Connector and exchange credentials for a Bearer token

In your Bubble editor, click **Plugins** in the left sidebar → **Add plugins** → search for **API Connector** (published by Bubble) → click **Install**. This plugin is free and powers all outbound API calls from Bubble.

Now open the API Connector plugin settings and click **Add another API**. Name this group **JetBrains Space Token**. Set the base URL to `https://{yourorg}.jetbrains.space/oauth/token` — replace `{yourorg}` with your actual Space subdomain.

Click **Add a call** inside this group. Set the method to **POST**. Leave the path blank (the base URL is the full token endpoint). Under **Body**, select **form-data** and add three key-value pairs:
- `grant_type` → `client_credentials`
- `client_id` → paste your Client ID
- `client_secret` → paste your Client Secret (tick **Private** on this field)

Click **Initialize call**. Bubble will make a real POST request. If successful, you will see a JSON response containing `access_token`, `token_type`, and `expires_in`. Bubble reads this shape and maps the fields automatically.

Copy the `access_token` value from the response preview — you will paste it into the next API group as the Bearer token. In production, you should store this token in a Bubble data type and refresh it before it expires, which requires a Backend Workflow on a paid plan.

```
{
  "method": "POST",
  "url": "https://{yourorg}.jetbrains.space/oauth/token",
  "body": {
    "grant_type": "client_credentials",
    "client_id": "<your-client-id>",
    "client_secret": "<private>"
  },
  "response": {
    "access_token": "eyJ...",
    "token_type": "Bearer",
    "expires_in": 3600
  }
}
```

**Expected result:** Bubble's API Connector shows a successful token response with an `access_token` field. You have copied the token value to use as your Bearer credential in the next step.

### 4. Step 4 — Configure the Space API Connector group with Private Bearer header

Click **Add another API** to create a second API group — this one will hold all your Space data calls. Name it **JetBrains Space**. Set the base URL to `https://{yourorg}.jetbrains.space/api/http`.

Under **Shared headers**, click **Add a shared header**. Set the key to `Authorization` and the value to `Bearer {paste-your-access-token-here}`. Immediately tick the **Private** checkbox next to this header. When Private is ticked, Bubble strips this header from any response sent to the browser — your token is never visible in client-side network traffic.

Now add your first data call. Click **Add a call** inside the **JetBrains Space** group. Set the method to **GET** and the path to `/projects/id:{projectKey}/issues`. Replace `{projectKey}` with your actual Space project key (find it in Space → your project → Settings → copy the short key, e.g. `BACKEND`). Add a Bubble parameter for `projectKey` so you can pass different projects dynamically later.

Click **Initialize call**. Bubble sends the GET request to Space and reads the response. If you see a list of issues with fields like `id`, `title`, `status`, and `assignee`, the initialisation succeeded. Bubble will create a field mapping from these response fields that you can use in Repeating Groups.

Repeat for a second call: GET `/projects/id:{projectKey}/code-reviews`. Initialize that call too. Bubble will detect fields like `state` (Open / Closed / Needs Review), `title`, and `createdBy`.

```
{
  "api_group": "JetBrains Space",
  "base_url": "https://{yourorg}.jetbrains.space/api/http",
  "shared_headers": [
    {
      "key": "Authorization",
      "value": "Bearer <private>",
      "private": true
    }
  ],
  "calls": [
    {
      "name": "Get Issues",
      "method": "GET",
      "path": "/projects/id:{projectKey}/issues"
    },
    {
      "name": "Get Code Reviews",
      "method": "GET",
      "path": "/projects/id:{projectKey}/code-reviews"
    },
    {
      "name": "Get Deployments",
      "method": "GET",
      "path": "/projects/id:{projectKey}/deployments"
    }
  ]
}
```

**Expected result:** The API Connector shows green 'Initialized' status for both the Get Issues and Get Code Reviews calls. The response field mapping panel lists fields like `id`, `title`, `status`, and `state`.

### 5. Step 5 — Build a Bubble page to display code reviews and pipeline status

Now that the API Connector is configured, you can surface JetBrains Space data in your Bubble UI. This step builds a simple DevOps dashboard showing open code reviews with conditional colour coding.

In your Bubble editor, open the page where you want the dashboard (or create a new page called `devops-dashboard`). From the element toolbar, drag in a **Repeating Group**. Click the Repeating Group to open its property panel. Set **Type of content** to **JetBrains Space Get Code Reviews** (Bubble auto-created this type when you initialized the call). Set **Data source** to **Get data from an external API → JetBrains Space - Get Code Reviews**, and pass the `projectKey` parameter as a text input value or hardcode it for now.

Inside the Repeating Group's first cell, add three text elements:
1. **Title** — bind to `Current cell's JetBrains Space Get Code Reviews → title`
2. **State** — bind to `Current cell's JetBrains Space Get Code Reviews → state`
3. **Author** — bind to `Current cell's JetBrains Space Get Code Reviews → createdBy → name`

Select the **State** text element and click **Conditional** at the top of its property panel. Add a condition: `When this element's text is 'Open'` → set text colour to `#E53E3E` (red). Add another condition: `When this element's text is 'Closed'` → set text colour to `#38A169` (green). Add a third: `When this element's text is 'NeedsReview'` → set text colour to `#D69E2E` (amber).

Preview the page. You should see a live list of code reviews from your JetBrains Space project with colour-coded status. Each row updates when the page loads — no manual refresh needed.

For the Spring Boot / Ktor Path B integration (Step 6), you would follow the same Repeating Group pattern, simply pointing the API call at your own backend's endpoint instead of the Space URL.

**Expected result:** The Bubble page displays a live list of open code reviews from your JetBrains Space project, with state labels coloured red (Open), green (Closed), and amber (NeedsReview).

### 6. Step 6 — Connect Bubble to a Spring Boot or Ktor backend built in IntelliJ (Path B)

If your team has built a REST API in IntelliJ IDEA using Spring Boot or Ktor, connecting it to Bubble is straightforward once the service is deployed to a public HTTPS URL. Services like Railway (`railway.app`) and Render (`render.com`) deploy Spring Boot JARs from GitHub with zero configuration and give you a free HTTPS domain.

Once your backend is live at, say, `https://my-api.railway.app`, return to the Bubble API Connector. Click **Add another API** and name it **My Backend API**. Set the base URL to `https://my-api.railway.app`.

If your Spring Boot API uses JWT auth, add a shared header `Authorization: Bearer {jwt}` (Private). If it uses an API key header like `X-API-Key`, add that instead (Private). If it is open for now (development only), leave headers empty.

Add a GET call for one of your endpoints, for example `/api/v1/reports`. Click **Initialize call** — Bubble sends the GET and maps the JSON response fields. If your Spring Boot controller returns a `List<ReportDto>` serialised as a JSON array, Bubble will detect each field in the DTO (`id`, `title`, `createdAt`, etc.) and create a data type for it.

One important note: Spring Boot with Spring HATEOAS or Spring Data REST often wraps responses in an `_embedded` key. For example, a list of reports might come back as `{ "_embedded": { "reports": [...] } }`. When this happens, set the response **Use as** field to point at `_embedded → reports` so Bubble sees the array correctly. You can reconfigure this by clicking the call → **Re-initialize** after adjusting the response path.

RapidDev's team has connected dozens of Spring Boot backends to Bubble apps using exactly this pattern — if you need help wiring up JWT refresh or scoping API calls per user role, book a free scoping call at rapidevelopers.com/contact.

```
{
  "api_group": "My Backend API",
  "base_url": "https://my-api.railway.app",
  "shared_headers": [
    {
      "key": "Authorization",
      "value": "Bearer <private>",
      "private": true
    }
  ],
  "calls": [
    {
      "name": "Get Reports",
      "method": "GET",
      "path": "/api/v1/reports",
      "use_as": "Data (list)"
    },
    {
      "name": "Create Report",
      "method": "POST",
      "path": "/api/v1/reports",
      "use_as": "Action"
    }
  ]
}
```

**Expected result:** The Bubble API Connector successfully initialises against your Spring Boot or Ktor backend, and the Repeating Group on your Bubble page displays real data returned from the JVM API.

## Best practices

- Always tick the 'Private' checkbox on the Authorization header in the API Connector — this prevents your JetBrains Space token or JWT from appearing in browser network traffic, even though Bubble's calls are already server-side.
- Use a JetBrains Space Service Application token rather than a personal user token for production Bubble apps. Service Application tokens can be scoped to specific projects and do not rotate when a team member leaves.
- Store the access token in a Bubble data type (e.g., a 'Settings' Thing with a text field 'space_token' and a date field 'token_expires_at'). Before each API call, check whether the token has expired and refresh it via a Backend Workflow if needed — this prevents silent 401 failures on pages that have been open for more than an hour.
- Grant the minimum scopes required for your use-case. If you only display code reviews, do not add Deployment write permissions. Least-privilege scoping limits blast radius if the token is ever compromised.
- Cache Space API responses in Bubble's database when they do not need to be real-time. Storing a list of issues with a 'last_synced' timestamp and only refreshing every 5 minutes avoids unnecessary WU consumption on each page load.
- Ensure your Spring Boot or Ktor backend is deployed with HTTPS before wiring it to Bubble's API Connector — Bubble rejects HTTP endpoints. Railway and Render both provision TLS certificates automatically on free plans.
- Add Privacy rules to any Bubble data types that store Space issue data or backend API responses. Without Privacy rules, Bubble's default behaviour exposes all records to all logged-in users via the API Connector data endpoint.

## Use cases

### Internal DevOps dashboard

Surface open code reviews, pipeline status (running / success / failed), and upcoming deployments from JetBrains Space in a Bubble dashboard visible to project managers and stakeholders — without giving everyone a Space account.

Prompt example:

```
Show me how to display the status of all open code reviews from JetBrains Space in a Bubble Repeating Group, with green/red text based on the review state.
```

### Client portal for Java API consumers

Build a Bubble app that lets clients explore API documentation, trigger test requests, and view usage metrics from a Spring Boot backend built in IntelliJ — replacing a static PDF spec sheet with a live interactive portal.

Prompt example:

```
I have a Spring Boot REST API deployed on Railway. How do I let my Bubble clients call the /reports endpoint and see the JSON response rendered in a clean table?
```

### Deployment approval workflow

Create a Bubble workflow where a manager can see all pending JetBrains Space deployment requests and click an Approve button that calls the Space API to confirm the deployment — bringing a code-review gating step into a non-developer-friendly UI.

Prompt example:

```
How can I build a Bubble button that triggers a JetBrains Space deployment for a specific environment using the Space REST API?
```

## Troubleshooting

### Initialize call returns 'There was an issue setting up your call' with a 401 status

Cause: The JetBrains Space Bearer token has expired (tokens from the client_credentials flow typically last one hour) or the token was pasted incorrectly into the Authorization header.

Solution: Re-run the token exchange call from Step 3 to obtain a fresh `access_token`. Open the JetBrains Space API Connector group, click the Authorization header value, replace the old token with the new one, and click Initialize call again. For a long-term fix on a paid Bubble plan, store the token in a Bubble 'Settings' data type and use a Backend Workflow scheduled every 50 minutes to refresh it automatically.

### API Connector returns a 404 for Space endpoints like /projects/id:{key}/issues

Cause: The project key is incorrect, the Space organisation subdomain in the base URL is wrong, or the endpoint path is missing the `/api/http` prefix.

Solution: Check three things: (1) The base URL is `https://{yourorg}.jetbrains.space/api/http` — not `jetbrains.space` without the org, and not `api.jetbrains.space`. (2) The project key matches exactly what Space shows in your project Settings (it is case-sensitive). (3) You are not doubling the path prefix — the base URL already ends in `/api/http`, so the call path should start with `/projects/`, not `/api/http/projects/`.

### Repeating Group shows an empty list even though Initialize call succeeded

Cause: The call's 'Use as' setting is set to 'Action' instead of 'Data (list)', or the response is wrapped in a key like `data` or `_embedded` that Bubble is not unwrapping.

Solution: Open the API Connector call settings and check the 'Use as' dropdown — it should be 'Data (list)' for Repeating Group data sources. If your Space or Spring Boot API wraps the list in an object key, click the call → scroll to the response preview → expand the wrapper key → re-initialise with the path pointing to the array. In Bubble's response mapping panel, you can select a sub-key as the root of the returned data.

### Backend Workflow does not receive incoming Space webhook events

Cause: Backend Workflows (API Workflows) are only available on paid Bubble plans. The Free plan cannot expose a public webhook endpoint.

Solution: Upgrade to a paid Bubble plan. Once upgraded, go to Settings → API → tick 'This app exposes a Workflow API'. Then create a new Backend Workflow and use its endpoint URL (format: `https://yourapp.bubbleapps.io/api/1.1/wf/{workflow-name}`) as the webhook URL in JetBrains Space → your project → Settings → Webhooks.

## Frequently asked questions

### Does IntelliJ IDEA have its own REST API I can call from Bubble?

No. IntelliJ IDEA is a desktop IDE application — it runs locally on a developer's machine and exposes no hosted endpoints. The two integration paths are: (1) the JetBrains Space REST API (the hosted DevOps companion to IntelliJ, available at `https://{yourorg}.jetbrains.space/api/http`), and (2) any Java or Kotlin backend service that your team built using IntelliJ and deployed to a public HTTPS URL.

### Do I need a paid Bubble plan to call the JetBrains Space API?

No — outbound API Connector calls work on Bubble's free plan. You can fetch issues, code reviews, and deployment data from Space and display them in Repeating Groups without upgrading. A paid plan is only required if you want to receive inbound webhook events from Space (e.g., trigger a Bubble workflow when a code review is merged) — that requires Backend Workflows, which are a paid-plan feature.

### How do I handle the Space token expiring every hour?

Store the `access_token` and its `expires_in` value in a Bubble data type when you first fetch it. Before each API call, compare the current time to the stored expiry time. If it has expired, trigger a Backend Workflow that re-runs the client_credentials token exchange call and updates the stored token. This pattern requires a paid Bubble plan. On the free plan, you can manually refresh the token by re-running the token call and pasting the new value into the Authorization header — less convenient but functional for low-traffic apps.

### My Spring Boot API returns data wrapped in '_embedded' — how do I handle that in Bubble?

Spring Boot with Spring Data REST wraps list responses in `{ "_embedded": { "items": [...] } }`. In Bubble's API Connector, after clicking Initialize call and seeing the response, look for the response path selector. Click into the `_embedded` object and then select your array key. Re-initialize the call with this path selected as the root — Bubble will then treat the nested array as the list returned by the call, which you can bind to a Repeating Group directly.

### Can I trigger a JetBrains Space CI/CD pipeline from a Bubble button?

Yes. In the API Connector, add a POST call to `/applications/{appId}/deployments` (or the Space CI/CD trigger endpoint for your project). Set it as 'Use as: Action'. In your Bubble workflow, add the step 'Plugins → JetBrains Space - Trigger Deployment' and pass the required parameters. The button click triggers the workflow, which fires the POST call server-side. No paid plan required for outbound calls.

### What is the difference between this IntelliJ IDEA integration and the PyCharm integration?

Both use the same JetBrains Space REST API, so the API Connector setup is identical. The difference is in the backend use-case: the PyCharm brief targets Python developers building Flask, FastAPI, or Django backends; this IntelliJ brief targets Java and Kotlin developers building Spring Boot or Ktor services. If your backend is Python, follow the PyCharm guide instead — the Space API steps are interchangeable, but the backend deployment examples differ.

---

Source: https://www.rapidevelopers.com/bubble-integrations/intellij-idea
© RapidDev — https://www.rapidevelopers.com/bubble-integrations/intellij-idea
