The Sensible Trader
REST API
Add trades to your journal programmatically — from scripts, spreadsheets, automations (n8n, Zapier, Make), or any custom tooling. Authentication uses an API key you generate inside the app.
https://api.the-sensible-trader.com/api
Authentication #
All API requests must include your API key in the x-api-key request header. Keys are generated per-user inside the app and grant write access to your trade journal.
Generating a key
Log into me.the-sensible-trader.com, open Settings → API tokens, enter a name for the key, and click Generate key. The full key is shown exactly once — copy it immediately.
POST https://api.the-sensible-trader.com/api/v1/trades x-api-key: st_your_api_key_here Content-Type: application/json
Base URL #
All endpoints are relative to the base URL below. Currently only v1 is available.
https://api.the-sensible-trader.com/api
All requests and responses use application/json.
Rate limits #
The API enforces per-IP and per-user limits to protect service quality.
| Limit | Value | Scope |
|---|---|---|
| Requests / minute | 100 | Per IP address |
| AI parses / day | 20 | Per user (screenshot parsing only — not the trades API) |
| AI parses / month | 500 | Per user (screenshot parsing only) |
When a rate limit is exceeded the API returns 429 Too Many Requests or 403 Forbidden.
POST /v1/trades #
Creates a new trade in your journal. Supports all trade types: options (CSP, CC, Long Call, Long Put, spreads), shares, and multi-leg strategies.
Parameters
Send parameters as a JSON body with Content-Type: application/json.
| Name | Type | Required | Description |
|---|---|---|---|
| ticker | string | Required | Stock or ETF ticker symbol. Automatically uppercased. AAPLTSLASPY |
| tradeStrategy | string | Required | The strategy used for this position. Must be one of the supported values.
CSPCCLong CallLong Put
SharesNaked CallDebit Spread
Credit SpreadIron CondorButterfly
|
| action | string | Required | The trade action. Opening actions create new positions; closing actions mark a position closed.
BTOSTOBTCSTC
BUYSELLEXPASN
See Strategies & actions for the valid pairings.
|
| brokerPlatform | string | Required | Broker or platform where the trade was executed.
RobinhoodMerrill Edgetastytrade
SchwabFidelityE*TRADE
IBKRWebullOther
|
| contracts | number | Required | Number of contracts (options) or shares (for the Shares strategy). Must be ≥ 1. |
| dateOpened | string | Required | Date the position was opened, in YYYY-MM-DD format. |
| openPrice | number | Required | Per-share/contract price at which the position was opened (premium collected or paid). |
| strike | number | Optional | Strike price for options. Required for all options strategies; omit for Shares. |
| expiration | string | Optional | Option expiration date in YYYY-MM-DD format. Recommended for all options positions. |
| dateClosed | string | Optional | Date the position was closed, in YYYY-MM-DD format. Include to log a fully closed trade in a single call. |
| closedPrice | number | Optional | Per-share/contract price at which the position was closed. Required if dateClosed is provided. |
| isExpired | boolean | Optional | Set to true if the option expired worthless. Defaults to false. |
| comments | string | Optional | Free-text notes for this trade. Supports up to 2,000 characters. |
| reviewFlag | boolean | Optional | Mark this trade for manual review in the app. Useful when logging from automation and some fields are uncertain. |
| tags | string[] | Optional | Array of custom string tags for filtering and grouping trades. |
| legs | object[] | Optional | Array of leg objects for multi-leg strategies (spreads, iron condors, butterflies). Each leg has: action, optionType (Call/Put), strike, expiration, contracts, openPrice. |
Strategies & actions
Each strategy has a fixed set of valid opening and closing actions. Mismatched combinations are rejected with a validation error.
| Strategy | Open action | Close action | Notes |
|---|---|---|---|
| CSP | STO | BTC | Cash-secured put — sell to open, buy to close |
| CC | STO | BTC | Covered call — sell to open, buy to close |
| Long Call | BTO | STC | Buy to open, sell to close |
| Long Put | BTO | STC | Buy to open, sell to close |
| Shares | BUY | SELL | Use contracts for share quantity |
| Credit Spread | STO | BTC | Use legs array for individual legs |
| Debit Spread | BTO | STC | Use legs array for individual legs |
| Iron Condor | STO | BTC | Use legs for all 4 legs |
| Butterfly | STO | BTC | Use legs for all legs |
| Naked Call | STO | BTC | Sell to open, buy to close |
| Any | — | EXP / ASN | EXP = expired worthless · ASN = assigned |
Responses
On success the full trade object is returned:
{
"_id": "685312abc1234def56789012",
"ticker": "AAPL",
"tradeStrategy": "CSP",
"action": "STO",
"brokerPlatform": "Robinhood",
"contracts": 1,
"strike": 170,
"dateOpened": "2026-06-08",
"expiration": "2026-06-20",
"openPrice": 2.5,
"closedPrice": null,
"dateClosed": null,
"isOpen": true,
"isExpired": false,
"reviewFlag": false,
"createdAt": "2026-06-08T18:32:11.000Z"
}
Example: Cash-secured put #
Sell to open a CSP on AAPL with a $170 strike expiring June 20.
curl -X POST https://api.the-sensible-trader.com/api/v1/trades \ -H "x-api-key: st_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "ticker": "AAPL", "tradeStrategy": "CSP", "action": "STO", "brokerPlatform": "Robinhood", "contracts": 1, "strike": 170, "dateOpened": "2026-06-08", "expiration": "2026-06-20", "openPrice": 2.50 }'
Example: Covered call #
Sell to open a covered call on TSLA with a $350 strike.
curl -X POST https://api.the-sensible-trader.com/api/v1/trades \ -H "x-api-key: st_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "ticker": "TSLA", "tradeStrategy": "CC", "action": "STO", "brokerPlatform": "Merrill Edge", "contracts": 2, "strike": 350, "dateOpened": "2026-06-08", "expiration": "2026-06-27", "openPrice": 4.20, "comments": "Selling against 200 shares held" }'
Example: Long call / put #
Buy to open a long call on NVDA.
curl -X POST https://api.the-sensible-trader.com/api/v1/trades \ -H "x-api-key: st_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "ticker": "NVDA", "tradeStrategy": "Long Call", "action": "BTO", "brokerPlatform": "tastytrade", "contracts": 3, "strike": 130, "dateOpened": "2026-06-08", "expiration": "2026-07-18", "openPrice": 8.75 }'
Example: Closing a trade #
To log an already-closed position in one call, include dateClosed and closedPrice. The app will compute realized P&L automatically.
curl -X POST https://api.the-sensible-trader.com/api/v1/trades \ -H "x-api-key: st_your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "ticker": "CRWD", "tradeStrategy": "CSP", "action": "BTC", "brokerPlatform": "Merrill Edge", "contracts": 3, "strike": 670, "dateOpened": "2026-06-04", "expiration": "2026-06-05", "openPrice": 3.40, "dateClosed": "2026-06-05", "closedPrice": 0.30 }'
Error codes #
All errors return JSON with a message, error, and statusCode field.
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Invalid or revoked API key"
}
Client libraries #
The API is plain HTTP+JSON — use any HTTP client. Here are quick-start snippets for the most common environments.
JavaScript / Node.js
// Works in Node.js 18+ (native fetch) and modern browsers const res = await fetch( 'https://api.the-sensible-trader.com/api/v1/trades', { method: 'POST', headers: { 'x-api-key': 'st_your_api_key_here', 'Content-Type': 'application/json', }, body: JSON.stringify({ ticker: 'AAPL', tradeStrategy: 'CSP', action: 'STO', brokerPlatform: 'Robinhood', contracts: 1, strike: 170, dateOpened: '2026-06-08', expiration: '2026-06-20', openPrice: 2.50, }), } ); const trade = await res.json(); console.log(trade._id);
Python
import requests
res = requests.post(
"https://api.the-sensible-trader.com/api/v1/trades",
headers={
"x-api-key": "st_your_api_key_here",
"Content-Type": "application/json",
},
json={
"ticker": "AAPL",
"tradeStrategy": "CSP",
"action": "STO",
"brokerPlatform": "Robinhood",
"contracts": 1,
"strike": 170,
"dateOpened": "2026-06-08",
"expiration": "2026-06-20",
"openPrice": 2.50,
},
)
res.raise_for_status()
print(res.json()["_id"])