Set up own API for end users

Hi all,

It’s amazing that we can extend our app functionality with API’s.

Is there also a way we can create our own Public Api? So users can GET and POST to it and thus connect any app with ours?

Thanks!

1 Like

Hi! :wave:

You can do it thru the Backend Workflows.

To find them, click on the top to see your app pages and, in the bottom, you will see a menu item called “Backend workflows”.

Hope it help! :grin:

1 Like

Yes, through the Bubble API…

API - Bubble Docs

1 Like

@rpetribu @adamhholmes Awesome, thanks! :smiley:

1 Like

@adamhholmes @rpetribu I believe I got the grasp of it. As for the authentication, is there a ‘secret API key’ for each individual I can create? Or is it okay if they all use the same Bearer token/API key? Thanks!

If you setup a simple backend endpoint / workflow per the below with a Login (or Signup) action within it then you’ll get a unique access key for that user within the response.

You’ll need to call this endpoint using the API Connector (rather than Schedule API Workflow) in order to get the response back with the token and expiry date inside.

Endpoint to issue token

Response when you call that endpoint from the API Connector

You can find more on it here under Authentication

7 Likes

It depends on what you are planning to do… Generally, it is best to create an “API Key” for each user and save it in their database (secured by the privacy rules). So to perform any interaction (POST/GET), your user will need to send his uniq_id along with his api_key. And, in the backend, you can check if they match :+1:

1 Like

Thanks for the reply!

If I’m not mistaken, this is what we call HTTP basic authentication?

Your users will be using HTTP Bearer authentication (or token authentication) once things are setup… that first call does work a bit like HTTP basic auth though yes.

I should have made this clearer in my previous message… you’ll only use the API workflow that I described for the initial minting of the token for your user…

So somewhere on your frontend (user’s profile / settings?) you’ll provide the option for them to request an API access token (just like in Bubble) and when they press the button you’ll call that issue_token API workflow, then capture the response token back and show it to them (and ask them to copy it), plus save it in the database.

They can then use that token to POST data to Bubble API workflows from 3rd party platforms by adding a key / value pair to the Header of the call of Key : Authorization Value: Bearer **their API access token**

Is that making sense?

3 Likes

This makes a lot of sense, thanks for the detailed answer. I believe I understand the logic/theory behind it.

The only thing I struggle with is generating the token. :confused:

So, I’ve set up a new API call in the api connector.

I use the POST method, the link is
https://myapp.bubbleapps.io/version-test/api/1.1/wf/my_workflow.
I have no authentication set up in the API connector itself. (Which gives an error message). Not sure which authentication I should use here.

In the headers of that API Call, I have the key values: 1) email field, 2) password field.

Also, when this works, does it automatically return the Token? Or do I have to set up a separate GET call? :sweat_smile:

To run this issue_token workflow you’ll use an admin token that you’ve created in Bubble. From an earlier message it looks as though you’ve already found these (Settings > API > API Tokens) and you’ll attach it as a Header to the call you’re making in the API Connector. You’ll also add two Parameters (not Headers) for email address and password. So it should look like this:

For testing purposes, use your own test account email and password.

No need to make a second call. When you Initialize the call shown above you will receive the following back:

Hit Save and then you’ll be able to access that response within your app via any subsequent step in the workflow that calls that API.

As part of your ‘Request Access Token’ UI that you give users, you’ll just ask them to confirm their password via an input field… you can get their email from your Current User object. So, on the frontend, the call will be setup like this:


One thing that I haven’t mentioned - and you can come back to this once the basics of it are all working - is that you’ll need to create a token refresh process. The positive of the token that we’re creating here is that it will outlive password changes etc., but the downer is that it will expire one year from when it is issued and no longer work. It’s not a biggie but you’ll need to think about the best way to manage that in your context.

This can simply an email to them, scheduled for 9 months from the moment the token is issued with a link to an ‘update token’ UI, which will be a repeat of the process as above.

7 Likes

Thank you very much for the help! It is working like a charm. :smiley:

the downer is that it will expire one year from when it is issued and no longer work.

My returned value says it expires after 86,400 seconds (1 day). How can I increase this number to have the same output as you do? (365 days)? :slight_smile:

EDIT: I found the solution. Apparently you have to set the ‘stay log in’ under the login flow to ‘yes’. Thanks again for all the help @edwardbutcher!

1 Like

Hi @exception-rambler, your instructions were super useful! Thanks but I’m still stuck on the final part.

For the issue_token part, this works smoothly and my user can mint his own token that will expire after one year.

Now that my user has his token, I want him to be able to create a “transaction” on my Bubble app.

I created another call as follows. The 3 parameters (account, phone, amount) are the ingredients that my user has to pass via API. As Authorization I added “Bearer”+ space + my admin token just for the sake of initialization.

I clicked initialize and got a success.

Then I created a backend WF named “create_transaction” having account, phone and amount as parameters. For the moment this just triggers an email as I’m testing the feature.


If at this point I try to reinitialize the call, the test email is sent.

I then went to postman.co and tried the call as follows

The authorization is “Bearer” + space + my user’s token

The result I got is a 400 Bad Request

    {
        "statusCode": 400,
        "body": {
            "status": "MISSING_DATA",
            "message": "Missing parameter for workflow create_transaction: parameter account"
        }
    }

It looks like “account” is missing but I do am passing it as a parameter.

I also tried to pass the Authorization in the Query Params rather that in the Header but in such a case I get a 401 Unauthorized.

Can you spot what I am doing wrong? Thank you in advance,
gl

It looks as though you’re adding these as query parameters - you can see them appended to the path URL.

On Bubble end you haven’t specified these as querystring parameters so it’s confused when it receives them. Try adding them to the Body on Postman instead (or switch your Bubble endpoint to be expecting querystrings)

1 Like

Super! It worked! Thank you very much!

I also noticed that I can set the WF to return parameters inside the response. Very useful.

{
    "status": "success",
    "response": {
        "test_response": 33
    }
}
1 Like

If the user generates more tokens, the old tokens remain usable to access the worklfow API. Surely when a user generates a new token, the previous token should be unusable. What if the token becomes compromised? Is there a way to delete tokens created by the Log-in action in a backend workflow?

1 Like

Wow! I’m finding this thread now and :exploding_head: I had no idea there was an actual way to generate API tokens for users in your Bubble app. Learning something new on the Bubble Forums everyday :blush:

2 Likes

Not sure if anyone has figured this out but I was able to get this set up for my users with a traditional login / password but most of my other users are using Google to sign in. Anyone know how that might work?

Yes did anyone locate any vids on this Yes i need a walkthrough from the very beginning.

undefined error: this header name is not correct undefined Yes what is this?