System hard limits
System hard limits
When creating plugins for Bubble, it's important to be mindful of Bubble's hard system limits. These constraints for plugin development mirror those present in general Bubble development. See the Hard Limits article for more detail.
API calls are a way to get data from external services or trigger actions on the service's end (send a message, charge a card, etc.). Usually (but not always), the first type of calls are GET requests, while the second type are POST. A call usually requires some authentication so the service can identify who's calling it (and may charge per call, etc.). You add calls in the API Tab of the Plugin Editor, where you'll define how the calls are authenticated and which calls are used as data sources or actions.
Note: If an API call takes longer than 150 seconds to complete, Bubble will automatically retry it. This is relevant if you're handling actions like sending emails where it may take more than 150 seconds to receive confirmation back from the service. This may result in additional emails being sent if confirmation hasn't been processed.
You can see an example of the implementation of an iTunes API call in the plugin editor.
Implementing API connections can be different based on the API. While most APIs follow a few standards, if you hit some issues, we recommend reaching out to the API provider and asking for help on the forum.
Authentication
Designing the calls starts with the authentication method, which will sign the calls in run-mode. Authentication can be done in several standard ways. Note that whenever you're building an API connection with some keys, you'll need to enter actual keys to test. These keys are only saved to help you work on your plugin — they'll never be sent to users who use your plugin. Instead, they'll have to enter their own API keys in the Plugins tab of the editor.
No authentication
Nothing is added to the call, or you're handling authentication with custom parameters and handlers. Note that we don't recommend handling authentication yourself — use Bubble's built-in authentication system instead for a more secure connection.
Private key in URL
A key is added in the URL. The key name can be modified in the editor.
Private key in header
A key is added in the headers of all requests. It works similarly to the private key in URL option. Often, the header will look like Authorization: KEY, but you can customize the name Authorization if needed.
HTTP Basic Auth
A username and password will be sent with each request, following the HTTP Basic Auth protocol.
Oauth2 Password Flow
A password and username are used to get a token that can expire and is renewed automatically by your app. The token is returned when calling an endpoint that you'll need to fill in the Editor. You can find this endpoint in the API documentation — search for 'token' or 'OAuth Bearer token'.
Oauth2 Custom Token
This flow is similar to the Password flow, but lets you define the call that returns the token yourself, in case it doesn't follow the standard approach above. The token will be added to calls as a Bearer Token and automatically renewed when necessary. Note that for this to function, the token should be returned as an object with at least two keys: access_token and expires_in.
Oauth2 User-Agent Flow
This flow is the way most services connect when you use the API on behalf of the user (Facebook, Pinterest, Google, etc.). It lets you access users' data when using the API, like a profile name for Facebook. Setting up such a service involves a few steps, as you'll need to authenticate with your own account to make authenticated calls in edit mode and initialize calls.
You usually start by setting up an 'app' with the service you want to authenticate with. The service will then provide a Client ID and a Secret that your app uses to communicate with it.
You first need to fill in the information and endpoints needed to get the token and the user ID. All this information will be in the API documentation. When reading such documentation, we recommend looking for the web/HTTP section rather than the SDK section.
Scope: each Oauth2 provider will require you to enter a scope that defines the level of permissions you're asking for from your users — it can be readonly, write, send-messages, etc.
Login Dialog redirect: the URL that takes the user to the service to authorize your app (and maybe log in first). It often looks like https://www.facebook.com/v2.8/dialog/oauth.
Access token endpoint: the URL used server-side to exchange a temporary code for an access token. For Facebook, this is https://graph.facebook.com/v2.8/oauth/access_token.
User profile endpoint: the URL you use, once authenticated, to retrieve the current user's profile. This includes an ID and usually an email. For Facebook, this URL is https://graph.facebook.com/v2.7/me (the 'me' is a common pattern). In some cases, if the ID isn't returned at the top level of the response, or has a different key than 'id', you can overwrite this in the two settings under the endpoint box.
Here is what authentication for Spotify looks like:
In the case of Oauth2 User-Agent Flow, you'll need to authenticate yourself with your own personal account to initialize the calls. A button will prompt you to go through the flow and save the token once you've completed the process. Your personal identity and credentials with the service will not be shared with users who use your plugin.
JSON Web Token
Some services use this more advanced protocol (see jwt.io) to handle scope and permissions. This is usually for enterprise-type services like Box or Google Cloud. To authenticate, you'll need to enter the scope, the email used to set up the service account, and the endpoint that returns the token. You'll also need to enter the private RSA key provided by the service. The key should be formatted as follows, including the BEGIN and END markers:
-----BEGIN RSA PRIVATE KEY----- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ................................................................ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -----END RSA PRIVATE KEY-----
Shared Headers
If you need to add shared headers to all calls, including authentication ones, you can define them here. The values you set can be 'hidden' or 'secret'. Hidden settings are hardcoded by you as the plugin builder — plugin users won't fill them in. This is most often used for technical headers like content-type. Secret settings will prompt your plugin users to enter a key in the Plugins Tab.
Defining the call endpoint
Once you've entered authentication information, you can start setting up your calls. Begin by defining the request method, copying the endpoint URL, and defining the parameters the user will need to fill in. Note that if you wrap part of the URL in [ and ], that value becomes a parameter.
Parameters can be of several types: public, hidden, or secret.
Public parameters will be modified by the user at the call level — for instance, a search term for a query API call.
Hidden parameters are for the plugin builder and won't be exposed to users. For instance, an encoding type.
Secret parameters are good for keys and similar values. Users will enter these in the Plugins Tab of the editor.
Once a call is defined, you need to initialize it to make it usable in Bubble. An API call can return five different types of data.
JSON
This is the most typical case for a REST API — it returns an object with keys and values. If you pick this type, you'll be prompted to assign a data type to each key in a popup after initializing the call. When you initialize a call, Bubble makes the actual request and analyzes the returned data.
XML
Some APIs return their response as XML. Often, this can be converted into a JSON object. If you're dealing with such an API, you can use XML and get data as a JSON object, going through the same flow described above. Note that not all XML responses can be converted to JSON — if Bubble fails to do so, an error message will be displayed.
Image
Some APIs return a raw image as the response. It can be a URL you use in an tag, for instance. In this case, the API call in Bubble will return an image that can be used in an Image element or as a page background.
Text, Number
If the API returns a string or number (without structuring it as a JSON object), pick this option.
Note that changing types once an API is public can be non-backwards compatible, so do this with caution and document it as a breaking change when you publish your plugin.
Date Range, Number Range
While these are Bubble data types, we don't support them for the API Connector. If you want to use the API Connector for date ranges or number ranges, a workaround is to send dates or numbers as two separate fields, or as a two-item list, and format them as ranges elsewhere in your app. If you want to use the API Connector to query range data from another Bubble app, we suggest using the App Connector instead.
