API reference
Pattern history
/tickers/{symbol}/historyKey requiredPast occurrences on a tracked ticker, newest first
Returns past occurrences of patterns on one tracked ticker with what happened next, newest entry first: entry, stop, target, exit, realized move, R multiple and hold time. outcome narrows the rows to resolved (win or loss) or open trades; limit caps the rows returned and total says how many matched. Per-ticker samples are small, so quote the count beside any rate. The ticker must be tracked.
Authentication
Needs a key: send Authorization: Bearer tp_live_… (see Authentication). Counted against the key's limits of 60 requests a minute and 10,000 a day.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
symbol | path | string | yes | Exchange symbol, upper case (BRK.B, not BRK-B). Lower case is accepted and upper-cased. |
limit | query | integer | no | Maximum number of rows to return, 1 to 100 (default 50). Values outside the range are clamped; a non-integer answers 400 bad_request. total says how many rows matched before the limit. |
outcome | query | string (enum) | no | Which rows to include: all, resolved (win or loss only) or open (still running). Case-insensitive; any other value answers 400 bad_request. One of all, resolved, open. |
X-TradingPal-Client | header | string | no | Optional name of the agent or script making the call. It is recorded in the account's usage log so the user can see which client made which calls; the User-Agent is recorded when it is absent. |
Request
curl "https://api.tradingpal.io/api/v1/tickers/NVDA/history?limit=50&outcome=resolved" \
-H "Authorization: Bearer $TRADINGPAL_API_KEY"Response
JSON. The fields this route adds are below; every response also carries the envelope fields (api_version, as_of_session, data_version, source, disclaimer).
| Field | Type | Description |
|---|---|---|
symbol | string | The symbol asked for, upper-cased. |
available | boolean | True when a current-schema pattern history is stored for the symbol. False when none is; occurrences is then empty and total is 0. |
occurrences | array of History row | The rows, newest entry first, after the outcome filter and the limit. |
count | integer | Number of rows in occurrences. |
total | integer | Number of rows matching the outcome filter before the limit was applied. |
Example response
{
"api_version": "v1",
"symbol": "NVDA",
"available": true,
"occurrences": [
{
"setup_id": "NVDA:D:falling_wedge:500",
"lineage_id": "l500",
"family": "falling_wedge",
"family_label": "Falling wedge",
"pattern_type": "falling_wedge",
"direction": "bullish",
"outcome": "win",
"entry_date": "2026-05-04",
"entry_price": 100,
"stop_price": 95,
"target_price": 108,
"exit_date": "2026-05-20",
"exit_price": 108,
"realized_move_pct": 8,
"target_move_pct": 8,
"r_multiple": 1.6,
"unrealized_r": null,
"hold_bars": 12,
"attempt": {
"number": 1,
"count": 1
}
}
],
"count": 1,
"total": 1
}Errors
Errors are JSON with the Error shape; the fix field says what to do.
| 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. |