Skip to content
Cirrus home
Sign in

Reference

Triggers

Alerts, stop-loss, targets, entries, ladders and loss limits the server watches tick by tick.

Read the guide first

List v2 triggers #

GET /v2/triggers scope read

Every v2 trigger of the caller, newest first, with its state.

More about this

Ended triggers stay listed for 8 days.

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/triggers" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": [
    {
      "trigger_id": "01M5VVFCDFABPK086FBZD11WZ5",
      "account": "P1",
      "strategy": null,
      "kind": "bracket",
      "legs": [
        {
          "side": "BUY",
          "quantity": 5,
          "product": "MIS",
          "instrument_token": "CT:TEST:RELIANCE"
        }
      ],
      "spec": {
        "entry_px": 2500,
        "target": {
          "when": "ltp >= entry_px * 1.02"
        },
        "stop_loss": {
          "init_sl": "entry_px - 25",
          "trail": {
            "step": "5"
          }
        }
      },
      "valid_until": null,
      "state": "submitted",
      "transition_seq": 0,
      "reason": null,
      "created_at": "2026-10-26T15:48:09.715+05:30",
      "updated_at": "2026-10-26T15:48:09.715+05:30",
      "protection": {
        "stop_loss": {
          "held_by": "server",
          "broker_order_id": null,
          "level": 2475,
          "adjusted_by_server": false,
          "status": "held_by_server",
          "note": null
        },
        "target": {
          "held_by": "server",
          "broker_order_id": null,
          "level": 2550,
          "adjusted_by_server": false,
          "status": "held_by_server",
          "note": null
        },
        "trail": {
          "held_by": "server",
          "broker_order_id": null,
          "level": 2475,
          "adjusted_by_server": false,
          "status": "held_by_server",
          "note": null
        }
      },
      "created_via": "app",
      "route": "trigger"
    }
  ],
  "error": null
}

Create a v2 trigger #

POST /v2/triggers scope triggers

Creates a v2 trigger: an alert, a bracket (entry, target, stop-loss, trailing), a ladder (several targets) or a risk_limit (loss / profit limits on an account, the user or a strategy), with conditions on any tick field.

More about this

The trigger is checked first (its conditions compile, the account is the caller's, every leg's instrument exists; bracket and ladder legs need product), then handed to the trigger engine: 202 with the new trigger's id, made by the server. Read it with GET /v2/triggers/{trigger_id}; state is submitted until the engine reports. A bracket protecting a position already held (entry_px, no entry) may set its stop-loss at or beyond entry_px to lock in profit (long: entry_px <= init_sl < the current price; short mirrored); a waiting bracket's stop stays on the protective side of its entry.

Where the protection lives (route, default auto): a simple protection (a bracket on one leg already held, entry_px and no entry, with a plain price stop-loss and / or target and nothing else: no trail, no other condition, no on: close / hold_s, no valid_until, strategy or watch) is placed at the broker by the rules of POST /v1/triggers: a broker GTT for a positional product where the broker has GTTs (a broker whose GTT takes one leg holds the stop-loss and a server-side trigger the target; a CARRYFORWARD GTT never covers more than the broker holds), a broker stop-loss order for an intraday (MIS) position where the broker's stop orders are proven. It is placed before the 202, which then names its display record in trigger_id and says route gtt / stop_order; read, change and cancel it here like any v2 trigger (a change moves it at the broker and keeps the same parts; a cancel cancels it at the broker and it is no longer listed). If the broker refuses it a server-side trigger protects the position at once (route trigger, the broker's reason in route_reason); if the broker does not answer, nothing else is created (504 broker_outcome_unknown). Anything else, and route trigger, is a v2 trigger the server evaluates (route trigger).

Body fields

  • account string required

    Account id (see /v1/accounts).

  • kind string required

    The machine that runs a trigger.

    One of: alert, bracket, ladder, risk_limit

  • spec object required

    Kind-specific rules, conditions written in the CEL subset (ltp <= 120 && bid_qty > ask_qty). Checked before anything is sent: an unknown field or a condition that does not compile is a 422.

  • strategy string | null

    Strategy the trigger belongs to (risk limits at strategy level).

  • legs object[]
  • valid_until string | null

    RFC 3339; the trigger expires then.

  • watch object[]

    Instruments the conditions read but the trigger never trades (at most 3), for indicator conditions: [{"name": "nifty", "symbol": "<instrument token>"}] lets a condition say nifty.rsi(14, '5m') or nifty.ltp. Names are [a-z][a-z0-9_]{0,15}, not a variable or function name. Each counts toward the distinct-instrument limit. Fixed at create (a change keeps them). Refused (422) while indicator conditions are not available.

  • route string

    Where a bracket protecting a held position lives. auto (default) puts a simple protection (one leg already held, a plain price stop-loss and / or target, nothing else) at the broker with the rules of POST /v1/triggers: a broker GTT for a positional product where the broker has GTTs (a one-leg-GTT broker holds the stop-loss, a server-side trigger the target), a broker stop-loss order for an intraday (MIS) position where the broker's stop orders are proven; anything else is a v2 trigger the server evaluates. trigger always makes the v2 trigger (the earlier behaviour). gtt / stop_order ask for that route and are refused (422) where auto would not take it; bracket / cover are refused.

    One of: auto, bracket, cover, gtt, trigger, stop_order

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).

404account_not_found

No linked broker account with this id 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.

504broker_outcome_unknown

The broker did not answer in time: it may or may not have applied the change. Check before retrying.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v2/triggers" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account": "P1",
    "kind": "bracket",
    "legs": [
      {
        "instrument_token": "CT:TEST:RELIANCE",
        "side": "BUY",
        "quantity": 5,
        "product": "MIS"
      }
    ],
    "spec": {
      "entry_px": 2500,
      "target": {
        "when": "ltp >= entry_px * 1.02"
      },
      "stop_loss": {
        "init_sl": "entry_px - 25",
        "trail": {
          "step": "5"
        }
      }
    }
  }'
Response · 202
{
  "status": "success",
  "data": {
    "trigger_id": "01M5VVFCDFRZFZ0A56Z1VHC8WJ",
    "command_id": "01M5VVFCDM23ZD6N7BKFGJ3KZD",
    "status": "accepted",
    "route": "trigger",
    "route_reason": "a trailing stop-loss is evaluated by the server (a GTT or broker stop cannot trail)"
  },
  "error": null
}

One v2 trigger #

GET /v2/triggers/{trigger_id} scope read

One v2 trigger of the caller.

More about this

Another user's id is not found.

Parameters

  • trigger_id path · string required

    The trigger's 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).

404trigger_not_found

No trigger with this id 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…

GET
curl "https://cirrus.pocketful.in/v2/triggers/<trigger_id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "trigger_id": "01M5VVFCDF60NDFJ5SMKG675R2",
    "account": "P1",
    "strategy": null,
    "kind": "bracket",
    "legs": [
      {
        "side": "BUY",
        "quantity": 5,
        "product": "MIS",
        "instrument_token": "CT:TEST:RELIANCE"
      }
    ],
    "spec": {
      "entry_px": 2500,
      "target": {
        "when": "ltp >= entry_px * 1.02"
      },
      "stop_loss": {
        "init_sl": "entry_px - 25",
        "trail": {
          "step": "5"
        }
      }
    },
    "valid_until": null,
    "state": "active",
    "transition_seq": 1,
    "reason": null,
    "created_at": "2026-10-26T15:48:09.715+05:30",
    "updated_at": "2026-10-26T15:48:09.719+05:30",
    "protection": {
      "stop_loss": {
        "held_by": "server",
        "broker_order_id": null,
        "level": 2480,
        "adjusted_by_server": false,
        "status": "held_by_server",
        "note": null
      },
      "target": {
        "held_by": "server",
        "broker_order_id": null,
        "level": 2550,
        "adjusted_by_server": false,
        "status": "held_by_server",
        "note": null
      },
      "trail": {
        "held_by": "server",
        "broker_order_id": null,
        "level": 2475,
        "adjusted_by_server": false,
        "status": "held_by_server",
        "note": null
      }
    },
    "created_via": "app",
    "route": "trigger"
  },
  "error": null
}

Change a v2 trigger #

PATCH /v2/triggers/{trigger_id} scope triggers

Replaces a v2 trigger's spec (and optionally its expiry).

More about this

The new spec is checked like on create; the engine then applies what the trigger's state allows (for example a stop-loss is never loosened, an entry cannot change once active). 202: read the trigger to see the result. Protection the broker holds (route gtt / stop_order) is changed at the broker first and answered once the broker agreed: its spec must stay a plain price stop-loss / target with the same parts, and valid_until cannot be set.

Parameters

  • trigger_id path · string required

    The trigger's id.

Body fields

  • spec object required

    The whole new spec (same shape as on create).

  • valid_until string | null

    New expiry (RFC 3339); unchanged when absent.

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).

404trigger_not_found

No trigger with this id for the caller.

404account_not_found

No linked broker account with this id for the caller.

409trigger_fired

The trigger already fired; its exit is being handled.

409broker_held

The protection is held by the broker; change the broker order instead.

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).

502broker_refused

The broker refused the change.

503service_unavailable

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

504broker_outcome_unknown

The broker did not answer in time: it may or may not have applied the change. Check before retrying.

All fields (request and response schema)

Loading fields…

PATCH
curl -X PATCH "https://cirrus.pocketful.in/v2/triggers/<trigger_id>" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "spec": {
      "entry_px": 2500,
      "target": {
        "when": "ltp >= entry_px * 1.02"
      },
      "stop_loss": {
        "init_sl": "entry_px - 20",
        "trail": {
          "step": "5"
        }
      }
    }
  }'
Response · 202
{
  "status": "success",
  "data": {
    "trigger_id": "01M4GF38AQ39WVJZHH8YWWNNQZ",
    "command_id": "01M4GF38BEE9Y3N9T9M8EHNXKX",
    "status": "accepted"
  },
  "error": null
}

Cancel a v2 trigger #

DELETE /v2/triggers/{trigger_id} scope triggers

Cancels a v2 trigger.

More about this

202: the engine ends it within moments (state cancelled); one that fires first ends as fired instead. Protection the broker holds (route gtt / stop_order) is cancelled at the broker first (a stop order is read back final; one that already went off is exiting and is kept: 502, retry), then removed with its paired target: broker_cancel says how the broker answered. A refusal never removes it on its own: shown ended at the broker it is removed (cancelled), shown fired it ends as fired (409), otherwise it stays live with state cancel_pending (broker_cancel pending) and is re-checked until the broker shows a final state.

Parameters

  • trigger_id path · string required

    The trigger's 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).

404trigger_not_found

No trigger with this id for the caller.

409trigger_fired

The trigger already fired; its exit is being handled.

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).

502broker_refused

The broker refused the change.

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/v2/triggers/<trigger_id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 202
{
  "status": "success",
  "data": {
    "trigger_id": "01M4GF38B4NDN7T4SDYK85MKNM",
    "command_id": "01M4GF38BK9BQ5Z9NTES6C5R31",
    "status": "accepted"
  },
  "error": null
}

Pause a v2 trigger #

POST /v2/triggers/{trigger_id}/pause scope triggers

Pauses a v2 trigger: the engine stops evaluating it (state paused) until it is resumed.

More about this

A paused trigger does not act on any condition, its stop-loss included; a part the broker holds stays at the broker. 202: the engine applies it within moments; read the trigger to see the result.

Parameters

  • trigger_id path · string required

    The trigger's 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).

404trigger_not_found

No trigger with this id for the caller.

409trigger_fired

The trigger already fired; its exit is being handled.

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/v2/triggers/<trigger_id>/pause" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 202
{
  "status": "success",
  "data": {
    "trigger_id": "01M4QNBZ1SPDJ4F3K9NA9H72SC",
    "command_id": "01M4QNBZ21PD87BG3EHS08AN78",
    "status": "accepted"
  },
  "error": null
}

Resume a paused v2 trigger #

POST /v2/triggers/{trigger_id}/resume scope triggers

Resumes a paused v2 trigger: the engine evaluates it again from the next tick, in the state it was paused in.

More about this

202: read the trigger to see the result (the engine refuses a resume of a trigger that is not paused).

Parameters

  • trigger_id path · string required

    The trigger's 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).

404trigger_not_found

No trigger with this id for the caller.

409trigger_fired

The trigger already fired; its exit is being handled.

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/v2/triggers/<trigger_id>/resume" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 202
{
  "status": "success",
  "data": {
    "trigger_id": "01M4QNBZ1SH6BRRRMPJ7RRSVMY",
    "command_id": "01M4QNBZ1Z8KTB78CXT3BMKEBB",
    "status": "accepted"
  },
  "error": null
}

Check a v2 trigger without creating it #

POST /v2/triggers/validate scope triggers

A dry run of POST /v2/triggers with the same body: nothing is sent to the engine, stored or counted against the account's order budget.

More about this

200 with valid and every reason create would refuse it (errors, the same field and message as create's 422), what its conditions read (reads), where it stands against the limits (limits) and, for bracket / ladder, who would hold each part of its protection on this account and product (protection: the broker or the server).

**Expressions** (a strict CEL subset; numbers are doubles). Variables: leg 0's tick fields ltp, bid, ask, bid_qty, ask_qty, volume, oi, atp, open, high, low; prev.<field> (previous tick); legs[i].<field> and legs[i].prev.<field>; entry_px, sl_px, state; account.mtm, user.mtm, strategy.mtm, position.qty; now_ist (minutes since midnight IST, 09:15 = 555). Functions: crosses_above(a, b) / crosses_below(a, b) (against the previous tick; a gap counts), min, max, abs. Operators: || && ! == != < <= > >= + - * / and c ? a : b. Prices (init_sl, trail.step, ladder price) read only entry_px and literals. Limits: 2048 bytes and 32 levels of nesting per condition; the per-trigger limits in limits. Errors name the spec path and byte, e.g. when: unknown variable ltpp (at byte 0). Full reference with examples per kind: docs/api/trigger-expressions.md.

Body fields

  • account string required

    Account id (see /v1/accounts).

  • kind string required

    The machine that runs a trigger.

    One of: alert, bracket, ladder, risk_limit

  • spec object required

    Kind-specific rules, conditions written in the CEL subset (ltp <= 120 && bid_qty > ask_qty). Checked before anything is sent: an unknown field or a condition that does not compile is a 422.

  • strategy string | null

    Strategy the trigger belongs to (risk limits at strategy level).

  • legs object[]
  • valid_until string | null

    RFC 3339; the trigger expires then.

  • watch object[]

    Instruments the conditions read but the trigger never trades (at most 3), for indicator conditions: [{"name": "nifty", "symbol": "<instrument token>"}] lets a condition say nifty.rsi(14, '5m') or nifty.ltp. Names are [a-z][a-z0-9_]{0,15}, not a variable or function name. Each counts toward the distinct-instrument limit. Fixed at create (a change keeps them). Refused (422) while indicator conditions are not available.

  • route string

    Where a bracket protecting a held position lives. auto (default) puts a simple protection (one leg already held, a plain price stop-loss and / or target, nothing else) at the broker with the rules of POST /v1/triggers: a broker GTT for a positional product where the broker has GTTs (a one-leg-GTT broker holds the stop-loss, a server-side trigger the target), a broker stop-loss order for an intraday (MIS) position where the broker's stop orders are proven; anything else is a v2 trigger the server evaluates. trigger always makes the v2 trigger (the earlier behaviour). gtt / stop_order ask for that route and are refused (422) where auto would not take it; bracket / cover are refused.

    One of: auto, bracket, cover, gtt, trigger, stop_order

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).

404account_not_found

No linked broker account with this id 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/v2/triggers/validate" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account": "P1",
    "kind": "bracket",
    "legs": [
      {
        "instrument_token": "CT:TEST:RELIANCE",
        "side": "BUY",
        "quantity": 5,
        "product": "MIS"
      }
    ],
    "spec": {
      "entry_px": 2500,
      "target": {
        "when": "ltp >= entry_px * 1.02"
      },
      "stop_loss": {
        "init_sl": "entry_px - 25"
      }
    }
  }'
Response · 200
{
  "status": "success",
  "data": {
    "valid": true,
    "errors": [],
    "reads": {
      "symbols": [
        "CT:TEST:RELIANCE"
      ],
      "fields": [
        "ltp"
      ],
      "variables": [
        "entry_px",
        "sl_px"
      ]
    },
    "limits": {
      "ok": true,
      "reason": null,
      "legs": 1,
      "max_legs": 8,
      "expressions": 2,
      "max_expressions": 32,
      "bytes": 310,
      "max_bytes": 16384
    },
    "protection": {
      "parts": {
        "stop_loss": {
          "held_by": "server",
          "level": 2475,
          "adjusted_by_server": false,
          "note": null
        },
        "target": {
          "held_by": "server",
          "level": 2550,
          "adjusted_by_server": false,
          "note": null
        }
      },
      "reason": "broker placement of v2 protection is switched off (OMS_TRIGGERS_V2_BROKER_PROTECTION)"
    }
  },
  "error": null
}

What v2 triggers can do #

GET /v2/triggers/capabilities scope read

The kinds and their spec fields, the expression language (variables, functions, operators and its size limits), the limits this deployment runs with and, with ?account=, what that account's broker can hold (order types, and each protection fact verified or unverified) and whether broker protection is on.

More about this

See docs/api/trigger-expressions.md.

Parameters

  • account query · string

    One of the caller's accounts: adds what its broker can hold.

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).

404account_not_found

No linked broker account with this id 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).

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v2/triggers/capabilities" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200 · lists shortened
{
  "status": "success",
  "data": {
    "kinds": [
      {
        "kind": "alert",
        "description": "Notifies once `when` holds, then ends (`fired`).",
        "legs": "one or more",
        "spec_fields": [
          {
            "name": "when",
            "type": "condition",
            "required": true,
            "description": "Tick fields of every leg, risk variables, `now_ist`."
          }
        ]
      },
      {
        "kind": "bracket",
        "description": "Entry (a condition, or a known `entry_px`), target, stop-loss and trailing stop on one position.",
        "legs": "one",
        "spec_fields": [
          {
            "name": "entry.when",
            "type": "condition",
            "required": false,
            "description": "Waits (`pending`) until it holds; `entry_px` becomes that tick's LTP. Exclusive with `entry_px`."
          },
          {
            "name": "entry_px",
            "type": "number",
            "required": false,
            "description": "The entry price of a position already held (starts `active`). Exclusive with `entry`."
          }
        ]
      }
    ],
    "expressions": {
      "variables": [
        {
          "name": "ltp",
          "description": "Leg 0's tick field; `prev.<field>` the previous tick's, `legs[i].<field>` leg i's."
        },
        {
          "name": "bid",
          "description": "Leg 0's tick field; `prev.<field>` the previous tick's, `legs[i].<field>` leg i's."
        }
      ],
      "functions": [
        {
          "name": "crosses_above",
          "description": "crosses_above(a, b): a was at or below b on the previous tick and is above it now."
        },
        {
          "name": "crosses_below",
          "description": "crosses_below(a, b): a was at or above b on the previous tick and is below it now."
        }
      ],
      "operators": [
        "||",
        "&&"
      ],
      "max_source_bytes": 2048,
      "max_depth": 32,
      "max_nodes": 256
    },
    "limits": {
      "max_triggers": 500,
      "max_legs": 8,
      "max_expressions": 32,
      "max_symbols": 100,
      "max_trigger_bytes": 16384,
      "max_rungs": 20
    },
    "entries_enabled": false,
    "account": null
  },
  "error": null
}

A v2 trigger's journey #

GET /v2/triggers/{trigger_id}/journey scope read

Everything that happened to one of the caller's v2 triggers, newest first: what was asked (api: created, modified with the spec diff, paused, resumed, cancelled, with who asked), what the engine did and why (engine: each transition with the condition that decided it and the values it read, e.g.

More about this

ltp=2479.5, sl_px=2480 in ltp <= sl_px; notes such as an input not known), commands it refused (result), exit orders (exit) and the broker protection (protection). Kept for 90 days by default, also after the trigger ended. Another user's trigger is not found.

Parameters

  • trigger_id path · string required

    The trigger's id.

  • limit query · integer

    Entries per page, 1 to 200 (default 50).

  • cursor query · string

    next_cursor of the previous page.

  • source query · string

    Only entries from api, engine, result, exit or protection.

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).

404trigger_not_found

No trigger with this id 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…

GET
curl "https://cirrus.pocketful.in/v2/triggers/<trigger_id>/journey" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "entries": [
      {
        "entry_id": "evt:01M4QRFDBAQC442FN7H0ATGR3A:1",
        "at": "2026-10-12T15:23:05.396+05:30",
        "seq": 1,
        "source": "engine",
        "kind": "transition",
        "summary": "active -> active",
        "actor": null,
        "details": {
          "from": "active",
          "to": "active",
          "actions": [
            {
              "type": "move_sl",
              "legs": [
                0
              ],
              "price": 2480
            }
          ],
          "tick": {
            "symbol": "CT:TEST:RELIANCE",
            "ltp": 2551
          },
          "reason": null,
          "explain": null
        }
      },
      {
        "entry_id": "api:01M4QRFDBBMKYVDBYQ05TTGVX2",
        "at": "2026-10-12T15:23:05.386+05:30",
        "seq": 0,
        "source": "api",
        "kind": "created",
        "summary": "created in the app (command 01M4QRFDBBMKYVDBYQ05TTGVX2)",
        "actor": {
          "user": "user-01M4QRFD9EACA9SER6K3EHY0BQ",
          "credential": "app"
        },
        "details": {
          "kind": "bracket",
          "legs": [
            {
              "symbol": "CT:TEST:RELIANCE",
              "side": "BUY",
              "qty": 5,
              "product": "MIS"
            }
          ],
          "spec": {
            "entry_px": 2500,
            "target": {
              "when": "ltp >= entry_px * 1.02"
            },
            "stop_loss": {
              "init_sl": "entry_px - 25"
            }
          },
          "valid_until": null
        }
      }
    ],
    "next_cursor": null
  },
  "error": null
}

A v2 trigger's indicator values now #

GET /v2/triggers/{trigger_id}/indicators scope read

Each indicator a trigger's conditions read, as the engine holds it now: the last closed candle's value, the forming candle's, its warm-up status, how far it is from the condition's level and a tick-mode hold in progress.

More about this

Read from the engine's memory (nothing is computed or stored for it); poll every 2 s while a page shows it. status unavailable when the engine did not answer within 500 ms. At most one request per second per trigger.

Parameters

  • trigger_id path · string required

    The trigger's 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).

404trigger_not_found

No trigger with this id 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…

GET
curl "https://cirrus.pocketful.in/v2/triggers/<trigger_id>/indicators" \
  -H "Authorization: token $CIRRUS_API_KEY"