Core entities
My Prop Journal's API exposes several core entities that represent your trading data:
1. Trade Groups
A trade group represents a complete trade from entry to exit. Each trade contains:
- Entry and exit prices, dates, and times
- Overall P&L calculations (gross and net)
- Position size and direction (long/short)
- Status (win/loss/not_counted/open)
- Associated executions (fills)
2. Executions
Executions are individual buy/sell orders that make up a trade. Each execution includes:
- Side (buy/sell)
- Price and quantity
- Timestamp
- Commission/fees
- Execution type (scale_in, scale_out, full)
A single trade can have multiple executions (e.g., scaling in/out of positions).
3. Accounts
Trading accounts represent your prop firm or retail broker accounts. Fields include:
- Account type (prop or retail)
- Firm/broker name
- Account number
- Balance or current value
- Status (for prop accounts)
4. Playbooks
Playbooks are collections of trading strategies and rules. Each playbook contains:
- Name and description
- Entry criteria (conditions to enter trades)
- Exit criteria (conditions to exit trades)
- Associated strategies
5. Strategies
Strategies are specific trading approaches within playbooks. Each strategy has:
- Name and description
- Parent playbook reference
- Creation timestamp
6. Trading Plans
Trading plans are high-level business plans for your trading operation. Each plan includes:
- Plan name and description
- Multi-format content (JSON/HTML/Markdown)
- Creation and update timestamps
7. Trade Writeups
Trade writeups provide post-trade analysis and reflections. Each writeup has:
- Associated trade reference
- Multi-format content for detailed notes
- Lessons learned and improvement areas
8. Report Cards
Report cards are performance reviews for specific time periods. They include:
- Date range for the review period
- Multi-format content with performance analysis
- Self-assessment and goals
9. Chart Books
Chart books organize trading charts and screenshots. Each chart book contains:
- Name and description
- Collection of chart images
- Organization for different setups or strategies
10. Session Notes
Session notes capture daily trading journal entries. Each session note includes:
- Session date
- Multi-format content (JSON/HTML/Markdown)
- Tags and optional quick notes (ticker-specific observations)
11. Quick Notes
Quick notes are short ticker-specific observations attached to a session note:
- Symbol (optional)
- Body text
- Parent session note reference
12. Trader Notes
Trader notes are personal notes in the Trader's Notebook:
- Rich text content (TipTap JSON)
- Optional folder assignment
- Tags for organization
13. Trader Folders
Trader folders organize trader notes hierarchically:
- Name and color
- Optional parent folder (nested folders)
- Custom sort order
14. Rules
Rules define strategy-specific trading rules with parameters:
- Description and category
- Rule type and scope (
accountortrade) - Linked strategy reference
- Sort order for display
15. Trade Rule Evaluations
Trade rule evaluations record how a trade performed against linked rules at review time:
- Rule snapshot (name, type, parameters)
- Result (
passedorviolated) - Violation details and severity
- Evaluation timestamp
16. Embed References
Embed references identify embedded content within rich text fields:
- Entity type (e.g.,
session_note,trade_writeup,playbook,trade) - Entity ID (UUID)
Used when parsing TipTap content for linked journal entries.
Entity relationships
Understanding how entities relate helps you build effective integrations:
Trade hierarchy
Account
└─ Trade Group
├─ Execution 1 (entry)
├─ Execution 2 (scale in)
├─ Execution 3 (scale out)
└─ Execution 4 (exit)
Example query pattern:
// Get all trades for a specific account
const trades = await fetch(
`${BASE_URL}/trades?account_id=${accountId}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
// Each trade includes its executions
trades.data.forEach(trade => {
console.log(`Trade ${trade.symbol}: ${trade.executions.length} fills`);
});
Playbook hierarchy
Playbook
├─ Entry Criteria
│ ├─ Criterion 1
│ └─ Criterion 2
├─ Exit Criteria
│ ├─ Criterion 1
│ └─ Criterion 2
└─ Strategies
├─ Strategy 1
└─ Strategy 2
Example query pattern:
# Get playbooks with all nested data
playbooks = get_playbooks()
for playbook in playbooks['data']:
print(f"\n{playbook['name']}")
print(f" Entry rules: {len(playbook['entry_criteria'])}")
print(f" Exit rules: {len(playbook['exit_criteria'])}")
print(f" Strategies: {len(playbook['strategies'])}")
Data ownership and isolation
User-scoped data
All API operations are automatically scoped to the authenticated user:
- Users can only access their own data
- Cross-user queries return empty results or 404 errors
- Data isolation is strictly enforced
Example:
// User A's API key
const userA_key = "mpj_user_a_key";
// User B's API key
const userB_key = "mpj_user_b_key";
// User A creates a trade
const trade = await createTrade(tradeData, userA_key);
console.log(`Created trade: ${trade.data.id}`);
// User B tries to access User A's trade
const response = await fetch(
`${BASE_URL}/trades/${trade.data.id}`,
{ headers: { Authorization: `Bearer ${userB_key}` } }
);
// Returns 404 - trade doesn't "exist" for User B
console.log(response.status); // 404
ID formats
All entity IDs are UUIDs (version 4):
- Format:
a1b2c3d4-e5f6-7890-1234-567890abcdef - Globally unique
- Safe to use in URLs and JSON
Field types and formats
Dates and times
- Dates: ISO 8601 date format (
YYYY-MM-DD) - Times: 24-hour format (
HH:MM:SS) - Timestamps: ISO 8601 with timezone (
2024-01-15T10:30:00Z)
Examples:
{
"entry_date": "2024-01-15",
"entry_time": "10:30:00",
"created_at": "2024-01-15T10:30:00Z"
}
Monetary values
- Type: Number (float)
- Precision: Up to 2 decimal places for currencies
- Format: No currency symbols, just numeric values
Examples:
{
"entry_price": 245.50,
"net_pnl": 158.25,
"balance": 150000.00
}
Enumerations
Several fields use predefined string values:
Trade side:
"long"— Buy/long position"short"— Sell/short position
Trade status:
"win"— Profitable trade"loss"— Losing trade"not_counted"— Excluded from performance stats (zero or negligible P&L)"open"— Trade still in progress
Account type:
"prop"— Prop trading firm account"retail"— Retail broker account
Execution side:
"buy"— Buy order"sell"— Sell order
Complete example: Trade object
Here's a fully-annotated trade object showing all fields and their types:
{
"id": "fd07b82a-164c-4c24-885a-7f4db54dab62", // UUID
"account_id": "f1588e0d-93fd-4a76-b876-b0753f93bc09", // UUID (foreign key)
"symbol": "NQ", // string
"side": "short", // enum: "long" | "short"
"quantity": 1, // number (integer)
"entry_price": 29298, // number (float)
"exit_price": 29290, // number (float) | null
"entry_time": "10:17:54", // string (HH:MM:SS)
"exit_time": "10:18:29", // string (HH:MM:SS) | null
"gross_pnl": 160, // number (float)
"net_pnl": 158, // number (float)
"total_commission": 2, // number (float)
"status": "win", // enum: "win" | "loss" | "not_counted" | "open"
"entry_date": "2026-02-05", // string (YYYY-MM-DD)
"exit_date": "2026-02-05", // string (YYYY-MM-DD) | null
"asset_class": "futures", // string
"star_rating": 4, // number (1-5) | null
"review_notes": { "summary": "Clean execution" }, // object | null
"stop_loss_levels": [ // array of price levels
{ "price": 29310, "label": "Initial stop" }
],
"take_profit_levels": [ // array of price levels
{ "price": 29280, "label": "T1" }
],
"r_ratio": 2.5, // number | null
"r_ratio_basis": "stop_loss", // enum: "stop_loss" | "max_trade_risk" | null
"playbook_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef", // UUID | null
"criteria_checklist": { // object | null
"entry": { "volume_confirmed": true, "above_vwap": true }
},
"reviewed_at": "2026-02-05T15:20:00+00:00", // string (ISO 8601) | null
"created_at": "2026-02-05T15:17:54+00:00", // string (ISO 8601)
"updated_at": "2026-02-05T15:18:29+00:00", // string (ISO 8601)
"executions": [ // array of execution objects
{
"id": "1ed21bd6-8ea2-42d0-b16e-142f9484ecb9", // UUID
"side": "sell", // enum: "buy" | "sell"
"price": 29298, // number (float)
"quantity": 1, // number (integer)
"commission": 1, // number (float)
"execution_time": "10:17:54", // string (HH:MM:SS)
"execution_type": "scale_in", // string
"execution_timestamp": "2026-02-05T15:17:54+00:00" // string (ISO 8601)
}
]
}
Working with nested data
Accessing executions
// Get trades and analyze execution patterns
const trades = await getTrades();
trades.data.forEach(trade => {
const numExecutions = trade.executions.length;
const avgPrice = trade.executions.reduce((sum, exec) =>
sum + exec.price, 0) / numExecutions;
console.log(`${trade.symbol}: ${numExecutions} fills, avg price: ${avgPrice}`);
});
Filtering by nested properties
# Find all trades with more than 3 executions
trades = get_trades(limit=100)
complex_trades = [
trade for trade in trades['data']
if len(trade['executions']) > 3
]
print(f"Found {len(complex_trades)} trades with 3+ executions")