> For the complete documentation index, see [llms.txt](https://docs.heyhal.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.heyhal.xyz/api-documentation/get-ohlc-data.md).

# Get OHLC Data

**Endpoint:** <mark style="color:yellow;">`GET /api/v1/coin/ohlc`</mark>

### Description

This endpoint retrieves candlestick (OHLC) data for a specific token within an optional time range. The data is useful for creating price charts and analyzing token price movements over time.

### Authentication

Required: No

Type: None

### Request

#### Headers

#### Content-Type: application/json

#### Query Parameters

| Parameter | Type   | Required | Description                     |
| --------- | ------ | -------- | ------------------------------- |
| token     | string | Yes      | The mint address of the token   |
| from      | number | No       | Start timestamp in Unix seconds |
| to        | number | No       | End timestamp in Unix seconds   |

Example Requests:

GET /api/v1/coin/ohlc?token=ABC                         // All data for token

GET /api/v1/coin/ohlc?token=ABC\&from=1234567890        // Data from timestamp

GET /api/v1/coin/ohlc?token=ABC\&from=1234567890\&to=1234567899  // Data in range

### Response

#### Success Response

Status Code: 200 OK

Content-Type: application/json

type OHLCResponse = Array<{

&#x20; id: number;

&#x20; coinId: string;

&#x20; timestamp: Date;

&#x20; unixTimestamp: string;

&#x20; open: string;

&#x20; high: string;

&#x20; low: string;

&#x20; close: string;

&#x20; volume: string;

}>

Example Response:

\[

&#x20; {

&#x20;   "id": 1,

&#x20;   "coinId": "TokenMintAddress123",

&#x20;   "timestamp": "2024-02-20T12:00:00.000Z",

&#x20;   "unixTimestamp": "1708428000",

&#x20;   "open": "1.5",

&#x20;   "high": "1.8",

&#x20;   "low": "1.4",

&#x20;   "close": "1.6",

&#x20;   "volume": "1000000"

&#x20; },

&#x20; // ... more candles

]

#### Error Response

Status Code: 500 Internal Server Error

{

&#x20; "error": "An internal error occurred. Please try again later."

}

### Example Usage

### interface OHLCData {

### &#x20; id: number;

### &#x20; coinId: string;

### &#x20; timestamp: string;

### &#x20; unixTimestamp: string;

### &#x20; open: string;

### &#x20; high: string;

### &#x20; low: string;

### &#x20; close: string;

### &#x20; volume: string;

### }

### // Function to fetch OHLC data

### async function getOHLCData(

### &#x20; tokenMintAddress: string,&#x20;

### &#x20; fromTimestamp?: number,&#x20;

### &#x20; toTimestamp?: number

### ) {

### &#x20; try {

### &#x20;   let url = \`<https://api.heyhal.xyz/api/v1/coin/ohlc?token=${tokenMintAddress}\\`>;

### &#x20;  &#x20;

### &#x20;   if (fromTimestamp) {

### &#x20;     url += \`\&from=${fromTimestamp}\`;

### &#x20;   }

### &#x20;   if (toTimestamp) {

### &#x20;     url += \`\&to=${toTimestamp}\`;

### &#x20;   }

### &#x20;  &#x20;

### &#x20;   const response = await fetch(url);

### &#x20;  &#x20;

### &#x20;   if (!response.ok) {

### &#x20;     throw new Error(\`HTTP error! status: ${response.status}\`);

### &#x20;   }

### &#x20;  &#x20;

### &#x20;   const candles: OHLCData\[] = await response.json();

### &#x20;   return candles;

### &#x20; } catch (error) {

### &#x20;   console.error('Error fetching OHLC data:', error);

### &#x20;   throw error;

### &#x20; }

### }

### // Example usage with TradingView Lightweight Charts

### import { createChart } from 'lightweight-charts';

### async function createPriceChart(

### &#x20; containerId: string,&#x20;

### &#x20; tokenMintAddress: string

### ) {

### &#x20; const chart = createChart(containerId, {

### &#x20;   width: 800,

### &#x20;   height: 400

### &#x20; });

### &#x20;&#x20;

### &#x20; const candlestickSeries = chart.addCandlestickSeries();

### &#x20;&#x20;

### &#x20; // Get last 7 days of data

### &#x20; const toTimestamp = Math.floor(Date.now() / 1000);

### &#x20; const fromTimestamp = toTimestamp - (7 \* 24 \* 60 \* 60);

### &#x20;&#x20;

### &#x20; try {

### &#x20;   const ohlcData = await getOHLCData(

### &#x20;     tokenMintAddress,&#x20;

### &#x20;     fromTimestamp,&#x20;

### &#x20;     toTimestamp

### &#x20;   );

### &#x20;  &#x20;

### &#x20;   const formattedData = ohlcData.map(candle => ({

### &#x20;     time: parseInt(candle.unixTimestamp),

### &#x20;     open: parseFloat(candle.open),

### &#x20;     high: parseFloat(candle.high),

### &#x20;     low: parseFloat(candle.low),

### &#x20;     close: parseFloat(candle.close)

### &#x20;   }));

### &#x20;  &#x20;

### &#x20;   candlestickSeries.setData(formattedData);

### &#x20; } catch (error) {

### &#x20;   console.error('Error creating chart:', error);

### &#x20; }

### }

### Implementation Notes

Time Range Handling

If no time range is specified, returns all available data

Timestamps should be in Unix seconds format

Data is ordered by timestamp in descending order (newest first)

Data Format

All price values are returned as strings to preserve precision

Volume is denominated in the smallest token unit

Timestamps are provided in both ISO 8601 (timestamp) and Unix seconds (unixTimestamp) formats

3\. Performance Considerations

// Example of paginated data fetching

async function fetchAllOHLCData(tokenMintAddress: string) {

&#x20; const CHUNK\_SIZE = 7 \* 24 \* 60 \* 60; // 7 days in seconds

&#x20; const now = Math.floor(Date.now() / 1000);

&#x20; let currentTo = now;

&#x20; let allData: OHLCData\[] = \[];

&#x20;&#x20;

&#x20; while (true) {

&#x20;   const from = currentTo - CHUNK\_SIZE;

&#x20;   const chunk = await getOHLCData(

&#x20;     tokenMintAddress,&#x20;

&#x20;     from,&#x20;

&#x20;     currentTo

&#x20;   );

&#x20;  &#x20;

&#x20;   if (chunk.length === 0) break;

&#x20;  &#x20;

&#x20;   allData = \[...allData, ...chunk];

&#x20;   currentTo = from;

&#x20; }

&#x20;&#x20;

&#x20; return allData;

}

Data Analysis Utilities

// Calculate moving average

function calculateMA(candles: OHLCData\[], period: number) {

&#x20; return candles.map((candle, index) => {

&#x20;   if (index < period - 1) return null;

&#x20;  &#x20;

&#x20;   const sum = candles

&#x20;     .slice(index - period + 1, index + 1)

&#x20;     .reduce((acc, curr) => acc + parseFloat(curr.close), 0);

&#x20;  &#x20;

&#x20;   return sum / period;

&#x20; });

}

// Calculate daily returns

function calculateDailyReturns(candles: OHLCData\[]) {

&#x20; return candles.map((candle, index) => {

&#x20;   if (index === 0) return 0;

&#x20;  &#x20;

&#x20;   const previousClose = parseFloat(candles\[index - 1].close);

&#x20;   const currentClose = parseFloat(candle.close);

&#x20;  &#x20;

&#x20;   return ((currentClose - previousClose) / previousClose) \* 100;

&#x20; });

}

### Best Practices

Data Caching

const CACHE\_DURATION = 60000; // 1 minute

const cache = new Map\<string, {

&#x20; timestamp: number;

&#x20; data: OHLCData\[];

}>();

async function getCachedOHLCData(

&#x20; tokenMintAddress: string,&#x20;

&#x20; fromTimestamp?: number,&#x20;

&#x20; toTimestamp?: number

) {

&#x20; const cacheKey = \`${tokenMintAddress}-${fromTimestamp}-${toTimestamp}\`;

&#x20; const now = Date.now();

&#x20; const cached = cache.get(cacheKey);

&#x20;&#x20;

&#x20; if (cached && now - cached.timestamp < CACHE\_DURATION) {

&#x20;   return cached.data;

&#x20; }

&#x20;&#x20;

&#x20; const data = await getOHLCData(tokenMintAddress, fromTimestamp, toTimestamp);

&#x20; cache.set(cacheKey, { timestamp: now, data });

&#x20;&#x20;

&#x20; return data;

}

Error Handling

function validateTimestamps(from?: number, to?: number) {

&#x20; if (from && to && from > to) {

&#x20;   throw new Error('From timestamp must be less than to timestamp');

&#x20; }

&#x20;&#x20;

&#x20; if (from && from > Date.now() / 1000) {

&#x20;   throw new Error('From timestamp cannot be in the future');

&#x20; }

}

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.heyhal.xyz/api-documentation/get-ohlc-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
