Help with Freshbooks API?

I’m trying to figure out this api… Can anyone help?

I’ve got steps 1-4 to work great. I just can’t figure out how to send step 5?? Should I be using “OAuth2 user-agent flow” or “OAuth2 Custom Token”? I’ve been banging my head against the wall for hours…

I was thinking it was a user agent one, but no. This is not a standard process and I don’t think you can use the authentication available in Bubble. I think you may follow a process I’ve suggested for another API.
The step 5 will be a normal API call.

  1. You have the authorization link on one of your page, they follow step 2 and 3.
    (step 4)You create an empty page that will only have a workflow On page load, Update current user: Get parameters from page URL code
    After that, you call the API endpoint with requested information and current user code. to be able to make other API call. with bearer token.
1 Like

Thank you!!! This moves me in the right direction. So, one follow-up question:

On the black code-pane on this page, it shows 3 different ways to make that call (step 5)… Which should I use??

I’m assuming it’s the bottom one… IF it’s the bottom one, where does the "res = " section go in Bubble editor?


Thank you

No. This is to use with a library. You cannot follow this. What you need to check if more the CURL stuff or just the requested parameters/json.
According to curl:
curl -X POST -H “Api-Version: alpha” -H “Content-Type: application/json” -d '{
“grant_type”: “authorization_code”,
“client_secret”: “”,
“code”: “”,
“client_id”: “”,
“redirect_uri”: “https://localhost:3000/just_an_example

So actually, you correctly set everything correct but you cannot make the authorization code private because you will need to use it in flows.

Also add the content type header (Content-Type: application/json)

I’ve checked the doc again you sent. And I see what you mean for three different kind of request. The request part is ok for the url, header and payload. If you copy that in Bubble, you should be good :wink:
So just uncheck private for the authorization code and add header

Hmmm – anything I’m forgetting?

I’m getting this error:


With this in Bubble:


Change the redirect url for the one you have set in freshbook and use to authorize/get code
And change all ’ for "

1 Like

This is regular old oauth, but these are a PITA to build. (Entirely possible though.)

I built an integration exactly like this for Lodgable’s API.

I could maybe do a video about how you do this token handshake in Bubble if there are others who would also find it useful.

That did it!! Thank you!!!

1 Like

This is not exactly an old oauth but not a standard oauth2 too. A kind of mix of both.

ALSO, after you get that first set of tokens, now you have to manage them yourself. There’s just a bunch of little tricks to this that are very hard to figure out the first time you go through it.

(And afterward you will not be excited to do it again…) :stuck_out_tongue_winking_eye:


“Regular old” is a Western American idiom meaning “not unusual.”

I’m saying this way of granting access to an app to perform API actions as and on behalf of a user of one’s app is entirely standard and very common.

But I just hate hate hate this scenario. Total pain to deal with and only gets more complex when you go to USE the API calls that you now have access to.

(Because 1, you’re almost always going to use these in the ABSENCE of the user. So every time you have an API workflow that calls that external API, you first have to do the token hokey pokey (check validity of token, refresh if expired) and THEN proceed to make your call. It’s just super annoying.)


BTW, as I reread this, I’m reminded of a clarification I should make about API authentication schemes like this:

Typically, you only need this if you must execute API calls when the user is not present. Think about whether you need to do this at all.

Because, if you don’t need to do arbitrary scheduled API workflows on behalf of the user when not preent, you could instead just have them log in to freshbooks (or whatever API provider) when they are in your app.

There is usually a single-user API with stuff like this and these are much easier to setup and manage in Bubble.