# How to Create a Custom Data Provider Extension for OpenBB: Complete Implementation Guide

> Learn how to create a custom data provider extension for OpenBB by implementing the Provider abstract base class and setting up your pyproject.toml. Integrate seamlessly with ExtensionLoader.

- Repository: [OpenBB/OpenBB](https://github.com/OpenBB-finance/OpenBB)
- Tags: how-to-guide
- Published: 2026-03-05

---

**To create a custom data provider extension for OpenBB, implement the `Provider` abstract base class from `openbb_core`, define an entry-point in your [`pyproject.toml`](https://github.com/OpenBB-finance/OpenBB/blob/main/pyproject.toml) under the `openbb_provider_extension` group, and install the package to enable automatic discovery by the `ExtensionLoader`.**

The OpenBB Platform enables developers to integrate proprietary or specialized data sources through its extensible provider architecture. By building a custom data provider extension for OpenBB, you can expose external APIs to the OpenBB SDK, CLI, and notebook environment with full credential management and standardized output handling. This guide walks through the complete implementation using the actual source patterns found in the `OpenBB-finance/OpenBB` repository.

## Understanding the Extension Architecture

OpenBB loads provider extensions dynamically at runtime using Python entry-points. The architecture relies on three core components that work together to discover, validate, and instantiate provider objects.

### The Provider Abstract Base Class

Every custom provider must inherit from `Provider`, defined in [`openbb_core/provider/abstract/provider.py`](https://github.com/OpenBB-finance/OpenBB/blob/main/openbb_core/provider/abstract/provider.py). This abstract class enforces a consistent interface that the platform expects, including standardized attributes for `name`, `version`, and `credentials`. When you subclass `Provider`, you implement data-fetching methods that return raw data dictionaries, which the platform later transforms into `OBBject` instances.

### The ExtensionLoader Discovery Mechanism

The `ExtensionLoader` class in [`openbb_core/app/extension_loader.py`](https://github.com/OpenBB-finance/OpenBB/blob/main/openbb_core/app/extension_loader.py) acts as a singleton that scans for installed packages at startup. It specifically looks for entry-points registered under the group `openbb_provider_extension` (accessed via `OpenBBGroups.provider.value`). The loader imports each entry point and filters for objects that are instances of `Provider`, storing them in the `provider_objects` dictionary for runtime access by the CLI and SDK.

## Scaffold the Provider Package

Create a standard Python package structure with a dedicated module for your provider implementation:

```text
my_custom_provider/
├─ my_custom_provider/
│   ├─ __init__.py
│   └─ provider.py
├─ pyproject.toml
└─ README.md

```

The [`provider.py`](https://github.com/OpenBB-finance/OpenBB/blob/main/provider.py) file will contain your concrete `Provider` subclass, while [`pyproject.toml`](https://github.com/OpenBB-finance/OpenBB/blob/main/pyproject.toml) handles the entry-point registration that makes the extension discoverable.

## Implement the Provider Subclass

Create your provider implementation by subclassing the abstract base class and defining the required attributes.

```python

# my_custom_provider/provider.py

from openbb_core.provider.abstract.provider import Provider
from typing import Any, Dict

class MyCustomProvider(Provider):
    """Example provider that fetches data from a fictional API."""

    name = "my_custom_provider"
    version = "0.1.0"
    credentials = ["MY_API_KEY"]

    def __init__(self, **kwargs: Any):
        """Initialize with credentials passed via kwargs."""
        super().__init__(**kwargs)
        self.api_key = kwargs.get("MY_API_KEY")

    def fetch(self, ticker: str, start: str, end: str) -> Dict[str, Any]:
        """Core method returning raw data for a ticker."""
        # Use self.api_key to query the external API

        return {
            "ticker": ticker,
            "prices": [],  # Your price data here

            "metadata": {"source": "my_custom_provider"},
        }

```

### Required Attributes and Methods

Every provider implementation must define:

- **`name`**: String identifier used throughout the SDK (e.g., `obb.provider.name.fetch()`)
- **`version`**: Semantic version string for documentation and compatibility tracking
- **`credentials`**: List of strings naming required environment variables or settings keys
- **`fetch()`**: Primary data retrieval method that returns a dictionary parsable into an `OBBject`

### Handling Credentials

The `credentials` list declares which API keys or tokens the provider requires. When OpenBB initializes, it checks the system settings JSON or environment variables for these values. Missing credentials trigger an error at startup, ensuring users configure access before attempting data retrieval.

## Register the Entry-Point

Declare your provider in [`pyproject.toml`](https://github.com/OpenBB-finance/OpenBB/blob/main/pyproject.toml) to enable discovery by the `ExtensionLoader`:

```toml
[project]
name = "my_custom_provider"
version = "0.1.0"
description = "A custom data provider for OpenBB"
requires-python = ">=3.9"

[project.entry-points."openbb_provider_extension"]
my_custom_provider = "my_custom_provider.provider:MyCustomProvider"

```

The key `openbb_provider_extension` must match exactly what the loader expects (`OpenBBGroups.provider.value`). This registration maps the entry-point name to the import path of your `Provider` subclass.

## Install and Verify

Install your package in editable mode for development:

```bash
pip install -e ./my_custom_provider

```

Verify the loader recognizes your provider by inspecting the `provider_objects` dictionary:

```python
from openbb_core.app.extension_loader import ExtensionLoader

loader = ExtensionLoader()
print(loader.provider_objects.keys())

# Expected: dict_keys(['my_custom_provider', ...])

```

### Configuration and Credentials

If your provider requires credentials, configure them via environment variables:

```bash
export MY_API_KEY="your-actual-key"

```

Alternatively, add them to the system settings JSON file used by OpenBB:

```json
{
  "my_custom_provider": {
    "MY_API_KEY": "your-actual-key"
  }
}

```

## Add an OBBject Accessor (Optional)

To enable pandas-like accessor syntax (`obb.my_custom_provider`), create an extension using the `Extension` class from [`openbb_core/app/model/extension.py`](https://github.com/OpenBB-finance/OpenBB/blob/main/openbb_core/app/model/extension.py):

```python

# my_custom_provider/obbject_extension.py

from openbb_core.app.model.extension import Extension

my_ext = Extension(
    name="my_custom_provider",
    description="Accessor for MyCustomProvider",
    on_command_output=False,
)

@my_ext.obbject_accessor
def my_custom_provider(obb):
    """Return provider-bound OBBject."""
    return obb.provider("my_custom_provider")

```

Register this under the `openbb_obbject_extension` entry-point group in [`pyproject.toml`](https://github.com/OpenBB-finance/OpenBB/blob/main/pyproject.toml) if you want automatic loading alongside your provider.

## Summary

- **Subclass `Provider`**: Inherit from [`openbb_core/provider/abstract/provider.py`](https://github.com/OpenBB-finance/OpenBB/blob/main/openbb_core/provider/abstract/provider.py) and implement required attributes (`name`, `version`, `credentials`) and data methods (`fetch`).
- **Define Entry-Point**: Register under `openbb_provider_extension` in [`pyproject.toml`](https://github.com/OpenBB-finance/OpenBB/blob/main/pyproject.toml) to enable discovery by `ExtensionLoader`.
- **Handle Credentials**: Declare required keys in the `credentials` list and supply values via environment variables or system settings.
- **Verify Installation**: Check `ExtensionLoader().provider_objects` to confirm your provider loads correctly at runtime.
- **Optional Accessor**: Use the `Extension` class to add pandas-like accessors for enhanced SDK usability.

## Frequently Asked Questions

### What methods must a custom OpenBB provider implement?

At minimum, you must implement the `fetch()` method to return raw data as a dictionary. You may optionally implement additional methods like `search()` depending on your data source capabilities. The `Provider` abstract base class requires `name`, `version`, and `credentials` class attributes, along with an `__init__` method that accepts credential kwargs.

### How does OpenBB discover installed provider extensions?

The `ExtensionLoader` singleton in [`openbb_core/app/extension_loader.py`](https://github.com/OpenBB-finance/OpenBB/blob/main/openbb_core/app/extension_loader.py) scans for Python entry-points under the group `openbb_provider_extension` at startup. It imports each entry point and validates that the object is an instance of the `Provider` abstract class before adding it to the `provider_objects` dictionary used by the SDK and CLI.

### Where should API credentials be stored for a custom provider?

Store credentials as environment variables matching the strings listed in your provider's `credentials` attribute, or place them in the OpenBB system settings JSON file under the provider's name key. OpenBB validates these at initialization and raises errors if required credentials are missing, preventing runtime authentication failures.

### Can a custom provider expose data through the OpenBB CLI?

Yes. Once registered and installed, your provider becomes available throughout the OpenBB ecosystem, including the CLI (`ob fetch my_custom_provider ...`), Python SDK (`obb.provider.my_custom_provider.fetch()`), and Jupyter notebooks. The standardized `Provider` interface ensures seamless integration with existing OpenBB commands and output formatting.