Resources
Errors
Every error code, its status, what it means and what to do.
Every error is JSON with the same four fields, whatever the route, and the fix field says what to do next. An agent can act on fix directly; a person can read it. The MCP server returns the same codes as tool errors whose text starts with the code and ends with the fix.
{
"error": "ticker_not_tracked",
"message": "NVDA is not one of the tickers this account tracks",
"fix": "Add it to the tracked tickers (3 of 50 slots used): PUT /api/v1/tickers, or the set_tracked_tickers MCP tool.",
"docs_url": "https://tradingpal.io/developers"
}Codes
| Status | Code | Meaning | Fix |
|---|---|---|---|
| 401 | missing_api_key | The request had no Authorization: Bearer tp_live_… header and the route needs one. | Send the header on every keyed call. Only the demo, families and universe routes answer without it. |
| 401 | invalid_api_key | The key is not one we know, or it has been revoked. | Create a new key on the Keys page and replace it wherever the old one was stored. |
| 403 | forbidden | The account behind the key is not on a plan with API access. | During the beta, keys work on Premium accounts. Upgrade the account, then retry with the same key. |
| 403 | ticker_not_tracked | The ticker is not on the account’s tracked list, and pattern, history and chart calls work only on tracked tickers. | Add it with PUT /tickers (or the set_tracked_tickers MCP tool), then retry. The fix field says how many slots are free. |
| 429 | rate_limited | The key passed 60 requests in a minute or 10,000 in a day, or a keyless caller passed 30 a minute from one IP. | Wait details.retry_after_seconds, then retry. Cache the nightly answers; they do not change until the next session. |
| 400 | bad_request | A query parameter is malformed: limit is not an integer, or outcome is not all, resolved or open. | The message names the parameter. Correct it and retry. |
| 400 | invalid_symbol | A symbol in a PUT /tickers body is not a valid ticker symbol (letters, digits and a dot, as in BRK.B). | Use the exchange symbol in upper case. details lists the rejected values. |
| 400 | unknown_symbol | A symbol in a PUT /tickers body is well formed but not a ticker TradingPal knows. | Check the spelling against GET /universe. details lists the unknown values. |
| 400 | ticker_cap_exceeded | The PUT /tickers body has more symbols than the account’s cap. Nothing was changed. | Send at most cap symbols (GET /tickers returns the cap). The beta cap is 50. |
| 404 | unknown_family | The {family} in the path is not one of the pattern families. | Use one of rising_wedge, falling_wedge, bullish_pennant, bearish_pennant, triangle. |
| 404 | setup_not_found | No current setup on that ticker has the setup_id you passed to chart.png. | Call the patterns route again and use a setup_id from tonight’s answer; ids change when a pattern is redrawn. |
| 404 | chart_unavailable | The setup exists but cannot be drawn, usually because its price history is not stored. | Present the setup from its JSON instead; the lines are two dated endpoints you can draw yourself. |
| 404 | not_a_demo_symbol | The keyless demo answers only for its fixed set of large caps. | GET /demo lists the demo symbols. For any other ticker, use a key and track it. |
Handling errors
-
Branch on
error, never onmessage; messages can change, codes do not within v1. -
On
429, waitdetails.retry_after_secondsand retry once; then back off. The data is nightly, so a retry a minute later loses nothing. -
On
ticker_not_tracked, add the ticker and retry; thefixsays how many slots are free. -
On
401and403, stop and surface thefix; retrying will not help until a key or plan changes. -
detailsis present when there is structure to give: rejected symbols, the cap, or the wait in seconds.