# UDF adapter

## Overview

UDF (Universal Datafeed) protocol is a data format based on HTTP.
The library includes a built-in **UDF adapter**, which is a ready-to-use implementation of the [Datafeed API].

### Why use UDF

- It's the fastest way to get your data connected to the chart.
- It allows you to connect your data by implementing a simple HTTP backend that provides data in a JSON format.
- Its source code can be used as a reference for your Datafeed API implementation.

### Limitations

- The UDF adapter does not support real-time data streaming out of the box but you can implement it.
- Because the UDF adapter is built on a fixed set of HTTP endpoints, it does not offer protocol flexibility.

:::tip

For applications requiring real-time data and greater flexibility, implementing the [Datafeed API] is the recommended approach.

:::

## How to use

1. Create a server-side HTTP service that gets the data from your storage and responds to library requests.
2. Instantiate `Datafeeds.UDFCompatibleDatafeed` and pass it to the [`datafeed`] property of the [Widget Constructor].
    ```js
    // highlight-next-line
    const datafeed = new Datafeeds.UDFCompatibleDatafeed("https://demo-feed-data.tradingview.com");

    new TradingView.widget({
        container: 'tv_chart_container',
        locale: 'en',
        library_path: 'charting_library/',
        // highlight-next-line
        datafeed: datafeed,
        symbol: 'AAPL',
        interval: '1D',
    });
    ```

### Constructor

```javascript
Datafeeds.UDFCompatibleDatafeed = function(datafeedURL, updateFrequency, limitedServerResponse)
```

| Parameter | Type | Description |
|---|---|---|
| `datafeedURL` | string | The URL of your UDF-compatible data server that will receive requests and return data. |
| `updateFrequency` | number | Optional. The frequency in milliseconds at which the datafeed will send requests to the server. Default is `10000` (10 seconds). |
| `limitedServerResponse` | object | Optional. An object for configuring truncated server responses if your server has a maximum response size. The object has the following properties:maxResponseLength: (number) The maximum number of bars the server can supply in a single response. This doesn't affect or change the library behavior regarding how many bars it will request. It just allows the datafeed implementation to correctly handle this situation.expectedOrder: ("latestFirst" or "earliestFirst") Specifies whether the server sends the newest or oldest data first when the response is chunked. |

## UDF data format

A core principle of the UDF format is the "response-as-a-table" concept.
This helps keep responses compact and efficient.
For example, a response for a symbol list can be treated as a table where each symbol is a row with several columns (`min_price_move`, `description`, `has_intraday`, etc.).

To optimize the response size, if all rows in a column have the same value, that property can be sent as a single value instead of an array.
If values differ, the property should be an array with a value for each symbol.

### Example

A response for a symbol group might look like this:

```javascript
{
   symbol: ["MSFT", "AAPL", "AMZN", "GOOG"],
   min_price_move: 0.1,
   description: ["Microsoft Corporation", "Apple Inc.", "Amazon.com", "Alphabet Inc."]
}
```

Here, `min_price_move` is a single value because it's the same for all symbols, while `symbol` and `description` are arrays because their values differ for each symbol.
This response can be visualized as the following table:

| symbol | min_price_move | description |
|---|---|---|
| MSFT | 0.1 | Microsoft Corporation |
| AAPL | 0.1 | Apple Inc. |
| AMZN | 0.1 | Amazon.com |
| GOOG | 0.1 | Alphabet Inc. |

## UDF endpoints

### Configuration

This is the first request the library makes when the chart is initialized.
This method provides the library with the datafeed configuration data such as supported symbol types, exchanges, time intervals (resolution), currency codes and more.

#### Request

`GET /config`

#### Response

A JSON object with the same structure as the [`DatafeedConfiguration`] object returned by the [`onReady`] call of the Datafeed API.
Additionally, it must include two specific properties:

| Property | Type | Description |
|---|---|---|
| `supports_search` | boolean | Set to `true` if your datafeed supports symbol search and individual symbol resolution. |
| `supports_group_request` | boolean | Set to `true` if your datafeed only provides symbols in groups and cannot perform individual searches. Not recommended if your backend provides more than 100 symbols. Use `supports_search: true` instead. |

:::info

You must set either `supports_search` or `supports_group_request` to `true`.
If this endpoint is not implemented, the library will use the following default configuration.

```js
{
    supported_resolutions: ['1', '5', '15', '30', '60', '1D', '1W', '1M'],
    supports_group_request: true,
    supports_marks: false,
    supports_search: false,
    supports_timescale_marks: false,
}
```

:::

---

### Symbol group request

Provides information for an entire group of symbols at once.
Note the following:

- This endpoint is only used if your datafeed's [`/config`](#configuration) response includes `supports_group_request: true`.
- If your datafeed does not support the requested symbol group, you should return a 404 error.
- This mode **can be inefficient** if your symbol list is large, as it requires the browser to store data for many symbols that may not be used. If you have more than 100 symbols, it is highly recommended to implement the [symbol search](#symbol-search) and [resolve](#symbol-resolve) endpoints for better performance.

#### Request

`GET /symbol_info?group=<group_name>`, where `group_name` is a string representing the name of the symbol group to be fetched (e.g., `NYSE`).

#### Response

A JSON object that follows the "response-as-a-table" concept described in the [UDF data format](#udf-data-format) section.
Each property in the object represents a column, and its value can be either a single value (if it's the same for all symbols) or an array of values.

The response structure is similar, but not identical, to the [`LibrarySymbolInfo`] object. The following properties are supported:

| Property | Description |
|---|---|
| `symbol` | Symbol name. |
| `exchange_listed_name` | The name of the exchange where the symbols are listed. |
| `description` | Symbol description. See [`description`].|
| `minmovement` | The number of units that make up one tick. See [Price format]. |
| `minmovement2` | The fraction of a fraction. See [Price format]. |
| `fractional` | A boolean indicating if the price should have a complex formatting. See [Price format]. |
| `pricescale` | The number of decimal places or fractions for the price. See [Price format]. |
| `has-intraday` | A boolean indicating if intraday data is available. See [`has_intraday`]. |
| `has-daily` | A boolean indicating if daily data is available. See [`has_daily`]. |
| `has-weekly-and-monthly` | A boolean indicating if weekly and monthly data is available. See [`has_weekly_and_monthly`]. |
| `visible-plots-set` | The set of visible plots (e.g., ohlcv, ohlc, c). See [`visible_plots_set`]. |
| `type` | The type of the instrument. See [`type`]. |
| `ticker` | A unique identifier for the symbol. See [`ticker`]. |
| `timezone` | The time zone of the exchange. See [`timezone`]. |
| `session-regular` | Trading hours for the symbol. This property is mapped to [`session`]. |
| `session-holidays` | A string of non-trading holidays. See [`session_holidays`]. |
| `corrections` | A string defining session corrections. See [`corrections`]. |
| `supported-resolutions` | An array of supported resolutions. See [`supported_resolutions`]. |
| `intraday-multipliers` | An array of supported intraday resolutions. See [`intraday_multipliers`]. |
| `volume_precision` | The number of decimal places for volume. See [`volume_precision`]. |
| `has-empty-bars` | A boolean indicating if empty bars should be generated for periods of no data. See [`has_empty_bars`]. |

Example response for `GET /symbol_info?group=NYSE`:

```javascript
{
   symbol: ["AAPL", "MSFT", "SPX"],
   description: ["Apple Inc", "Microsoft corp", "S&P 500 index"],
   exchange_listed_name: ["NASDAQ", "NASDAQ", "TVC"],
   minmovement: 1,
   minmovement2: 0,
   pricescale: [1, 1, 100],
   has-intraday: true,
   type: ["stock", "stock", "index"],
   ticker: ["AAPL~0", "MSFT~0", "$SPX500"],
   timezone: "America/New_York",
   session-regular: "0900-1600",
}
```

---

### Symbol search

Provides a list of symbols that match the user's search query.
This endpoint is only used if your datafeed's [`/config`](#configuration) response includes `supports_group_request: false` and `supports_search: true`.

#### Request

`GET /search?query=<query>&type=<type>&exchange=<exchange>&limit=<limit>`

| Parameter | Type | Description |
|---|---|---|
| `query` | string | Text typed by the user in the [Symbol Search]. |
| `type` | string | The [supported symbol type] selected by the user. |
| `exchange` | string | The [supported exchange] selected by the user. |
| `limit` | number | The maximum number of symbols to return. |

Example: `GET /search?query=AA&type=stock&exchange=NYSE&limit=15`

#### Response

An array of symbol objects, where each object matches the [`SearchSymbolResultItem`] structure.

---

### Symbol resolve

Provides a list of symbols that match the user's search query.
This endpoint is only used if your datafeed's [`/config`](#configuration) response includes `supports_group_request: false` and `supports_search: true`.

#### Request

`GET /symbols?symbol=<symbol>`, where `symbol` is a string representing a symbol name or ticker.

Example: `GET /symbols?symbol=AAPL`, `GET /symbols?symbol=NYSE:MSFT`

#### Response

A JSON object with the structure of [`LibrarySymbolInfo`].

---

### Get bars

Provides historical bar data for a symbol.

#### Request

`GET /history?symbol=<ticker_name>&from=<unix_timestamp>&to=<unix_timestamp>&resolution=<resolution>&countback=<countback>`

| Parameter | Description |
|---|---|
| `symbol` | Symbol name or ticker. |
| `from` | Unix timestamp (UTC) of the leftmost required bar. |
| `to` | Unix timestamp (UTC) of the rightmost required bar (not inclusive). |
| `resolution` | A resolution string. |
| `countback` | The number of bars to return, starting with `to`. This has higher priority than `from`. If `countback` is set, `from` should be ignored. |

Example: `GET /history?symbol=BEAM~0&resolution=D&from=1386493512&to=1395133512&countback=500`

#### Response

A JSON object that follows the "response-as-a-table" concept described in the [UDF data format](#udf-data-format) section.
Each property in the object represents a column, and its value can be either a single value (if it's the same for all symbols) or an array of values.

| Property | Description |
|---|---|
| `s` | Status code: `ok`, `error`, or `no_data`. |
| `errmsg` | Error message if `s` is `error`. |
| `t` | Array of bar timestamps (Unix timestamp UTC). |
| `c` | Closing price. |
| `o` | Optional. Opening price. |
| `h` | Optional. High price. |
| `l` | Optional. Low price. |
| `v` | Optional. Volume. |
| `nextTime` | Optional. Unix timestamp of the next available bar if `s` is `no_data`. |

Consider the example below.

```javascript
{
    s: "ok",
    t: [1386493512, 1386493572, 1386493632, 1386493692],
    c: [42.1, 43.4, 44.3, 42.8],
    o: [41.0, 42.9, 43.7, 44.5],
    h: [43.0, 44.1, 44.8, 44.5],
    l: [40.4, 42.1, 42.8, 42.3],
    v: [12000, 18500, 24000, 45000]
}
```

##### How nextTime works

`nextTime` is the time of the closest available bar in the past.
Consider the following example. The current symbol is AAPL and the chart resolution is one minute.
The library requests data in the `[2015-04-03 16:00 UTC+0, 2015-04-03 19:00 UTC+0]` range.
There was no trade on 2015&#8209;04&#8209;03 due to a public holiday.
In this case, the library expects the following response from the datafeed:

```javascript
{
  s: "no_data",
  nextTime: 1428001140000 // 2 Apr 2015 18:59:00 GMT+0
}
```

##### Notes

- Bar time for daily bars should be 00:00 UTC and represent a trading day, not a day when the session starts.
- Bar time for monthly bars should be 00:00 UTC and represent the first trading day of the month.
- Prices must be numbers, not strings.
- For performance reasons, it is highly recommended to handle the `countback` parameter. Correctly handling `countback` helps avoid requests for time ranges with no data, making the `nextTime` parameter less critical.

---

### Marks on the chart

Provides [marks] that are displayed on the chart's bars. Marks can be used to indicate events like news, dividends, or other significant points in time.
This endpoint is only used if your datafeed's [`/config`](#configuration) response includes `supports_marks: true`.

#### Request

`GET /marks?symbol=<ticker_name>&from=<unix_timestamp>&to=<unix_timestamp>&resolution=<resolution>`

| Parameter | Description |
|---|---|
| `symbol` | Symbol name or ticker. |
| `from` | Unix timestamp (UTC) of the leftmost visible bar. |
| `to` | Unix timestamp (UTC) of the rightmost visible bar. |
| `resolution` | A resolution string. |

#### Response

A JSON object that follows the "response-as-a-table" concept described in the [UDF data format](#udf-data-format) section.
Each property in the object represents a column, and its value can be either a single value (if it's the same for all symbols) or an array of values.

| Property | Description |
|---|---|
| `id` | Mark ID. |
| `time` | Unix timestamp in seconds for a mark. |
| `color` | Mark color. |
| `text` | Text content for the mark. |
| `label` | Letter displayed in the mark circle. |
| `labelFontColor` | Text color for the mark. |
| `minSize` | Minimum size for the mark. |

:::info

By default, only the first character of the label string is displayed.
To display two characters, enable the [`two_character_bar_marks_labels`] featureset.

:::

---

### Time scale marks

Provides [marks] that are displayed on the time scale. Marks can be used to indicate events like news, dividends, or other significant points in time.
This endpoint is only used if your datafeed's [`/config`](#configuration) response includes `supports_marks: true`.

#### Request

`GET /timescale_marks?symbol=<ticker_name>&from=<unix_timestamp>&to=<unix_timestamp>&resolution=<resolution>`

| Parameter | Description |
|---|---|
| `symbol` | Symbol name or ticker. |
| `from` | Unix timestamp (UTC) of the leftmost visible bar. |
| `to` | Unix timestamp (UTC) of the rightmost visible bar. |
| `resolution` | A resolution string. |

#### Response

The response is a JSON array of objects with the following properties.

| Property | Description |
|---|---|
| `id` | Mark ID. |
| `color` | Mark color. |
| `label` | Letter displayed in the mark circle. |
| `time` | Unix timestamp in seconds for a mark. |
| `tooltip` | Tooltip text. |
| `shape` | Optional. The shape of the mark. See [`TimeScaleMarkShape`]. |

---

### Server time

Provides the current server time to the library.

#### Request

`GET /time`

#### Response

The response should be a numeric value representing the current server time as a Unix timestamp in seconds (without milliseconds).
Example: `1445324591`.

---

### Quotes

Provides [quote data] that is required by trading-specific UI components in [Trading Platform].

#### Request

`GET /quotes?symbols=<ticker_name_1>,<ticker_name_2>,...,<ticker_name_n>`

Example: `GET /quotes?symbols=NYSE%3AAA%2CNYSE%3AF%2CNasdaqNM%3AAAPL`

#### Response

The response is a JSON object with the following properties.

| Property | Description |
|---|---|
| `s` | Status of the request. Expected values are `ok` or `error`. |
| `errmsg` | An error message if `s` is `error`. |
| `d` | An array of [`QuoteData`] objects, one for each symbol requested. |

Example:

```json
{
    "s": "ok",
    "d": [
        {
            "s": "ok",
            "n": "NYSE:AA",
            "v": {
                "ch": 0.16,
                "chp": 0.98,
                "short_name": "AA",
                "exchange": "NYSE",
                "description": "Alcoa Inc. Common",
                "lp": 16.57,
                "ask": 16.58,
                "bid": 16.57,
                "open_price": 16.25,
                "high_price": 16.60,
                "low_price": 16.25,
                "prev_close_price": 16.41,
                "volume": 4029041
            }
        },
        {
            "s": "ok",
            "n": "NYSE:F",
            "v": {
                "ch": 0.15,
                "chp": 0.89,
                "short_name": "F",
                "exchange": "NYSE",
                "description": "Ford Motor Company",
                "lp": 17.02,
                "ask": 17.03,
                "bid": 17.02,
                "open_price": 16.74,
                "high_price": 17.08,
                "low_price": 16.74,
                "prev_close_price": 16.87,
                "volume": 7713782
            }
        }
    ]
}
```

[`corrections`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#corrections
[`datafeed`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.ChartingLibraryWidgetOptions#datafeed
[`DatafeedConfiguration`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.DatafeedConfiguration
[`description`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#description
[`has_daily`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#has_daily
[`has_empty_bars`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#has_empty_bars
[`has_intraday`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#has_intraday
[`has_weekly_and_monthly`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#has_weekly_and_monthly
[`intraday_multipliers`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#intraday_multipliers
[`LibrarySymbolInfo`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo
[`onReady`]: https://charting-library-docs.xstaging.tv/latest/connecting_data/datafeed-api/required-methods.md#onready
[`QuoteData`]: https://charting-library-docs.xstaging.tv/latest/api/modules/Datafeed#quotedata
[`SearchSymbolResultItem`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.SearchSymbolResultItem
[`session`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#session
[`session_holidays`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#session_holidays
[`supported_resolutions`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#supported_resolutions
[`ticker`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#ticker
[`TimeScaleMarkShape`]: https://charting-library-docs.xstaging.tv/latest/api/modules/Datafeed#timescalemarkshape
[`timezone`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#timezone
[`two_character_bar_marks_labels`]: https://charting-library-docs.xstaging.tv/latest/customization/Featuresets.md#two_character_bar_marks_labels
[`type`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#type
[`visible_plots_set`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#visible_plots_set
[`volume_precision`]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.LibrarySymbolInfo#volume_precision

[Datafeed API]: https://charting-library-docs.xstaging.tv/latest/connecting_data/datafeed-api.md
[marks]: https://charting-library-docs.xstaging.tv/latest/ui_elements/Marks.md
[Price format]: https://charting-library-docs.xstaging.tv/latest/connecting_data/Symbology.md#price-format
[quote data]: https://charting-library-docs.xstaging.tv/latest/trading_terminal/trading-concepts/quotes.md
[supported symbol type]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.DatafeedConfiguration#symbols_types
[supported exchange]: https://charting-library-docs.xstaging.tv/latest/api/interfaces/Charting_Library.DatafeedConfiguration#exchanges
[Symbol Search]: https://charting-library-docs.xstaging.tv/latest/ui_elements/Symbol-Search.md
[Trading Platform]: https://charting-library-docs.xstaging.tv/latest/trading_terminal.md
[Widget Constructor]: https://charting-library-docs.xstaging.tv/latest/configuration/Widget-Constructor.md

---

## Sitemap

- [All documentation pages](https://charting-library-docs.xstaging.tv/llms.txt)
- [Full page map with headings](https://charting-library-docs.xstaging.tv/docs_map.md)
