MENU navbar-image

Introduction

TradeJournal 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.

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://groupresearch.net/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://groupresearch.net/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"
}
 

Request      

GET api/v1/trades

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

from   string  optional    

Filter trades from this date (YYYY-MM-DD). Example: 2025-01-01

to   string  optional    

Filter trades up to this date (YYYY-MM-DD). Example: 2025-12-31

instrument   string  optional    

Filter by instrument/symbol. Example: BTCUSDT

side   string  optional    

Filter by trade side. Example: long

per_page   integer  optional    

Number of results per page (1-100). Example: 25

Create a trade

requires authentication

Create a new trade in your journal.

Example request:
curl --request POST \
    "https://groupresearch.net/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://groupresearch.net/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."
        ]
    }
}
 

Request      

POST api/v1/trades

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

instrument   string     

The trading instrument. Example: BTCUSDT

side   string     

Trade direction: long or short. Example: long

quantity   number     

Trade size/volume. Example: 0.5

entry_time   string     

Entry timestamp (ISO 8601). Example: 2025-03-15T10:30:00Z

entry_price   number     

Entry price. Example: 65000

exit_time   string  optional    

Exit timestamp (ISO 8601). Example: 2025-03-15T14:00:00Z

exit_price   number  optional    

Exit price. Example: 66500

stop_loss   number  optional    

Stop loss price. Example: 64000

take_profit   number  optional    

Take profit price. Example: 68000

commission   number  optional    

Commission/fees. Example: 1.5

notes   string  optional    

Trade notes. Example: Strong momentum breakout

setup_type   string  optional    

Setup type tag. Example: breakout

Get account stats

requires authentication

Get aggregated performance statistics for your account.

Example request:
curl --request GET \
    --get "https://groupresearch.net/api/v1/stats" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://groupresearch.net/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"
}
 

Request      

GET api/v1/stats

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

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://groupresearch.net/api/v1/leaderboard" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://groupresearch.net/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"
}
 

Request      

GET api/v1/leaderboard

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json