blog hero

May 13, 2025 18 MIN

A step-by-step guide to building custom crypto applications with OpenBB

Table of Contents:

  1. Bringing data into your application
  2. Leveraging OpenBB Widgets
  3. Ensuring consistent data styling
  4. Integrating Custom AI Agents
  5. Creating an OpenBB App

The exploding volume of financial data and the rise of AI-driven solutions have transformed expectations for financial tools, making customization and scalability essential for meeting diverse user needs.

At OpenBB, we are committed to providing developers with the resources they need to create tailored solutions that meet their unique requirements. This guide outlines how developers can leverage OpenBB’s capabilities to build advanced crypto applications using Python and FastAPI.

Minimal code examples will be provided for reference, utilizing Python and the FastAPI framework. However, developers proficient in other programming languages and frameworks can adapt the concepts to suit their preferred tools and technologies.

1. Bringing data into your application

The foundation of any robust crypto application lies in its data. OpenBB enables developers to seamlessly integrate data from various vendors into their custom backends. This allows for:

  • Mixing raw datasets or processed data to gain deeper insights.
  • Sharing dashboards across teams for collaborative workflows.
  • Utilizing AI models for enhanced decision-making.

By centralizing data sources, developers can create a powerful backend that serves as the backbone of their application.

After integrating and combining your datasets, a dashboard can look something like this:

Crypto Dashboard example built by Matt Maximo, Investor in digital assets at VanEck

Part of the dashboard built by Matt was made open source here where instructions can be found on how to get started and requires API keys from a few data vendors.

To learn more about how to integrate custom data into OpenBB,

2. Leveraging OpenBB Widgets

OpenBB Widgets are versatile containers that display your data. These widgets encapsulate:

  • Data: The core information displayed in the application.

  • Parameters: User inputs such as dropdowns or date selectors.

  • Metadata: Additional context to enhance functionality, including AI features.

Widgets allow you to control the user experience, dictating how data flows and interacts within the application. These specifications are defined through a JSON file.

For example, here’s a decorator from an endpoint that defines a widget specification:

Example of a widget spec decorator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @register_widget({ "name": "Net Liquidations", "description": "Net liquidations (long - short) across exchanges", "category": "crypto", "source": "VeloData", "endpoint": "velo/net-liquidations", "type": "chart", "data": {"chart": {"type": "line"}}, "gridData": {"w": 40, "h": 12}, "params": [ { "paramName": "coin", "value": "ETH", "label": "Coin", "show": True, "description": "Cryptocurrency to display data for", }, { "paramName": "resolution", "value": "1d", "label": "Resolution", "show": True, "description": "Time resolution for data points", "type": "endpoint", "optionsEndpoint": "velo/resolution-options", }, { "paramName": "begin", "value": "2024-01-01", "label": "Start Date", "show": True, "description": "Start date for the data", "type": "date", } ], })

While this decorator simplifies adding specifications to widgets, it is optional. Developers can also use a widgets.json file to define widget specifications.

Parameters

Parameters are the key to enabling user interaction with widgets. They allow users to modify inputs, such as tickers, dates, numbers, or dropdown selections, directly in the interface. These changes trigger backend requests to update the displayed data based on the latest input, ensuring a seamless and responsive experience.

A notable example of this flexibility arose when a customer requested support for an input form field. Once implemented, one of our team members created a widget that enables users to execute trades directly within OpenBB, attesting the true the versatility of parameters.

Let’s explore some examples of parameter configurations to better understand their capabilities:

Coin Parameter

The coin symbol parameter is a string and allows users to select a cryptocurrency, with "ETH" set as the default value.

It includes a label and description that appear when hovering over the field, providing clear guidance for users. These fields are also leveraged by AI agents to make relevant data requests for the dataset.

1 2 3 4 5 6 7 { "paramName": "coin", "value": "ETH", "label": "Coin", "show": True, "description": "Cryptocurrency to display data for", }

Resolution Dropdown

The resolution parameter uses an endpoint to dynamically fetch available options. This ensures that users can search and select valid choices while developers maintain control over the options presented.

1 2 3 4 5 6 7 8 9 { "paramName": "resolution", "value": "1d", "label": "Resolution", "show": True, "description": "Time resolution for data points", "type": "endpoint", "optionsEndpoint": "velo/resolution-options", }

Date selector

The date parameter is commonly used in financial applications where users need to specify a starting date for data retrieval. This functionality is controlled by setting the "type" field.

1 2 3 4 5 6 7 8 { "paramName": "begin", "value": "2024-01-01", "label": "Start Date", "show": True, "description": "Start date for the data", "type": "date", }

More information on parameters can be found here.

Metadata

Metadata provides additional context about the widget, including its title, description, category, and source. This information is sent to the workspace's AI agent(s), enabling it to identify the most relevant widget when responding to user queries.

For example, if a user asks, “What was the net liquidation of BTC on March 17 of this year?”, the AI agent can retrieve the correct widget and use its parameters to provide an accurate response.

This is achieved through function calling, which is explained in detail in a dedicated post available here.

If users want to explore further, they can add the referenced widget directly to their dashboard with all parameters pre-configured by checking the citation and clicking “Add widget to dashboard”:

This new widget will look like this:

Others specs

Beyond parameters and metadata, widgets include other critical specifications such as:

  • The API endpoint used to retrieve data (e.g., "velo/net-liquidations").
  • The default visualization type (e.g., chart or raw data).
  • The chart type (e.g., line chart) if using AgGrid.
  • Widget dimensions when added to a dashboard.
  • Any additional customization options required for specific use cases.

These elements ensure that widgets are not only functional but also adaptable to various workflows, allowing developers to streamline user interaction and create dynamic dashboards tailored to specific use cases.

3. Ensuring consistent data styling

A consistent and visually appealing interface is crucial for users. OpenBB supports data styling through Plotly configurations, ensuring uniformity across charts and visualizations. Think of it as your own design system for OpenBB widgets. Developers can dynamically adjust themes and implement dark and light themes.

This flexibility ensures that applications remain visually cohesive while catering to user preferences.

Plotly charts customization

OpenBB supports advanced data visualization through Plotly charts, a powerful visualization tool known for its extensive customization options.

To maintain consistency across your application, it is recommended to create a centralized Plotly configuration. This ensures that your interface retains the same branding and visual style, regardless of the workflow or functionality being executed within your app.

Example of Plotly config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 def get_layout_update(theme="dark"): """ Returns standard layout updates to apply to all charts. Parameters: theme (str): The theme to use, either "light" or "dark" Returns: dict: A dictionary of layout settings to update Plotly charts """ # Define color schemes based on theme if theme == "light": text_color = '#333333' grid_color = 'rgba(221, 221, 221, 0.3)' # Very faded grid line_color = '#AAAAAA' tick_color = '#AAAAAA' bg_color = '#ffffff' # More opaque background active_color = '#3366CC' # Nice blue color for light theme # Black text for better contrast in light mode legend_text_color = '#000000' # Darker border for better visibility legend_border_color = '#ffffff' else: # dark theme (default) text_color = '#FFFFFF' grid_color = 'rgba(51, 51, 51, 0.3)' # Very faded grid line_color = '#444444' tick_color = '#444444' bg_color = '#151518' # More opaque background active_color = '#FF8000' # Orange color for dark theme legend_text_color = text_color # Use the same text color legend_border_color = "#151518" # Use the same border color return { 'uirevision': 'constant', # Maintains view state during updates 'autosize': True, # Enables auto-sizing for responsive behavior 'dragmode': 'zoom', # Sets default mode to zoom instead of pan 'hovermode': 'closest', # Improves hover experience 'clickmode': 'event', # Makes clicking more responsive 'margin': { 't': 50, # Top margin - increase this for more modebar space 'r': 30, # Right margin 'b': 40, # Bottom margin 'l': 40, # Left margin 'pad': 4 # Padding between the plotting area and the axis lines }, 'transition': { 'duration': 50, # Small transition for smoother feel 'easing': 'cubic-in-out' # Smooth easing function }, 'modebar': { 'orientation': 'v', # Vertical orientation for modebar 'activecolor': active_color # Active button color }, 'font': { 'family': 'Arial, sans-serif', # Sans-serif font 'size': 12, 'color': text_color # Text color based on theme }, 'xaxis': { 'rangeslider': {'visible': False}, # Disable rangeslider 'autorange': True, # Enable autorange 'constrain': 'domain', # Constrain to domain for better zoom 'showgrid': True, # Show vertical grid lines 'gridcolor': grid_color, # Very faded grid lines 'linecolor': line_color, # Axis line color based on theme 'tickcolor': tick_color, # Tick color based on theme 'linewidth': 1, # Match y-axis line width 'mirror': True, # Mirror axis to match y-axis 'showline': False, # Hide the axis line to remove the box 'zeroline': False, # Hide zero line to match y-axis 'ticks': 'outside', # Place ticks outside 'tickwidth': 1 # Match y-axis tick width }, 'yaxis': { 'autorange': True, # Enable autorange 'constrain': 'domain', # Constrain to domain 'fixedrange': False, # Allow y-axis zooming 'showgrid': True, # Show horizontal grid lines 'gridcolor': grid_color, # Very faded grid lines 'linecolor': line_color, # Axis line color based on theme 'tickcolor': tick_color, # Tick color based on theme 'linewidth': 1, # Consistent line width 'mirror': True, # Mirror axis 'showline': False, # Hide the axis line to remove the box 'zeroline': False, # Hide zero line 'ticks': 'outside', # Place ticks outside 'tickwidth': 1 # Consistent tick width }, 'legend': { # Legend text color with better contrast 'font': {'color': legend_text_color}, 'bgcolor': bg_color, # More opaque background 'bordercolor': legend_border_color, # Better visible border 'borderwidth': 1 # Add border width for better visibility }, }

Example of a dashboard that utilizes that same Plotly config file

Dark and light mode

Even though dark mode has always been a favorite among our team, through conversations with our users, we discovered that some have a strong preference for light mode.

To accommodate everyone, OpenBB Workspace was designed to support both themes, allowing users to switch seamlessly with a simple Ctrl+M shortcut.

Same dashboard in light mode

To ensure a consistent visual experience across both themes, the Plotly configuration is prepared to handle dark and light modes dynamically. But how does the system know which theme to apply?

Whenever a user retrieves data through an API request, an additional theme parameter is sent, specifying whether the user is in dark or light mode. This allows the application to adjust its visual styling accordingly.

For instance, here’s an example of how theme support is implemented in a FastAPI endpoint:

Example of a FastAPI endpoint with theme support
1 2 3 4 5 6 async def get_velo_net_liquidations( coin: str = "BTC", begin: str = None, resolution: str = "1d", theme: str = "dark" # defaults to dark mode )

4. Building Custom AI Agents

Combining all your data in a comprehensive and user-friendly UI is helpful, but it's not enough.

AI agents are becoming an integral part of modern applications. With OpenBB, developers can not only leverage our out-of-the-box AI agent but also integrate tailored agents that are specialized to perform specific tasks. This includes:

  • Designing agents for distinct use cases.
  • Incorporating multiple agents into a single application for enhanced functionality.

These AI-driven features enable applications to adapt to complex scenarios and provide actionable insights.

Additional examples for building your own AI agent with OpenBB are available in our open-source repository.

A full step-by-step guide is coming soon — subscribe to our newsletter to be notified.

5. Creating an App on OpenBB

Efficiency is key when building applications, and reusable workflows play a significant role in achieving it.

Once you’ve integrated the data you need into OpenBB and refined the user interface for an optimal experience, the next step is to bring everything together into a cohesive workflow and be able to replicate it.

The recently released concept of OpenBB Apps allows you to package your dashboard and workflows into a reusable format, so you can build applications that include:

  1. Pre-configured dashboard layouts with all your data widgets organized and grouped.
  2. Pre-saved prompts that can be reused to interact with AI agents for consistent results.
  3. Integrated custom AI agents designed for specific use cases.

Building reusable layouts

Anyone with access to your App can load the exact same dashboard you’ve designed, complete with all widgets, their configurations, and even their grouping relationships.

All of this ensures that your specific workflow can be replicated seamlessly.

Creating these Apps is straightforward. Simply export a dashboard you’ve built and save it as an App. For example:

The exported app is now available for reuse via the apps.json. This approach allows you to create and manage multiple custom workflows tailored to different use cases.

You can have multiple different Apps for different use cases

Automating repetitive tasks with pre-saved prompts

An App on OpenBB is more than just a collection of widgets and their layout. It’s a combination of steps designed to help automate manual, time-consuming tasks. To achieve this, OpenBB allows users to save prompts into their Apps.

Instead of having to write the same prompts everyday, this will allow you to save time when interacting with the data on your dashboard. For instance:

By running a prompt on the data available, users can streamline complex processes and focus on deriving insights rather than performing repetitive tasks.

This feature allows users to replicate successful workflows across multiple projects, saving time and effort.

Conclusion

OpenBB provides a comprehensive framework for building powerful crypto applications that are both customizable and scalable. By integrating data, combining data visualization widgets, creating workflows, and incorporating AI agents, developers can craft solutions tailored to their needs.

Following some requests, we’re planning an upcoming workshop in which we'll guide you through building your own custom application using OpenBB’s tools. Keep an eye on our newsletter to get more details soon.

Explore the
Terminal Pro


We use cookies

This website uses cookies to meausure and improve your user experience.