API Documentation

Use DrawdownAlerts data in your apps and spreadsheets

Choose the data you'd like to access

Select which endpoint you need:

API Setup

1

Get Your API Key

Both endpoints use the same API key. Generate yours to get started.

Get Your API Key
2

Setup Endpoint & Request

Send a GET request with your ticker (e.g., AAPL) and API key:

⚠️ Use This EXACT URL

This is the complete API endpoint URL. Do not modify it or create your own URL structure:

https://drawdownalerts.com/api/data

Add ?ticker=AAPL to the end of this URL

Complete Example URL
https://drawdownalerts.com/api/data?ticker=AAPL
Parameter
?ticker=AAPL

Replace AAPL with your ticker

Header
X-API-Key: your_api_key
Example with cURL:
curl -H "X-API-Key: YOUR_KEY" "https://drawdownalerts.com/api/data?ticker=AAPL"
βœ“

Get the Data

The API returns comprehensive data for the ticker you requested.

You'll receive:
  • severityScore - Drawdown Severity Scoreβ„’ (0 to 10+)
  • currentPrice - Latest market price
  • alertStatus - WATCH, BUY, or STRONG BUY signals (based on your alert settings)
  • + More (see below for full list)

Response Data

Ticker Information

ticker

Stock or crypto symbol

Example: AAPL
companyName

Full company or asset name

Example: Apple Inc.
assetType

Type of asset

"stock" or "crypto"
url

Link to ticker page

drawdownalerts.com/ticker/AAPL

Price Data

currentPrice

Latest market price

Example: 226.50
allTimeHigh

Highest price ever

Example: 237.23

Drawdown Metrics

severityScore

Drawdown Severity Scoreβ„’ (0 to 10+)

Example: 0.89
severityStatus

Status in plain English (12 levels)

Example: typical, elevated, strong, extreme, etc.
currentDrawdown

Current drawdown percentage

Example: -4.52%
daysInDrawdown

Days currently in drawdown

Example: 23
avgMaxDrawdown

Historical average max drawdown

Example: -5.12%
avgDaysInDrawdown

Average duration of historical drawdowns

Example: 28

Alert Information

alertStatus

Whether this ticker triggers your personal alert thresholds

{ watchTriggered: false, buyTriggered: false, strongBuyTriggered: false }

Other Fields

dateLastUpdated

When data was last refreshed

Example: 2025-11-11
requestsRemaining

Requests left today

Example: 999

Full Example Response (AAPL)

Request for: AAPL
{
  "success": true,
  "data": {
    "ticker": "AAPL",
    "companyName": "Apple Inc.",
    "assetType": "stock",
    "url": "https://drawdownalerts.com/ticker/AAPL",
    "currentPrice": 226.50,
    "allTimeHigh": 237.23,
    "currentDrawdown": "-4.52%",
    "daysInDrawdown": 23,
    "severityScore": 0.89,
    "severityStatus": "typical",
    "avgMaxDrawdown": "-5.12%",
    "avgDaysInDrawdown": 28,
    "dateLastUpdated": "2025-11-11",
    "alertStatus": {
      "watchTriggered": false,
      "buyTriggered": false,
      "strongBuyTriggered": false,
      "ultraBuyTriggered": false,
      "userWatchThreshold": "elevated",
      "userBuyThreshold": "strong",
      "userStrongBuyThreshold": "very-large",
      "userUltraBuyThreshold": "historic",
      "alertNames": {
        "watch": "Watch",
        "buy": "Buy",
        "strongBuy": "Strong Buy",
        "ultraBuy": "Ultra Buy"
      }
    }
  },
  "requestsRemaining": 999
}

Platform Integrations

Use DrawdownAlerts data in your favorite tools:

Google Sheets
Click to expand

Setup:

  1. 1. Go to Extensions β†’ Apps Script in your Google Sheet
  2. 2. Delete any existing code and paste the code below
  3. 3. Replace YOUR_API_KEY on line 8 with your actual key
  4. 4. Click Save (disk icon or Ctrl+S)
  5. 5. Go back to your sheet and use the formulas!
/**
 * DrawdownAlerts Google Sheets Integration
 * TESTED AND WORKING - Copy this entire code
 * 
 * IMPORTANT: Replace YOUR_API_KEY on line 8 with your actual key from:
 * https://drawdownalerts.com/account/api
 */

const API_KEY = 'YOUR_API_KEY';
const API_URL = 'https://drawdownalerts.com/api/data';

/**
 * Get severity score: =SEVERITY("AAPL")
 */
function SEVERITY(ticker) {
  const data = fetchData(ticker);
  if (!data) return 'ERROR';
  if (data.error) return data.error; // Show "Processing (retry in 1 min)"
  return data.severityScore;
}

/**
 * Get current price: =PRICE("AAPL")
 */
function PRICE(ticker) {
  const data = fetchData(ticker);
  if (!data) return 'ERROR';
  if (data.error) return data.error; // Show "Processing (retry in 1 min)"
  return data.currentPrice;
}

/**
 * Get alert status: =ALERT("AAPL")
 * Returns: ULTRA BUY, STRONG BUY, BUY, WATCH, or blank
 */
function ALERT(ticker) {
  const data = fetchData(ticker);
  if (!data) return 'ERROR';
  if (data.error) return data.error; // Show "Processing (retry in 1 min)"
  if (data.alertStatus.ultraBuyTriggered) return 'ULTRA BUY';
  if (data.alertStatus.strongBuyTriggered) return 'STRONG BUY';
  if (data.alertStatus.buyTriggered) return 'BUY';
  if (data.alertStatus.watchTriggered) return 'WATCH';
  return '';
}

/**
 * Get drawdown percentage: =DRAWDOWN("AAPL")
 */
function DRAWDOWN(ticker) {
  const data = fetchData(ticker);
  if (!data) return 'ERROR';
  if (data.error) return data.error; // Show "Processing (retry in 1 min)"
  // currentDrawdown is now a string like "-4.52%", parse it
  return parseFloat(data.currentDrawdown);
}

/**
 * Get days in drawdown: =DAYSINDD("AAPL")
 */
function DAYSINDD(ticker) {
  const data = fetchData(ticker);
  if (!data) return 'ERROR';
  if (data.error) return data.error;
  return data.daysInDrawdown;
}

/**
 * Internal function - fetches data from API
 * DO NOT CALL DIRECTLY - use the functions above
 */
function fetchData(ticker) {
  try {
    const url = API_URL + '?ticker=' + ticker;
    const response = UrlFetchApp.fetch(url, {
      method: 'get',
      headers: { 'X-API-Key': API_KEY },
      muteHttpExceptions: true
    });
    
    const statusCode = response.getResponseCode();
    
    if (statusCode === 200) {
      const json = JSON.parse(response.getContentText());
      return json.success ? json.data : null;
    }
    
    // Handle error responses with helpful messages
    const json = JSON.parse(response.getContentText());
    
    // Log helpful messages for each error code
    if (statusCode === 202) {
      Logger.log(ticker + ': Processing - retry in 1 min');
    } else if (statusCode === 503) {
      Logger.log(ticker + ': Data processing - retry in 1-2 min');
    } else if (statusCode === 404) {
      Logger.log(ticker + ': Not available - ' + (json.error || json.reason || 'Check ticker format'));
    } else {
      Logger.log(ticker + ': Error ' + statusCode);
    }
    
    // Return a clear error message instead of null
    // This shows in the cell: "Processing (retry)" instead of "ERROR"
    if (statusCode === 202 || statusCode === 503) {
      return { error: 'Processing (retry in 1 min)' };
    }
    
    return null;
    
  } catch (e) {
    Logger.log(ticker + ': Exception - ' + e);
    return null;
  }
}

βœ“ Available Formulas:

=SEVERITY("AAPL") β†’ Get severity score (e.g., 2.43)
=PRICE("MSFT") β†’ Get current price (e.g., 428.50)
=ALERT("BTC-USD") β†’ Get alert status (WATCH/BUY/etc.)
=DRAWDOWN("TSLA") β†’ Get drawdown % (e.g., -12.5)
=DAYSINDD("AAPL") β†’ Get days in drawdown (e.g., 23)

Drag formulas down to apply to your entire portfolio!

⚠️ Important: Google Sheets Formatting Issue

Problem: Google Sheets may auto-format integer fields like daysInDrawdown and avgDaysInDrawdown as percentages (e.g., showing 1735 as 173500%).

Solution: After writing data to your sheet, explicitly format these columns as plain numbers:

// After writing data to sheet: outputSheet.getRange(2, 9, rows.length, 1).setNumberFormat("0"); // Days in Drawdown outputSheet.getRange(2, 11, rows.length, 1).setNumberFormat("0"); // Avg Days

πŸ“Š All Available Data Fields:

When fetching data programmatically, the API returns all these fields. Use descriptive column headers in your sheet:

ticker β†’ Ticker
companyName β†’ Company Name
assetType β†’ Asset Type
severityScore β†’ Drawdown Severity Scoreβ„’
severityStatus β†’ Severity Status
currentPrice β†’ Current Price
allTimeHigh β†’ All-Time High
currentDrawdown β†’ Current Drawdown %
daysInDrawdown β†’ Days in Drawdown
avgMaxDrawdown β†’ Avg Max Drawdown %
avgDaysInDrawdown β†’ Avg Days in Drawdown
dateLastUpdated β†’ Last Updated
url β†’ URL
alertStatus.* β†’ Alert Flags (watchTriggered, buyTriggered, etc.) + Your Custom Thresholds + Alert Names

πŸ’‘ Tip: Use the descriptive names (right side) as your column headers for better readability!

Excel / Power BI
Click to expand

Use Power Query or VBA to call the API. Here's what you need:

Endpoint:https://drawdownalerts.com/api/data
Parameter:?ticker=AAPL
Header:X-API-Key: your_key

Tip: Search online for "Excel Power Query REST API" for step-by-step guides on connecting to REST APIs in Excel.

Understanding Alert Status

How alertStatus Flags Are Calculated

The API calculates alert triggers by comparing the current severityScore against your custom thresholds using numeric comparison:

Calculation Logic:

  1. 1. Each threshold status maps to a numeric value:
    • β€’ "elevated" = 3.0
    • β€’ "strong" = 5.0
    • β€’ "very-large" = 8.0
    • β€’ "historic" = 12.0
  2. 2. Compare: If severityScore >= threshold, flag = true
  3. 3. Return all applicable flags in alertStatus

πŸ“Š Example:

Stock has severityScore: 5.3

Your thresholds: watch="elevated" (3.0), buy="strong" (5.0)

Result:

  • βœ… watchTriggered: true (5.3 >= 3.0)
  • βœ… buyTriggered: true (5.3 >= 5.0)
  • ❌ strongBuyTriggered: false (5.3 < 8.0)

πŸ’‘ Note: Alert thresholds are customizable in your account settings. The API returns your personalized thresholds in userWatchThreshold, userBuyThreshold, etc.

Error Codes

API Status Codes & What They MeanClick to collapse
200

Success

Data returned successfully. Everything worked!

202

Processing - Retry in 1 Minute

We're fetching this ticker for you. Wait 60 seconds and try again.

What to do: Wait 1 minute, then make the same request again. The data will be ready!

400

Missing Ticker Parameter

You forgot to include ?ticker=AAPL in the URL.

401

Invalid API Key

Check that you copied your API key correctly from your settings.

403

Ticker Not in Watchlist

Free through Advanced plans can only query watchlist tickers. Upgrade to Unlimited for any-ticker access.

404

Ticker Not Available

This ticker either doesn't exist or failed to fetch after 5 attempts.

What to do: Double-check the ticker symbol. For crypto, use BTC-USD not BTC.

429

Rate Limit Exceeded

You've used your daily limit. Limits: Free (500), Starter (2,000), Growth (5,000), Advanced (15,000), Unlimited (100,000). Resets at midnight ET.

503

Data Still Processing

The ticker is in our database but data isn't ready yet.

What to do: Wait 1-2 minutes and try again.

Common Questions

What plan do I need?

All plans have API access:

  • Free through Advanced: Query your watchlist tickers
  • Unlimited: Query any ticker in our database
How many requests can I make?

10,000 per day. Resets at midnight Eastern Time. That's enough to track 1,000 stocks and refresh 10 times daily, or 500 stocks refreshed 20 times.

When does data update?

Every day at 5 PM Eastern Time. Refresh your data after 5 PM to get the latest.

Getting "ticker not found" errors?

Check your ticker format. For Bitcoin use BTC-USD not BTC.

Visit drawdownalerts.com/ticker/YOUR_TICKER and copy the exact format from the URL.