API reference
Similar past trades for one current setup
/tickers/{symbol}/similarKey requiredSimilar past trades for one current setup
Returns the Similar trades of one current setup, as the TradingPal site's Similar trades panel shows them: earlier breakout trades on any stock whose pattern looked most like this order's, same side, each entered and exited before it, closest first, with their outcomes, and their record. Every plan on the patterns and scan routes already carries the record (similar_trades); this route lists the trades. direction picks the order of a two-sided setup (default: the long side).
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. |
setup_id | query | string | yes | A setup_id from the patterns route for the same symbol (the demo patterns route for demo charts). Setups change nightly; an id that is no longer current answers 404 setup_not_found. |
direction | query | string (enum) | no | The order of a two-sided setup; omit for the long side. One of bullish, bearish. |
limit | query | integer | no | How many matched trades to list. |
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/similar?setup_id=NVDA:D:falling_wedge:1&direction=value&limit=5" \
-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. |
setup_id | string | The setup asked for. |
direction | string (enum) | The order whose similar trades these are. One of bullish, bearish. |
trigger_price | number · nullable | That order's trigger. |
available | boolean | False when the evening search holds no answer for the order yet. |
similar_trades | SimilarRecord | The record of the matched trades. Null when available is false. |
matches | array of object | The similar trades, closest match first. |
matches[].symbol | string | Its stock. |
matches[].company_name | string · nullable | Its company. |
matches[].listed | boolean | False for a stock that no longer trades. |
matches[].pattern_type | string | Its pattern type. |
matches[].direction | string | Its side. |
matches[].entry_date | date | Entry session. |
matches[].exit_date | date | Exit session. |
matches[].entry_price | number · nullable | Entry. |
matches[].stop_price | number · nullable | Stop. |
matches[].target_price | number · nullable | Target. |
matches[].exit_price | number · nullable | Exit. |
matches[].outcome | string | win or loss. |
matches[].return_pct | number · nullable | Return in percent before costs. |
matches[].r_multiple | number · nullable | R multiple. |
matches[].hold_bars | integer · nullable | Daily bars held. |
matches[].similarity_distance | number · nullable | How far its shape was from this order's; smaller is closer. |
searched_session | string · nullable | The session the resting order was searched for. |
through | string · nullable | The last session the search covered. |
page_url | string · nullable | The setup on the TradingPal site. |
Example response
{
"api_version": "v1",
"as_of_session": "2026-11-12",
"symbol": "NVDA",
"setup_id": "NVDA:…",
"direction": "bullish",
"available": true,
"similar_trades": {
"count": 50,
"wins": 21,
"losses": 29,
"win_rate_pct": 42,
"avg_return_pct": 1.8,
"avg_r": 0.12,
"locked": false,
"summary": "Similar trades: 50 earlier look-alike trades, 21 won (42%), average return +1.8% (+0.12R) per trade."
},
"matches": []
}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 API Keys page and replace it wherever the old one was stored. |
| 403 | forbidden | The account behind the key is not on Premium+. API and MCP access requires Premium+ subscription at $30/month; Premium alone does not unlock the API. | Get Premium+ ($30/month, all of the benefits in Premium plus API and MCP access) from the Quickstart, where a first subscription is $0 for 1 month, or switch an existing Premium subscription to it there, then retry with the same key. |
| 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 or offset is not an integer, outcome is not all, resolved or open, a scan filter (family, direction, status, max_distance_pct) is not one of its allowed values, or filters is not a valid predicate list (the message names the predicate). | The message names the parameter. Correct it and retry. |
| 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. |