Strategy gallery
Browse, copy, buy and publish strategy templates.
List a strategy in the gallery #
/v2/strategies/{strategy_id}/gallery scope strategiesSends a saved version (default: the newest) to the public gallery for staff review.
More about this
It needs at least 20 finished trades of that version in your own paper or live runs (the badge), a deployable version with no unlimited loss left without a combined stop, and no promise of results in its name or description. Published performance is in percent of the capital you ran it with (return, max drawdown, win rate, trades): never rupees or quantities; the capital itself is seen by you and the reviewers only. You appear under display_name, never your username or email. price_credits above 0 makes it a paid template: only while paid templates are on (GET /v2/gallery/pricing), within the tenant's limits, else 422. One listing per strategy may wait for review at a time. Off unless OMS_AUTO_GALLERY is on. Takes an optional Idempotency-Key.
Parameters
- strategy_id path · string required
Strategy id.
Body fields
- display_name string required
The name shown as the author (3–40 letters, digits, spaces,
.,_,-; never your username or email). - badge string required
Whose results to publish: your
paperor yourliveruns of this version (shown as a badge).One of: paper, live, unknown
- capital number (double) required
The capital (₹) you ran it with: every published percent is of this. Seen by you and the reviewers only.
- price_credits integer (int64)
Credits to copy it (0 or absent: free). Only while paid templates are on, and within the tenant's limits (
GET /v2/gallery/pricing). - version integer (int32) | null
The saved version (default: the newest).
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. |
| 409 | no_saved_version | A strategy is shared as a saved version, never its draft: save a version first. |
| 409 | not_enough_cycles | A gallery listing needs at least 20 finished trades of the version in the author's runs with the chosen badge. |
| 409 | listing_pending | A listing of this strategy is already waiting for review; withdraw it first. |
| 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/<strategy_id>/gallery" \
-H "Authorization: token $CIRRUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Theta Lab",
"badge": "paper",
"capital": 200000,
"price_credits": 25
}'import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/gallery",
headers={
"Authorization": f"token {os.environ['CIRRUS_API_KEY']}",
},
json={
"display_name": "Theta Lab",
"badge": "paper",
"capital": 200000,
"price_credits": 25,
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch('https://cirrus.pocketful.in/v2/strategies/<strategy_id>/gallery', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"display_name": "Theta Lab",
"badge": "paper",
"capital": 200000,
"price_credits": 25
}),
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"listing": {
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"underlying": "NIFTY",
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"author": "Theta Lab",
"badge": "paper",
"label": "Past results on paper (simulated); not advice.",
"performance": {
"return_pct": 1.75,
"max_drawdown_pct": 0.74,
"win_rate_pct": 66.67,
"trades": 21,
"since": "2026-09-01",
"until": "2026-09-21"
},
"price_credits": 25,
"effective_price": 25,
"is_free": false,
"price_reason": "priced",
"non_refundable": true,
"copies": 0,
"listed_at": "2026-10-26T14:14:50.318Z",
"can_copy": true,
"mine": true
},
"strategy_id": "01M5W90R03C4SMJZRNMFG0AM8Q",
"version": 1,
"status": "pending",
"review_notes": "",
"capital": 200000,
"purchases": 0,
"asking_price_credits": 25,
"admin_free": false
},
"error": null
}Browse the gallery #
/v2/gallery app sessionApproved listings, newest first (or by return / popular), searchable.
More about this
Each shows the author's display name, a Paper or Live badge, and past performance in percent of capital only, with "not advice". Never the author's username, accounts, rupee amounts or quantities. Without documents.
Parameters
- q query · string
Words to find in the name, description, tags, underlying or author (at most 64 characters).
- badge query · string
paperorlive. - price query · string
freeorpaid. - sort query · string
newest(default),returnorpopular. - limit query · integer (int64)
1–50 (default 20).
- offset query · integer (int64)
Listings to skip (at most 1,000).
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). |
| 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 "https://cirrus.pocketful.in/v2/gallery" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/gallery",
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/gallery', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": [
{
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"underlying": "NIFTY",
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"author": "Theta Lab",
"badge": "paper",
"label": "Past results on paper (simulated); not advice.",
"performance": {
"return_pct": 1.75,
"max_drawdown_pct": 0.74,
"win_rate_pct": 66.67,
"trades": 21,
"since": "2026-09-01",
"until": "2026-09-21"
},
"price_credits": 25,
"effective_price": 25,
"is_free": false,
"price_reason": "priced",
"non_refundable": true,
"copies": 0,
"listed_at": "2026-10-26T14:14:50.411Z",
"can_copy": false,
"mine": false
}
],
"error": null
}Your gallery listings #
/v2/gallery/mine app sessionYour listings in every state (pending, approved, rejected, taken_down, withdrawn) with the reviewers' notes, newest first.
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/gallery/mine" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/gallery/mine",
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/gallery/mine', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": [
{
"listing": {
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"underlying": "NIFTY",
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"author": "Theta Lab",
"badge": "paper",
"label": "Past results on paper (simulated); not advice.",
"performance": {
"return_pct": 1.75,
"max_drawdown_pct": 0.74,
"win_rate_pct": 66.67,
"trades": 21,
"since": "2026-09-01",
"until": "2026-09-21"
},
"price_credits": 25,
"effective_price": 25,
"is_free": false,
"price_reason": "priced",
"non_refundable": true,
"copies": 0,
"listed_at": "2026-10-26T14:14:50.318Z",
"can_copy": true,
"mine": true
},
"strategy_id": "01M5W90R03C4SMJZRNMFG0AM8Q",
"version": 1,
"status": "pending",
"review_notes": "",
"capital": 200000,
"purchases": 0,
"asking_price_credits": 25,
"admin_free": false
}
],
"error": null
}Get a gallery listing #
/v2/gallery/{listing_id} app sessionOne approved listing (or one of yours, in any state).
More about this
document is included when you may copy it: free, bought, or yours.
Parameters
- listing_id path · string required
Listing 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 | listing_not_found | No such gallery listing for the caller: withdrawn, taken down, not approved yet (and not theirs), or it never existed. |
| 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/gallery/<listing_id>" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/gallery/<listing_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/gallery/<listing_id>', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"underlying": "NIFTY",
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"author": "Theta Lab",
"badge": "paper",
"label": "Past results on paper (simulated); not advice.",
"performance": {
"return_pct": 1.75,
"max_drawdown_pct": 0.74,
"win_rate_pct": 66.67,
"trades": 21,
"since": "2026-09-01",
"until": "2026-09-21"
},
"price_credits": 25,
"effective_price": 25,
"is_free": false,
"price_reason": "priced",
"non_refundable": true,
"copies": 0,
"listed_at": "2026-10-26T14:14:50.411Z",
"can_copy": false,
"mine": false
},
"error": null
}Withdraw your listing #
/v2/gallery/{listing_id} app sessionTakes your listing out of the gallery (or out of review).
More about this
Copies already made and purchases stay. Takes an optional Idempotency-Key.
Parameters
- listing_id path · string required
Listing 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 | listing_not_found | No such gallery listing for the caller: withdrawn, taken down, not approved yet (and not theirs), or it never existed. |
| 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/gallery/<listing_id>" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.delete(
"https://cirrus.pocketful.in/v2/gallery/<listing_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/gallery/<listing_id>', {
method: 'DELETE',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"listing": {
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"underlying": "NIFTY",
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"author": "Theta Lab",
"badge": "paper",
"label": "Past results on paper (simulated); not advice.",
"performance": {
"return_pct": 1.75,
"max_drawdown_pct": 0.74,
"win_rate_pct": 66.67,
"trades": 21,
"since": "2026-09-01",
"until": "2026-09-21"
},
"price_credits": 25,
"effective_price": 25,
"is_free": false,
"price_reason": "priced",
"non_refundable": true,
"copies": 2,
"listed_at": "2026-10-26T14:14:50.411Z",
"can_copy": true,
"mine": true
},
"strategy_id": "01M5W90R03C4SMJZRNMFG0AM8Q",
"version": 1,
"status": "withdrawn",
"review_notes": "Checked: stop-loss present, honest name",
"capital": 200000,
"purchases": 1,
"asking_price_credits": 25,
"admin_free": false
},
"error": null
}Copy a listing into your strategies #
/v2/gallery/{listing_id}/copy app sessionA new draft of yours from the listed version, recording where it came from (the author's display name).
More about this
It never deploys. A priced listing is bought (and copied) with POST /v2/gallery/{id}/purchase; free ones (paid templates off, staff made it free, no price) and ones you bought copy here. Takes an optional Idempotency-Key.
Parameters
- listing_id path · string required
Listing 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 | listing_not_found | No such gallery listing for the caller: withdrawn, taken down, not approved yet (and not theirs), or it never existed. |
| 409 | purchase_required | A paid gallery template must be bought before it is copied. |
| 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/gallery/<listing_id>/copy" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/gallery/<listing_id>/copy",
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/gallery/<listing_id>/copy', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"strategy": {
"id": "01M5W90RG5GJE0A04VDBQ3MKPN",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"display_status": "draft",
"latest_version": 0,
"revision": 1,
"visibility": "private",
"forked_from": {
"strategy_id": "01M5W90R03C4SMJZRNMFG0AM8Q",
"version": 1
},
"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; 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": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"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": null,
"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-26T14:14:50.629Z",
"updated_at": "2026-10-26T14:14:50.629Z"
},
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"compiled_hash": "sha256:44ffd35c2d50344cd553dba925e707521b55be5023eae9a4a165acdc1190a9cf",
"components": [
"chain@1",
"combined@1"
],
"warm_up": null
}
},
"error": null
}Buy a paid listing #
/v2/gallery/{listing_id}/purchase app sessionBuys a priced listing with your platform credits and makes your copy in the same step (copy, a new draft): **purchases are non-refundable**, and nothing is charged unless the copy is made.
More about this
The price is the listing's effective_price (free while paid templates are off, during a promotion, or when staff made it free: copy those instead). The author receives their share of the credits (GET /v2/gallery/pricing). Buying again changes nothing (charged: 0, your receipt); retry a failed attempt with the same Idempotency-Key (it is never charged twice), or a new one after purchase_failed. Your own listings are copied, not bought. Needs an Idempotency-Key.
Parameters
- listing_id path · string required
Listing id.
Errors
| HTTP | Code | When |
|---|---|---|
| 400 | idempotency_key_required | The |
| 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 | listing_not_found | No such gallery listing for the caller: withdrawn, taken down, not approved yet (and not theirs), or it never existed. |
| 409 | insufficient_credits | Not enough platform credits for this purchase; nothing was charged. |
| 409 | purchase_failed | A gallery purchase did not complete and nothing was charged; retry with a new Idempotency-Key. |
| 409 | purchase_in_progress | A gallery purchase with this Idempotency-Key is still being made; retry with the same key. |
| 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 |
| 503 | credits_unavailable | Platform credits can't be reached right now; nothing was charged. Retry. |
All fields (request and response schema)
Loading fields…
curl -X POST "https://cirrus.pocketful.in/v2/gallery/<listing_id>/purchase" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.post(
"https://cirrus.pocketful.in/v2/gallery/<listing_id>/purchase",
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/gallery/<listing_id>/purchase', {
method: 'POST',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"charged": 25,
"balance": 75,
"receipt": {
"receipt_id": "gal_f75aea3e834242cd8c671c041702e4a6",
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"author": "Theta Lab",
"charged_credits": 25,
"strategy_id": "62M3WVQ8PSDFR8MSDHPBFG6E4D",
"bought_at": "2026-10-26T14:14:50.557Z",
"non_refundable": true
},
"copy": {
"strategy": {
"id": "62M3WVQ8PSDFR8MSDHPBFG6E4D",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"tags": [
"weekly"
],
"display_status": "draft",
"latest_version": 0,
"revision": 1,
"visibility": "private",
"forked_from": {
"strategy_id": "01M5W90R03C4SMJZRNMFG0AM8Q",
"version": 1
},
"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; 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": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"description": "Weekly ATM straddle with a combined stop",
"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": null,
"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-26T14:14:50.566Z",
"updated_at": "2026-10-26T14:14:50.566Z"
},
"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; no per-leg stops; at most 3 trades a day. No re-entries.",
"compiled_hash": "sha256:44ffd35c2d50344cd553dba925e707521b55be5023eae9a4a165acdc1190a9cf",
"components": [
"chain@1",
"combined@1"
],
"warm_up": null
}
}
},
"error": null
}Your platform credits #
/v2/credits app sessionYour credit balance (your platform credits wallet: buys paid gallery templates; your share of your templates' sales adds to it) and its latest gallery changes.
More about this
Only while paid templates are on (else 403).
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 |
| 503 | credits_unavailable | Platform credits can't be reached right now; nothing was charged. Retry. |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/credits" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/credits",
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/credits', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"balance": 75,
"entries": [
{
"at": "2026-10-26T14:14:50.558Z",
"delta": -25,
"balance_after": 75,
"kind": "purchase",
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"note": "Gallery template \"Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH\" by Theta Lab (non-refundable)"
},
{
"at": "2026-10-26T14:14:50.530Z",
"delta": 100,
"balance_after": 100,
"kind": "grant",
"listing_id": null,
"note": "Credits added by staff"
}
]
},
"error": null
}Whether a version may be listed #
/v2/strategies/{strategy_id}/gallery/eligibility scope readFor a saved version (default: the newest), per badge (paper, live): its finished trades in your own runs of that mode, and whether they reach the 20 a listing needs, with the reason when not.
More about this
Counted from the same runs as listing it. The other listing checks (a deployable version, a combined stop for unlimited loss, no promise of results, one listing waiting for review) run when you list it. Off unless OMS_AUTO_GALLERY is on.
Parameters
- strategy_id path · string required
Strategy id.
- version query · integer (int32)
The saved version (default: the newest).
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 | no_saved_version | A strategy is shared as a saved version, never its draft: save a version first. |
| 429 | rate_limited | Too many requests for this credential (or too many failed attempts); retry after the |
| 503 | service_unavailable | A dependency is temporarily unavailable, or the feature is off on this server; retry later. |
All fields (request and response schema)
Loading fields…
curl "https://cirrus.pocketful.in/v2/strategies/<strategy_id>/gallery/eligibility" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/strategies/<strategy_id>/gallery/eligibility",
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>/gallery/eligibility', {
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": "01M5W6711PRZGP3VMPA499ES8J",
"version": 1,
"required_cycles": 20,
"badges": [
{
"badge": "paper",
"finished_cycles": 20,
"eligible": true,
"reason": null
},
{
"badge": "live",
"finished_cycles": 0,
"eligible": false,
"reason": "A listing needs at least 20 finished trades of this version with the chosen badge; it has 0."
}
]
},
"error": null
}Paid-template settings #
/v2/gallery/pricing app sessionWhether paid templates are on for this tenant, the promotion, the price limits authors set within, the author's share of a sale, and that purchases are non-refundable.
More about this
Each listing also carries effective_price, is_free and price_reason.
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/gallery/pricing" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/gallery/pricing",
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/gallery/pricing', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"paid_enabled": true,
"all_free": false,
"min_price_credits": 10,
"max_price_credits": 10000,
"author_share_pct": 70,
"non_refundable": true,
"purchases_available": true
},
"error": null
}Your purchase receipts #
/v2/gallery/purchases app sessionTemplates you bought, newest first (at most 500): what you paid, your copy and the receipt id (also on your wallet's transaction).
More about this
Purchases are non-refundable.
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/gallery/purchases" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/gallery/purchases",
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/gallery/purchases', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": [
{
"receipt_id": "gal_f75aea3e834242cd8c671c041702e4a6",
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"author": "Theta Lab",
"charged_credits": 25,
"strategy_id": "62M3WVQ8PSDFR8MSDHPBFG6E4D",
"bought_at": "2026-10-26T14:14:50.557Z",
"non_refundable": true
}
],
"error": null
}Your earnings as an author #
/v2/gallery/earnings app sessionSales of your templates (latest 500) and your share of them in platform credits, overall and per template.
More about this
Earnings are credits you can spend on the platform: no withdrawal or payout. Never names a buyer.
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/gallery/earnings" \
-H "Authorization: token $CIRRUS_API_KEY"import os
import requests
response = requests.get(
"https://cirrus.pocketful.in/v2/gallery/earnings",
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/gallery/earnings', {
method: 'GET',
headers: {
Authorization: `token ${process.env.CIRRUS_API_KEY}`,
},
});
const body = await response.json();
console.log(response.status, body);{
"status": "success",
"data": {
"author_share_pct": 70,
"sales": 1,
"credits_earned": 17,
"templates": [
{
"listing_id": "01M5W90R6E1MM606W1ZM1WW4S1",
"name": "Weekly straddle 01M5W90QZWNR5ZDD6W1Z44VGCH",
"sales": 1,
"credits_earned": 17
}
]
},
"error": null
}