Skip to main content

429: Credit Limit Reached

A 429 TOO MANY REQUESTS can be returned for two different reasons:

  • Credit limit reached
  • Too many concurrent requests

This page is only for the credit limit case. If your issue is concurrency, use 429: Too Many Concurrent Requests.

For full policy details, see Rate Limits.

Fast Triage

Use the response message and headers to identify which 429 you hit.

Typical credit-limit error payload:

{
"s": "error",
"errmsg": "API credit limit reached for current window.",
"troubleshootingGuide": "https://www.marketdata.app/docs/api/troubleshooting/running-out-of-credits"
}

Credit-limit 429 indicators:

  • Error message indicates credit/rate budget exhaustion for your plan window
  • X-Api-Ratelimit-Remaining is 0 (or effectively exhausted)

Concurrency 429 indicators:

  • Error message indicates too many simultaneous requests
  • Usually occurs during bursts with many in-flight requests
  • Official SDKs handle concurrency automatically and maximize throughput up to the 50-request limit without exceeding it

30-Second Action Checklist

  1. Confirm this is a credit-limit 429 (not concurrency).
  2. Read X-Api-Ratelimit-Remaining and X-Api-Ratelimit-Reset.
  3. Find your plan group below and apply its primary workflow.
  4. Check X-Api-Ratelimit-Consumed on recent heavy requests.
  5. If still blocked repeatedly after optimization, escalate (support or plan change).

Plan Groups

Troubleshooting should follow your plan's optimization capabilities.

Plan GroupPlansLimit Windowmode=cached Available
Free + TrialsFree Forever, Starter Trial, Trader TrialDailyNo
Starter + TraderStarter, TraderDailyYes
Quant + PrimeQuant, PrimePer-minuteYes
Trial plan limitation

mode=cached is not available on Starter Trial and Trader Trial.

Reset Window Gotcha (All Daily-Reset Plans)

All plans with daily credit windows (Free Forever, Starter Trial, Trader Trial, Starter, Trader) reset at 9:30 AM Eastern Time, not midnight.

This is intentional safety behavior: if a script runs out of control overnight, the reset timing limits impact to one trading day budget instead of potentially consuming two trading-day budgets across a midnight boundary.

Plan Playbooks

Free Forever + Trial Plans (No Cached Mode)

These plans cannot use cached mode. For bulk option use, use one of these workflows:

  1. One-step server-side filtering: keep quote columns and aggressively reduce contracts on the chain request using filters such as strikeLimit, expiration, type, strike, minBid, and maxBid.
  2. Two-step local filtering: pull the full/large chain without quote columns, apply your own logic locally, then request quotes only for selected contracts using options/quotes.

If current-day quote freshness is not required, a third strategy can be cheaper: use historical option chains with the date parameter. Historical chains are billed at 1 credit per 1,000 option symbols, while real-time/15-minute delayed quote chains are billed per symbol.

# One-step: server-side liquidity + contract filters (quotes included)
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?expiration=YYYY-MM-DD&type=call&strikeLimit=5&minBid=0.50&maxBid=10&columns=symbol,strike,expiration,type,bid,ask,mid,last,openInterest,volume

# Two-step (Step 1): broad chain without costly quote columns
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?expiration=all&columns=symbol,strike,expiration,type,openInterest,volume

# Two-step (Step 2): quotes only for selected contracts
GET https://api.marketdata.app/v1/options/quotes/OPTION_SYMBOL/

# Historical chain example (lower-cost bulk snapshot)
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?date=YYYY-MM-DD&expiration=all

If you are still getting credit-limit 429 after these optimizations, the primary path is to upgrade to a paid plan.

Starter + Trader (Daily Limits + Cached Mode)

Primary optimization for this plan group is mode=cached on bulk requests.

Recommended process:

  1. Request bulk data with mode=cached (optionally with maxage).
  2. Inspect the updated field in the response to measure snapshot age.
  3. If fresh enough, use cached data.
  4. If too old, re-request only required contracts/symbols in live mode instead of re-pulling the full chain.
# Step 1: bulk chain from cache (cheap, 1 credit)
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?mode=cached&maxage=5min&expiration=YYYY-MM-DD

# Step 2: only if selected contracts are too stale per `updated`, request live quotes for those contracts
GET https://api.marketdata.app/v1/options/quotes/OPTION_SYMBOL/

Additional controls for Starter + Trader:

  1. Filter option chains aggressively (strikeLimit, expiration, type, strike, liquidity filters).
  2. Exclude bid, ask, mid, last when current pricing is not needed.
  3. Add daily credit guardrails to avoid getting blocked for the rest of the day.

Quant + Prime (Per-Minute Limits + Cached Mode)

Use cached-mode bulk strategy and filter optimization, plus minute-window pacing:

  1. Smooth burst traffic (queue + worker pool)
  2. Pace large chain pulls across the minute window
  3. Prefer cached mode for full-chain or broad bulk pulls

Quant/Prime have no daily credit cap. 429s here are the result of per-minute bursts, not daily depletion.

How Pricing Actually Works

The mental model 1 request = 1 credit is often wrong for bulk and candles workloads.

Common baseline

  • Many non-bulk responses: 1 request = 1 credit

High-usage endpoints where pricing scales

  1. options/chain
    • Real-time or delayed quote chains can consume per option symbol returned when quote fields are included.
    • Historical chain requests (date parameter) are billed at 1 credit per 1,000 option symbols.
  2. stocks/quotes
    • Multi-symbol quote responses with quote fields can consume per symbol returned.
  3. stocks/prices
    • Multi-symbol price/quote responses with quote fields can consume per symbol returned.
  4. stocks/bulkcandles
    • Bulk candle responses can consume per symbol returned.
  5. stocks/candles
    • Candle responses are billed at 1 credit per 1,000 candles, so large ranges can consume multiple credits in one request.

Practical rule: credit usage scales with response size on bulk quote endpoints and long candle responses.

High-impact example

# Full live chain can consume very large credits
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?expiration=all

# Filtered chain reduces returned symbols
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?expiration=all&strikeLimit=1

# Cached mode (paid plans only) reduces credits to 1
GET https://api.marketdata.app/v1/options/chain/UNDERLYING/?mode=cached

For cached mode details, see mode parameter.

Diagnose With Headers

Check these headers on every response:

  • X-Api-Ratelimit-Consumed: credits consumed by current request
  • X-Api-Ratelimit-Remaining: credits remaining in current window
  • X-Api-Ratelimit-Limit: total credits for current window
  • X-Api-Ratelimit-Reset: reset time in UTC epoch seconds
curl -i -X GET "https://api.marketdata.app/v1/stocks/quotes/AAPL/" \
-H "Authorization: Bearer YOUR_TOKEN"

Common Cost Traps

  1. Pulling full option chains without filters
  2. Including bid/ask/mid/last unnecessarily
  3. Repeating expensive live requests without caching or deduplication
  4. Ignoring rate-limit headers during production runs

Common Scenarios

Scenario 1: "I requested one option chain and ran out of credits"

What happened:

  • A single options/chain request returned a very large number of contracts.
  • With quote fields included, credits scaled by returned contracts.

What to do:

  • Free + Trials: use server-side filters or two-step local filtering; consider historical chains for bulk snapshots.
  • Starter + Trader and Quant + Prime: use mode=cached for bulk pulls, then selectively refresh only contracts you need live.

Scenario 2: "I made a small number of requests but used far more credits than expected"

What happened:

  • Requests hit bulk endpoints (options/chain, stocks/quotes, stocks/prices) with quote fields.
  • Credit usage scaled with symbols/contracts returned, not request count.

What to do:

  • Inspect X-Api-Ratelimit-Consumed for high-cost requests.
  • Remove unnecessary quote fields or reduce returned symbols/contracts with filters.

Scenario 3: "My credits did not reset at midnight"

What happened:

  • You expected a calendar-day reset.
  • Daily-limit plans reset at 9:30 AM Eastern Time, not midnight.

What to do:

  • Use X-Api-Ratelimit-Reset as source of truth for exact reset timing.
  • Align scheduler logic to America/New_York and the 9:30 AM ET window.

Scenario 4: "I need bulk option data every day on Free/Trial"

What happened:

  • No access to mode=cached on Free/Trial makes full quote-chain pulls expensive.

What to do:

  • Use one-step server-side liquidity/contract filters or two-step local filtering.
  • If intraday quote freshness is not required, prefer historical chain snapshots (date) for lower credit burn.
  • If this remains insufficient, upgrade to a paid plan.

Scenario 5: "I am on Starter/Trader and still getting blocked daily"

What happened:

  • Cached mode is not being used as primary bulk strategy, or stale cache fallback is too broad (full live repulls).

What to do:

  • Make mode=cached the default bulk path.
  • Check updated freshness and only re-request live data for required contracts/symbols.
  • Add daily guardrails to stop or degrade workload before hard-limit exhaustion.

When to Contact Support

Open a support ticket if you have optimized for your plan group and still cannot operate within limits.

Include:

  1. Recent X-Api-Ratelimit-* header values
  2. Sample expensive requests
  3. Your current plan
  4. Expected request volume and interval