🧩Developer API

Build on Qortle

Wire our SEBI-registered research into your own trading program β€” read top-picks and their research reports, and stream entry / exit / SL-hit / TP-hit signals over REST and WebSocket. You keep control of every order.

Developer preview. The base URL below is the development environment and the contract may change before general availability. Qortle never places orders. The optional β€œplace in your broker” flow below hands you a pre-filled basket that you review and place in your own broker; automated execution and portfolio are not part of this phase.

1. Get an API key

In the app, go to Account β†’ API keys β†’ New key and choose the scopes your client needs:

  • Read top picks β€” the GET /v2/top-picks and per-pick GET /v2/picks/{id}/research endpoints.
  • Read notifications β€” GET /v2/events + the WebSocket stream.

Copy the full secret when it's shown β€” it starts with fk_live_ and is displayed once. Optionally lock the key to your server's IP(s), and set an expiry. Your plan must include API access.

2. Authenticate

Send the key as a bearer token on every REST call:

curl -H "Authorization: Bearer fk_live_xxxxxxxxxxxx" \
  "https://dev.api.qortle.ai/v2/top-picks?universe=NIFTY50&mode=Swing"

For the WebSocket, pass it in the query string:

wss://dev.api.qortle.ai/v1/ws/notifications?api_key=fk_live_xxxxxxxxxxxx

3. Read today's picks

GET https://dev.api.qortle.ai/v2/top-picks?universe=NIFTY50&mode=Swing&limit=5

Each item carries the symbol, recommendation, direction and the trade plan (entry / stop-loss / targets) where available. Use mode=ALL / universe=ALL to aggregate every cell server-side.

3b. Read the research report

Every pick carries an RA research report β€” the reasoning behind the call β€” so you (or your end user) can apply your own rules before acting. Fetch the machine-readable view with the same picks.read key:

GET https://dev.api.qortle.ai/v2/picks/{pick_id}/research

Returns the instrument, the recommendation with numeric levels ({entry, stop_loss, targets}), the structured rationale and risk, and the mandatory SEBI disclosures. The full signed document stays available at /v2/picks/{pick_id}/report.html and .pdf.

4. Stream notifications

Connect the WebSocket and read JSON frames:

  • {"type":"connected","user_id":"…"} β€” stream open.
  • {"type":"notification","notification":{…}} β€” a live trade-signal event.
  • {"type":"pong"} β€” reply to a keepalive containing ping.

One live stream per key β€” a second concurrent connection is closed with code 4409. Other close codes: 4401 unauthenticated, 4402 plan lacks API access, 4403 missing scope.

5. Never miss an exit (replay)

The WebSocket is low-latency push; the guaranteed source of truth is the cursor-paged replay endpoint:

GET https://dev.api.qortle.ai/v2/events?since=<cursor>&limit=100

Start with no since (or your last saved cursor), process each event, then pass the response's next_cursor as the next since. Keep polling while has_more is true. Delivery is at-least-once β€” dedupe on id. Event types: PICK_NEW, PICK_ENTRY_NEAR, POSITION_SL_HIT, POSITION_TP_HIT, POSITION_CLOSED.

On (re)connect you can also fold replay into the stream with ?since=<cursor>; the stream emits the missed events, then {"type":"replay_complete"}, before going live.

6. Limits & errors

StatusMeaning
401Missing / malformed / expired / revoked key.
402Your plan doesn't include API access.
403Key lacks the scope this endpoint needs.
429Rate / daily limit β€” see Retry-After and X-RateLimit-Limit.

One key per client; keep the secret server-side; rotate before expiry.

7. Minimal Python client

import requests, websocket  # pip install requests websocket-client

BASE = "https://dev.api.qortle.ai"
KEY  = "fk_live_xxxxxxxxxxxx"
H    = {"Authorization": f"Bearer {KEY}"}

# pull today's picks
picks = requests.get(f"{BASE}/v2/top-picks",
                     params={"universe": "NIFTY50", "mode": "Swing"},
                     headers=H, timeout=10).json()

# catch up on missed events, tracking a cursor
cursor = None
while True:
    r = requests.get(f"{BASE}/v2/events",
                     params={"since": cursor} if cursor else {},
                     headers=H, timeout=10).json()
    for ev in r["events"]:
        handle(ev)            # dedupe on ev["id"]
    cursor = r["next_cursor"]
    if not r["has_more"]:
        break

# live stream, replaying from the cursor on connect
ws = websocket.create_connection(
    f"{BASE.replace('https','wss')}/v1/ws/notifications"
    f"?api_key={KEY}" + (f"&since={cursor}" if cursor else ""))

8. How to run the code

Save the reference client as qortle_client.py (the snippet above is the core; the full client adds typed errors, cursor persistence, WebSocket reconnect, and the basket command in step 9). Then:

1. Install the two dependencies

pip install requests websocket-client

2. Set your API key

export QORTLE_API_KEY=fk_live_xxxxxxxxxxxx

3. Read picks and catch up on events (no stream)

python qortle_client.py --universe NIFTY50 --mode Options --no-stream

4. Or hold the live stream open

python qortle_client.py --universe NIFTY50 --mode Options

You'll see today's picks (empty outside market hours, 09:15–15:30 IST), then events paging by cursor, then live frames. If a call errors, the status code tells you which gate hit β€” see step 6 (401 key, 402 plan, 403 scope, 429 rate limit).

9. Place picks in your own broker (optional)

Prefer review-and-place over full automation? The reference client can turn today's picks into a pre-filled order basket that you open and confirm in your own broker (Zerodha today). Qortle does not place the order β€” your broker executes only after you review and tap Place, and no broker credentials are used or stored.

QORTLE_API_KEY=fk_live_… QORTLE_KITE_PUBLISHER_KEY=your_kite_publisher_key \
  python qortle_client.py --basket --universe NIFTY50 --mode Options \
  --capital-per-trade 20000 --basket-out basket.html
# open basket.html β†’ review in your own Zerodha account β†’ place

Sizing is your choice: --qty, --capital-per-trade, or --risk-per-trade. Orders are LIMIT at the recommended entry by default; stop-loss and targets are shown for you to set yourself. A pick that has already hit its stop-loss or target is no longer placeable.

You stay in control. Qortle provides research recommendations and prepares the basket; your broker places the orders only after you review and confirm them. This is not an instruction to trade β€” review every order before placing.
Full API reference

Every endpoint, parameter and schema (OpenAPI / Redoc).

Join the developer community

Questions, ideas and feedback are welcome β€” and the client SDK is open source, so you can read it, adapt it, and contribute.

Community channels are for building with the API β€” please keep trading tips, solicitation and personalized advice out of them.

Qortle is a brand of Tradesurf Research Private Limited, a SEBI-registered Research Analyst (Reg. No. INH000029810). Research and recommendations are for informational purposes only and are not investment advice. Investments in securities markets are subject to market risks; read all related documents carefully. Registration, enlistment or certification do not guarantee performance or assure returns.