Skip to content
Cirrus home
Sign in

Reference

Signal URLs

Secret URLs that turn TradingView, Chartink or Kuberhunt alerts into orders.

List signal modes #

GET /v2/signal-modes app session

Each of the caller's signal URLs with its strategy's mode: direct (alerts place orders from the Signals strategy's settings, as before) or algo (alerts become signals to a bound automated-strategy deployment, which decides with its own rules and safety checks).

More about this

App session only; works whatever the flags (a URL left in algo mode while algo mode is off shows algo: its alerts are ignored until it is switched back).

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v2/signal-modes" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": [
    {
      "endpoint_id": "we_5aD4VrIDQtbAm8xA",
      "kind": "kuberhunt",
      "strategy_id": "kh-01M59MFHD1WNSQAQCAHHX3DEXZ",
      "mode": "direct",
      "deployment_id": null,
      "switched_at": null,
      "can_use_algo": false
    },
    {
      "endpoint_id": "we_q02Q5Ag9f6C6q0o5",
      "kind": "tradingview",
      "strategy_id": "nifty-alerts-01M59MFHCN0NJ023A39J4CQN2X",
      "mode": "algo",
      "deployment_id": "01M59MFHD6BJ6PM60WFMFAV16X",
      "switched_at": "2026-10-19T08:29:35.023+00:00",
      "can_use_algo": true
    }
  ],
  "error": null
}

Switch a signal URL's mode #

PUT /v2/signal-modes/{endpoint_id} app session

Switches the URL's Signals strategy to algo (bound to deployment_id) or back to direct.

More about this

The URL, its secrets and what the provider sends do not change. In algo mode an alert is not placed: it becomes a signal to the deployment (TradingView entry asks to enter, exit to exit; a Chartink alert asks to enter), and the deployment decides with every safety check (entry window, risk, combined stop, daily limits, kill switch, at most one entry per cycle); an exit closes only what the deployment opened.

Allowed only when flat: no position held by the Signals strategy and no open trade on the deployments involved (409 not_flat). Kuberhunt URLs stay direct. The deployment must be the caller's, not stopped, and its strategy must take alerts on a signal URL (webhook@1). Switching to algo needs automated strategies and algo mode for signals enabled for the user; switching back to direct always works. While algo mode is off, alerts on a URL left in algo are ignored (never placed directly) and the user is told. Takes an optional Idempotency-Key. App session only.

Parameters

  • endpoint_id path · string required

    The signal URL's endpoint_id.

Body fields

  • mode string required

    direct or algo.

    One of: direct, algo, unknown

  • deployment_id string | null

    algo: one of the caller's running deployments whose strategy takes alerts on a signal URL (webhook@1). Absent for direct.

Errors

HTTPCodeWhen
400malformed_json

The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types).

401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

403own_session_required

Credentials can only be created from the user's own signed-in session.

404endpoint_not_found

No signal URL with this id (or this secret) for the caller.

404deployment_not_found

No deployment with this id for the caller.

409not_flat

A signal strategy's mode can change only when flat: a position held by the signal strategy, or an open trade on the deployment, must close first. Nothing was changed.

409deployment_finished

The deployment is stopped; deploy the strategy again to run it.

422invalid_request

The request is well-formed but not valid; field names the input.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

PUT
curl -X PUT "https://cirrus.pocketful.in/v2/signal-modes/<endpoint_id>" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "algo",
    "deployment_id": "01M59MFHD6BJ6PM60WFMFAV16X"
  }'
Response · 200
{
  "status": "success",
  "data": {
    "endpoint_id": "we_q02Q5Ag9f6C6q0o5",
    "kind": "tradingview",
    "strategy_id": "nifty-alerts-01M59MFHCN0NJ023A39J4CQN2X",
    "mode": "algo",
    "deployment_id": "01M59MFHD6BJ6PM60WFMFAV16X",
    "switched_at": "2026-10-19T08:29:35.023+00:00",
    "can_use_algo": true
  },
  "error": null
}

List signal URLs #

GET /v1/hooks/endpoints app session

The signed-in user's live signal URLs (never their secrets).

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v1/hooks/endpoints" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": [
    {
      "endpoint_id": "we_6USUzj3Fc2VUfgXa",
      "kind": "tradingview",
      "strategy_id": "nifty-breakout-01M3PGPS2RED832PWZ7N5VS16P",
      "created_at": "2026-09-29T12:02:21.916811+00:00",
      "has_body_secret": true
    }
  ],
  "error": null
}

Issue a signal URL #

POST /v1/hooks/endpoints app session

Issues a secret URL for one strategy and provider.

More about this

Give the provider the API origin followed by path; for TradingView also put "secret": "<body_secret>" in the alert message. The URL (and body secret) are shown only in this response. Issuing a new URL for the same strategy and provider revokes the previous one at once.

What each provider sends to the URL, and every reply, is described on POST /v1/hooks/{kind}/{secret}. Only the account holder, signed in themselves, can issue URLs.

Body fields

  • kind string required

    The provider that will call the URL.

    One of: kuberhunt, tradingview, chartink

  • strategy_id string required

    The strategy's id: 1-64 letters, digits, - or _.

Errors

HTTPCodeWhen
400malformed_json

The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types).

401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

422invalid_request

The request is well-formed but not valid; field names the input.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/hooks/endpoints" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "tradingview",
    "strategy_id": "nifty-breakout-01M3PGPS2RED832PWZ7N5VS16P"
  }'
Response · 201
{
  "status": "success",
  "data": {
    "endpoint_id": "we_6USUzj3Fc2VUfgXa",
    "kind": "tradingview",
    "strategy_id": "nifty-breakout-01M3PGPS2RED832PWZ7N5VS16P",
    "created_at": "2026-09-29T12:02:21.916811+00:00",
    "has_body_secret": true,
    "path": "/v1/hooks/tradingview/wh_wDMkI4XGVWLhusCX9Bb0UatmpoJdHTLECRdRR9ggged",
    "body_secret": "tvs_bD1ZOvrvN4dKZrKmCkfTL7eg7i0LVOW0",
    "note": "Keep this URL private: anyone with it can send signals. Issuing a new one revokes this."
  },
  "error": null
}

Revoke a signal URL #

DELETE /v1/hooks/endpoints/{endpoint_id} app session

Revokes the URL at once: the provider's next request gets 404.

Parameters

  • endpoint_id path · string required

    The signal URL's endpoint_id.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404endpoint_not_found

No signal URL with this id (or this secret) for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

DELETE
curl -X DELETE "https://cirrus.pocketful.in/v1/hooks/endpoints/<endpoint_id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "endpoint_id": "we_6USUzj3Fc2VUfgXa",
    "revoked": true
  },
  "error": null
}

Rotate a signal URL #

POST /v1/hooks/endpoints/{endpoint_id}/rotate app session

Issues a new secret URL (and, for TradingView, a new body secret) for the same endpoint_id, shown only in this response.

More about this

The old URL stops working at once. Only the account holder, signed in themselves, can rotate URLs.

Parameters

  • endpoint_id path · string required

    The signal URL's endpoint_id.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404endpoint_not_found

No signal URL with this id (or this secret) for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/hooks/endpoints/<endpoint_id>/rotate" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "endpoint_id": "we_6USUzj3Fc2VUfgXa",
    "kind": "tradingview",
    "strategy_id": "nifty-breakout-01M3PGPS2RED832PWZ7N5VS16P",
    "created_at": "2026-09-29T12:02:21.926086+00:00",
    "has_body_secret": true,
    "path": "/v1/hooks/tradingview/wh_afgJybcPb09zIeVruYYtBlwm1paQkKo1VtryahqbOTB",
    "body_secret": "tvs_GKEskzlA7wA0oZ2TWs3ph7g0mHUeiPba",
    "note": "Give the provider this new URL now: the old one no longer works. It is shown only once."
  },
  "error": null
}

List what a signal URL received #

GET /v1/hooks/endpoints/{endpoint_id}/deliveries app session

Every request the URL received in the last 7 days, newest first: when, the outcome in one word, why in plain words, the orders it placed and the status the provider was answered with (never the payload).

More about this

Page with limit and cursor.

Parameters

  • endpoint_id path · string required

    The signal URL's endpoint_id.

  • limit query · integer

    Page size, at least 1 (default 50; above 200 counts as 200).

  • cursor query · string

    next_cursor of the previous page.

Errors

HTTPCodeWhen
400invalid_query

The query string does not fit the route's parameters.

401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404endpoint_not_found

No signal URL with this id (or this secret) for the caller.

422invalid_request

The request is well-formed but not valid; field names the input.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v1/hooks/endpoints/<endpoint_id>/deliveries" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "items": [
      {
        "delivery_id": "01M3PGPS5220JGR75R52C6M2XY",
        "at": "2026-09-29T12:02:21.986Z",
        "provider": "chartink",
        "outcome": "rate_limited",
        "reason": "too many alerts in a short time; extra ones were refused",
        "orders_placed": 0,
        "order_ids": [],
        "http_status": 429,
        "request_id": "01M3PGPS4YGSNDQW6RQGZXNDP9"
      },
      {
        "delivery_id": "01M3PGPS4YZ5CPAXJSB94WSXSQ",
        "at": "2026-09-29T12:02:21.982Z",
        "provider": "chartink",
        "outcome": "duplicate",
        "reason": "the same alert arrived twice; the copy was skipped",
        "orders_placed": 0,
        "order_ids": [],
        "http_status": 200,
        "request_id": "01M3PGPS4WS2X3TGFQEG16DYKD"
      },
      {
        "delivery_id": "01M3PGPS4WTGQ0EJZRCMW5RA52",
        "at": "2026-09-29T12:02:21.980Z",
        "provider": "chartink",
        "outcome": "duplicate",
        "reason": "the same alert arrived twice; the copy was skipped",
        "orders_placed": 0,
        "order_ids": [],
        "http_status": 200,
        "request_id": "01M3PGPS4V5PYNQGZ8ZC2A4FV2"
      },
      {
        "delivery_id": "01M3PGPS4VERYPXBJRKY6DFR6Y",
        "at": "2026-09-29T12:02:21.979Z",
        "provider": "chartink",
        "outcome": "placed",
        "reason": null,
        "orders_placed": 1,
        "order_ids": [
          "PAPER-1"
        ],
        "http_status": 200,
        "request_id": "01M3PGPS4KQG8PH1F4PJ1YC283"
      }
    ],
    "next_cursor": null
  },
  "error": null
}

Dry-run a signal #

POST /v1/hooks/endpoints/{endpoint_id}/test app session

Runs a payload through the same checks, parsing and strategy rules as a real delivery to this URL and says which orders it would place, without placing anything or touching any state (duplicate / sequence checks, daily entry counts, the URL's rate limit, the activity and delivery logs).

More about this

Send the provider's payload as the body (for Kuberhunt, with its signature headers to check the signature too); an empty body checks a sample alert. Problems with the payload are reported in errors with 200, not as HTTP errors.

Parameters

  • endpoint_id path · string required

    The signal URL's endpoint_id.

  • X-Kuberhunt-Signature header · string

    Kuberhunt only: v1=<hex HMAC-SHA256>; without it the signature is not checked (a warning says so).

  • X-Kuberhunt-Timestamp header · string

    Kuberhunt only: Unix seconds the signature was made at.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404endpoint_not_found

No signal URL with this id (or this secret) for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/hooks/endpoints/<endpoint_id>/test" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "stocks": "TESTSU",
    "trigger_prices": "100.03",
    "triggered_at": "9:30 am",
    "scan_name": "Breakouts",
    "alert_name": "Breakout alert"
  }'
Response · 200
{
  "status": "success",
  "data": {
    "valid": true,
    "errors": [],
    "warnings": [],
    "would_place": [
      {
        "account": "P1",
        "symbol": "TESTSU-EQ",
        "exchange": "NSE",
        "side": "BUY",
        "qty": 3,
        "order_type": "LIMIT",
        "price": 100.55,
        "product": "MIS"
      }
    ]
  },
  "error": null
}

Receive a provider signal #

POST /v1/hooks/{kind}/{secret} no auth

The URL a provider (TradingView, Chartink, Kuberhunt) calls; no Authorization: the secret in the URL is the credential (plus the body secret for TradingView and the signature for Kuberhunt).

More about this

The body depends on kind (see TradingViewAlert, ChartinkAlert, KuberhuntEvent). Orders are placed as the URL's owner, following the strategy's settings.

Replies are not the REST envelope: they are made for the providers, which only look at the status. 200 means received (whatever it came to: see the URL's deliveries and the activity log); only 503 asks for the same delivery again. Each URL has its own rate limit, shown in X-RateLimit-Limit / X-RateLimit-Remaining on every reply once the URL is known.

Parameters

  • kind path · string required

    The provider the URL was issued for.

  • secret path · string required

    The URL secret (wh_...), from path when the URL was issued.

  • X-Kuberhunt-Signature header · string

    Kuberhunt: v1=<hex HMAC-SHA256> of {timestamp}.{raw body}, keyed with the strategy's Kuberhunt webhook secret.

  • X-Kuberhunt-Timestamp header · string

    Kuberhunt: Unix seconds, within 300 s of now.

Errors

HTTPCodeWhen
403—

A TradingView alert with the wrong body secret

403oms_not_enabled

Order management is not enabled for this user.

404—

An unknown or revoked URL

429—

Over the URL's rate limit

503—

Temporarily unavailable; send the same delivery again later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/hooks/<kind>/<secret>" \
  -H "Content-Type: application/json" \
  -d '{
    "stocks": "TESTSU",
    "trigger_prices": "100.03",
    "triggered_at": "9:20 am",
    "scan_name": "Breakouts",
    "alert_name": "Breakout alert"
  }'
Response · 200
{
  "message": "Webhook received"
}