> 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-sol-price.md).

# Get SOL Price

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

### Description

This endpoint retrieves the current price of SOL in USD from CoinGecko's API. The response is cached for 60 seconds to minimize API calls and improve performance.

### Authentication

Required: No

Type: None

### Request

#### Headers

#### Content-Type: application/json

No parameters required.

### Response

#### Success Response

Status Code: 200 OK

Content-Type: application/json

interface SolPriceResponse {

&#x20; price: number;  // SOL price in USD

}

Example Response:

{

&#x20; "price": 102.45

}

#### Error Response

Status Code: 500 Internal Server Error

{

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

}

### Example Usage

### // Basic fetch

### async function getSOLPrice() {

### &#x20; try {

### &#x20;   const response = await fetch('<https://api.heyhal.xyz/api/v1/coin/sol-price>');

### &#x20;  &#x20;

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

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

### &#x20;   }

### &#x20;  &#x20;

### &#x20;   const { price } = await response.json();

### &#x20;   return price;

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

### &#x20;   console.error('Error fetching SOL price:', error);

### &#x20;   throw error;

### &#x20; }

### }

### // With client-side caching

### class SOLPriceManager {

### &#x20; private cache: {

### &#x20;   price: number;

### &#x20;   timestamp: number;

### &#x20; } | null = null;

### &#x20;&#x20;

### &#x20; private readonly CACHE\_DURATION = 60000; // 60 seconds

### &#x20;&#x20;

### &#x20; async getPrice(): Promise\<number> {

### &#x20;   // Check cache

### &#x20;   if (this.cache &&&#x20;

### &#x20;       Date.now() - this.cache.timestamp < this.CACHE\_DURATION) {

### &#x20;     return this.cache.price;

### &#x20;   }

### &#x20;  &#x20;

### &#x20;   // Fetch new price

### &#x20;   const response = await fetch('<https://api.heyhal.xyz/api/v1/coin/sol-price>');

### &#x20;   const { price } = await response.json();

### &#x20;  &#x20;

### &#x20;   // Update cache

### &#x20;   this.cache = {

### &#x20;     price,

### &#x20;     timestamp: Date.now()

### &#x20;   };

### &#x20;  &#x20;

### &#x20;   return price;

### &#x20; }

### &#x20;&#x20;

### &#x20; clearCache() {

### &#x20;   this.cache = null;

### &#x20; }

### }

### Implementation Notes

1\. Caching

The endpoint uses server-side caching with a 60-second expiration

If CoinGecko API fails, returns 0 as a fallback value

Cache is automatically invalidated after expiration

Error Handling

// Example of robust error handling

async function getSOLPriceWithRetry(

&#x20; maxRetries = 3,

&#x20; retryDelay = 1000

): Promise\<number> {

&#x20; let attempts = 0;

&#x20;&#x20;

&#x20; while (attempts < maxRetries) {

&#x20;   try {

&#x20;     const response = await fetch(

&#x20;       '<https://api.heyhal.xyz/api/v1/coin/sol-price>'

&#x20;     );

&#x20;    &#x20;

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

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

&#x20;     }

&#x20;    &#x20;

&#x20;     const { price } = await response.json();

&#x20;    &#x20;

&#x20;     if (typeof price !== 'number' || isNaN(price)) {

&#x20;       throw new Error('Invalid price received');

&#x20;     }

&#x20;    &#x20;

&#x20;     return price;

&#x20;   } catch (error) {

&#x20;     attempts++;

&#x20;    &#x20;

&#x20;     if (attempts === maxRetries) {

&#x20;       throw error;

&#x20;     }

&#x20;    &#x20;

&#x20;     await new Promise(resolve =>&#x20;

&#x20;       setTimeout(resolve, retryDelay \* attempts)

&#x20;     );

&#x20;   }

&#x20; }

&#x20;&#x20;

&#x20; throw new Error('Failed to fetch SOL price');

}

3\. Price Monitoring

class SOLPriceMonitor {

&#x20; private price: number = 0;

&#x20; private listeners: ((price: number) => void)\[] = \[];

&#x20; private intervalId: NodeJS.Timeout | null = null;

&#x20;&#x20;

&#x20; constructor(private pollInterval: number = 60000) {}

&#x20;&#x20;

&#x20; addListener(callback: (price: number) => void) {

&#x20;   this.listeners.push(callback);

&#x20; }

&#x20;&#x20;

&#x20; async start() {

&#x20;   await this.updatePrice();

&#x20;  &#x20;

&#x20;   this.intervalId = setInterval(

&#x20;     () => this.updatePrice(),

&#x20;     this.pollInterval

&#x20;   );

&#x20; }

&#x20;&#x20;

&#x20; stop() {

&#x20;   if (this.intervalId) {

&#x20;     clearInterval(this.intervalId);

&#x20;     this.intervalId = null;

&#x20;   }

&#x20; }

&#x20;&#x20;

&#x20; private async updatePrice() {

&#x20;   try {

&#x20;     const response = await fetch(

&#x20;       '<https://api.heyhal.xyz/api/v1/coin/sol-price>'

&#x20;     );

&#x20;     const { price } = await response.json();

&#x20;    &#x20;

&#x20;     if (price !== this.price) {

&#x20;       this.price = price;

&#x20;       this.notifyListeners();

&#x20;     }

&#x20;   } catch (error) {

&#x20;     console.error('Error updating SOL price:', error);

&#x20;   }

&#x20; }

&#x20;&#x20;

&#x20; private notifyListeners() {

&#x20;   this.listeners.forEach(listener => listener(this.price));

&#x20; }

}

### Best Practices

1\. Price Display

function formatSOLPrice(price: number): string {

&#x20; return new Intl.NumberFormat('en-US', {

&#x20;   style: 'currency',

&#x20;   currency: 'USD',

&#x20;   minimumFractionDigits: 2,

&#x20;   maximumFractionDigits: 2

&#x20; }).format(price);

}

Price Change Tracking

interface PricePoint {

&#x20; price: number;

&#x20; timestamp: number;

}

class PriceTracker {

&#x20; private history: PricePoint\[] = \[];

&#x20; private readonly MAX\_HISTORY = 100;

&#x20;&#x20;

&#x20; addPrice(price: number) {

&#x20;   this.history.push({

&#x20;     price,

&#x20;     timestamp: Date.now()

&#x20;   });

&#x20;  &#x20;

&#x20;   if (this.history.length > this.MAX\_HISTORY) {

&#x20;     this.history.shift();

&#x20;   }

&#x20; }

&#x20;&#x20;

&#x20; getPercentageChange(timeframeMs: number): number {

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

&#x20;   const compareTime = now - timeframeMs;

&#x20;  &#x20;

&#x20;   const oldPrice = this.history.find(

&#x20;     point => point.timestamp <= compareTime

&#x20;   );

&#x20;  &#x20;

&#x20;   if (!oldPrice) return 0;

&#x20;  &#x20;

&#x20;   const currentPrice = this.history\[this.history.length - 1].price;

&#x20;   return ((currentPrice - oldPrice.price) / oldPrice.price) \* 100;

&#x20; }

}

Price Alert System

Ask

Copy

Apply to kingOfTheHil...

interface PriceAlert {

&#x20; threshold: number;

&#x20; isAbove: boolean;

&#x20; callback: (price: number) => void;

}

class SOLPriceAlerts {

&#x20; private alerts: PriceAlert\[] = \[];

&#x20; private currentPrice: number = 0;

&#x20;&#x20;

&#x20; addAlert(alert: PriceAlert) {

&#x20;   this.alerts.push(alert);

&#x20;   this.checkAlert(alert);

&#x20; }

&#x20;&#x20;

&#x20; updatePrice(newPrice: number) {

&#x20;   this.currentPrice = newPrice;

&#x20;   this.checkAlerts();

&#x20; }

&#x20;&#x20;

&#x20; private checkAlerts() {

&#x20;   this.alerts.forEach(alert => this.checkAlert(alert));

&#x20; }

&#x20;&#x20;

&#x20; private checkAlert(alert: PriceAlert) {

&#x20;   const triggered = alert.isAbove&#x20;

&#x20;     ? this.currentPrice > alert.threshold

&#x20;     : this.currentPrice < alert.threshold;

&#x20;    &#x20;

&#x20;   if (triggered) {

&#x20;     alert.callback(this.currentPrice);

&#x20;   }

&#x20; }

}

<br>
