# The API Connector

In the [Bubble API section](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/the-bubble-api) we covered API requests that are incoming – they are initiated by an outside system and Bubble takes some kind of action based on their credentials, endpoint and parameters.

{% hint style="info" %}
This is our in-depth manual article on the API Connector.\
\
If you are familiar with APIs and want the shorter technical reference go to the [API Connector reference entry](https://manual.bubble.io/~/changes/1188/core-resources/api/the-api-connector). We also have a dedicated article covering [API Connector security](https://manual.bubble.io/~/changes/1188/help-guides/security/api-security/api-connector-security).
{% endhint %}

In this section we’ll look at requests that are **outbound** – when your Bubble app sends a request to an external system. When you use the API Connector, your Bubble app is the *client* and the API service is the *server*.

{% hint style="info" %}
You can read more about the client/server relationship in our [Introduction to APIs](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis).\
\
Article section: [The client/server relationship](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis#client-and-server)
{% endhint %}

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fa4uqiDqJuz4vjLjfPW5B%2Foutgoing-api-call.jpeg?alt=media&#x26;token=b715ebac-1632-4dc1-bbe9-e46597584246" alt=""><figcaption><p>The API Connector handles calls that come <em><strong>from</strong></em> your Bubble app <em><strong>to</strong></em> another application.</p></figcaption></figure>

By pointing the API Connector to different URLs (Universal Resource Locator) you can access specific resources[^1] that the API provider offers.

Just like incoming requests these calls can ask for some data to be returned or for an action to be performed.

Structurally, you’ll recognize what they look like: they also use an [HTTP request](#user-content-fn-2)[^2] that includes a method[^3] like GET, POST, PATCH and DELETE.

{% hint style="info" %}
**Plugins:** Bubble's plugin store offers thousands of plugins both made by Bubble and the community. Many plugins let you connect to well-known API services quickly and effortlessly without having to set it up in the API Connector.\
\
Link: [Plugin store](https://bubble.io/plugins)\
Article: [Plugins that connect to APIs](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/plugins-that-connect-to-apis)
{% endhint %}

## The API Connector

The API Connector is a special plugin built by Bubble's development team that lets you connect to any service that exposes a JSON-based[^4], [RESTful web API](#user-content-fn-5)[^5]. You can use this to add API calls to fetch data from an external service, or post data to trigger some actions on the service's end.

{% embed url="<https://www.youtube.com/watch?t=745s&v=nO8PSqeJaWk>" %}
Our long-form video course gives you an introduction to how APIs work and how to use the API Connector.
{% endembed %}

### **Installing the API Connector**

The API Connector is a plugin created by Bubble and needs to be installed in your application before it can be used.

To install the plugin:

1. Navigate to the *Plugins* section of the Bubble editor and click *Add plugin*.
2. Search for *API Connector*
3. Click the *Install* button

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F1fdizjb0dOUpZWUwyefs%2Fapi-connector-plugin-install%402x.png?alt=media&#x26;token=fe200852-fb4f-4b4e-bb85-b2ae94b531c6" alt=""><figcaption><p>Click the Install button to use the API Connector in your application.</p></figcaption></figure>

## **External API documentation**

Every API service is different and to make it possible to connect successfully to their platform, most providers offer API documentation. Using the external documentation is critical to understand how to authenticate and make calls to that specific service, so we recommend you get to know it before you start.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FLfIOXaYMOBmsmk5DcDP8%2Fstripe-documentation.png?alt=media&#x26;token=56c60a40-c75a-4d8c-b35e-5c0e8caf2a44" alt=""><figcaption><p>API providers like Stripe offer detailed <a href="https://stripe.com/docs">documentation</a> on how to set up API connections.</p></figcaption></figure>

If this is your first time working with APIs, the documentation may seem fairly technical at first, but you’ll find that with the RESTful API style most providers follow a similar standard.

Most APIs will go through three steps before they can be used:

1. First set up the [**authentication**](#user-content-fn-6)[^6] for the API service
2. Secondly we set up the different [**call**](#user-content-fn-7)[^7]\(s) we want to use
3. Then we [**initialize**](#user-content-fn-8)[^8] the call to make sure it works and to see the server's response

### Test accounts

Many API providers such as Stripe offer a demo account that you can use to test your API calls without making any actual changes (or payments in the case of Stripe). Check whether the service you want to connect to offers this kind of testing environment to be able to properly test all your calls with no risk.

## **Naming API providers**

The first part of setting up a new API request is to give the service a name. This will typically be a descriptive name (often the same as the provider’s name) such as Stripe, Google Cloud and OpenWeatherAPI.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F5X3y6qxbwEigVt1mc4Jz%2Fapi-name-bubble.png?alt=media&#x26;token=e1933dc6-67df-4130-a7ca-db2708f2ee27" alt=""><figcaption><p>Giving your API a descriptive name makes it easier to organize the different providers.</p></figcaption></figure>

The name is used around the Bubble editor to organize the different calls that we’ll add later. It’s therefore a good idea to use a name that makes the relevant call easy to find later.

{% hint style="danger" %}
The API name becomes part of your application’s client-side code and should not contain any sensitive information.
{% endhint %}

## **Authentication**

As we covered in our general guide on how APIs work, many API services will require authentication[^9]. This is the process of identifying **who** the client is in order to determine what resources it should have access to.

### Authentication methods

There are many different ways to authenticate. Most API providers will have documentation available online that specifies their authentication method and many require you to generate a unique API token.

{% hint style="info" %}
The list below represents the most common authentication types. You can read more about each type in the article below:\
\
Article: [Authenticating with the API Connector](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/the-api-connector/authentication)
{% endhint %}

<table><thead><tr><th width="259">Method</th><th>Description</th></tr></thead><tbody><tr><td>None or self-handled</td><td>No authentication required.<br><mark style="color:orange;">⚠️ (see security note</mark> <a href="#security-risk-with-api-connector-configuration"><mark style="color:orange;">below</mark></a><mark style="color:orange;">)</mark></td></tr><tr><td>Private key in URL</td><td>The private key is included as a parameter in the URL.</td></tr><tr><td>Private key in header</td><td>The private key is included as an HTTP header in the request.</td></tr><tr><td>HTTP Basic Auth</td><td>The client sends username and password in plain text.</td></tr><tr><td>OAuth2 Password Flow</td><td>The client sends username and password and receives an access token in return.</td></tr><tr><td>OAuth2 User-Agent Flow</td><td>Similar to OAuth2 Password Flow, but for user-agents.<br><mark style="color:orange;">⚠️ (see security note</mark> <a href="#security-risk-with-api-connector-configuration"><mark style="color:orange;">below</mark></a><mark style="color:orange;">)</mark></td></tr><tr><td>OAuth2 Custom Token</td><td>The client sends a custom token to the server for verification.</td></tr><tr><td>JSON Web Token (JWT)</td><td>The client sends a JSON web token to the server for verification.</td></tr><tr><td>Client-side SSL certificate</td><td>The client presents a SSL certificate to the server for verification.</td></tr></tbody></table>

<details>

<summary><mark style="color:orange;">⚠️</mark> Privacy considerations when using the API Connector as data</summary>

#### Scenario

When configuring API calls in the API Connector as Data (i.e. “Use as: Data”\ <img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FOp3eddrEXCKPZlOTMsDf%2FCleanShot%202025-04-10%20at%2018.15.29%402x.png?alt=media&#x26;token=ad6441a5-9dd2-4a8c-8b57-1ae0c23f734a" alt="" data-size="line"> ) there is a potential security risk if the Authentication method is set to either:

* `None or self-handled`
* `OAuth2 User-Agent Flow`

…and the API relies on private keys or other sensitive parameters passed as query strings or body parameters.

#### Behavior to be aware of:

In these configurations, Bubble does not enforce privacy rules or validate these requests against the current database state. As a result, sensitive data may be exposed or become accessible to users who should not have access. We suggest the configuration below to ensure stronger control over access.

**Recommended solution:**\
To mitigate this risk, do not only pass private keys as parameters. Instead, use the `Private key in header` authentication method in the API Connector. This ensures:

* The key is securely stored and only sent from the server.
* Bubble’s server-side logic handles the call and can enforce privacy rules.

</details>

### **API tokens and security**

{% hint style="warning" %}
We recommend learning how to set up the API Connector in a secure way. If you want to learn more about this, check out our dedicated article on API Connector security.

Article: [API Connector security](https://manual.bubble.io/~/changes/1188/help-guides/security/api-security)
{% endhint %}

If you are new to APIs it’s important to emphasize here the importance of keeping your API token **secret**. API tokens in principle serve the same function as a username and password, but they add security and flexibility that is useful to an API provider:

1. They can be easily generated and revoked: Unlike a username and password, which are typically created and managed by an actual person, API tokens can be easily generated and revoked by the API provider. This makes it easy to control access to the API and limit the impact of any security breaches.
2. They are more secure: API tokens are generally more secure than username and password combinations, because they are typically harder to guess or brute force. They can also be rotated regularly to further improve security.
3. They are more convenient: API tokens are generally easier for developers to work with than username and password combinations, because they do not require any special handling. This can make it easier for developers to use your API and can increase adoption of your API.

Just like a username and password, a token is only as secure as the one who manages it. Tokens to important services like Stripe should be handled with the utmost confidentiality.

{% hint style="danger" %}
API keys/tokens should never be stored in Option Sets or in on-page elements and/or workflows, since that makes them visible in your application’s client-side source code.
{% endhint %}

## Shared headers

Sometimes you'll need to add the same header to all your calls. This can be related to authentication, but it doesn't have to be. Another typical key and value included in the header section is the *content-type,* which specifies the expected format of the call.

Consult the external API documentation to see if they require any specific headers.

## Shared parameters

Shared parameters, like the headers described above, will be added to each and every call in the relevant API. Shared parameters are added to the *body* of the request rather than the header.&#x20;

{% hint style="info" %}
It doesn't make any technical difference whether you add *headers* and *parameters* directly to each call or use the *Shared headers/parameters feature*.\
\
Adding them to this section will simply save you some time and make the headers and parameters easier to set up and manage.
{% endhint %}

## **Adding calls**

Now that we have 1) given our API service a descriptive name and 2) authenticated as a client (if necessary) it’s time to add the actual calls.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FbVIX65t8fVUgzIN6dJQ9%2Fadd-call-api-connector.png?alt=media&#x26;token=085ddf94-e3e4-4d1a-882c-690b3f7300e7" alt=""><figcaption><p>To add a call, click the <em>Add another call</em> button</p></figcaption></figure>

Again we need to name the call before doing anything else. Give it a descriptive name that can be combined with the name you gave earlier to the API provider. For example, you might name the API Provider Stripe and the API Call Create payment.

Secondly, we need to tell Bubble what this call will be used for in the Use as dropdown.

### Use as

The *Use as* dropdown lets you select whether to use that particular API call as a data source or an action:

#### Data

Use as data means that Bubble will treat the API call as a data source. Use this for calls that you set up to retrieve data that you want to display in your app. You will find API data sources in the Get data from external API in the dropdown list of data sources.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FCQsQyzv6tRJN97osw0cB%2Fget-data-external-api%402x.png?alt=media&#x26;token=69a962e6-283e-4ac9-90aa-c03c4ad76be4" alt=""><figcaption><p>Setting the API call to be of type <strong>Data</strong> allows you to use the call as a data source. That way you can use it to populate Repeating Group for example.</p></figcaption></figure>

#### Action

Use as action makes the API call available as an action in your Workflow editor. You will find API action calls in the workflow editor under Plugins.&#x20;

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FkROoSioQn77ihqEDSPRI%2Frun-api-call-as-action-bubbl%402x.png?alt=media&#x26;token=2c6d9a35-6e4f-4377-b574-3412d2c45bc3" alt=""><figcaption><p>Setting an API call to type <strong>Action</strong> lets you run that call from a workflow in your application. The label (RentalSoftware - Create Unit) is a combination of the name you gave the API provider and the name of the call in the API Connector.</p></figcaption></figure>

### **The HTTP method**

When a call is made to a specific resource[^10], we need to specify an [HTTP method](#user-content-fn-11)[^11] that tells the server what kind of action we want to initiate. The five most used HTTP methods are:

<table data-header-hidden><thead><tr><th width="134"></th><th></th></tr></thead><tbody><tr><td><strong>Action</strong></td><td><strong>Description</strong></td></tr><tr><td>GET</td><td>Retrieve data</td></tr><tr><td>POST</td><td>Create data</td></tr><tr><td>PUT</td><td>Update data</td></tr><tr><td>PATCH</td><td>Replace data</td></tr><tr><td>DELETE</td><td>Delete data</td></tr></tbody></table>

\
HTTP methods are sometimes called *HTTP verbs*. Generally they are used as illustrated in the table above, but to find the correct HTTP method for the resource you want to access, check the API providers documentation.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FQX2wWdVVneNsxvrVgNsQ%2Fbubble-http-method.png?alt=media&#x26;token=9f69caf7-09b1-4a14-885f-4db189a1f6d9" alt=""><figcaption><p>Setting the HTTP method in the dropdown in red tells the external app what kind of action you want to take. GET usually means you want to return data.</p></figcaption></figure>

### **The URL and endpoint**

In our [general article on APIs](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis) we explored how a [RESTful API](#user-content-fn-12)[^12] call uses a URL to identify a specific resource.

For example, when we were looking at Bubble’s [Data API](#user-content-fn-13)[^13] (used to give external systems access to the database) and [Workflow API](#user-content-fn-14)[^14] (used to give external systems access to workflows) we looked at how Bubble generates a unique URL for each data type you choose to expose in the Data API and each API Workflow you choose to expose in the backend workflow editor.

External RESTful APIs work in the same way: you direct your Bubble application to a specific URL in order to reach the resource that you want. Together, the HTTP method and the endpoint form a unique API endpoint that defines the specific action that is being requested.

For example, a GET request to a "/users" endpoint might be used to retrieve a list of users from an API, while a POST request to the "/users" endpoint might be used to create a new user.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2F5Y49MTVcEAjDZ7RMc9pI%2Fapi-endpoint%402x.png?alt=media&#x26;token=2da6d871-c819-4d84-85d5-d52d0acf13b8" alt=""><figcaption><p>In the example above, we have found the correct endpoint to translate a text using the Google Cloud Translation API. The documentation also </p></figcaption></figure>

#### Finding the correct endpoint

The endpoint is the combination of the HTTP method and the URL (resource locator). What method to use and what the URL is differs between different API services, and you can usually find the correct endpoint by consulting the documentation of the API provider.

## Initializing a call

{% hint style="warning" %}
When you initialize a call, keep in mind that Bubble sends an actual call to the server, potentially loading and manipulating data.
{% endhint %}

{% hint style="danger" %}
The test data that you enter in the *value* field of a parameter, is visible in your app's code unless the *Private* box is ticked. You should remove any sensitive data from this field before you deploy.
{% endhint %}

When a call is set up, it needs to be initialized. This means to run the call to test it. This is a required step before the call can be used in your app, for a few reasons:

* It informs us about the **success or failure** of the call.
* It furnishes us with a response that **outlines the JSON data format**. This enables Bubble to establish the call as a data source, as it understands its organization.
  * You can also have a look at the data (structured or raw) that the server returns, to verify that it gives the expected results, and to understand its structure

When you click the *Initialize a call* button, Bubble sends the call to the server, and displays the response in a popup. If the call is unsuccessful, the API Connector will show you the relevant error message.

### Raw body text

{% hint style="info" %}
*Raw body text* is an experimental feature. Currently, it is only accessible via the API connector when the *include errors* or *include headers* checkbox is clicked.

Also, it is not available if you use a nested field in a dynamic expressions, such as `first items's raw body text`.
{% endhint %}

You can also view the raw body text returned by the server. This refers to the unprocessed information received from the API endpoint.&#x20;

Raw data provides the foundational information that can then be parsed, manipulated, or displayed as needed within your app. It forms the basis for further processing and integration within the app's actions and data sources.

<details>

<summary>Case: Setting up Google Translate in the API Connector</summary>

To have a closer look at how the API Connector works in practice, you can check out our guide on how to connect to Google Cloud to utilize the Cloud Translation API.\
\
Article: [Case: Connecting to Google Translate with the API Connector](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/the-api-connector/api-guides/google-translate)

</details>

[^1]: A resource is a specific piece of data or functionality that can be accessed through the API.\
    \
    Article section: [What are resources?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis#resource)

[^2]: An HTTP request is the technical term for the protocol that is being used in an API call.

    The HTTP protocol is used to ensure that the client and the server are communicating in the same "language" so that the call is successful.\
    \
    Article: [What is a RESTful API?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis/what-is-a-restful-api)\
    Article section: [The HTTP protocol](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis/what-is-a-restful-api#what-is-the-http-protocol)

[^3]: The HTTP method (sometimes called HTTP verb) is the instruction that tells the server what action to take. It is a part of the endpoint of every RESTful API call.\
    \
    Article: [What is a RESTful API?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis/what-is-a-restful-api)

    Article section: [The HTTP method](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis/what-is-a-restful-api#http-method)

[^4]: JSON is a lightweight data interchange format typically used in Javascript. It uses human-readable text to transmit data objects that consist of attribute–value pairs and array data types.\
    \
    It is used both in incoming API Connections and outbound API Connections (The API Connector).\
    \
    Article section: [What is the JSON format?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis/what-is-a-restful-api#what-is-the-json-format)<br>

[^5]: REST, or Representational State Transfer, is not actually a protocol, but more of a set of guidelines that define how a client and server should interact with each other.\
    \
    Article: [What is a RESTful API?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis/what-is-a-restful-api)

[^6]: Authentication is the process of identifying **who** a client is in order to determine **what** resources they should have access to.\
    \
    Article: [Authenticating with the API Connector](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/the-api-connector/authentication)

[^7]: A *call* in this context is one type of request that you send to a server. For example, one call may be used to get access to some data, while another is used to write data or start a workflow.\
    \
    You can add as many calls as you want to each API provider you set up in the API Connector.

[^8]: *Initializing* a call means to make an initial call to the server to test that it works.\
    \
    This serves two purposes: \
    1\) To verify that the call is successful\
    2\) To get the server's response so that Bubble can learn how the response is structured

[^9]: Authentication is the process of identifying **who** a client is in order to determine what resources they should be given access to.\
    \
    Article: [Authentication in the API Connector](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/broken-reference)

[^10]: A resource is a specific piece of data or a service that's made available by an API and can be accessed via a unique endpoint or URL using methods such as GET, POST, PUT, and DELETE.

[^11]: The HTTP method is sent along with an API request to instruct the server on **what** actions we want to take.\
    \
    It is part of the HTTP protocol.\
    \
    Article: [What is a RESTful API?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis/what-is-a-restful-api)\
    Article section: [The HTTP protocol](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis/what-is-a-restful-api#what-is-the-http-protocol)\
    Article section: [The HTTP method](https://manual.bubble.io/~/changes/1188/help-guides/integrations/introduction-to-apis/what-is-a-restful-api#http-method)

[^12]: REST, or Representational State Transfer, is a way to structure API Calls to make sure they are compatible with other systems using the same architecture.\
    \
    Article: [What is a RESTful API?](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/introduction-to-apis/what-is-a-restful-api)

[^13]: The Data API is Bubble's built-in API service that lets you configure your app to accept incoming connections to your app's database.\
    \
    Article: [The Data API](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/the-bubble-api/the-data-api)\
    Reference: [The Data API](https://manual.bubble.io/~/changes/1188/core-resources/api/the-bubble-api/the-data-api)

[^14]: The Workflow API is Bubble's built in service that lets you configure your app's workflows to be triggered from an external application.\
    \
    Article: [The Workflow API](https://manual.bubble.io/~/changes/1188/help-guides/integrations/api/the-bubble-api/the-workflow-api)\
    Reference: [The Workflow API](https://manual.bubble.io/~/changes/1188/core-resources/api/the-bubble-api/the-workflow-api)
