Automated strategies
Write, check, version and share strategy documents.
List strategies #
/v2/strategies scope readThe 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
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/strategies" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/strategies",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies scope strategiesCreates 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
revisionlast read; a draft changed since is refused (409strategy_busy) rather than overwritten.
Errors
| HTTP | Code | When |
|---|---|---|
| 400 | malformed_json | The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types). |
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 422 | invalid_document | The strategy document has problems; |
| 422 | invalid_request | The request is well-formed but not valid; |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
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
}
}
}
}
}
}'import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/strategies",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
json={
"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,
},
},
},
},
},
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"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
}
}
}
}
}
}),
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id} scope readOne 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
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/strategies/<strategy_id>" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id} scope strategiesReplaces 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
revisionlast read; a draft changed since is refused (409strategy_busy) rather than overwritten.
Errors
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 409 | strategy_busy | The strategy changed since it was read (or is archived); read it again and retry. |
| 422 | invalid_document | The strategy document has problems; |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
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
}'import os
import requests
response = requests.patch(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
json={
"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,
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>', {
method: 'PATCH',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"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
}),
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id} scope strategiesArchives 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
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 409 | strategy_in_use | The strategy has a deployment that is not stopped; stop it first. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
curl -X DELETE "https://cirrus.pocketful.in/v2/strategies/<strategy_id>" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.delete(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>', {
method: 'DELETE',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id}/versions scope readEvery saved version, newest first (documents left out).
Parameters
- strategy_id path · string required
Strategy id.
Errors
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id}/versions scope strategiesSaves 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
revisionthe user saw; refused (409) when the draft changed since.
Errors
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 409 | strategy_busy | The strategy changed since it was read (or is archived); read it again and retry. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
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
}'import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
json={
"revision": 2,
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"revision": 2
}),
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id}/versions/{n} scope readOne immutable version with its normalized document.
Parameters
- strategy_id path · string required
Strategy id.
- n path · integer (int32) required
Version number.
Errors
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | version_not_found | No such version of the strategy. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions/<n>" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions/<n>",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>/versions/<n>', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id}/clone scope strategiesA 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
| HTTP | Code | When |
|---|---|---|
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 404 | version_not_found | No such version of the strategy. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
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"
}'import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/clone",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
json={
"version": 1,
"name": "My copy",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>/clone', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"version": 1,
"name": "My copy"
}),
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/{strategy_id}/export scope readThe 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) oryaml. - version query · integer (int32)
A version (default: the draft).
Errors
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_query | The query string does not fit the route's parameters. |
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 404 | version_not_found | No such version of the strategy. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/export" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/export",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>/export', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"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 #
/v2/strategies/import scope strategiesCreates 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
| HTTP | Code | When |
|---|---|---|
| 400 | malformed_json | The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types). |
| 401 | unauthorized | No credential, or the credential is invalid, expired or revoked. |
| 403 | forbidden | The credential may not use this route (missing scope, app-session-only route, IP not allowed). |
| 404 | strategy_not_found | No automated strategy with this id for the caller. |
| 404 | version_not_found | No such version of the strategy. |
| 422 | invalid_document | The strategy document has problems; |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
All fields (request and response schema)
Loading fields…
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"
}'import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/strategies/import",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
json={
"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",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/import', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"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"
}),
});
const body = await response.json();
console.log(response.status, body);{
"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
}