Let's continue learning Kelp!

This tutorial will lead you through easy steps for creating a Stock Quotes app. You will need a list of stocks - in this example, we'll use free API to pull a list of S&P 500 companies, but you can easily substitute it later with your own portfolio of stocks by pulling it from Google Spreadsheets, for example. You will also need to connect to a market data provider to retrieve the stock price and other indicators for your list's stocks. And you will need historical data to display on a chart. We can use IEX Cloud free tier API for that. Here goes! πŸ’ͺ

Create new app

Go to https://public.kelp.app/ and login to Kelp. Please Sign Up if you don't have an account yet. Create a new app by clicking the New app button. Remember that when the app is created, you will be switched to app Developer mode.

πŸ’‘ Tip! If it's your first experience with Kelp, we suggest reading through our Kelp 101 article to learn the Kelp basics. Also, you can refer to Kelp Glossary.

Connect the list of stocks

Right-click anywhere on the canvas to open the Components Library dialog. Lookup the HTTP component and place it on the canvas. HTTP component allows you to make requests to any RESTful API.

We will get the list of stocks from here πŸ‘‰ https://datahub.io/core/s-and-p-500-companies/. We need to provide a URL string to the url input port of the HTTP component. Again, right-click on the canvas, lookup the String component, and add it to the app schema.

πŸ’‘ Tip! The String component is a constant of type string. It will emit its contents as soon as its initialized. Constants are typically the origin of events in the Kelp app.

To set the String constant's value, open the component's settings dialog by pressing the space bar on the selected String node. Alternatively, you can paste the string anywhere on the canvas. Kelp will recognize you want to add a string and place a new String component on the canvas for you. Sweet! 😊

Use this direct link to the JSON file with the stocks list:


Next, we need a way to display the results of the HTTP request. The simplest way to see the output of any Kelp component is through the Log widget. Log widget displays anything it receives on its input as is without any changes. Look up and add the Log widget.

πŸ“– Note. Widgets in Kelp are similar to components but can render the content in their unique way. You can place them on the screen layout in the design mode and create your app's user interface.

Now connect output port of the String component to url port of the HTTP component. And response port of the HTTP component to the data port of the Log widget. You can enlarge the Log widget to see the output right on the canvas by stretching its bottom-right corner. Click the Restart button (at the top bar's right-hand side) to run the app.

Great job! We can now use the retrieved dataset to get the stock symbols. But first, let's display it on the app screen in a more user-friendly way.

Move the Log out of the way by dragging it to the side; no need to disconnect it. Add Table widget from the library and connect it to the response port of the HTTP.

If you now restart the app and open the Preview dialog of the Table widget (select the widget and click the space bar), you will see an empty table. Why? The reason is that the Table widget received the data in a format it doesn't understand. The Table expects the data as an array of objects, like this:


"Name": "3M Company",
"Sector": "Industrials",
"Symbol": "MMM"
"Name": "A.O. Smith Corp",
"Sector": "Industrials",
"Symbol": "AOS"

But HTTP component returns the data in the following format:


"data": [
"Name": "3M Company",
"Sector": "Industrials",
"Symbol": "MMM"
// ...
"Name": "Zoetis",
"Sector": "Health Care",
"Symbol": "ZTS"
"meta": {
"request": {
"url": "https://datahub.io/core/s-and-p-500-companies/r/0.json"
"response": {
"status": 200,
"statusText": "OK",
"headers": {
"content-type": "application/json",
"last-modified": "Sun, 23 Aug 2020 01:05:42 GMT"

We need to extract the value of the data property. To do that, Kelp supports Data Transformations on the connections between the component ports.

πŸ’‘ Tip! Kelp supports several query languages for data transformations. Choose the one that is more appropriate for the task. Learn more about Data Transformations and the supported query languages.

Click on the connection between the HTTP component and Table and press the space bar to open the Transformation dialog. Select KelpQL query language and enter data in the middle text area. This query will extract and pass on the value of data path from all the events passing through this connection. Let's agree that all transformations in this guide will be using KelpQL query language unless explicitly pointed otherwise.

Hit Ok. You can restart the app and open the preview dialog of the Table widget or enlarge the widget on the canvas. You should see a nicely formatted list of S&P 500 companies.

Perfect! We have a list of stocks ready; now, let's get quotes and other market data for our app.

Get Stocks Quotes from the secured data source.

We will use IEX Cloud API to get quotes and market data. IEX Cloud is a great source of essential financial data; it offers free access to a sandbox-style environment. Before you proceed, register at https://iexcloud.io/. Make sure you turn on the "Sandbox Testing" mode and grab your free API Key.

<a href=https://cdn.sanity.io/images/n16unevp/production/66ad1f6d862bb363f69d40278774a64f6abe7000-1070x728.png?w=800&fit=max"/>

To connect to a secured IEX Cloud API resource, you need to configure a Secured Connection record in your Kelp account and store your IEX Cloud publishable token. Kelp will use this record to allow only your Kelp app to connect to the IEX Cloud API and only when you're using it. No other users or apps will have access to your token.

πŸ’‘ Tip! Learn more about Kelp Security.

Quick steps to create a new Secured Connection:

  1. Go to Home > Settings > Connections page.

  2. Click the "Add Connection" button, then "Create New", and select API Key authentication scheme.

  3. Fill in the form with the following details and click on Submit.

Schema: API Key
Connection name: My IEX Cloud sandbox
Key value: <*your IEX Cloud publishable token*>
Placement: query
Param name: token
Param value: {token}

Go back to your app. Add another HTTP component with the following configuration:

  • Path parameter processing: Path parameters

  • Request method: GET

  • Leave other fields with default values.

Connect new String component to url port with the following value. This endpoint returns the results any time of the day (see Previous Day Price endpoint documentation for more details).


As you can see {symbol} is a parameter inside the URL path. This parameter will be replaced with the value that the HTTP component is expecting on its params port. We need to send to this port the symbol of the selected company in our Table widget. To test it, add a temporary JSON constant with the following value and connect it to the params port of the HTTP component:

{ "symbol": "MMM" }

Before making the request, we need to provide credentials details. Add the HTTP Credentials component and configure it to use your IEX Cloud connection you set up earlier.

πŸ“– Note. The HTTP component will not request any data if it's inactive (not connected to any widget). We did it to reduce the number of requests that your application sends outside, to maintain perfect performance. So to make the HTTP work, connect it to the Log widget in the expanded mode.

Restart the app and check the response output. If you generated IEX Cloud keys and configured the Secured Connection correctly, you should see the API's response.

Add interaction to the app.

Let’s make this app interactive - by selecting a row in the table, we will display market data for the corresponding stock.

Remove temporary JSON constant and connect Table selection output to the params port of the HTTP with the following KelpQL transformation on the connection:

{symbol: [0].Symbol}

On the other side of the HTTP, add Metric Card widget, connect its data port to the response port of the HTTP, and set the following transformation:

data |

name: 'Latest price',
value: close,
name: 'Volume',
value: volume
name: 'Open price',
value: open
name: 'Intraday high',
value: high
name: 'Intraday low',
value: low

πŸ’‘ Tip! You can check how exactly these transformations work - open Transformation dialog and toggle Capture events. Close the dialog, restart the app and open the dialog again to see how KelpQL transformation changes the flowing data. Don't forget to select any Stock in the table to activate this branch of the app.

This transformation generates metrics to display on Metric Card in the format accepted by the widget by updating the values returned by HTTP. See the Metric Card widget for more details.

Restart the app, then open the Table widget preview dialog and click on any row to select a stock. You should see the Metric Card widget updated with details.

Supplement the app with a historical chart.

Following the same pattern, we will retrieve the historical prices data for the selected stock and render it on a chart.

Let's add another HTTP component and point it to the URL of the Historical Prices endpoint:


Connect Table output to the params port with the following transformation.

{ symbol: [0].Symbol, range: '6m' }

Notice that we use 2 parameters to substitute in the URL path: symbol and range. You can play with different values of the range parameter to achieve the desired results.

You can re-use the HTTP Credentials by connecting its output to the credentials port of this HTTP component.

To add the chart, we will be using the Vega Chart widget. And for simplicity, we will specify the configuration of our chart using Vega-Lite specification. We will need the Vega-Lite Adapter component to convert the Vega-Lite spec to regular Vega spec, consumed by Vega Chart.

πŸ’‘ Tip! VEGA and its lighter version VEGA-LITE are declarative languages for creating a variety of charts and data visualizations. Learn more about VEGA at https://vega.github.io/vega/

Connect the response output of HTTP to the data input of the Vega-Lite Adapter. Don't forget to apply a transformation to the connection between them! In this case, use data as a KelpQL query to unwrap the incoming array.

Use the following Vega-Lite chart configuration to pass to the vega-lite-spec port of the Vega-Lite Adapter component as JSON constant.


"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "stock price over time",
"mark": "line",
"encoding": {
"x": {
"field": "date",
"type": "temporal"
"y": {
"field": "close",
"type": "quantitative"

You can expand the Vega chart on the canvas and restart the app to see the close price history loaded for the selected stock.

Voila! We've finished the development and now ready to create an application layout.

Design the layout.

To create the end-user view, we need to design the app's layout by arranging widgets configured on the canvas. To open the design mode, click on the Design Mode button on the development toolbar, and then click on the Widgets Panel button to open up a panel with a list of all widgets initialized in our app.

Let's start with a table. Drag the Table widget and drop it to the lattice.

Now, let's finish the layout of our app. Feel free to experiment with the widgets arrangement any way you like. For example, it can look like

When you've done, switch to user mode and test your app. Once it's ready for prime time, click the Share button at the top of the screen to share it with your team and to publish it to the world!

πŸŽ‰ Congratulations! You've built a quick app that pulls the data from two sources, visualizes it, and enables a simple interaction. Now you can go and build your own apps!

What's next?

If you need help or have any questions join our Kelp community on Slack or reach out to our support team.

Did this answer your question?