The last five sessions, in full.See the record →
DEVELOPER DOCUMENTATION

NIFTY Signals API

Every call published to the NIFTY Signals page, as JSON. Same entitlement, same content, same five-second delay — nothing is computed here that a subscriber does not already see on the page.

For informational and educational purposes only. Not investment advice, not a recommendation to buy or sell, and not personalised to your circumstances. NiftyDesk is not a SEBI-registered Research Analyst or Investment Adviser. Derivatives trading carries substantial risk of loss. Redistribution of these signals to third parties is prohibited.

Generate a credential on the NIFTY Signals page. You need an account and the accepted risk agreement; a session pass is required to read data, not to create a key.

Authentication

A credential is a pair. The Key ID is public and stays visible on your dashboard; the Secret is shown once, at generation, and is stored only as a hash — we cannot recover it for you. Present both, over HTTPS, either as HTTP Basic or as two headers.

# HTTP Basic — Key ID as the user, Secret as the password
curl -u "ndk_YOUR_KEY_ID:nds_live_YOUR_SECRET" \
  https://niftydesk.app/api/v1/developer/signals/live

# or as headers
curl -H "X-API-Key: ndk_YOUR_KEY_ID" \
     -H "X-API-Secret: nds_live_YOUR_SECRET" \
  https://niftydesk.app/api/v1/developer/signals/live

A bearer token carrying the Secret alone is not accepted — both halves are required. Base URL is https://niftydesk.app/api/v1/developer/signals. Every timestamp this API emits is IST (UTC+05:30), and a naive since you send is read as IST.

Endpoints

GET/live

The current state: the live call if there is one, plus the running scoreboard.

{
  "state": "live",
  "signal": {
    "id": "6f1c…",
    "underlying": "NIFTY",
    "direction": "SHORT",
    "conviction_score": 78.0,
    "conviction_band": "STRONG",
    "expected_move_points": 45.0,
    "spot_at_signal": 24812.4,
    "points_captured": null,
    "published_at": "2026-08-18T10:47:12+05:30",
    "visible_at": "2026-08-18T10:47:17+05:30",
    "ended_at": null,
    "end_reason": null,
    "is_live": true,
    "is_reevaluating": false,
    "log_date": "2026-08-18"
  },
  "last_signal": { "…": "the same object, even once it has ended" },
  "market_open": true,
  "server_time": "2026-08-18T10:52:00+05:30",
  "session_date": "2026-08-18",
  "delay_seconds": 5,
  "session_signal_count": 2,
  "spot_now": 24798.1,
  "engine_ok": true,
  "points_today": 18.5,
  "points_week": 61.0,
  "points_overall": 402.5,
  "settled_today": 1,
  "disclaimer": "…"
}

state is one of live, stand_down, idle, pre_open, closed. A call the engine has already stepped away from is never returned as signal — it stays available on last_signal, so reading signal always means a call that is open right now.

points_captured is signed, so positive always means the call went the way it said. It is null when the result is not known — never 0, because zero is a claim.

GET/events?since={'{'}cursor{'}'}&limit=100

The append-only event stream. Poll this with the cursor you were last given.

{
  "events": [
    {
      "event_id": "6f1c…:SIGNAL_OPEN",
      "event": "SIGNAL_OPEN",
      "at": "2026-08-18T10:47:17+05:30",
      "reason": null,
      "reversal": false,
      "reversal_of": null,
      "signal": { "…": "as above" }
    }
  ],
  "cursor": "2026-08-18T10:47:17+05:30",
  "server_time": "2026-08-18T10:52:00+05:30",
  "delay_seconds": 5,
  "disclaimer": "…"
}

Events are ordered oldest-first, so applying them in sequence leaves you in the state we are in. Feed cursor straight back as since on the next poll; it is echoed even when the list is empty, so you never have to decide what to send. event_id is stable and idempotent — re-polling the same window is a no-op whether you deduplicate or simply trust the cursor. Omitting since returns the last day, not a month of backlog. limit is 1–500, default 100; if you hit it, advance the cursor and collect the rest rather than skipping a session.

GET/history?days=10&page=1

Recent published calls, newest first, windowed by day.

{
  "signals": [ { "…": "as above" } ],
  "days": ["2026-08-18", "2026-08-17"],
  "silent_days": ["2026-08-17"],
  "page": 1,
  "total": 7,
  "has_more": true,
  "disclaimer": "…"
}

Pagination is by day window, not by row offset — page=2 reaches older sessions rather than more rows from the same ones. silent_days are sessions where nothing qualified: a gap in the record is a fact about the product being selective, and inferring it from missing rows would read as an outage instead.

GET/access

What your credential is currently entitled to. Useful for telling a quiet market apart from a lapsed pass.

{
  "mode": "paid",
  "unlocked": true,
  "session_date": "2026-08-18",
  "trial_days_left": 0,
  "trial_ends_on": null,
  "paid_through": "2026-08-25",
  "comped_session": false,
  "delay_seconds": 5,
  "disclaimer": "…"
}

Event types

EventMeaning
SIGNAL_OPENA new call has been published.
SIGNAL_BOOKEDThe call was closed with a result.
SIGNAL_DONEThe expected move was reached.
SIGNAL_CLOSEDThe call ended without a result of its own.
SIGNAL_REEVALUATINGThe call is being reconsidered. It has not ended and may resume.

A reversal is not its own event. It arrives as a SIGNAL_BOOKED immediately followed by a SIGNAL_OPEN the other way, with reversal: true and reversal_of naming the closed call. A consumer that ignores the flag still behaves correctly — close, then open; one that reads it can treat the pair atomically.

Errors

StatuscodeWhat to do
401SIGNALS_API_KEY_INVALIDMissing, malformed, unknown or revoked. Stop and check the credential; retrying will not help.
402SIGNALS_ACCESS_REQUIREDNo pass for this session. Back off to a slow poll and resume when /access unlocks.
403SIGNALS_AGREEMENT_REQUIREDAccept the risk agreement on the website. It cannot be accepted over the API.
429SIGNALS_API_RATE_LIMITEDHonour Retry-After. Do not retry in a tight loop.
400SIGNALS_API_BAD_CURSORsince was not an ISO 8601 timestamp.

Rate limits and delay

  • 60 requests per minute and 10,000 per day, counted per credential — so one runaway loop cannot lock your other integrations out of a live session. A one-second poll of /live fits inside both.
  • Up to 5 active credentials per account. Revoked ones do not count against it.
  • Signals reach the API on the same five-second delay as the website, and that applies to every credential without exception — there is no undelayed tier.
  • Redistribution to third parties is not permitted, and a credential can be revoked at any time from your dashboard.

Get API access

Generate a Key ID and Secret from the NIFTY Signals page. The first five trading days are free, and weekends don't burn them.

For informational and educational purposes only. Not investment advice, not a recommendation to buy or sell, and not personalised to your circumstances. NiftyDesk is not a SEBI-registered Research Analyst or Investment Adviser. Derivatives trading carries substantial risk of loss. Redistribution of these signals to third parties is prohibited.