Skip to Content
Technical Articles
Author's profile photo Kirill Leventcov

Using OpenAI Models in SAP Build Apps


AI or Artificial Intelligence is an idea to teach computers to perform human tasks at a much greater speed and efficiency. What makes AI even more useful is an ability to learn, based on the provided context and material. Furthermore, AI is usually taught to respond in a human manner, often creating a feeling of conversation and familiarity.

In particular, ChatGPT has truly taken internet by storm. Released in November 2022, this OpenAI language model was able to get 1 million users in just 5 days. This is a record-breaking performance, as other popular tech products took months, sometimes even years to reach that capability.

In short, ChatGPT is a chatbot that tries to answer any given question. It has proven to shorten research time for unfamiliar topics. For instance, figuring out an answer to a common question has become a matter of asking the AI, not reading several resources.

In this blog, let’s create a Q&A application, based on OpenAI’s language models, similar to ChatGPT.



ChatGPT and AI trend lines



First, make sure to subscribe to SAP Build Apps and create a new SAP Build Apps – Web & Mobile project. I encourage you to complete a series of onboarding videos, found at the bottom of the screen. This will allow you to better understand further instructions.

Next, sign-up for a free user account at and generate a new API key by clicking your profile picture in the top right corner and choosing “View API keys” from the drop-down menu. Take note of the key, as you will need it later. Remember not to share it with others, as the following key can be used to make requests from your account.

Optionally familiarize yourself with OpenAI’s documentation to get a better understanding of the technology. In particular, Text completion is the main topic of this blog.


Building your application

Let’s start by building the foundation of the User Interface. With the use of drag and drop, put the following components to the view canvas: Title, Input field, Button, Spinner and Text. Feel free to change the title label and apply styling to the components.


User Interface


Switch over to the Variables view via a slider and open the Page Variables tab.


Page Variables configuration view


Here, we want to define all variables that we are going to use in the application. We would need three:

  1. question
    1. This variable will handle user input
    2. Variable value type should be Text
  2. answer
    1. Stores the response from the AI model
    2. Text type as well
  3. thinkingInProgress
    1. Tracks the progress of the execution
    2. Type: True/false

You can create all three by clicking the Plus icon and entering a name in the “Variable name” section on the right. Please pay attention to the variable types, whereas thinkingInProgress will require a type change to True/false.


All the required page variables

Switch back to the view canvas with the same slider and click on the Input field component. From the properties view on the right, you should notice that the Value field has no value. Here, we want to bind it to our question variable. To do so, click on the binding icon (square icon with a cross), then choose “Data and Variables”. Select “Page variable” and lastly question. Click Save to apply the binding. You should now see the following:



question page variable bound to input field’s value


Select the Text component, and with the same exact procedure, bind the “Content” property to the page variable answer. Afterward, expand the Advanced Properties drop-down to reveal the “Visible” property. Click on the binding icon (square box) and choose “Formula”. Click on the white field with a word ‘true’ to enter the formula editor. Here, erase all content and paste the following:



To finalize the visibility login, choose the Spinner component and expand the advanced properties. Bind the “Visible” property to variable thinkingInProgress. The idea here is to reverse the visibility of Text and Spinner, making the application show just the spinner when the execution is still in progress. A formula NOT() will modify a True/false variable to the exact opposite value.

Find the final result of all bindings below (Spinner on the left, Text on the right):


Final Properties Configuration


Now we approach the last and the most important step: configuring the execution logic. Choose the Button component and expand the Logic Canvas from the bottom of the screen. An image below portrays the final logic. Let’s work through each flow function separately.



Button Component logic


1 – Set page variable

This flow function will be executed first. Here, we want to set the thinkingInProgress variable to True to indicate that the execution has begun. Choose thinkingInProgress in the “Variable name” property and choose True as the “Assigned value”.

2 – HTTP request

Let’s design this flow function according to the OpenAI API Reference. We can see the following cURL POST request example available:

curl \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -d '{
  "model": "text-davinci-003",
  "prompt": "Say this is a test",
  "max_tokens": 7,
  "temperature": 0


Firstly, we can deduct that is the destination URL. Secondly, there are 2 required headers: Content-Type and Authorization, and the body of the request is a JSON object with four keys.

Begin by installing the HTTP Request flow function from the Marketplace (Relevant Documentation). Connect it to the end of the Set page variable.

For URL, put the destination URL mentioned previously. Choose POST as the HTTP method. Expand the “Optional Inputs” drop-down to reveal more settings. Open the Headers list and fill in the values in the following way, substituting <API_KEY> with the key obtained on OpenAI’s website:

  • Header 1
    • header: Content-Type
    • value: application/json
  • Header 2
    • header: Authorization
    • value: Bearer <API_KEY>

Your list should look the following way:


Headers List


Next, open the binding icon for “Request body” and choose ‘Formula’. Paste the following:

{ "model": "text-davinci-003", "prompt": pageVars.question,  "max_tokens": 250,  "temperature": 0.5 }

Here, we define 4 core values: AI model to be used (model), the question (prompt), measure of randomness (max_tokens) and originality (temperature). The following request is compatible with all GPT-3 and Codex models, so feel free to modify the model value. Use gpt-3.5-turbo for the most advanced model. The max_token value allows you to define the maximum randomness and length of a response, check out the Tokenizer tool to explore the correlation between sentence complexity and amount of tokens needed. Temperature is the measure of ‘creativity’ which takes values between 0 and 1. Finally, save the formula.

3 – Alert (Optional)

Alert is responsible for error handling. Connect it to the third output of HTTP request and bind its “Dialog title” to ‘Output value of another node’ → ‘HTTP request’ → ‘Error’ → Save. This way, you will get an error message if the API request fails.

4 – Set page variable

Connect this flow function to the first output of the HTTP request. Since this output means success, we need to indicate that the execution has concluded. To do so, simply reverse step 1 – bind thinkingInProgress to False.

5 – Set page variable

Lastly, let’s input the result of the API request to the answer variable. Bind the “Assigned value” to the following formula:

STRING(outputs["HTTP request"].resBodyParsed.choices[0].text)

You may notice that the formula editor will show a warning. This happens because the formula does not have access to HTTP requests’ result just yet, so it does not guarantee that the desired object will be available. Since we are sure of the response existing, this warning can be dismissed.


The app is now ready! We can test it by navigating to the Launch tab and opening the preview portal. Kindly find a video demonstration below:

In this blog, we have built a simple app, powered by GPT-3. With the same concept, you can now go far and beyond and create anything you put your mind to. While AI is a fast-growing field, it is still far from being even close to humans, so always be tolerant of mistakes that the language model can make.


👉 Stay tuned for more.

SAP notes that posts about potential uses of generative AI and large language models are merely the individual poster’s ideas and opinions, and do not represent SAP’s official position or future development roadmap. SAP has no legal obligation or other commitment to pursue any course of business, or develop or release any functionality, mentioned in any post or related content on this website.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Nico Wyss
      Nico Wyss

      Very well written! Thank you for this article.

      Would be interesting to see, if it also could work with the wrapper in some way: GitHub - mmabrouk/chatgpt-wrapper: API for interacting with ChatGPT using Python and from Shell.

      Author's profile photo Kirill Leventcov
      Kirill Leventcov
      Blog Post Author

      It seems like this wrapper has a library, so you can quite easily turn it into a public API with Flask. Since any API can be integrated to SAP Build Apps, it surely can work. See an example here:

      Author's profile photo Daniel Wroblewski
      Daniel Wroblewski

      Wondering use case 🤖

      Author's profile photo Raoul Shiro
      Raoul Shiro

      Excellent, easy to follow, works as a charm !


      Author's profile photo Ivan Simic
      Ivan Simic

      Great and very useful article. Tnx

      Author's profile photo Leandro Ribeiro
      Leandro Ribeiro

      A very good article!

      For me who is studying and learning SAP Build APP, articles like these are very useful ( with a clear step by step guide ) .

      I thank you for your effort.

      Interesting that it wasn't necessary to use data resources such as REST API, OData integration to integrate with the OPENAI API.

      Reading only the blog title, I thought I would have to create some kind of data resource to consume the API.

      Another very useful point are the formulas used. Do you have any tips like:

      Which formulas are essential to know? Which ones will most apps use? What is a good way to practice and learn these formulas?

      Kind regards.

      Author's profile photo Esmee Xavier
      Esmee Xavier

      Hi Leandro, thank you for the questions! The topic of formulas is indeed complex, and I wanted to let you know that we're planning some specific learning content around formulas. In the meantime, feel free to check out our docs about formulas. And let us know any feedback 😊

      Author's profile photo Mark Fogle
      Mark Fogle

      Hi Leandro,

      Regarding the use of a data entity to access the API, see this blog where I took that approach rather than using an HTTP Flow function.



      Author's profile photo Sukhpreet Dhatt
      Sukhpreet Dhatt

      This is awesome!


      Kirill Leventcov  Is there a way to potentially integrate this with MS Teams to pull specific documents?



      Author's profile photo Mauricio Predolim
      Mauricio Predolim

      Great job Kirill Leventcov !

      I´m having an issue using the API authorization. I generated the API KEY and i followed all those steps you described but i´m having this error saying i didn´t provide an API key:

          "error": {
              "message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from",
              "type": "invalid_request_error",
              "param": null,
              "code": null

      i´m using this properties into HTTP flow function:

      Mauricio Predolim

      Author's profile photo Kirill Leventcov
      Kirill Leventcov
      Blog Post Author



      You should check for extra space in the Authorization header. It can be before "Bearer" or between "Bearer" and the key. Also, make sure that you have the latest version of this flow function by installing all latest updates from the marketplace.

      Author's profile photo Mauricio Predolim
      Mauricio Predolim

      Thanks, i will try it.

      Author's profile photo Mauricio Predolim
      Mauricio Predolim

      I have found the issue...Exceed quota limit using free subscription. Now i´m using a paid subscription and it´s working like a charm!

      Mauricio Predolim

      Author's profile photo Patro Srinivasa
      Patro Srinivasa

      Hello Mauricio Predolim,

      Glad to hear that your scenario is working well. I am facing 1 issue, Can you help me here

      I am able to get AI response in "content" but unable to see in Buildapps output field. I have added formulae as per Point 5 described in above blog.

      STRING(outputs["HTTP request"].resBodyParsed.choices[0].text)



      Thanks in Advance,


      Author's profile photo Mauricio Predolim
      Mauricio Predolim

      Hi Patro,

      Have you done this step please?

      You should bind the variable to the text component in order to show the answer from chatGPT. Please revise this step and see if it works for you 🙂

      Mauricio Predolim

      Author's profile photo Patro Srinivasa
      Patro Srinivasa

      Hello Mauricio Predolim, Thanks for reply.

      Yes. I have done everything as per mentions steps in blog. Please check all bindings for input,spinner,output field controls. Here is screenshot of input,spinner and Text bindings. Can you check and suggest what I am missing!!






      Author's profile photo Patro Srinivasa
      Patro Srinivasa

      hello Kirill Leventcov,

      I have followed all the steps but while testing i am getting below error. Can you please help here!

      my payload is:

      { "model": "gpt-3.5-turbo", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"}], "prompt": pageVars.question, "max_tokens": 500, "temperature": 0.5 }


      Error message:

      "error": {
      "message": "Unrecognized request argument supplied: prompt",
      "type": "invalid_request_error",
      "param": null,
      "code": null