Put Reflect anywhere.
Everything the application shows you is available over HTTP as JSON, and trades can be pushed in as they close. No SDK, no webhook registration, no OAuth dance — one bearer token and ordinary REST.
Thirty seconds
Create a key in Settings, then:
curl https://trader-reflect.com/api/v1/insights \ -H "Authorization: Bearer rk_your_key_here"
const res = await fetch("https://trader-reflect.com/api/v1/insights", {
headers: { Authorization: `Bearer ${process.env.REFLECT_KEY}` },
});
const { insights } = await res.json();
console.log(insights[0].headline); // "You size up exactly when you should not."
console.log(insights[0].evidence); // the numbers it rests on
console.log(insights[0].confidence); // 77import os, requests
r = requests.get(
"https://trader-reflect.com/api/v1/report",
headers={"Authorization": f"Bearer {os.environ['REFLECT_KEY']}"},
)
report = r.json()
print(report["insights"][0]["headline"])Authentication
Every request carries Authorization: Bearer rk_…. A key belongs to one account and can reach nothing else — there is no endpoint that takes a user id, so no key can be pointed at somebody else's data.
The key is shown once, at creation. Only a SHA-256 digest is stored, so a lost key cannot be recovered by you or by us — revoke it and make another. Keys come in two scopes: read reaches every GET endpoint, write also allows POST and DELETE. Use read wherever the caller only needs to display something.
Reading
Base URL https://trader-reflect.com/api/v1
/meThe account behind the key, plus trade and import counts.
/reportThe full coaching report: findings, psychology scores, risk state, hourly and session breakdowns.
/insights?category=riskFindings only, ranked by cost.
/performanceEquity curve, drawdown, expectancy, profit factor, streaks, per-instrument.
/trades?limit=100&offset=0&from=2026-01-01&to=2026-12-31Your trades, newest first.
/journalPer-day totals: trades, net R, net P&L, wins.
/milestonesBehavioural milestones with what each one counted.
/importsEvery batch of trades on the account, pushed or uploaded.
Writing
Needs a write-scoped key. Reflect never places orders — these endpoints only record trades that already happened.
/tradesPush trades in. The natural integration point — call it as each trade closes.
/importsUpload a broker statement as CSV text and let Reflect parse it.
/imports/:idRemove a batch and every trade that came in with it.
curl -X POST https://trader-reflect.com/api/v1/trades \
-H "Authorization: Bearer rk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"source": "my-bot",
"trades": [
{
"instrument": "XAUUSD",
"direction": "long",
"openedAt": "2026-08-04T09:15:00Z",
"rMultiple": 1.8,
"pnl": 180.00,
"sizeR": 1.0,
"followedPlan": true
}
]
}'instrument— stringdirection— "long" or "short"openedAt— ISO 8601rMultiple— number, negative is a loss
pnl— broker currencysizeR— risk taken, defaults to 1followedPlan— defaults to truesource— names the batch
Put a zone on openedAt. Without one it is read as UTC, and a timestamp meant as local time will land in a different trading session — which changes the analysis rather than failing loudly.
A batch is written whole or not at all. The response gives the importId, how many were accepted, and the index and reason for each one that was not — so a partial payload tells you exactly which trade to fix. Sending the same batch twice creates two batches: there is no deduplication yet.
Embedding without code
If all you want is one figure inside Notion, a team dashboard or your own site, you do not need the API. Create an embed in Settings and paste the iframe.
<iframe src="https://trader-reflect.com/embed?t=re_your_token&theme=dark"
width="360" height="220" frameborder="0"
style="border:0;border-radius:12px"></iframe>Four widgets: the current finding, your standing, your practice streak, and the equity curve. theme takes dark or light.
An embed token is not an API key and the difference matters. It travels in a URL that is visible in the hosting page's source, so it is read-only, bound to the single widget it was created for, revocable on its own, and rejected outright by every endpoint above. Anyone with the link sees that one figure — treat it as public.
Limits and errors
- 120 reads per minute
- 30 writes per minute
- 1000 trades per push
- 2 MB per request body
Every response carries X-RateLimit-Remaining and X-RateLimit-Reset. A 429 also carries Retry-After.
400— malformed body401— missing or revoked key403— read key used for a write404— no such endpoint or record422— well-formed but unusable429— rate limited
{
"error": {
"code": "read_only_key",
"message": "This key is read-only. Create a write key in Settings."
}
}Branch on code, show message to a person. CORS is open, so a browser can call this directly — but a key in front-end JavaScript is a key you have published. Use a read key, or keep it on your server.