Partner API Documentation
Integrate PropTally analytics into your prop firm dashboard. Embed widgets, query trader data, and receive real-time webhooks.
Try it now
curl -H "X-API-Key: pt_YOUR_KEY" \ https://proptally.app/api/partner/stats?period=30d
Authentication
All API requests require authentication. There are two methods:
API Key Authentication
Include your API key in requests using any of these methods (in order of preference):
# 1. X-API-Key header (recommended) curl -H "X-API-Key: pt_YOUR_KEY" https://proptally.app/api/partner/stats # 2. Authorization Bearer header curl -H "Authorization: Bearer pt_YOUR_KEY" https://proptally.app/api/partner/stats # 3. Query parameter (for embeds/iframes) curl "https://proptally.app/api/partner/stats?api_key=pt_YOUR_KEY"
embed:read). Use server-side requests for sensitive operations.Session Authentication (Portal)
The partner portal uses magic link email authentication. After clicking the link, a secure pt_session httpOnly cookie is set. Portal requests use this cookie automatically — no API key needed in the browser.
API Key Scopes
| Scope | Description | Tier |
|---|---|---|
embed:read | Access embed widget endpoints | Starter+ |
stats:read | Read individual trader statistics | Starter+ |
stats:aggregate | Read aggregate platform statistics | Starter+ |
accounts:list | List connected trading accounts | Starter+ |
webhooks:manage | Create and manage webhook subscriptions | Growth+ |
Rate Limits
Limits are per API key, per calendar day (UTC). Check X-RateLimit-* response headers for current usage.
| Tier | Daily Requests | Embed Widgets | Price |
|---|---|---|---|
| starter | 1,000 | 3 widgets | Free |
| growth | 10,000 | All widgets | $149/mo |
| enterprise | 100,000 | All + white-label | Custom |
HTTP/1.1 200 OK X-RateLimit-Limit: 10000 X-RateLimit-Remaining: 9847 Access-Control-Allow-Origin: *
403 until midnight UTC. Upgrade your tier or contact us for higher limits.Error Codes
All errors return JSON with an error field describing the issue.
{
"error": "Missing required scope: webhooks:manage"
}| Code | Name | Description |
|---|---|---|
400 | Bad Request | Missing required parameters or invalid values. |
401 | Unauthorized | Missing API key or session cookie. |
403 | Forbidden | Invalid API key, inactive partner, rate limit exceeded, or missing scope. |
404 | Not Found | Requested resource does not exist. |
429 | Rate Limited | Daily request limit exceeded. Resets at midnight UTC. |
500 | Internal Error | Server error. Contact support if persistent. |
REST API Endpoints
Base URL: https://proptally.app/api/partner
/api/partner/statsstats:readGet trader performance statistics for a specific account or aggregate across all accounts.
| Name | Type | Required | Description |
|---|---|---|---|
account_id | string | Optional | Specific account ID. Omit for aggregate stats across all accounts. |
period | string | Optional | "7d", "30d", "90d", "1y", or "all". Default: "30d". |
{
"account": { "id": "acc_456", "nickname": "Apex 50K" },
"period": "30d",
"stats": {
"tradeCount": 142,
"winRate": 58.5,
"avgPnl": 27.10,
"totalPnl": 3847.50,
"bestTrade": 450.00,
"worstTrade": -180.25,
"profitFactor": 1.82,
"instrumentsTraded": 4
},
"dailyPnl": [
{ "day": "2026-03-01", "pnl": 125.50, "trades": 8 }
],
"instruments": [
{ "symbol": "ES", "trades": 85, "win_rate": 61.2, "total_pnl": 2450.00 }
]
}/api/partner/accountsaccounts:listList all trading accounts on the platform with basic statistics.
| Name | Type | Required | Description |
|---|---|---|---|
firm_id | string | Optional | Filter accounts by prop firm ID. |
limit | number | Optional | Max results per page (default: 50, max: 200). |
offset | number | Optional | Pagination offset. |
{
"accounts": [
{
"id": "acc_456",
"nickname": "Apex 50K",
"trade_count": 142,
"total_pnl": 3847.50
}
],
"total": 250,
"limit": 50,
"offset": 0
}/api/partner/tradesstats:readGet paginated trade history for a specific account. Supports filtering and sorting.
| Name | Type | Required | Description |
|---|---|---|---|
account_id | string | Required | The account to query trades for. |
page | number | Optional | Page number (default: 1). |
limit | number | Optional | Results per page (default: 50, max: 100). |
period | string | Optional | "7d", "30d", "90d", "1y", or "all". |
symbol | string | Optional | Filter by instrument symbol (e.g., "ES", "NQ"). |
direction | string | Optional | "long" or "short". |
sort | string | Optional | "entry_time" (default), "exit_time", "pnl", "symbol", "quantity". |
order | string | Optional | "desc" (default) or "asc". |
{
"account": { "id": "acc_456", "nickname": "Apex 50K" },
"period": "30d",
"pagination": {
"page": 1,
"limit": 50,
"total": 142,
"total_pages": 3,
"has_more": true
},
"trades": [
{
"id": "trd_abc",
"symbol": "ES",
"direction": "long",
"quantity": 2,
"entry_price": 5250.50,
"exit_price": 5254.25,
"entry_time": 1710072000000,
"exit_time": 1710073800000,
"pnl": 187.50,
"commission": -4.60,
"setup_type": "breakout",
"duration_minutes": 30
}
]
}/api/partner/dashboardGet self-service dashboard data: partner info, API keys (masked), usage stats, tier limits, and billing status.
{
"partner": {
"id": "ptr_abc",
"name": "Apex Trader Funding",
"contact_email": "[email protected]",
"tier": "growth",
"billing_status": "active",
"created_at": 1710000000000
},
"keys": [
{
"id": "key_123",
"prefix": "pt_9f2e5c97",
"label": "Production",
"scopes": ["embed:read", "stats:read"],
"rate_limit_daily": 10000,
"is_active": true,
"requests_today": 847
}
],
"usage": {
"total_30d": 24500,
"errors_30d": 12,
"daily": [{ "day": "2026-03-10", "requests": 847, "avg_ms": 45, "errors": 0 }],
"by_endpoint": [{ "endpoint": "/api/partner/stats", "method": "GET", "requests": 15200 }]
},
"limits": {
"daily_requests": 10000,
"embed_widgets": ["stats-card", "performance-summary", "equity-curve", "trade-heatmap", "instrument-breakdown", "drawdown-gauge", "leaderboard"],
"features": ["basic_stats", "detailed_stats", "embed", "bulk_query", "webhooks"]
}
}/api/partner/keysGenerate a new API key (max 10 per partner). The full key is returned only once — save it immediately.
/api/partner/keys?key_id=xxxRevoke an API key. Cannot revoke the key being used for this request.| Name | Type | Required | Description |
|---|---|---|---|
label | string | Optional | Label for the key (default: "API Key", max 50 chars). |
scopes | string[] | Optional | Array of scopes. Default: ["embed:read", "stats:read", "stats:aggregate", "accounts:list"]. |
{
"label": "Production Widget Key",
"scopes": ["embed:read", "stats:read"]
}{
"key": "pt_a1b2c3d4e5f6...",
"id": "key_abc123",
"prefix": "pt_a1b2c3d4",
"label": "Production Widget Key",
"scopes": ["embed:read", "stats:read"],
"message": "Save this key now — it will not be shown again."
}/api/partner/brandingGet or update your white-label branding settings. Custom branding colors and logos appear on all embed widgets.
/api/partner/brandingUpdate branding. Send only the fields you want to change. hide_powered_by requires Enterprise tier.// PUT body
{
"primary_color": "#10b981",
"logo_url": "https://yourfirm.com/logo.svg",
"company_name": "Apex Trader Funding",
"hide_powered_by": true
}{
"branding": {
"primary_color": "#3b82f6",
"logo_url": "https://yourfirm.com/logo.svg",
"company_name": "Your Firm Name",
"hide_powered_by": false
},
"tier": "growth",
"can_white_label": false
}/api/partner/webhookswebhooks:manageManage webhook endpoints. Get notified in real-time when trades, milestones, or account events occur.
/api/partner/webhooksCreate a webhook (max 5). URL must use HTTPS. Returns a signing secret./api/partner/webhooks?webhook_id=xxxDelete a webhook subscription.// POST body
{
"url": "https://yourfirm.com/webhooks/proptally",
"events": ["trade.created", "milestone.reached", "daily_summary"]
}{
"webhooks": [
{
"id": "wh_abc",
"url": "https://yourfirm.com/webhooks/proptally",
"events": ["trade.created", "milestone.reached"],
"is_active": true,
"last_triggered_at": 1710072000000,
"failure_count": 0
}
],
"available_events": [
"trade.created", "trade.updated", "milestone.reached",
"account.created", "account.updated", "daily_summary"
]
}/api/partner/auth/magic-linkAuthentication endpoints for the partner portal. Magic link sends a login email; session manages cookie auth.
/api/partner/auth/verify?token=xxxVerify magic link token. Sets session cookie and redirects to dashboard./api/partner/auth/sessionCheck current session status./api/partner/auth/sessionExchange API key for session cookie (alternative login)./api/partner/auth/sessionSign out and clear session cookie.// POST /api/partner/auth/magic-link
{ "email": "[email protected]" }
// POST /api/partner/auth/session (exchange API key for session)
{ "api_key": "pt_YOUR_KEY" }// POST /magic-link response (always returns success)
{ "success": true, "message": "If an account exists with that email, a login link has been sent." }
// GET /session response
{
"authenticated": true,
"partner": { "id": "ptr_abc", "name": "Your Firm", "tier": "growth" }
}
// DELETE /session response
{ "success": true }Webhook Events
Webhooks deliver real-time event notifications to your server via HTTPS POST. All payloads are signed with HMAC-SHA256.
Signature Verification
Every webhook includes an X-PropTally-Signature header containing an HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret.
Event Types
trade.createdA new trade was imported or manually added.
{
"event": "trade.created",
"timestamp": "2026-03-10T14:30:00.000Z",
"data": {
"trade_id": "abc123",
"account_id": "acc_456",
"symbol": "ES",
"direction": "long",
"quantity": 2,
"entry_price": 5250.50,
"pnl": 187.50
}
}trade.updatedA trade was modified (notes, setup type, etc).
{
"event": "trade.updated",
"timestamp": "2026-03-10T14:35:00.000Z",
"data": {
"trade_id": "abc123",
"account_id": "acc_456",
"changes": ["notes", "setup_type"]
}
}milestone.reachedA trader reached a milestone (e.g., 100 trades, $10K profit).
{
"event": "milestone.reached",
"timestamp": "2026-03-10T15:00:00.000Z",
"data": {
"account_id": "acc_456",
"milestone": "total_pnl_10000",
"label": "$10,000 Total Profit",
"value": 10247.50
}
}account.createdA new trading account was connected.
{
"event": "account.created",
"timestamp": "2026-03-10T10:00:00.000Z",
"data": {
"account_id": "acc_789",
"nickname": "Apex 50K",
"firm": "Apex Trader Funding"
}
}account.updatedAccount settings or status changed.
{
"event": "account.updated",
"timestamp": "2026-03-10T10:05:00.000Z",
"data": {
"account_id": "acc_789",
"changes": ["nickname", "status"]
}
}daily_summaryEnd-of-day summary for all active accounts. Sent daily at ~00:15 UTC.
{
"event": "daily_summary",
"timestamp": "2026-03-11T00:15:00.000Z",
"data": {
"date": "2026-03-10",
"accounts": [
{
"account_id": "acc_456",
"trades": 8,
"pnl": 425.00,
"win_rate": 62.5
}
],
"totals": { "trades": 12, "pnl": 580.00 }
}
}Embed Widgets
Drop analytics widgets into your website with a single <iframe> tag. All widgets support dark/light themes and custom accent colors.
Quick Embed
<iframe src="https://proptally.app/embed/partner/stats-card?key=pt_YOUR_KEY&account_id=acc_456&theme=dark" width="100%" height="280" frameborder="0" style="border:none;border-radius:12px;" ></iframe>
Customization
| Parameter | Values | Description |
|---|---|---|
theme | "dark" | "light" | Widget color scheme. Default: "dark" |
accent | Hex color (no #) | Primary accent color, e.g., "10b981" for green |
period | "7d" | "30d" | "90d" | "1y" | "all" | Data time period |
account_id | string | Specific account (omit for aggregate) |
hide_powered_by: true.Available Widgets
Compact overview: win rate, P&L, trade count, profit factor.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account (omit for aggregate) |
period | No | "7d", "30d", "90d", "1y", "all" |
theme | No | "dark" (default) or "light" |
accent | No | Hex color for accents (e.g., "3b82f6") |
<iframe src="https://proptally.app/embed/partner/stats-card?key=pt_YOUR_KEY&theme=dark" width="100%" height="280" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Detailed summary with sparkline, instruments, and metrics grid.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
period | No | Time period filter |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/performance-summary?key=pt_YOUR_KEY&theme=dark" width="100%" height="380" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Canvas-rendered equity curve chart with daily P&L overlay.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
period | No | Time period filter |
theme | No | "dark" or "light" |
accent | No | Chart line color |
<iframe src="https://proptally.app/embed/partner/equity-curve?key=pt_YOUR_KEY&theme=dark" width="100%" height="300" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Top traders ranked by P&L, win rate, or trade count.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
firm_id | No | Filter by prop firm |
limit | No | Number of traders (default: 10) |
theme | No | "dark" or "light" |
sort | No | "pnl", "win_rate", or "trades" |
<iframe src="https://proptally.app/embed/partner/leaderboard?key=pt_YOUR_KEY&theme=dark" width="100%" height="400" frameborder="0" style="border:none;border-radius:12px;"></iframe>
P&L heatmap by day of week and hour of day.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
period | No | Time period filter |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/trade-heatmap?key=pt_YOUR_KEY&theme=dark" width="100%" height="200" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Per-instrument performance with trade count bars and win rates.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
period | No | Time period filter |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/instrument-breakdown?key=pt_YOUR_KEY&theme=dark" width="100%" height="260" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Visual arc gauge showing current drawdown vs max allowed.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
theme | No | "dark" or "light" |
max_drawdown | No | Max drawdown limit in dollars |
<iframe src="https://proptally.app/embed/partner/drawdown-gauge?key=pt_YOUR_KEY&theme=dark" width="100%" height="180" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Current winning/losing streak with recent W/L history dots.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
period | No | Time period filter |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/win-streak?key=pt_YOUR_KEY&theme=dark" width="100%" height="240" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Calendar heatmap showing daily P&L with month navigation.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
month | No | YYYY-MM format (default: current month) |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/monthly-calendar?key=pt_YOUR_KEY&theme=dark" width="100%" height="380" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Sharpe ratio, Sortino, max drawdown, VaR, risk:reward, and more.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
period | No | Time period filter |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/risk-metrics?key=pt_YOUR_KEY&theme=dark" width="100%" height="320" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Live scrolling feed of latest trades with P&L, direction, and duration.
| Param | Required | Description |
|---|---|---|
key | Yes | Your API key |
account_id | No | Specific account |
limit | No | Number of trades (default: 10, max: 25) |
theme | No | "dark" or "light" |
<iframe src="https://proptally.app/embed/partner/recent-trades?key=pt_YOUR_KEY&theme=dark" width="100%" height="420" frameborder="0" style="border:none;border-radius:12px;"></iframe>
Responsive Sizing
Widgets adapt to their container width. For responsive layouts, wrap the iframe in a container with the desired width:
<div style="max-width: 400px; width: 100%;">
<iframe
src="https://proptally.app/embed/partner/stats-card?key=pt_YOUR_KEY"
width="100%"
height="280"
frameborder="0"
style="border:none;border-radius:12px;"
></iframe>
</div>SDKs & Libraries
Official SDK libraries are coming soon. In the meantime, use any HTTP client with the REST API directly.
JavaScript / TypeScript
// Minimal PropTally client
class PropTallyClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://proptally.app/api/partner';
}
async request(path, options = {}) {
const url = new URL(this.baseUrl + path);
if (options.params) {
Object.entries(options.params).forEach(([k, v]) => url.searchParams.set(k, v));
}
const res = await fetch(url.toString(), {
method: options.method || 'GET',
headers: {
'X-API-Key': this.apiKey,
...(options.body ? { 'Content-Type': 'application/json' } : {}),
},
body: options.body ? JSON.stringify(options.body) : undefined,
});
if (!res.ok) throw new Error(`API error ${res.status}: ${(await res.json()).error}`);
return res.json();
}
getStats(params) { return this.request('/stats', { params }); }
getAccounts(params) { return this.request('/accounts', { params }); }
getTrades(params) { return this.request('/trades', { params }); }
getDashboard() { return this.request('/dashboard'); }
getBranding() { return this.request('/branding'); }
getWebhooks() { return this.request('/webhooks'); }
createKey(label, scopes) {
return this.request('/keys', { method: 'POST', body: { label, scopes } });
}
createWebhook(url, events) {
return this.request('/webhooks', { method: 'POST', body: { url, events } });
}
}
// Usage
const pt = new PropTallyClient('pt_YOUR_KEY');
const stats = await pt.getStats({ period: '30d' });Python
import requests
class PropTallyClient:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://proptally.app/api/partner'
def _request(self, method, path, params=None, json=None):
res = requests.request(method, f'{self.base_url}{path}',
params=params, json=json,
headers={'X-API-Key': self.api_key})
res.raise_for_status()
return res.json()
def get_stats(self, **params):
return self._request('GET', '/stats', params=params)
def get_accounts(self, **params):
return self._request('GET', '/accounts', params=params)
def get_trades(self, **params):
return self._request('GET', '/trades', params=params)
def get_dashboard(self):
return self._request('GET', '/dashboard')
def create_webhook(self, url, events):
return self._request('POST', '/webhooks', json={'url': url, 'events': events})
# Usage
pt = PropTallyClient('pt_YOUR_KEY')
stats = pt.get_stats(period='30d')
print(f"Win rate: {stats['stats']['winRate']}%")Changelog
- Added
/api/partner/tradesendpoint with pagination, filtering, and sorting - Added magic link authentication for the partner portal
- Added branding API for white-label customization
- Partner portal now uses secure httpOnly session cookies
- Added webhook system with 6 event types and HMAC-SHA256 signing
- Added self-service API key management (create/revoke)
- Added partner dashboard API with usage analytics
- Increased Growth tier daily limit from 5,000 to 10,000 requests
- Added Drawdown Gauge widget
- Added Instrument Breakdown widget
- Added Trade Heatmap widget
- Added Leaderboard widget with sort options
- Initial release: Stats Card, Performance Summary, Equity Curve widgets
- REST API: /stats and /accounts endpoints
- 3-tier system: Starter, Growth, Enterprise
Need Help?
Our enterprise team is here to help with integration, custom requirements, and technical support.