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-Remainingis0(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
- Confirm this is a credit-limit 429 (not concurrency).
- Read
X-Api-Ratelimit-RemainingandX-Api-Ratelimit-Reset. - Find your plan group below and apply its primary workflow.
- Check
X-Api-Ratelimit-Consumedon recent heavy requests. - If still blocked repeatedly after optimization, escalate (support or plan change).
Plan Groups
Troubleshooting should follow your plan's optimization capabilities.
| Plan Group | Plans | Limit Window | mode=cached Available |
|---|---|---|---|
| Free + Trials | Free Forever, Starter Trial, Trader Trial | Daily | No |
| Starter + Trader | Starter, Trader | Daily | Yes |
| Quant + Prime | Quant, Prime | Per-minute | Yes |
mode=cached is not available on Starter Trial and Trader Trial.
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:
- 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, andmaxBid. - 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:
- Request bulk data with
mode=cached(optionally withmaxage). - Inspect the
updatedfield in the response to measure snapshot age. - If fresh enough, use cached data.
- 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:
- Filter option chains aggressively (
strikeLimit,expiration,type,strike, liquidity filters). - Exclude
bid,ask,mid,lastwhen current pricing is not needed. - 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:
- Smooth burst traffic (queue + worker pool)
- Pace large chain pulls across the minute window
- 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
options/chain- Real-time or delayed quote chains can consume per option symbol returned when quote fields are included.
- Historical chain requests (
dateparameter) are billed at 1 credit per 1,000 option symbols.
stocks/quotes- Multi-symbol quote responses with quote fields can consume per symbol returned.
stocks/prices- Multi-symbol price/quote responses with quote fields can consume per symbol returned.
stocks/bulkcandles- Bulk candle responses can consume per symbol returned.
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 requestX-Api-Ratelimit-Remaining: credits remaining in current windowX-Api-Ratelimit-Limit: total credits for current windowX-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
- Pulling full option chains without filters
- Including
bid/ask/mid/lastunnecessarily - Repeating expensive live requests without caching or deduplication
- 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/chainrequest 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=cachedfor 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-Consumedfor 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-Resetas source of truth for exact reset timing. - Align scheduler logic to
America/New_Yorkand the 9:30 AM ET window.
Scenario 4: "I need bulk option data every day on Free/Trial"
What happened:
- No access to
mode=cachedon 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=cachedthe default bulk path. - Check
updatedfreshness 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:
- Recent
X-Api-Ratelimit-*header values - Sample expensive requests
- Your current plan
- Expected request volume and interval