Introduction
TradeJournal Lab API — Programmatic access to your trade journal data, stats, and leaderboard.
This documentation aims to provide all the information you need to work with our API.
<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
You can retrieve your token by visiting your dashboard and clicking Generate API token.
Endpoints
POST /api/webhooks/tradingview/{token}
requires authentication
Expected body (JSON, plain-text JSON, or form-encoded): { "symbol": "BTCUSDT", "side": "buy" | "sell" | "long" | "short", "price": 67500.5, "quantity": 0.01, "time": "2026-04-25T12:34:56Z", // optional, defaults to now "comment": "RSI alert" // optional }
Example request:
curl --request POST \
"https://tradejournallab.com/api/webhooks/tradingview/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://tradejournallab.com/api/webhooks/tradingview/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST /api/webhooks/mt-bridge/{token}
requires authentication
Expected body (from MT4/MT5 EA or cAlgo bot): Single trade: { symbol, side, quantity, entry_price, entry_time, exit_price?, exit_time?, commission?, swap?, pnl?, ticket? } Or batch: { trades: [ { ... }, { ... } ] }
Example request:
curl --request POST \
"https://tradejournallab.com/api/webhooks/mt-bridge/consequatur" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://tradejournallab.com/api/webhooks/mt-bridge/consequatur"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/mobile/login
requires authentication
Example request:
curl --request POST \
"https://tradejournallab.com/api/mobile/login" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"qkunze@example.com\",
\"password\": \"O[2UZ5ij-e\\/dl4m{o,\"
}"
const url = new URL(
"https://tradejournallab.com/api/mobile/login"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "qkunze@example.com",
"password": "O[2UZ5ij-e\/dl4m{o,"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/mobile/logout
requires authentication
Example request:
curl --request POST \
"https://tradejournallab.com/api/mobile/logout" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://tradejournallab.com/api/mobile/logout"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/mobile/notifications/register
requires authentication
Example request:
curl --request POST \
"https://tradejournallab.com/api/mobile/notifications/register" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"token\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
"https://tradejournallab.com/api/mobile/notifications/register"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"token": "vmqeopfuudtdsufvyvddq"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/mobile/trades
requires authentication
Example request:
curl --request POST \
"https://tradejournallab.com/api/mobile/trades" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"instrument\": \"vmqeopfuudtdsufvy\",
\"side\": \"short\",
\"quantity\": 76,
\"entry_price\": 10,
\"exit_price\": 10,
\"entry_time\": \"2026-07-19T17:43:49\",
\"exit_time\": \"2107-08-18\",
\"commission\": 45,
\"setup_type\": \"qeopfuudtdsufvyvddqam\",
\"notes\": \"niihfqcoynlazghdtqtqx\",
\"rating\": 1,
\"screenshots\": [
\"consequatur\"
]
}"
const url = new URL(
"https://tradejournallab.com/api/mobile/trades"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"instrument": "vmqeopfuudtdsufvy",
"side": "short",
"quantity": 76,
"entry_price": 10,
"exit_price": 10,
"entry_time": "2026-07-19T17:43:49",
"exit_time": "2107-08-18",
"commission": 45,
"setup_type": "qeopfuudtdsufvyvddqam",
"notes": "niihfqcoynlazghdtqtqx",
"rating": 1,
"screenshots": [
"consequatur"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Public API
Endpoints for external integrations via API keys.
All endpoints require a valid API key in the Authorization: Bearer {key} header.
List trades
requires authentication
Get a paginated list of your trades with optional filters.
Example request:
curl --request GET \
--get "https://tradejournallab.com/api/v1/trades?from=2025-01-01&to=2025-12-31&instrument=BTCUSDT&side=long&per_page=25" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://tradejournallab.com/api/v1/trades"
);
const params = {
"from": "2025-01-01",
"to": "2025-12-31",
"instrument": "BTCUSDT",
"side": "long",
"per_page": "25",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": 1,
"instrument": "BTCUSDT",
"side": "long",
"quantity": 0.5,
"entry_time": "2025-03-15T10:30:00.000000Z",
"entry_price": 65000,
"exit_time": "2025-03-15T14:00:00.000000Z",
"exit_price": 66500,
"pnl": 750,
"net_pnl": 748.5,
"commission": 1.5,
"setup_type": "breakout",
"notes": "Strong momentum breakout"
}
],
"current_page": 1,
"last_page": 3,
"per_page": 25,
"total": 72
}
Example response (403):
{
"error": "Insufficient scope: trades:read required"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a trade
requires authentication
Create a new trade in your journal.
Example request:
curl --request POST \
"https://tradejournallab.com/api/v1/trades" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"instrument\": \"BTCUSDT\",
\"side\": \"long\",
\"quantity\": 0.5,
\"entry_time\": \"2025-03-15T10:30:00Z\",
\"entry_price\": 65000,
\"exit_time\": \"2025-03-15T14:00:00Z\",
\"exit_price\": 66500,
\"stop_loss\": 64000,
\"take_profit\": 68000,
\"commission\": 1.5,
\"notes\": \"Strong momentum breakout\",
\"setup_type\": \"breakout\"
}"
const url = new URL(
"https://tradejournallab.com/api/v1/trades"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"instrument": "BTCUSDT",
"side": "long",
"quantity": 0.5,
"entry_time": "2025-03-15T10:30:00Z",
"entry_price": 65000,
"exit_time": "2025-03-15T14:00:00Z",
"exit_price": 66500,
"stop_loss": 64000,
"take_profit": 68000,
"commission": 1.5,
"notes": "Strong momentum breakout",
"setup_type": "breakout"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 99,
"instrument": "BTCUSDT",
"side": "long",
"entry_price": 65000,
"message": "Trade created"
}
Example response (403):
{
"error": "Insufficient scope: trades:write required"
}
Example response (422):
{
"error": "Validation failed",
"details": {
"instrument": [
"The instrument field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get account stats
requires authentication
Get aggregated performance statistics for your account.
Example request:
curl --request GET \
--get "https://tradejournallab.com/api/v1/stats" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://tradejournallab.com/api/v1/stats"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"total_trades": 150,
"win_rate": 62.5,
"net_pnl": 12450.75,
"profit_factor": 2.35,
"gross_profit": 25000.5,
"gross_loss": 10638.3,
"avg_win": 312.5,
"avg_loss": -189.25,
"best_trade": 1500,
"worst_trade": -650
}
Example response (403):
{
"error": "Insufficient scope: stats:read required"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get leaderboard
requires authentication
Get the top 25 traders ranked by net P&L over the last 30 days (minimum 5 trades).
Example request:
curl --request GET \
--get "https://tradejournallab.com/api/v1/leaderboard" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://tradejournallab.com/api/v1/leaderboard"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
[
{
"rank": 1,
"user": "TraderAce",
"trades": 45,
"pnl": 8500
},
{
"rank": 2,
"user": "SwingKing",
"trades": 32,
"pnl": 6200.5
}
]
Example response (403):
{
"error": "Insufficient scope: leaderboard:read required"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.