Skip to content
Cirrus home
Sign in

Reference

Automated strategies

Write, check, version and share strategy documents.

Read the guide first

List strategies #

GET /v2/strategies scope read

The caller's strategies, most recently changed first (at most 200), with the display status derived from their deployments.

Parameters

  • archived query · boolean

    Include archived strategies (default false).

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

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v2/strategies" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": [
    {
      "id": "01M59F60KB7GW11NNBWTQPQ8YX",
      "name": "NIFTY straddle",
      "description": "",
      "tags": [
        "weekly"
      ],
      "display_status": "draft",
      "latest_version": 0,
      "revision": 1,
      "deployments": {
        "active": 0,
        "paused": 0,
        "error": 0,
        "stopped": 0
      },
      "updated_at": "2026-10-19T06:57:00.011Z",
      "pnl": {
        "trading_day": "2026-10-19",
        "realized": 0,
        "unrealized": 0,
        "total": 0,
        "ltp_stale": false
      }
    }
  ],
  "error": null
}

Create a strategy #

POST /v2/strategies scope strategies

Creates a strategy draft from a portable document (document: an object, or its JSON or YAML text; or the raw YAML body with Content-Type: application/yaml) or from a definition (definition + name).

More about this

The document is checked with the same code as validate and import: problems are refused (422 invalid_document, one per line, field naming the first), blockers (a component not released yet) are saved and listed. Never deploys. Takes an optional Idempotency-Key.

Body fields

  • document any required

    The portable document: an object, or its JSON or YAML text (schema_version, kind, metadata, spec).

  • definition object | null

    Instead of document: the definition (spec) alone.

  • name string | null

    With definition: the strategy's name (at most 60 characters).

  • description string | null

    With definition.

  • tags string[] | null

    With definition.

  • revision integer (int64) | null

    Update only: the revision last read; a draft changed since is refused (409 strategy_busy) rather than overwritten.

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

422invalid_document

The strategy document has problems; message lists each (where in the wizard, what is wrong) and field names the first.

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

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v2/strategies" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO"
        },
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly"
              },
              "strike": {
                "by": "atm"
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly"
              },
              "strike": {
                "by": "atm"
              }
            }
          ]
        },
        "entry": {
          "window": {
            "start": "09:30",
            "end": "13:30"
          }
        },
        "risk": {
          "combined": {
            "type": "combined@1",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            }
          }
        }
      }
    }
  }'
Response · 201
{
  "status": "success",
  "data": {
    "id": "01M574VKA19TCCDQSGVJ9EN831",
    "name": "NIFTY straddle",
    "description": "",
    "tags": [
      "weekly"
    ],
    "display_status": "draft",
    "latest_version": 0,
    "revision": 1,
    "visibility": "private",
    "forked_from": null,
    "archived": false,
    "deployments": {
      "active": 0,
      "paused": 0,
      "error": 0,
      "stopped": 0
    },
    "summary": "Sell 1 lot of an ATM call (weekly expiry) and sell 1 lot of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "schema_version": 1,
    "draft": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    },
    "created_at": "2026-10-18T09:18:04.097Z",
    "updated_at": "2026-10-18T09:18:04.097Z"
  },
  "error": null
}

Get a strategy #

GET /v2/strategies/{strategy_id} scope read

One strategy with its draft document (normalized), its plain-English summary, and its blockers and warnings as this server sees them now.

Parameters

  • strategy_id path · string required

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

404strategy_not_found

No automated strategy 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/strategies/<strategy_id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "id": "01M574VKA19TCCDQSGVJ9EN831",
    "name": "NIFTY straddle",
    "description": "",
    "tags": [
      "weekly"
    ],
    "display_status": "draft",
    "latest_version": 0,
    "revision": 1,
    "visibility": "private",
    "forked_from": null,
    "archived": false,
    "deployments": {
      "active": 0,
      "paused": 0,
      "error": 0,
      "stopped": 0
    },
    "summary": "Sell 1 lot of an ATM call (weekly expiry) and sell 1 lot of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "schema_version": 1,
    "draft": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    },
    "created_at": "2026-10-18T09:18:04.097Z",
    "updated_at": "2026-10-18T09:18:04.097Z"
  },
  "error": null
}

Edit a strategy's draft #

PATCH /v2/strategies/{strategy_id} scope strategies

Replaces the draft with a new document (same body as create).

More about this

Versions never change: save the draft as a version to deploy it. With revision, a draft changed since that revision is refused (409 strategy_busy) instead of overwritten.

Parameters

  • strategy_id path · string required

    Strategy id.

Body fields

  • document any required

    The portable document: an object, or its JSON or YAML text (schema_version, kind, metadata, spec).

  • definition object | null

    Instead of document: the definition (spec) alone.

  • name string | null

    With definition: the strategy's name (at most 60 characters).

  • description string | null

    With definition.

  • tags string[] | null

    With definition.

  • revision integer (int64) | null

    Update only: the revision last read; a draft changed since is refused (409 strategy_busy) rather than overwritten.

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

404strategy_not_found

No automated strategy with this id for the caller.

409strategy_busy

The strategy changed since it was read (or is archived); read it again and retry.

422invalid_document

The strategy document has problems; message lists each (where in the wizard, what is wrong) and field names the first.

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…

PATCH
curl -X PATCH "https://cirrus.pocketful.in/v2/strategies/<strategy_id>" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document": {
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle, 2 lots",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO"
        },
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly"
              },
              "strike": {
                "by": "atm"
              },
              "lots": 2
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly"
              },
              "strike": {
                "by": "atm"
              },
              "lots": 2
            }
          ]
        },
        "entry": {
          "window": {
            "start": "09:30",
            "end": "13:30"
          }
        },
        "risk": {
          "combined": {
            "type": "combined@1",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            }
          }
        }
      }
    },
    "revision": 1
  }'
Response · 200
{
  "status": "success",
  "data": {
    "id": "01M574VKA19TCCDQSGVJ9EN831",
    "name": "NIFTY straddle, 2 lots",
    "description": "",
    "tags": [
      "weekly"
    ],
    "display_status": "draft",
    "latest_version": 0,
    "revision": 2,
    "visibility": "private",
    "forked_from": null,
    "archived": false,
    "deployments": {
      "active": 0,
      "paused": 0,
      "error": 0,
      "stopped": 0
    },
    "summary": "Sell 2 lots of an ATM call (weekly expiry) and sell 2 lots of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "schema_version": 1,
    "draft": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle, 2 lots",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    },
    "created_at": "2026-10-18T09:18:04.097Z",
    "updated_at": "2026-10-18T09:18:05.038Z"
  },
  "error": null
}

Archive a strategy #

DELETE /v2/strategies/{strategy_id} scope strategies

Archives the strategy (its versions are kept).

More about this

Refused while a deployment of it is not stopped (409 strategy_in_use): stop it first.

Parameters

  • strategy_id path · string required

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

404strategy_not_found

No automated strategy with this id for the caller.

409strategy_in_use

The strategy has a deployment that is not stopped; stop it first.

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…

DELETE
curl -X DELETE "https://cirrus.pocketful.in/v2/strategies/<strategy_id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "id": "01M574VKA19TCCDQSGVJ9EN831",
    "name": "NIFTY straddle, edited again",
    "description": "",
    "tags": [
      "weekly"
    ],
    "display_status": "stopped",
    "latest_version": 2,
    "revision": 4,
    "visibility": "private",
    "forked_from": null,
    "archived": true,
    "deployments": {
      "active": 0,
      "paused": 0,
      "error": 0,
      "stopped": 1
    },
    "summary": "Sell 1 lot of an ATM call (weekly expiry) and sell 1 lot of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "schema_version": 1,
    "draft": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle, edited again",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    },
    "created_at": "2026-10-18T09:18:04.097Z",
    "updated_at": "2026-10-18T09:18:07.208Z"
  },
  "error": null
}

List a strategy's versions #

GET /v2/strategies/{strategy_id}/versions scope read

Every saved version, newest first (documents left out).

Parameters

  • strategy_id path · string required

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

404strategy_not_found

No automated strategy 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/strategies/<strategy_id>/versions" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": [
    {
      "strategy_id": "01M574VKA19TCCDQSGVJ9EN831",
      "n": 1,
      "schema_version": 1,
      "compiled_hash": "sha256:c17de463c06b305846097f5abda141dc76f1ea91ebdd5ced4adce96223a8a7a4",
      "components": [
        "chain@1",
        "combined@1",
        "conditions@1",
        "fixed_lots@1",
        "limits@1",
        "per_leg@1",
        "protected_limit@1"
      ],
      "summary": "Sell 2 lots of an ATM call (weekly expiry) and sell 2 lots of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
      "deployable": true,
      "blockers": [],
      "warnings": [],
      "created_at": "2026-10-18T09:18:05.615Z"
    }
  ],
  "error": null
}

Save the draft as a version #

POST /v2/strategies/{strategy_id}/versions scope strategies

Saves the draft as the next immutable version (numbered from 1).

More about this

A version never changes afterwards: deployments run exactly what it holds. With revision, a draft changed since is refused (409). Takes an optional Idempotency-Key.

Parameters

  • strategy_id path · string required

    Strategy id.

Body fields

  • revision integer (int64) | null

    The draft revision the user saw; refused (409) when the draft changed since.

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

404strategy_not_found

No automated strategy with this id for the caller.

409strategy_busy

The strategy changed since it was read (or is archived); read it again and retry.

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…

POST
curl -X POST "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "revision": 2
  }'
Response · 201
{
  "status": "success",
  "data": {
    "strategy_id": "01M574VKA19TCCDQSGVJ9EN831",
    "n": 1,
    "schema_version": 1,
    "compiled_hash": "sha256:c17de463c06b305846097f5abda141dc76f1ea91ebdd5ced4adce96223a8a7a4",
    "components": [
      "chain@1",
      "combined@1",
      "conditions@1",
      "fixed_lots@1",
      "limits@1",
      "per_leg@1",
      "protected_limit@1"
    ],
    "summary": "Sell 2 lots of an ATM call (weekly expiry) and sell 2 lots of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "created_at": "2026-10-18T09:18:05.615Z",
    "document": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle, 2 lots",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    }
  },
  "error": null
}

Get a version #

GET /v2/strategies/{strategy_id}/versions/{n} scope read

One immutable version with its normalized document.

Parameters

  • strategy_id path · string required

    Strategy id.

  • n path · integer (int32) required

    Version number.

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

404version_not_found

No such version of the strategy.

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/strategies/<strategy_id>/versions/<n>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "strategy_id": "01M574VKA19TCCDQSGVJ9EN831",
    "n": 1,
    "schema_version": 1,
    "compiled_hash": "sha256:c17de463c06b305846097f5abda141dc76f1ea91ebdd5ced4adce96223a8a7a4",
    "components": [
      "chain@1",
      "combined@1",
      "conditions@1",
      "fixed_lots@1",
      "limits@1",
      "per_leg@1",
      "protected_limit@1"
    ],
    "summary": "Sell 2 lots of an ATM call (weekly expiry) and sell 2 lots of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "created_at": "2026-10-18T09:18:05.615Z",
    "document": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle, 2 lots",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    }
  },
  "error": null
}

Clone a strategy #

POST /v2/strategies/{strategy_id}/clone scope strategies

A new draft from one of the strategy's versions (or its draft), recording where it came from.

More about this

Never deploys.

Parameters

  • strategy_id path · string required

    Strategy id.

Body fields

  • version integer (int32) | null

    The version to copy (default: the draft).

  • name string | null

    Name of the copy (default: Copy of <name>).

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

404strategy_not_found

No automated strategy with this id for the caller.

404version_not_found

No such version of the strategy.

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…

POST
curl -X POST "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/clone" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": 1,
    "name": "My copy"
  }'
Response · 201
{
  "status": "success",
  "data": {
    "id": "01M574VNT35HA09X24PQ7N0TD5",
    "name": "My copy",
    "description": "",
    "tags": [
      "weekly"
    ],
    "display_status": "draft",
    "latest_version": 0,
    "revision": 1,
    "visibility": "private",
    "forked_from": {
      "strategy_id": "01M574VKA19TCCDQSGVJ9EN831",
      "version": 1
    },
    "archived": false,
    "deployments": {
      "active": 0,
      "paused": 0,
      "error": 0,
      "stopped": 0
    },
    "summary": "Sell 2 lots of an ATM call (weekly expiry) and sell 2 lots of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
    "deployable": true,
    "blockers": [],
    "warnings": [],
    "schema_version": 1,
    "draft": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "My copy",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 2,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    },
    "created_at": "2026-10-18T09:18:06.659Z",
    "updated_at": "2026-10-18T09:18:06.659Z"
  },
  "error": null
}

Export a strategy #

GET /v2/strategies/{strategy_id}/export scope read

The portable document of the draft or a version: canonical (defaults written out, stable key order), with no account, secret or URL.

More about this

JSON comes as document, YAML as document_yaml (text). Importing it back gives the same document.

Parameters

  • strategy_id path · string required

    Strategy id.

  • format query · string

    json (default) or yaml.

  • version query · integer (int32)

    A version (default: the draft).

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

404strategy_not_found

No automated strategy with this id for the caller.

404version_not_found

No such version of the strategy.

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/strategies/<strategy_id>/export" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "format": "json",
    "filename": "nifty-straddle.strategy.json",
    "version": null,
    "schema_version": 1,
    "document": {
      "$schema": "/v2/strategies/schema/1.json",
      "schema_version": 1,
      "kind": "cirrus.strategy",
      "metadata": {
        "name": "NIFTY straddle",
        "description": "",
        "tags": [
          "weekly"
        ]
      },
      "spec": {
        "underlying": {
          "name": "NIFTY",
          "exchange": "NFO",
          "reference": "future"
        },
        "watch": {},
        "positional": false,
        "legs": {
          "selector": "chain@1",
          "items": [
            {
              "id": "sc",
              "instrument": "option",
              "side": "sell",
              "option_type": "call",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            },
            {
              "id": "sp",
              "instrument": "option",
              "side": "sell",
              "option_type": "put",
              "expiry": {
                "kind": "weekly",
                "n": 0
              },
              "strike": {
                "by": "atm",
                "offset": 0
              },
              "lots": 1,
              "hedge_for": null,
              "risk": null,
              "liquidity": {
                "max_spread_pct": 3,
                "min_oi": 0,
                "min_premium": 1
              }
            }
          ]
        },
        "entry": {
          "source": {
            "type": "conditions@1",
            "when": null,
            "on": "close",
            "hold_s": 0
          },
          "window": {
            "start": "09:30",
            "end": "13:30"
          },
          "skip_first_min": 0,
          "skip_last_min": 0,
          "days": [
            "mon",
            "tue",
            "wed",
            "thu",
            "fri"
          ],
          "expiry_day": "normal",
          "active_from": null,
          "active_until": null
        },
        "exit": {
          "sources": [],
          "square_off": "15:15",
          "expiry_day_exit": null,
          "max_hold_min": null
        },
        "sizing": {
          "type": "fixed_lots@1",
          "max_lots": 10
        },
        "execution": {
          "type": "protected_limit@1",
          "order": "auto",
          "hedge_wait_ms": 5000,
          "stagger_ms": 0,
          "buffer_pct": 0.5,
          "chase": {
            "every_ms": 1000,
            "max_slippage_pct": 1,
            "max_attempts": 10
          },
          "on_incomplete": "safest",
          "retry_next_signal": null
        },
        "risk": {
          "per_leg": {
            "type": "per_leg@1",
            "stop_loss": null,
            "target": null,
            "trail": null,
            "on_leg_stop": "nothing",
            "at_broker": false
          },
          "combined": {
            "type": "combined@1",
            "scope": "account",
            "basis": "rupees",
            "stop_loss": {
              "rupees": 3000
            },
            "target": {
              "rupees": 2000
            },
            "breakeven": null,
            "trail": null,
            "lock_ladder": [],
            "deployment": null
          },
          "limits": {
            "type": "limits@1",
            "max_loss_per_day": null,
            "max_profit_per_day": null,
            "max_loss_per_week": null,
            "max_cycles_per_day": 3,
            "max_orders_per_day": 50,
            "exit_on_limit": true,
            "on_breaker": "nothing"
          }
        },
        "reentry": {
          "on": [],
          "max": 0,
          "delay_s": 300,
          "require_fresh_signal": true,
          "same_direction_only": true,
          "until": null
        },
        "adjustments": [],
        "notify": [],
        "costs": {
          "model": "auto",
          "slippage_pct": null
        }
      }
    },
    "document_yaml": null
  },
  "error": null
}

Import a strategy #

POST /v2/strategies/import scope strategies

Creates the caller's own draft from a pasted or uploaded document (document: an object or its JSON / YAML text; or the raw YAML body) or from one of the caller's versions (from).

More about this

Imported documents are untrusted: at most 64 KiB (checked before parsing), YAML without anchors, aliases, merge keys or tags, nesting at most 20 deep, and the same limits as the wizard. Unknown fields and newer formats are refused with a problem naming them, never dropped; components not released yet are saved as blockers. Never deploys. Takes an optional Idempotency-Key.

Body fields

  • document any

    The document: an object, or its JSON or YAML text (or from).

  • from object | null

    Where an import comes from.

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

404strategy_not_found

No automated strategy with this id for the caller.

404version_not_found

No such version of the strategy.

422invalid_document

The strategy document has problems; message lists each (where in the wizard, what is wrong) and field names the first.

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…

POST
curl -X POST "https://cirrus.pocketful.in/v2/strategies/import" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document": "$schema: /v2/strategies/schema/1.json\nschema_version: 1\nkind: cirrus.strategy\nmetadata:\n  name: NIFTY straddle\n  description: \"\"\n  tags: [weekly]\nspec:\n  underlying:\n    name: NIFTY\n    exchange: NFO\n    reference: future\n  watch: {}\n  positional: false\n  legs:\n    selector: \"chain@1\"\n    items:\n      - id: sc\n        instrument: option\n        side: sell\n        option_type: call\n        expiry:\n          kind: weekly\n          \"n\": 0\n        strike:\n          by: atm\n          offset: 0\n        lots: 1\n        hedge_for: null\n        risk: null\n        liquidity:\n          max_spread_pct: 3\n          min_oi: 0\n          min_premium: 1\n      - id: sp\n        instrument: option\n        side: sell\n        option_type: put\n        expiry:\n          kind: weekly\n          \"n\": 0\n        strike:\n          by: atm\n          offset: 0\n        lots: 1\n        hedge_for: null\n        risk: null\n        liquidity:\n          max_spread_pct: 3\n          min_oi: 0\n          min_premium: 1\n  entry:\n    source:\n      type: \"conditions@1\"\n      when: null\n      \"on\": close\n      hold_s: 0\n    window:\n      start: \"09:30\"\n      end: \"13:30\"\n    skip_first_min: 0\n    skip_last_min: 0\n    days: [mon, tue, wed, thu, fri]\n    expiry_day: normal\n    active_from: null\n    active_until: null\n  exit:\n    sources: []\n    square_off: \"15:15\"\n    expiry_day_exit: null\n    max_hold_min: null\n  sizing:\n    type: \"fixed_lots@1\"\n    max_lots: 10\n  execution:\n    type: \"protected_limit@1\"\n    order: auto\n    hedge_wait_ms: 5000\n    stagger_ms: 0\n    buffer_pct: 0.5\n    chase:\n      every_ms: 1000\n      max_slippage_pct: 1\n      max_attempts: 10\n    on_incomplete: safest\n    retry_next_signal: null\n  risk:\n    per_leg:\n      type: \"per_leg@1\"\n      stop_loss: null\n      target: null\n      trail: null\n      on_leg_stop: nothing\n      at_broker: false\n    combined:\n      type: \"combined@1\"\n      scope: account\n      basis: rupees\n      stop_loss:\n        rupees: 3000\n      target:\n        rupees: 2000\n      breakeven: null\n      trail: null\n      lock_ladder: []\n      deployment: null\n    limits:\n      type: \"limits@1\"\n      max_loss_per_day: null\n      max_profit_per_day: null\n      max_loss_per_week: null\n      max_cycles_per_day: 3\n      max_orders_per_day: 50\n      exit_on_limit: true\n      on_breaker: nothing\n  reentry:\n    \"on\": []\n    max: 0\n    delay_s: 300\n    require_fresh_signal: true\n    same_direction_only: true\n    until: null\n  adjustments: []\n  notify: []\n  costs:\n    model: auto\n    slippage_pct: null\n"
  }'
Response · 201 · lists shortened
{
  "status": "success",
  "data": {
    "strategy": {
      "id": "01M574VMP7NY5WR1XNRJ9WF4P5",
      "name": "NIFTY straddle",
      "description": "",
      "tags": [
        "weekly"
      ],
      "display_status": "draft",
      "latest_version": 0,
      "revision": 1,
      "visibility": "private",
      "forked_from": null,
      "archived": false,
      "deployments": {
        "active": 0,
        "paused": 0,
        "error": 0,
        "stopped": 0
      },
      "summary": "Sell 1 lot of an ATM call (weekly expiry) and sell 1 lot of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
      "deployable": true,
      "blockers": [],
      "warnings": [],
      "schema_version": 1,
      "draft": {
        "$schema": "/v2/strategies/schema/1.json",
        "schema_version": 1,
        "kind": "cirrus.strategy",
        "metadata": {
          "name": "NIFTY straddle",
          "description": "",
          "tags": [
            "weekly"
          ]
        },
        "spec": {
          "underlying": {
            "name": "NIFTY",
            "exchange": "NFO",
            "reference": "future"
          },
          "watch": {},
          "positional": false,
          "legs": {
            "selector": "chain@1",
            "items": [
              {
                "id": "sc",
                "instrument": "option",
                "side": "sell",
                "option_type": "call",
                "expiry": {
                  "kind": "weekly",
                  "n": 0
                },
                "strike": {
                  "by": "atm",
                  "offset": 0
                },
                "lots": 1,
                "hedge_for": null,
                "risk": null,
                "liquidity": {
                  "max_spread_pct": 3,
                  "min_oi": 0,
                  "min_premium": 1
                }
              },
              {
                "id": "sp",
                "instrument": "option",
                "side": "sell",
                "option_type": "put",
                "expiry": {
                  "kind": "weekly",
                  "n": 0
                },
                "strike": {
                  "by": "atm",
                  "offset": 0
                },
                "lots": 1,
                "hedge_for": null,
                "risk": null,
                "liquidity": {
                  "max_spread_pct": 3,
                  "min_oi": 0,
                  "min_premium": 1
                }
              }
            ]
          },
          "entry": {
            "source": {
              "type": "conditions@1",
              "when": null,
              "on": "close",
              "hold_s": 0
            },
            "window": {
              "start": "09:30",
              "end": "13:30"
            },
            "skip_first_min": 0,
            "skip_last_min": 0,
            "days": [
              "mon",
              "tue"
            ],
            "expiry_day": "normal",
            "active_from": null,
            "active_until": null
          },
          "exit": {
            "sources": [],
            "square_off": "15:15",
            "expiry_day_exit": null,
            "max_hold_min": null
          },
          "sizing": {
            "type": "fixed_lots@1",
            "max_lots": 10
          },
          "execution": {
            "type": "protected_limit@1",
            "order": "auto",
            "hedge_wait_ms": 5000,
            "stagger_ms": 0,
            "buffer_pct": 0.5,
            "chase": {
              "every_ms": 1000,
              "max_slippage_pct": 1,
              "max_attempts": 10
            },
            "on_incomplete": "safest",
            "retry_next_signal": null
          },
          "risk": {
            "per_leg": {
              "type": "per_leg@1",
              "stop_loss": null,
              "target": null,
              "trail": null,
              "on_leg_stop": "nothing",
              "at_broker": false
            },
            "combined": {
              "type": "combined@1",
              "scope": "account",
              "basis": "rupees",
              "stop_loss": {
                "rupees": 3000
              },
              "target": {
                "rupees": 2000
              },
              "breakeven": null,
              "trail": null,
              "lock_ladder": [],
              "deployment": null
            },
            "limits": {
              "type": "limits@1",
              "max_loss_per_day": null,
              "max_profit_per_day": null,
              "max_loss_per_week": null,
              "max_cycles_per_day": 3,
              "max_orders_per_day": 50,
              "exit_on_limit": true,
              "on_breaker": "nothing"
            }
          },
          "reentry": {
            "on": [],
            "max": 0,
            "delay_s": 300,
            "require_fresh_signal": true,
            "same_direction_only": true,
            "until": null
          },
          "adjustments": [],
          "notify": [],
          "costs": {
            "model": "auto",
            "slippage_pct": null
          }
        }
      },
      "created_at": "2026-10-18T09:18:05.511Z",
      "updated_at": "2026-10-18T09:18:05.511Z"
    },
    "validation": {
      "ok": true,
      "deployable": true,
      "schema_version": 1,
      "migrated_from": null,
      "errors": [],
      "blockers": [],
      "warnings": [],
      "needs_ack": [],
      "summary": "Sell 1 lot of an ATM call (weekly expiry) and sell 1 lot of an ATM put (weekly expiry) on NIFTY. Enter as soon as the window opens, between 09:30 and 13:30, Monday to Friday. Everything closes at 15:15. Size: the legs' lots times each account's multiplier, at most 10 lots per leg. Orders: hedges first when there are any, limit prices 0.5% beyond the market, chasing up to 1% slippage; if only some legs fill: close a sold option left without its hedge, keep the rest. Protection: stop at ₹3,000 loss, take ₹2,000 profit; no per-leg stops; at most 3 trades a day. No re-entries.",
      "compiled_hash": "sha256:c030cdecce518bdf50067237a17de0b5508d3e962e743a87dd41e7df3ef01ff9",
      "components": [
        "chain@1",
        "combined@1"
      ],
      "warm_up": null
    }
  },
  "error": null
}

Share a strategy #

PUT /v2/strategies/{strategy_id}/sharing scope strategies

Shares the newest saved version (never the draft) with named users (visibility: users, shared_with) or by link (visibility: link; the token is in this answer only, link: create makes a new one and the old one stops working), or makes it private again.

More about this

Viewers see the version's document and summary, read-only, and may fork it into their own draft; they never see accounts, deployments, orders, P&L, journeys or webhooks. Stopping a share never touches existing forks. Off when OMS_AUTO_STRATEGIES is off. Takes an optional Idempotency-Key.

Parameters

  • strategy_id path · string required

    Strategy id.

Body fields

  • visibility string required

    private, users or link (public, the gallery, comes later).

    One of: private, users, link, public, unknown

  • shared_with string[] | null

    Usernames who may view and fork (for users; at most 50).

  • link string | null

    create a new link (the old one stops working) or revoke it.

    One of: create, revoke

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

404strategy_not_found

No automated strategy with this id for the caller.

409no_saved_version

A strategy is shared as a saved version, never its draft: save a version first.

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

All fields (request and response schema)

Loading fields…

PUT
curl -X PUT "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/sharing" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "visibility": "users",
    "shared_with": [
      "owner-01M59PAX3ZRBAGC80PT5N24KQR"
    ]
  }'
Response · 200
{
  "status": "success",
  "data": {
    "strategy_id": "01M59PAX5AS3FKX3W9D93JY57E",
    "visibility": "users",
    "shared_with": [
      "owner-01M59PAX3ZRBAGC80PT5N24KQR"
    ],
    "link": null,
    "shared_version": 1
  },
  "error": null
}

Stop sharing a strategy #

DELETE /v2/strategies/{strategy_id}/sharing scope strategies

Makes the strategy private: named users lose access and the link stops working at once.

More about this

Forks already made stay their owners'. Takes an optional Idempotency-Key.

Parameters

  • strategy_id path · string required

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

404strategy_not_found

No automated strategy 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…

DELETE
curl -X DELETE "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/sharing" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "strategy_id": "01M59PAX5AS3FKX3W9D93JY57E",
    "visibility": "private",
    "shared_with": [],
    "link": null,
    "shared_version": 2
  },
  "error": null
}