<b>Flowise offers several</b> <b>API endpoints that we can use</b> <b>to integrate our chat</b> <b>flows into custom applications</b> <b>or third party platforms. </b> <b>These APIs allow us to access and use</b> <b>our Flowwise chat flows</b> <b>from outside of Flowwise. </b> <b>But you might be</b> <b>wondering how this is different</b> <b>to the embed API.
</b> <b>We can use the embed API to</b> <b>add these little chat bubbles</b> <b>and chat windows to websites. </b> <b>Whereas the API</b> <b>endpoints allow us to access</b> <b>the chat flows from everywhere else. </b> <b>For example, we could call</b> <b>these APIs from custom code,</b> <b>which will allow us to add</b> <b>things like user authentication</b> <b>and session management.
</b> <b>Or we could also integrate these</b> <b>into workflow automation</b> <b>tools like Zapier and Make. </b> <b>Another popular use</b> <b>case is to call these APIs</b> <b>from AI chat flow platforms</b> <b>like BotPress and VoiceFlow. </b> <b>This video is slightly more technical</b> <b>than the previous videos in the series.
</b> <b>We won't write any code in this video</b> <b>and we won't be integrating</b> <b>this into any specific platform</b> <b>as there are way too many different</b> <b>options to consider. </b> <b>So instead, we will purely focus</b> <b>on how we can use these API endpoints. </b> <b>In order to test these APIs,</b> <b>I will be using a tool called Postman.
</b> <b>So if you would like to follow along</b> <b>and download and install Postman</b> <b>for your operating system. </b> <b>Let's also have a look at what we'll be</b> <b>doing in this video. </b> <b>We will start off by</b> <b>calling this chat flow</b> <b>by using the API endpoint.
</b> <b>We will also have a</b> <b>look at using that endpoint</b> <b>to override some of the</b> <b>values in this chat flow. </b> <b>And that will allow us to</b> <b>dynamically make changes</b> <b>to any chat flow using the API endpoint. </b> <b>Secondly, we will also</b> <b>have a look at calling this</b> <b>rag chat flow that will allow</b> <b>us to chat with custom data.
</b> <b>And we will also have</b> <b>a look at using the API</b> <b>to trigger the observing of this data</b> <b>as well as passing in</b> <b>files via the API endpoint. </b> <b>So let's start with a simple LLM chain. </b> <b>All this chain does is</b> <b>generate a company name</b> <b>based on a product description.
</b> <b>And this variable is called product. </b> <b>And if we look at the prompt values,</b> <b>I'm simply mapping the</b> <b>input from the user to product. </b> <b>And if we call this in the chat,</b> <b>and let's pass in</b> <b>something like balloons,</b> <b>we do get a response back.
</b> <b>Now, let's say we</b> <b>wanted to call this chat flow</b> <b>from outside of Flow-wise. </b> <b>What we could do is</b> <b>click on API endpoint,</b> <b>and here we can see a few options</b> <b>for Python, JavaScript, and Curl. </b> <b>Let's say you were</b> <b>writing a Python application</b> <b>and you would like to</b> <b>call your Flow-wise chat flow</b> <b>from Python.
</b> <b>You could simply copy this code. </b> <b>And the same thing goes for JavaScript. </b> <b>But let's say you are</b> <b>working on some Zapier</b> <b>or Voiceflow application.
</b> <b>You could simply go to the scroll tab</b> <b>to see the API</b> <b>endpoint that you need to call</b> <b>as well as the header information,</b> <b>as well as the fields</b> <b>that you need for the body. </b> <b>So what we could do is copy this URL,</b> <b>and then in Postman, click on Add,</b> <b>then paste in that URL,</b> <b>and change this from get to post. </b> <b>And we can see the</b> <b>type of request over here,</b> <b>and this is a post request.
</b> <b>Then we also have to set</b> <b>the header content type</b> <b>to application JSON. </b> <b>We can do that by going to Headers. </b> <b>Then we can create a new</b> <b>key and call it content type</b> <b>with a value of application JSON,</b> <b>and in the body, we can</b> <b>simply change this to raw,</b> <b>and we can then copy</b> <b>this value in the body</b> <b>and then paste it into this field.
</b> <b>So let's test this by clicking on Send,</b> <b>and we can see these values coming back,</b> <b>and this text field includes the response</b> <b>from our chat flow,</b> <b>which is trying to</b> <b>generate a business name. </b> <b>So let's change this</b> <b>to something like Cakes. </b> <b>Let's send this, and we are</b> <b>getting our response back.
</b> <b>So let's go back to</b> <b>Flow-wise for a second,</b> <b>and let's close this popup. </b> <b>When we go to Settings and View Messages,</b> <b>we can see that each</b> <b>time we call the API,</b> <b>a new conversation is being generated. </b> <b>Once we have a look</b> <b>at conversation chains,</b> <b>I will show you how you</b> <b>can reuse the same session ID</b> <b>to simply append messages</b> <b>to the same conversation,</b> <b>and that will allow us to simply continue</b> <b>with an existing conversation</b> <b>instead of generating new</b> <b>conversations with each API call.
</b> <b>So let's have a look at one of the most</b> <b>important properties</b> <b>on this API, and that is</b> <b>the override config property. </b> <b>Let's go back to this API popup,</b> <b>and let's check this</b> <b>Show Input Config checkbox,</b> <b>and here we can see a lot</b> <b>of additional information,</b> <b>which might seem intimidating,</b> <b>but this is actually really easy to use. </b> <b>First, we can see all</b> <b>the nodes on our canvas,</b> <b>and at the moment, we only have three,</b> <b>which is the chat</b> <b>model, the Allyl-in chain,</b> <b>as well as the prompt template.
</b> <b>We can use the override config property</b> <b>to override any of the</b> <b>properties for any of these nodes. </b> <b>So let's say as a silly example</b> <b>that we wanted to change the model</b> <b>for this chatOpenAI node dynamically,</b> <b>and at the moment, this</b> <b>model is set to GPT 3. 5 Turbo,</b> <b>but let's say that using the API,</b> <b>we want to override this value to GPT 4.
</b> <b>Now, let's go back to this popup,</b> <b>and let's see how we</b> <b>can override these values. </b> <b>First, we can add another</b> <b>property to this payload</b> <b>called override config. </b> <b>We can then add a colon,</b> <b>and then curly braces to</b> <b>specify further properties.
</b> <b>Now, let's find the</b> <b>property name for the model name. </b> <b>Let's expand this chatOpenAI node again,</b> <b>and we can see the name</b> <b>of the specific properties</b> <b>in this name column. </b> <b>Let's copy this model name property.
</b> <b>Let's add it to our payload. </b> <b>We can then specify a value with colon,</b> <b>and in quotes, let's</b> <b>pass in a value of GPT 4. </b> <b>Let's go ahead and run this.
</b> <b>We received our response,</b> <b>but how do we know that</b> <b>this was actually using GPT 4</b> <b>and not GPT 3. 5 Turbo? </b> <b>This is where an analytics tool</b> <b>like Langsmouth comes into play.
</b> <b>If you're unfamiliar with Langsmouth,</b> <b>I've already created a</b> <b>video on how to use it,</b> <b>and it is free to use. </b> <b>We can enable Langsmouth</b> <b>by going to configuration,</b> <b>then analyze chat flow,</b> <b>then under Langsmouth,</b> <b>I'm just going to select</b> <b>my Langsmouth credentials. </b> <b>Let's give it a</b> <b>project name like API demo.
</b> <b>Let's enable this. </b> <b>Let's click on save. </b> <b>Let's save the chat flow.
</b> <b>So now that we have Langsmouth enabled,</b> <b>let's run this query again. </b> <b>In Langsmouth, I can</b> <b>see this API demo project,</b> <b>and if I click on LLM chain,</b> <b>we can see the model that was used</b> <b>by clicking on this metadata tab,</b> <b>and in here, we can see that</b> <b>the model was indeed GPT 4. </b> <b>We can override some</b> <b>other properties as well.
</b> <b>For example, we can override this prompt</b> <b>template completely. </b> <b>So instead of generating a product name,</b> <b>let's say we want to</b> <b>generate a joke instead. </b> <b>So in order to override</b> <b>this prompt template value,</b> <b>we can get the property</b> <b>name by going to this popup,</b> <b>show input config, then on</b> <b>the prompt template itself,</b> <b>we can see two properties,</b> <b>the template as well</b> <b>as the template values.
</b> <b>To override the template,</b> <b>let's copy the name of this property,</b> <b>then in postman, let's pass in a template</b> <b>of tell me a joke about product,</b> <b>and product is the</b> <b>variable that we are mapping</b> <b>from the user input. </b> <b>Let's change the user</b> <b>input from cakes to dogs,</b> <b>and let's run this. </b> <b>And we can see in the response</b> <b>that we are now getting a</b> <b>joke instead of a business name.
</b> <b>We can also pass in a</b> <b>specific value for a variable</b> <b>by copying this prompt values property. </b> <b>Let's also add that</b> <b>to the override config,</b> <b>and let's change this</b> <b>one product to subject,</b> <b>and prompt values is</b> <b>actually an object as well. </b> <b>And in this object, we</b> <b>have to specify the name</b> <b>of the variable that we</b> <b>are trying to override,</b> <b>and in this example, this is subject,</b> <b>which has a value of, let's say cats.
</b> <b>And now when we run this,</b> <b>we are now receiving a joke about cats. </b> <b>So now we have completely</b> <b>overwritten both the template</b> <b>as well as the</b> <b>variable that we are using. </b> <b>Of course, you can use both variables</b> <b>by simply using both of these variables</b> <b>in this template string.
</b> <b>And we can also see that</b> <b>behavior in Langsmouth. </b> <b>And if we look at the</b> <b>prompt that we used,</b> <b>we can see that we've</b> <b>actually received two variables</b> <b>for product and subject. </b> <b>And the prompt</b> <b>template was indeed changed</b> <b>to tell me a joke about cats.
</b> <b>So you might also be</b> <b>wondering that at the moment,</b> <b>we are simply passing in a value</b> <b>to override a template and prompt values. </b> <b>But in the example where we</b> <b>have multiple prompt templates</b> <b>on the same flow, how does Flowwise know</b> <b>which template to</b> <b>override for which node? </b> <b>As an example, you might</b> <b>recall that in the series,</b> <b>we had a look at</b> <b>something called prompt chaining</b> <b>where we had multiple LLM</b> <b>chains in the same flow.
</b> <b>To change the value for a specific node</b> <b>is actually very easy. </b> <b>So let's assume we actually</b> <b>had multiple prompt templates</b> <b>on this canvas. </b> <b>So let's simply grab</b> <b>another prompt template</b> <b>and just place it randomly on the canvas.
</b> <b>Now, let's say we wanted to</b> <b>change the prompt template</b> <b>for this node only and not this one. </b> <b>We can do this very</b> <b>easily by getting the node ID</b> <b>by hovering over any node</b> <b>and then clicking on this info button. </b> <b>And this value in this yellow background</b> <b>is actually the node ID.
</b> <b>We can simply copy this node ID. </b> <b>So let's say we wanted</b> <b>to change the template</b> <b>for the specific node only. </b> <b>What we can do is</b> <b>remove this string value</b> <b>and replace it with an</b> <b>object or curly braces.
</b> <b>And now in quotes, we can</b> <b>specify the specific node</b> <b>that we'd like to change</b> <b>and then we can specify the new value. </b> <b>Like tell me a joke about subject. </b> <b>And if we wanted to, we</b> <b>could add additional nodes</b> <b>to that very same object.
</b> <b>So let's get the node ID for this node. </b> <b>Let's copy it. </b> <b>Let's add a comma.
</b> <b>It's passing the value of the node name. </b> <b>And now we could</b> <b>specify its prompt template</b> <b>and we could follow</b> <b>this exact same pattern</b> <b>for any node and for any property. </b> <b>Now let's move on to conversation chains.
</b> <b>So here I have a very</b> <b>simple conversation chain</b> <b>using the chat open AI</b> <b>model with a buffer memory node. </b> <b>So the thing about conversation chains</b> <b>is when we send messages,</b> <b>those messages will</b> <b>start a new conversation. </b> <b>And ideally within a conversation,</b> <b>we want to achieve two things.
</b> <b>We want the ability to continue with an</b> <b>existing conversation</b> <b>by appending messages</b> <b>to that conversation. </b> <b>And secondly, we want to be</b> <b>able to recall information</b> <b>from the chat history. </b> <b>So if I tell the model what my name is</b> <b>and continue the conversation days later,</b> <b>I want the model to be able</b> <b>to recall that information.
</b> <b>And at the moment, we are</b> <b>simply creating a new conversation</b> <b>for each and every API</b> <b>call, which is not ideal. </b> <b>There is something very unique</b> <b>that we can do with conversation chains</b> <b>using the API endpoint. </b> <b>Let's have a look at this.
</b> <b>Let's start by sending</b> <b>a message like hello. </b> <b>And now you will notice that with</b> <b>conversation chains,</b> <b>we actually get this</b> <b>session ID property back</b> <b>and we can use this session ID property</b> <b>to continue with an</b> <b>existing conversation. </b> <b>For example, I can now</b> <b>copy the session ID property</b> <b>along with its value</b> <b>and we can add this to</b> <b>the override config object.
</b> <b>Let's now change the message</b> <b>to something like how are you? </b> <b>And let's send this. </b> <b>We get our response back</b> <b>and you will also</b> <b>notice that the session ID</b> <b>that is being returned is</b> <b>the same as a session ID</b> <b>that we passed in over a year.
</b> <b>Now, if we go back to</b> <b>our review messages,</b> <b>we can see that conversation over a year</b> <b>with that session ID and</b> <b>looking at the messages,</b> <b>we can now see that these messages</b> <b>are indeed being appended to this list. </b> <b>So let's also send something like,</b> <b>my name is Leon, let's send this. </b> <b>Let's refresh this view messages page.
</b> <b>And indeed we can see</b> <b>those messages being appended. </b> <b>Next, let me show you a</b> <b>limitation with this conversation</b> <b>and I'll show you two possible solutions. </b> <b>Although I've told this</b> <b>model that my name is Leon,</b> <b>if I asked it what is my</b> <b>name using the same session ID,</b> <b>the model will actually tell us</b> <b>that it does not know our name.
</b> <b>And if I refresh this again,</b> <b>we can actually see this</b> <b>information is still in the chat. </b> <b>According to the</b> <b>developers from Flow-wise,</b> <b>this is currently a</b> <b>feature that is being worked on. </b> <b>And by the time you watch this video,</b> <b>this issue might be</b> <b>resolved natively within Flow-wise.
</b> <b>But thankfully there</b> <b>are two very easy ways</b> <b>to work around this limitation. </b> <b>The first option is to</b> <b>simply add a new property</b> <b>to your payload called history. </b> <b>And history is an array of values</b> <b>and each value will</b> <b>either represent a response</b> <b>from the AI or a user message.
</b> <b>So it's basically mimicking</b> <b>this list of messages over here. </b> <b>So this means we could add an object</b> <b>and these objects have two properties,</b> <b>the message, which is my name is Leon. </b> <b>And secondly is the type of message.
</b> <b>And this will be the user message. </b> <b>For the AI messages, we</b> <b>could simply add another object. </b> <b>We have to specify the</b> <b>message property for this</b> <b>with a message like, "Hi</b> <b>Leon, nice to meet you.
"</b> <b>And this type is the API message,</b> <b>which was the response from the model. </b> <b>And one very important thing to note</b> <b>is that the messages</b> <b>contained in this history property</b> <b>will not be appended to</b> <b>the final conversation. </b> <b>This is simply used as</b> <b>context for the AI model.
</b> <b>So if I now send this, the</b> <b>model is able to recall our name. </b> <b>But don't worry though,</b> <b>I am going to show you a super simple way</b> <b>of dealing with the</b> <b>chat history in a minute. </b> <b>So you might be wondering how on earth</b> <b>you will be able to</b> <b>fetch this chat history</b> <b>from your own applications</b> <b>in order to build up this history array.
</b> <b>Thankfully, that is really simple to do. </b> <b>Let's create a new session in Postman</b> <b>and then paste in the following URL. </b> <b>So first it needs to</b> <b>start with your server.
</b> <b>And by the way, I am running a local</b> <b>instance of Flow-wise</b> <b>for this demo, but in a</b> <b>production application</b> <b>where you need to access Flow-wise</b> <b>from something like Voice Flow,</b> <b>you need to use an instance of Flow-wise</b> <b>that is available in the cloud. </b> <b>So simply paste in your server details,</b> <b>then slash API V1 chat message slash,</b> <b>and then your workflow ID is something</b> <b>that you can copy from</b> <b>this prediction URL like so,</b> <b>and let's paste it in here. </b> <b>Now in order to fetch the messages</b> <b>for a specific session ID,</b> <b>we need to specify a key</b> <b>called session ID with a value.
</b> <b>And for the value we need</b> <b>to pass in the session ID. </b> <b>I'll simply copy it</b> <b>from this previous payload</b> <b>and let's paste it in</b> <b>here without this quote. </b> <b>Now when I run this, we</b> <b>can see in the response</b> <b>all of the messages</b> <b>related to that session ID.
</b> <b>And this contains everything we need</b> <b>to build up that array, like the role</b> <b>as well as this content property. </b> <b>But I'm actually going to</b> <b>show you the easiest way</b> <b>to deal with chat history. </b> <b>So I'm going to remove</b> <b>this history array completely</b> <b>and back in Flow-wise,</b> <b>let's actually remove</b> <b>this buffer memory node</b> <b>and let's go down to memory</b> <b>and let's grab this up stash</b> <b>Redis backed chat memory node</b> <b>and let's connect this to our chain</b> <b>and let's select our credentials.
</b> <b>If you're new to this,</b> <b>I've already created a</b> <b>video on using this up stash</b> <b>Redis backed chat memory</b> <b>node and this is free to use. </b> <b>And I highly recommend</b> <b>going with a solution like this</b> <b>for your production solutions. </b> <b>If I go back to up stash</b> <b>and if I click on data browser,</b> <b>we can see that this</b> <b>database is clean at the moment.
</b> <b>So let's go back to postman</b> <b>and let's start a new conversation. </b> <b>I'm actually going to</b> <b>delete the session ID</b> <b>and let's change this message to hello. </b> <b>It's send this and we</b> <b>can now see in the response</b> <b>that we are using this up stash</b> <b>for Redis backed chat memory node</b> <b>and let's copy the session ID property</b> <b>as I do want to</b> <b>continue with this conversation</b> <b>going forward.
</b> <b>Also, if I refresh up stash,</b> <b>I can see this entry for our conversation</b> <b>and this is the same</b> <b>value as our session ID</b> <b>as well as the two messages. </b> <b>So the AI message and our human message. </b> <b>And this is also in sync</b> <b>with our view messages over here</b> <b>where we can see our session ID as well</b> <b>as our two messages.
</b> <b>The big benefit of this</b> <b>is that we no longer have</b> <b>to pass the history node as Flow-wise</b> <b>will automatically fetch</b> <b>the chat history from Redis</b> <b>and inject that into the conversation. </b> <b>Let me prove that to you. </b> <b>Let's say my name is</b> <b>Leon and now let's ask it,</b> <b>what is my name?
</b> <b>And indeed we do get our response back. </b> <b>But this time this was way easier to use. </b> <b>And if we refresh up stash,</b> <b>we can see that there</b> <b>were new entries added</b> <b>to this database as well.
</b> <b>Next, let's have a look</b> <b>at how we can interact</b> <b>with a rag chat flow. </b> <b>The API allows us to do a couple</b> <b>of very interesting things with rag. </b> <b>First, we can chat with our</b> <b>data using the API endpoint,</b> <b>but we can also use the</b> <b>endpoint to absurd data</b> <b>to the vector database.
</b> <b>In this flow, we are using pinecone. </b> <b>And if I go back to the pinecone console,</b> <b>we can see that this</b> <b>index is empty at the moment. </b> <b>We will also have a look</b> <b>at replacing the web scraper</b> <b>with a text file</b> <b>uploader so that I can show you</b> <b>how you can upload files</b> <b>using the API endpoint as well.
</b> <b>But first, this video was a</b> <b>lot of effort to put together</b> <b>and I will greatly</b> <b>appreciate your support. </b> <b>Hit the like button and</b> <b>please subscribe to my channel</b> <b>to support my work. </b> <b>Let's start with the basics.
</b> <b>Let's scrape information from this Lang</b> <b>chain documentation. </b> <b>And this URL is simply this page</b> <b>in the Lang chain documentation. </b> <b>We will have a look at</b> <b>upserting this using the API</b> <b>in a second, but let's upload it using</b> <b>this button for now.
</b> <b>We get this message saying</b> <b>that the upset was successful</b> <b>and back in our pinecone</b> <b>index, we can see one new entry</b> <b>containing the content for that page. </b> <b>Now let's query our data using Postman. </b> <b>First, I'm going to</b> <b>remove override config.
</b> <b>We will get back to that in a second. </b> <b>And let's also replace this session ID</b> <b>with a session ID for this RAG chat flow. </b> <b>So I'm just going to copy this value</b> <b>and then replace this</b> <b>with our RAG chat flow ID.
</b> <b>Let's also change this</b> <b>question to what is Lang chain? </b> <b>Let's run this. </b> <b>And we are getting the</b> <b>correct response back.
</b> <b>Great, so we are able to query our data. </b> <b>But now let's have a</b> <b>look at using the API</b> <b>to run the upsert as well. </b> <b>I'm actually going to clear pinecone</b> <b>so that we start with no</b> <b>data, then back in flow wise,</b> <b>let's click on upsert again.
</b> <b>And this time let's check show API. </b> <b>Let's click on curl</b> <b>and let's copy this URL. </b> <b>In Postman, I'm actually</b> <b>going to create a new tab.
</b> <b>It's placed in that API. </b> <b>Let's change the type</b> <b>to post in the headers. </b> <b>Let's add the content type property</b> <b>with a value of application JSON.
</b> <b>Then in the body,</b> <b>let's change this to raw. </b> <b>And actually for now,</b> <b>we don't have to enter</b> <b>anything in the body. </b> <b>Let's simply click send.
</b> <b>We get this response</b> <b>saying successfully upserted. </b> <b>And in the pinecone</b> <b>database, we can refresh this</b> <b>and we can see that the</b> <b>data was indeed upserted. </b> <b>Now let's take this one step further</b> <b>and let's add our data</b> <b>to a specific namespace.
</b> <b>Adding data to specific namespaces</b> <b>can be extremely important</b> <b>for real world applications. </b> <b>A practical example is an application</b> <b>that has multiple users. </b> <b>And let's say that users need to</b> <b>authenticate themselves</b> <b>in order to chat to your chat flows.
</b> <b>After authenticating, users</b> <b>might want to upload documents</b> <b>to their knowledge spaces. </b> <b>And when they ask</b> <b>questions about the data,</b> <b>only data that belong</b> <b>to them should be query. </b> <b>So you could create a namespace</b> <b>for each user in your system</b> <b>and then run your prediction</b> <b>against that specific namespace only.
</b> <b>Let's have a look at that. </b> <b>Again, I'm going to delete this data</b> <b>just so that we have a</b> <b>clean database again. </b> <b>Now, when we do the upsert,</b> <b>I'm going to add something to the body.
</b> <b>In here, let's add the</b> <b>override config property,</b> <b>which is an object. </b> <b>And when we switch</b> <b>back over to flow wise,</b> <b>we can see which properties we can set. </b> <b>On this pinecone node,</b> <b>we can set the</b> <b>pinecone index dynamically,</b> <b>the pinecone namespace, et cetera.
</b> <b>What I want to change is</b> <b>the pinecone namespace. </b> <b>So I'm going to copy this value,</b> <b>then back in Postman, let's add this</b> <b>value as a property. </b> <b>And then we can specify any value</b> <b>for the namespace that we want.
</b> <b>This could be something</b> <b>like the user's unique ID</b> <b>or email address,</b> <b>like Leon-data as an example. </b> <b>This could be anything you want. </b> <b>Now let's run this upsert.
</b> <b>Let's go back to pinecone. </b> <b>Let's refresh this. </b> <b>And we can see that</b> <b>the entry was created.
</b> <b>However, when we click on namespaces,</b> <b>we can now see a namespace for Leon data. </b> <b>Also back in this browser,</b> <b>we can filter by namespace. </b> <b>At the moment, we only have one,</b> <b>and we can see the data</b> <b>belonging to this namespace only.
</b> <b>And if we go back to Postman,</b> <b>and let's go back to the prediction API,</b> <b>if I now ask this question as is,</b> <b>we actually won't</b> <b>receive the correct answer. </b> <b>And indeed we get this response back</b> <b>saying, I'm not sure. </b> <b>And that is because we are</b> <b>not specifying the namespace</b> <b>for which this query</b> <b>should be run against.
</b> <b>So let's add the</b> <b>override config property. </b> <b>And let's also specify the</b> <b>pinecone namespace property,</b> <b>which is Leon data. </b> <b>Now watch what happens</b> <b>when we run this query again.
</b> <b>This time we do</b> <b>receive the correct response. </b> <b>And this is a</b> <b>fantastic way to isolate data</b> <b>to specific sessions or users. </b> <b>Of course, we can also</b> <b>use the override property</b> <b>to override the URL</b> <b>that we are scraping from.
</b> <b>So we can see that</b> <b>property by going to curl,</b> <b>then clicking on show input config. </b> <b>Here we can click on Cheerio web scraper,</b> <b>and this property is simply called URL. </b> <b>So what you could do in the absurd API</b> <b>is to simply add this URL property,</b> <b>and then we can provide</b> <b>a different URL endpoint</b> <b>to scrape from.
</b> <b>But let's move on to the final example. </b> <b>Let's replace this web scraper</b> <b>with a text file uploader, like so. </b> <b>This is a very simple example,</b> <b>and I'm simply going to upload a file</b> <b>that says that Leon</b> <b>lives in South Africa.
</b> <b>That's really it. </b> <b>But of course you can use PDF files</b> <b>and way more</b> <b>complicated data if you want. </b> <b>So let's save this chat flow</b> <b>and let's clear this pinecone index.
</b> <b>And let's have a look</b> <b>at how we can pass files</b> <b>to this API for the upsell. </b> <b>So back in Postman,</b> <b>we need to change a few</b> <b>things when dealing with files. </b> <b>When dealing with files,</b> <b>we need to change the</b> <b>content type to form data.
</b> <b>In Postman, that's quite easy. </b> <b>We can simply click on</b> <b>this form data radio button. </b> <b>But if you are using</b> <b>this API programmatically,</b> <b>you can set the content type to</b> <b>multi-part slash form data.
</b> <b>In the body, we need to pass in a</b> <b>property called files,</b> <b>and I'll simply change</b> <b>it from text to file. </b> <b>And now we can select a</b> <b>file from our local machine. </b> <b>We can still specify</b> <b>the pinecone namespace</b> <b>by adding pinecone namespace,</b> <b>and let's call it Leon data again.
</b> <b>Of course, this namespace is optional. </b> <b>And if you do remove it from the upsell,</b> <b>then just remember to</b> <b>remove it from the query as well. </b> <b>Let's test this by clicking on send.
</b> <b>This is saying the upsell was successful. </b> <b>And if we refresh pinecone,</b> <b>we can see this data was indeed loaded. </b> <b>So in our predict method, let's say,</b> <b>where does Leon live?
</b> <b>It's send this and we</b> <b>do get our response back. </b> <b>As a bonus,</b> <b>I do want to show you a few</b> <b>more very important features</b> <b>about APIs. </b> <b>We are able to secure</b> <b>these APIs using an API key,</b> <b>and we can also prevent</b> <b>people from abusing the APIs</b> <b>by setting a rate limit.
</b> <b>We can do that by</b> <b>clicking on API endpoint,</b> <b>then under curl to selecting an API key. </b> <b>At the moment, we only have one,</b> <b>and that is this default key,</b> <b>and we can also add a new API key. </b> <b>Alternatively, we can go</b> <b>back to the Flow Wise dashboard.
</b> <b>We can go to API keys. </b> <b>Here we can see that default key,</b> <b>or we can generate a new API key. </b> <b>Let's give it a name.
</b> <b>I'll call mine YouTube,</b> <b>and we can then copy</b> <b>or view that API key. </b> <b>So let's go back to that chat flow. </b> <b>Let's go to API endpoints.
</b> <b>Let's click on curl. </b> <b>This changes from no</b> <b>authorization to YouTube,</b> <b>and let's save this chat flow. </b> <b>Now watch what happens</b> <b>when I call this prediction</b> <b>endpoint again.
</b> <b>Now it's responding with a</b> <b>message saying unauthorized. </b> <b>Now in order to</b> <b>authorize our applications</b> <b>to call these endpoints,</b> <b>we can actually see an</b> <b>example of how to use this. </b> <b>In this example payload,</b> <b>and in header, we now need to set an</b> <b>authorization property.
</b> <b>So let's do this. </b> <b>Under headers, let's add authorization,</b> <b>and we can simply copy this bearer token</b> <b>as well as the API key. </b> <b>So it's everything from</b> <b>bearer up until that final quote,</b> <b>and we can paste that value in here.
</b> <b>And now when we call this endpoint,</b> <b>we now get our response back. </b> <b>So this is perfect for</b> <b>protecting our API routes. </b> <b>We can also set write</b> <b>limiting by closing this popup.
</b> <b>Let's go to settings, configuration,</b> <b>and under this write limiting tab,</b> <b>we can set how many</b> <b>messages should be allowed</b> <b>within a given timeframe. </b> <b>For instance, 200</b> <b>messages for every 60 seconds. </b> <b>So 200 messages per minute.
</b> <b>If a limit is reached,</b> <b>we can also set the</b> <b>message that will be displayed</b> <b>back to the user, like slow down,</b> <b>try again in a minute. </b> <b>Just to demonstrate this,</b> <b>let's change the message</b> <b>limit to one message per minute. </b> <b>Let's save this, and in</b> <b>postman, let's execute this.
</b> <b>Let's immediately run it again,</b> <b>and we can see that message coming back. </b> <b>If you enjoyed this video,</b> <b>then you might enjoy this</b> <b>other Flow-wise API video,</b> <b>where we have a look at building a web UI</b> <b>for interacting with</b> <b>the Flow-wise chatbots.