Returns pro rata amounts that would move out-of-compliance classes
toward their aim: the class rule’s own Target % when set, otherwise
the midpoint of its allocation band, using the prices you provide.
Rows are ordered largest-dollar-value first. This is arithmetic on
the user’s own rules, not a recommendation.
A short (negative shares) or an option (a holding in the Options
class) gets no row, and not_rebalanced lists each one once. A
class’s move is the gap on its net value (shorts subtract), spread
over its long holdings outside Options only (ADR-153, ADR-145), so
one long can carry the whole gap. A class with no priced long holding
outside Options gets no row, and appears in unresolved if it stays
outside its band. For a class that holds only shorts and options, the
reason no_priced_holdings means there is nothing to trade, whatever
the prices.
A portfolio worth zero or less is not rebalanced: percentages are
undefined there, so trades is empty, each resulting_pct is null
and total_value is still reported, signed (ADR-153).
prices is required and must cover every non-cash position in the
portfolio, except a held option with a mark or one past its expiry
(ADR-147). Symbols you send that the portfolio does not hold are
ignored. Keys are matched to held symbols case-insensitively. If a
held symbol is missing from the map, the call fails with a 400 whose
body carries missing_symbols. Allocait never fills a symbol you
left out from its own market data (ADR-036).
Raw API key shown once when created in the Allocait app (Settings > API keys). Send it verbatim in this header; the server stores and compares only its SHA-256 hash. Allocait generates every key: alc_ followed by 64 lowercase hex characters. Keys issued before 2026-10-10 are 64 hex characters with no prefix and keep working. A key may carry an expiry (90 days or 1 year, or never). A malformed, unknown, revoked or expired key gets 401 with no further detail, and a malformed one is refused before any lookup. Keys cannot be created through this API.
Symbol-to-price map. Keys are ticker symbols, matched
case-insensitively (normalised to uppercase); values are numbers,
0 or more. 0 is a real price, for example an option that expired
worthless. On the agent surface, a symbol you leave out of this map is
never priced from Allocait's own data (ADR-036); it comes back
null, or the call is refused, depending on the endpoint. Two
exceptions are the user's own numbers, not Allocait's: a held option
with a mark is priced at its mark, so you may leave it out, and a
price you pass for it replaces the mark for that call only and is
never stored; an option past its expiry counts 0 whatever you pass
(ADR-147).
Signed. A portfolio worth zero or less has no percentages, so trades is empty and the class percentages are null; the total itself is still reported (ADR-153).
Always overrides on this surface. prices is required and checked to cover every non-cash position before this is computed, except a held option that owns its price (ADR-036, ADR-147).
Pro rata amounts, ordered largest-dollar-value first. A holding priced at 0 gets no row, since an amount cannot be priced at 0 (ADR-080). A short (negative shares) or an option (a holding in the Options class) gets no row; its class's move is spread over the class's long holdings outside Options only (ADR-153, ADR-145).
Each asset class's share of the portfolio after these amounts, Cash included. Proceeds from removed shares stay in Cash. Every resulting_pct is null when the portfolio is worth zero or less (ADR-153).
Pro rata amounts that would move each class toward its aim: the user's target, or the midpoint of their band. Arithmetic on the user's own rules; not a recommendation.
Classes still outside their band after these amounts, such as a class below its band with no holding to add to, each with the reason. The amounts don't resize holdings, so size_violations stand.
Every short and every Options class holding the rebalance leaves
as it is, once each, ordered by symbol (ADR-145). Always present,
empty when there are none. A holding with zero shares is not
listed. An entry carries no price, count or value.
Show child attributes
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Allocait","description":"Allocait checks a portfolio against the owner's own allocation rules. This site documents the REST API agents call and how to connect Claude, ChatGPT and Codex to it.","colors":{"primary":"#0b0b0b","light":"#ffc629","dark":"#0b0b0b"},"logo":{"light":"https://mintcdn.com/allocait/N9X8GrpLUSiZAKIm/logo/light.svg?fit=max\u0026auto=format\u0026n=N9X8GrpLUSiZAKIm\u0026q=85\u0026s=37c68a7ac5dc3550d24f484060530ea6","dark":"https://mintcdn.com/allocait/N9X8GrpLUSiZAKIm/logo/dark.svg?fit=max\u0026auto=format\u0026n=N9X8GrpLUSiZAKIm\u0026q=85\u0026s=64ac292a0a27672b4ff7d318734b0a5a","href":"https://allocait.app"},"favicon":"https://mintcdn.com/allocait/N9X8GrpLUSiZAKIm/logo/favicon.svg?fit=max\u0026auto=format\u0026n=N9X8GrpLUSiZAKIm\u0026q=85\u0026s=ff094ad764f4dfe37dbf99bdd5c9aaf4","api":{"playground":{"display":"simple"}},"appearance":{"default":"dark"},"background":{"color":{"light":"#ffffff","dark":"#09090b"}},"navbar":{"links":[{"href":"mailto:support@allocait.app","label":"Support"}],"primary":{"type":"button","label":"allocait.app","href":"https://allocait.app"}},"footer":{"links":[{"header":"Product","items":[{"label":"allocait.app","href":"https://allocait.app"},{"label":"Support","href":"mailto:support@allocait.app"}]}]},"icons":{"library":"tabler"},"contextual":{"options":["copy","view","chatgpt","claude","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"allocait","hasAudioNarration":false,"actualSubdomain":"allocait","customDomains":["docs.allocait.app"],"gitSource":{"type":"github","owner":"allocait-app","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"},"WEB_MCP":{"status":"DISABLED"},"NARRATION":{"status":"DISABLED"}},"buildId":"6af158c3927786a3649023cd","clientVersion":"0.0.4102","searchFilterCounts":[{"language":"default","tag":"API reference","count":95},{"language":"default","tag":"Endpoints","count":84},{"language":"default","tag":"Concepts","count":24},{"language":"default","tag":"Claude \u0026 MCP","count":23},{"language":"default","tag":"Rules","count":22},{"language":"default","tag":"Guides","count":13},{"language":"default","tag":"Tools","count":12},{"language":"default","tag":"Inputs","count":12},{"language":"default","tag":"ChatGPT \u0026 Codex","count":10},{"language":"default","tag":"Watchlists","count":9}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"img.nav-logo{height:1rem!important;width:auto!important}.callout[data-callout-type=\"note\"],.callout[data-callout-type=\"info\"],.callout[data-callout-type=\"tip\"]{background-color:rgb(255 198 41 / 0.2)!important;border-color:rgb(255 198 41 / 0.6)!important}.callout[data-callout-type=\"note\"] *,.callout[data-callout-type=\"info\"] *,.callout[data-callout-type=\"tip\"] *{color:#0b0b0b!important}.callout[data-callout-type=\"note\"] svg,.callout[data-callout-type=\"info\"] svg,.callout[data-callout-type=\"tip\"] svg{fill:#0b0b0b!important}html.dark .callout[data-callout-type=\"note\"],html.dark .callout[data-callout-type=\"info\"],html.dark .callout[data-callout-type=\"tip\"]{background-color:rgb(255 198 41 / 0.1)!important;border-color:rgb(255 198 41 / 0.35)!important}html.dark .callout[data-callout-type=\"note\"] *,html.dark .callout[data-callout-type=\"info\"] *,html.dark .callout[data-callout-type=\"tip\"] *{color:#ffc629!important}html.dark .callout[data-callout-type=\"note\"] svg,html.dark .callout[data-callout-type=\"info\"] svg,html.dark .callout[data-callout-type=\"tip\"] svg{fill:#ffc629!important}"}],"page":{"pagePath":"api-reference/checks/preview-rebalance-amounts-with-your-prices","slug":"/api-reference/checks/preview-rebalance-amounts-with-your-prices","pageMetadata":{"title":"Preview rebalance amounts with your prices","description":"Returns pro rata amounts that would move out-of-compliance classes\ntoward their aim: the class rule's own Target % when set, otherwise\nthe midpoint of its allocation band, using the prices you provide.\nRows are ordered largest-dollar-value first. This is arithmetic on\nthe user's own rules, not a recommendation.\n\nA short (negative `shares`) or an option (a holding in the Options\nclass) gets no row, and `not_rebalanced` lists each one once. A\nclass's move is the gap on its net value (shorts subtract), spread\nover its long holdings outside Options only (ADR-153, ADR-145), so\none long can carry the whole gap. A class with no priced long holding\noutside Options gets no row, and appears in `unresolved` if it stays\noutside its band. For a class that holds only shorts and options, the\nreason `no_priced_holdings` means there is nothing to trade, whatever\nthe prices.\n\nA portfolio worth zero or less is not rebalanced: percentages are\nundefined there, so `trades` is empty, each `resulting_pct` is null\nand `total_value` is still reported, signed (ADR-153).\n\n`prices` is required and must cover every non-cash position in the\nportfolio, except a held option with a mark or one past its expiry\n(ADR-147). Symbols you send that the portfolio does not hold are\nignored. Keys are matched to held symbols case-insensitively. If a\nheld symbol is missing from the map, the call fails with a 400 whose\nbody carries `missing_symbols`. Allocait never fills a symbol you\nleft out from its own market data (ADR-036).\n","deprecated":null,"version":null,"openapi":"/openapi.yaml post /rebalance/preview","href":"/api-reference/checks/preview-rebalance-amounts-with-your-prices","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Returns pro rata amounts that would move out-of-compliance classes\\ntoward their aim: the class rule’s own Target % when set, otherwise\\nthe midpoint of its allocation band, using the prices you provide.\\nRows are ordered largest-dollar-value first. This is arithmetic on\\nthe user’s own rules, not a recommendation.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"A short (negative \", _jsx(_components.code, {\n children: \"shares\"\n }), \") or an option (a holding in the Options\\nclass) gets no row, and \", _jsx(_components.code, {\n children: \"not_rebalanced\"\n }), \" lists each one once. A\\nclass’s move is the gap on its net value (shorts subtract), spread\\nover its long holdings outside Options only (ADR-153, ADR-145), so\\none long can carry the whole gap. A class with no priced long holding\\noutside Options gets no row, and appears in \", _jsx(_components.code, {\n children: \"unresolved\"\n }), \" if it stays\\noutside its band. For a class that holds only shorts and options, the\\nreason \", _jsx(_components.code, {\n children: \"no_priced_holdings\"\n }), \" means there is nothing to trade, whatever\\nthe prices.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"A portfolio worth zero or less is not rebalanced: percentages are\\nundefined there, so \", _jsx(_components.code, {\n children: \"trades\"\n }), \" is empty, each \", _jsx(_components.code, {\n children: \"resulting_pct\"\n }), \" is null\\nand \", _jsx(_components.code, {\n children: \"total_value\"\n }), \" is still reported, signed (ADR-153).\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"prices\"\n }), \" is required and must cover every non-cash position in the\\nportfolio, except a held option with a mark or one past its expiry\\n(ADR-147). Symbols you send that the portfolio does not hold are\\nignored. Keys are matched to held symbols case-insensitively. If a\\nheld symbol is missing from the map, the call fails with a 400 whose\\nbody carries \", _jsx(_components.code, {\n children: \"missing_symbols\"\n }), \". Allocait never fills a symbol you\\nleft out from its own market data (ADR-036).\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Preview rebalance amounts with your prices","description":"Returns pro rata amounts that would move out-of-compliance classes\ntoward their aim: the class rule's own Target % when set, otherwise\nthe midpoint of its allocation band, using the prices you provide.\nRows are ordered largest-dollar-value first. This is arithmetic on\nthe user's own rules, not a recommendation.\n\nA short (negative `shares`) or an option (a holding in the Options\nclass) gets no row, and `not_rebalanced` lists each one once. A\nclass's move is the gap on its net value (shorts subtract), spread\nover its long holdings outside Options only (ADR-153, ADR-145), so\none long can carry the whole gap. A class with no priced long holding\noutside Options gets no row, and appears in `unresolved` if it stays\noutside its band. For a class that holds only shorts and options, the\nreason `no_priced_holdings` means there is nothing to trade, whatever\nthe prices.\n\nA portfolio worth zero or less is not rebalanced: percentages are\nundefined there, so `trades` is empty, each `resulting_pct` is null\nand `total_value` is still reported, signed (ADR-153).\n\n`prices` is required and must cover every non-cash position in the\nportfolio, except a held option with a mark or one past its expiry\n(ADR-147). Symbols you send that the portfolio does not hold are\nignored. Keys are matched to held symbols case-insensitively. If a\nheld symbol is missing from the map, the call fails with a 400 whose\nbody carries `missing_symbols`. Allocait never fills a symbol you\nleft out from its own market data (ADR-036).\n","deprecated":null,"version":null,"openapi":"/openapi.yaml post /rebalance/preview","href":"/api-reference/checks/preview-rebalance-amounts-with-your-prices","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Checks"],"operationId":"previewRebalanceWithPrices","summary":"Preview rebalance amounts with your prices","description":"Returns pro rata amounts that would move out-of-compliance classes\ntoward their aim: the class rule's own Target % when set, otherwise\nthe midpoint of its allocation band, using the prices you provide.\nRows are ordered largest-dollar-value first. This is arithmetic on\nthe user's own rules, not a recommendation.\n\nA short (negative `shares`) or an option (a holding in the Options\nclass) gets no row, and `not_rebalanced` lists each one once. A\nclass's move is the gap on its net value (shorts subtract), spread\nover its long holdings outside Options only (ADR-153, ADR-145), so\none long can carry the whole gap. A class with no priced long holding\noutside Options gets no row, and appears in `unresolved` if it stays\noutside its band. For a class that holds only shorts and options, the\nreason `no_priced_holdings` means there is nothing to trade, whatever\nthe prices.\n\nA portfolio worth zero or less is not rebalanced: percentages are\nundefined there, so `trades` is empty, each `resulting_pct` is null\nand `total_value` is still reported, signed (ADR-153).\n\n`prices` is required and must cover every non-cash position in the\nportfolio, except a held option with a mark or one past its expiry\n(ADR-147). Symbols you send that the portfolio does not hold are\nignored. Keys are matched to held symbols case-insensitively. If a\nheld symbol is missing from the map, the call fails with a 400 whose\nbody carries `missing_symbols`. Allocait never fills a symbol you\nleft out from its own market data (ADR-036).\n","requestBody":"9d42bd47-4400-414d-8c3c-4ddaf166fb26","responses":{"200":"b11f6583-4f87-42c3-ae14-701bb9b406bd","400":"a71a9cf5-13de-4432-a968-dbf4bf305ddd","401":"b45b2824-3751-43d3-b1ab-b67695ae1d84","403":"2d99ab64-4e1f-4183-a315-bcf801276d96","404":"2d268209-992b-41e6-a3dd-f4fd01a78eb1","429":"f6ceffe8-96c4-4179-99be-1e620c2d2e07","500":"65b4e956-d453-4d82-8cda-af5ba8c2a373"},"method":"post","type":"path","servers":["13120e45-325e-41e1-99fd-a11d6f409d02"],"security":["7fd1832f-5a87-49c5-91d9-dd9065c02713"],"path":"/rebalance/preview","baseUrlOptions":["https://allocait.app/api/v1"],"title":"Preview rebalance amounts with your prices","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["portfolio_id","prices"],"properties":{"portfolio_id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"portfolio_id","typeLabel":"string\u003cuuid>"},"prices":{"type":"object","description":"Symbol-to-price map. Keys are ticker symbols, matched\ncase-insensitively (normalised to uppercase); values are numbers,\n0 or more. 0 is a real price, for example an option that expired\nworthless. On the agent surface, a symbol you leave out of this map is\nnever priced from Allocait's own data (ADR-036); it comes back\nnull, or the call is refused, depending on the endpoint. Two\nexceptions are the user's own numbers, not Allocait's: a held option\nwith a `mark` is priced at its mark, so you may leave it out, and a\nprice you pass for it replaces the mark for that call only and is\nnever stored; an option past its expiry counts 0 whatever you pass\n(ADR-147).\n","additionalProperties":{"type":"number","minimum":0,"uniqueKey":"prices.additionalProperties","typeLabel":"number"},"example":{"ALFA":181.5,"ECHO":98.1,"GOLF":62.3},"isRequired":true,"uniqueKey":"prices","typeLabel":"object"},"scenario_id":{"type":"string","format":"uuid","description":"Default is the portfolio's active scenario, and only that (ADR-187, ADR-232).","uniqueKey":"scenario_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"portfolio_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","prices":{"ALFA":181.5,"ECHO":98.1,"GOLF":62.3},"scenario_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a"}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"b11f6583-4f87-42c3-ae14-701bb9b406bd":{"description":"Rebalance preview computed with the prices you provided","headers":{"X-RateLimit-Limit":{"description":"The per-minute request budget, always `60`. Sent on every response that reaches a route and on the per-minute `429`.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current one-minute window, after this one. The daily count is not reported until it is reached.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"portfolio_id":{"type":"string","format":"uuid","uniqueKey":"portfolio_id","typeLabel":"string\u003cuuid>"},"scenario_id":{"type":"string","format":"uuid","uniqueKey":"scenario_id","typeLabel":"string\u003cuuid>"},"total_value":{"type":"number","description":"Signed. A portfolio worth zero or less has no percentages, so `trades` is empty and the class percentages are null; the total itself is still reported (ADR-153).","uniqueKey":"total_value","typeLabel":"number"},"price_source":{"type":"string","enum":["overrides"],"description":"Always `overrides` on this surface. `prices` is required and checked to cover every non-cash position before this is computed, except a held option that owns its price (ADR-036, ADR-147).","uniqueKey":"price_source","typeLabel":"enum\u003cstring>"},"trade_count":{"type":"integer","uniqueKey":"trade_count","typeLabel":"integer"},"trades":{"type":"array","description":"Pro rata amounts, ordered largest-dollar-value first. A holding priced at 0 gets no row, since an amount cannot be priced at 0 (ADR-080). A short (negative `shares`) or an option (a holding in the Options class) gets no row; its class's move is spread over the class's long holdings outside Options only (ADR-153, ADR-145).","items":{"type":"object","properties":{"symbol":{"type":"string","uniqueKey":"trades.items.[INDEX].symbol","typeLabel":"string"},"asset_class":{"type":"string","uniqueKey":"trades.items.[INDEX].asset_class","typeLabel":"string"},"action":{"type":"string","enum":["BUY","SELL"],"description":"The direction of the amount: BUY adds shares to the holding,\nSELL removes shares. The amount is arithmetic on the user's own\nrules, not a recommendation. It is sized from the class's priced\nholdings only. Allocait's own dashboard shows a per-class\npriced_count/unpriced_count/prices_complete disclosure for a\npartially priced class (ADR-057), never carried here, for the\nsame reason `Violation.status` above states (ADR-036).\n","uniqueKey":"trades.items.[INDEX].action","typeLabel":"enum\u003cstring>"},"direction":{"type":"string","enum":["ADD","REDUCE"],"description":"Mirrors `action`, in neutral words. ADD for BUY, REDUCE for SELL. Added beside `action`, which keeps its values.","uniqueKey":"trades.items.[INDEX].direction","typeLabel":"enum\u003cstring>"},"current_pct":{"type":"number","uniqueKey":"trades.items.[INDEX].current_pct","typeLabel":"number"},"target_pct":{"type":"number","description":"The class's target, the same value as `class_target_pct`. Kept for existing callers.","uniqueKey":"trades.items.[INDEX].target_pct","typeLabel":"number"},"class_target_pct":{"type":"number","description":"The asset class's target on its total that this amount moves toward -- the rule's own Target % when set, otherwise the midpoint of its allocation band.","uniqueKey":"trades.items.[INDEX].class_target_pct","typeLabel":"number"},"current_price":{"type":"number","uniqueKey":"trades.items.[INDEX].current_price","typeLabel":"number"},"shares":{"type":"number","uniqueKey":"trades.items.[INDEX].shares","typeLabel":"number"},"dollar_value":{"type":"number","uniqueKey":"trades.items.[INDEX].dollar_value","typeLabel":"number"},"resulting_pct":{"type":"number","uniqueKey":"trades.items.[INDEX].resulting_pct","typeLabel":"number"}},"uniqueKey":"trades.items.[INDEX]","typeLabel":"object"},"uniqueKey":"trades","typeLabel":"object[]"},"resulting_classes":{"type":"array","description":"Each asset class's share of the portfolio after these amounts, Cash included. Proceeds from removed shares stay in Cash. Every `resulting_pct` is null when the portfolio is worth zero or less (ADR-153).","items":{"type":"object","properties":{"asset_class_id":{"type":"string","format":"uuid","uniqueKey":"resulting_classes.items.[INDEX].asset_class_id","typeLabel":"string\u003cuuid>"},"asset_class":{"type":"string","uniqueKey":"resulting_classes.items.[INDEX].asset_class","typeLabel":"string"},"resulting_pct":{"oneOf":[{"type":"number","uniqueKey":"resulting_classes.items.[INDEX].resulting_pct.oneOf.0","typeLabel":"number"},{"type":"null","uniqueKey":"resulting_classes.items.[INDEX].resulting_pct.oneOf.1","typeLabel":"null"}],"uniqueKey":"resulting_classes.items.[INDEX].resulting_pct","typeLabel":"number | null"}},"uniqueKey":"resulting_classes.items.[INDEX]","typeLabel":"object"},"uniqueKey":"resulting_classes","typeLabel":"object[]"},"basis":{"type":"string","description":"Pro rata amounts that would move each class toward its aim: the user's target, or the midpoint of their band. Arithmetic on the user's own rules; not a recommendation.","uniqueKey":"basis","typeLabel":"string"},"unresolved":{"type":"array","description":"Classes still outside their band after these amounts, such as a class below its band with no holding to add to, each with the reason. The amounts don't resize holdings, so size_violations stand.","items":{"type":"object","properties":{"asset_class_id":{"type":"string","format":"uuid","uniqueKey":"unresolved.items.[INDEX].asset_class_id","typeLabel":"string\u003cuuid>"},"asset_class":{"type":"string","uniqueKey":"unresolved.items.[INDEX].asset_class","typeLabel":"string"},"resulting_pct":{"type":"number","uniqueKey":"unresolved.items.[INDEX].resulting_pct","typeLabel":"number"},"band_min_pct":{"type":"number","uniqueKey":"unresolved.items.[INDEX].band_min_pct","typeLabel":"number"},"band_max_pct":{"type":"number","uniqueKey":"unresolved.items.[INDEX].band_max_pct","typeLabel":"number"},"reason":{"type":"string","enum":["no_priced_holdings","zero_price","cash","outside_band_after_trades"],"description":"`no_priced_holdings`: the class has nothing the preview may\ntrade, whatever its prices (a short and an option are not\ntraded).\n`zero_price`: every holding in the class is priced at 0, so\nnone can be traded (ADR-080). `cash`: Cash moves only as\nother amounts settle. `outside_band_after_trades`: rounding\nto share units leaves the class just outside its band.\n","uniqueKey":"unresolved.items.[INDEX].reason","typeLabel":"enum\u003cstring>"}},"uniqueKey":"unresolved.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unresolved","typeLabel":"object[]"},"not_rebalanced":{"type":"array","description":"Every short and every Options class holding the rebalance leaves\nas it is, once each, ordered by symbol (ADR-145). Always present,\nempty when there are none. A holding with zero shares is not\nlisted. An entry carries no price, count or value.\n","items":{"type":"object","required":["symbol","asset_class","reason"],"properties":{"symbol":{"type":"string","isRequired":true,"uniqueKey":"not_rebalanced.items.[INDEX].symbol","typeLabel":"string"},"asset_class":{"oneOf":[{"type":"string","isRequired":true,"uniqueKey":"not_rebalanced.items.[INDEX].asset_class.oneOf.0","typeLabel":"string"},{"type":"null","isRequired":true,"uniqueKey":"not_rebalanced.items.[INDEX].asset_class.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"not_rebalanced.items.[INDEX].asset_class","typeLabel":"string | null"},"reason":{"type":"string","enum":["short","option"],"description":"`short`: a negative share count. `option`: a holding in the Options class.","isRequired":true,"uniqueKey":"not_rebalanced.items.[INDEX].reason","typeLabel":"enum\u003cstring>"}},"uniqueKey":"not_rebalanced.items.[INDEX]","typeLabel":"object"},"uniqueKey":"not_rebalanced","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"portfolio_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","scenario_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","total_value":123,"price_source":"overrides","trade_count":123,"trades":[{"symbol":"\u003cstring>","asset_class":"\u003cstring>","action":"BUY","direction":"ADD","current_pct":123,"target_pct":123,"class_target_pct":123,"current_price":123,"shares":123,"dollar_value":123,"resulting_pct":123}],"resulting_classes":[{"asset_class_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","asset_class":"\u003cstring>","resulting_pct":123}],"basis":"\u003cstring>","unresolved":[{"asset_class_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","asset_class":"\u003cstring>","resulting_pct":123,"band_min_pct":123,"band_max_pct":123,"reason":"no_priced_holdings"}],"not_rebalanced":[{"symbol":"\u003cstring>","asset_class":"\u003cstring>","reason":"short"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"a71a9cf5-13de-4432-a968-dbf4bf305ddd":{"description":"`portfolio_id` missing or not a UUID, `scenario_id` not a UUID or left out when the portfolio has no active scenario (`INVALID_INPUT`), or `prices` missing, not a `{SYMBOL: price}` object, or not covering every non-cash position (`PRICES_INCOMPLETE` with `missing_symbols`, or `PRICES_INVALID`)","content":{"application/json":{"schema":{"type":"object","description":"The 400 body when a `prices` or `price_overrides` map does not cover\nevery symbol an endpoint requires a price for. `missing_symbols` is\npresent whenever the refusal is a coverage gap (a hole in the map);\nit is absent when the map was missing, malformed, or carried a\nnegative value, since there is nothing to list in that case.\nA held option with a mark, and an expired option, are never listed\nin `missing_symbols`: `missing_symbols` is the exact list, even where\nthe message says \"every non-cash position\" (ADR-147).\n","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable message, e.g. \"prices must cover every non-cash position in the portfolio\".","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"error_code":{"type":"string","enum":["PRICES_INCOMPLETE","PRICES_INVALID"],"description":"`PRICES_INCOMPLETE` for a missing map or a hole in it (with `missing_symbols` when it is a hole), `PRICES_INVALID` for a map of the wrong shape or with a negative or non-numeric value.","uniqueKey":"error_code","typeLabel":"enum\u003cstring>"},"missing_symbols":{"type":"array","items":{"type":"string","uniqueKey":"missing_symbols.items.[INDEX]","typeLabel":"string"},"description":"Held symbols absent from the map, sorted. Fetch prices for exactly these and call again.","uniqueKey":"missing_symbols","typeLabel":"string[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":"\u003cstring>","error_code":"PRICES_INCOMPLETE","missing_symbols":["\u003cstring>"]}}},"exampleType":"generated"}},"exampleType":"generated"},"b45b2824-3751-43d3-b1ab-b67695ae1d84":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"type":"object","description":"Uniform error envelope returned by every non-2xx response. `error` is\na human-readable message, safe to show the user. A refusal also\ncarries `error_code`, a stable string from the catalog in the info\nblock's Error codes section, to branch on; the HTTP status follows\nthe code (ADR-134). Only `401`, the no-plan `403`, the `403` for a\nkey without `read` and the `429` for the request budget have none.\nA `500` carries `request_id`. Extra fields by code:\nTIER_LIMIT_EXCEEDED carries `limit_type`, `current_count` and\n`max_allowed`, so a caller can branch on how many it has versus the\ncap without a second call. Its `error` text names no plan. It covers\nthe portfolio and scenario limits and the account caps: 20 webhook endpoints, 50\nwatchlists, 200 symbols on one watchlist and 50 custom symbols on one\nmonitor. Don't retry it. RULES_INVALID (`POST\n/scenarios/{id}/rules`) carries `issues`. ALREADY_EXISTS carries\n`existing_id`, plus `duplicate_ids` where older duplicates exist.\nCONFIRMATION_REQUIRED carries `would_remove`; from `POST /setup/apply` it\ncarries a fresh preview instead (`digest`, `file`, `items` and the rest of\n`SetupPreview`). INVALID_INPUT from the setup routes carries `issues`, and\nIN_USE from `POST /setup/receipts/{id}/undo` carries `later_receipt_id`.\nNOT_FOUND on a name, and\nINVALID_INPUT on a CHOICE value, carry `valid_values`. INVALID_INPUT on a\nmonitor whose level input is not a number type carries `input_id`.\nIN_USE on an input whose type would change while a monitor uses it\ncarries `monitors`. IN_USE on `PATCH /portfolios/{id}` that turns\nAllow shorts off while a short is held carries `short_count` and\n`symbols`. INVALID_INPUT on the holdings writes (`POST\n/positions/{symbol}`, `POST /portfolios/{id}/positions/apply`) that\nrefuses a negative `shares`, a `moves` other than 1 on an Options\nholding, or a `mark` on a holding outside the Options class, carries\n`symbols`, the holdings it refused. (`symbols` also appears on `WOULD_CLOSE_POSITIONS`, MCP\nonly, where it lists the holdings a full list left out.)\n","required":["error"],"example":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"},"properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"error_code":{"type":"string","enum":["INVALID_INPUT","NOT_FOUND","ALREADY_EXISTS","IN_USE","CONFIRMATION_REQUIRED","PRICES_INCOMPLETE","PRICES_INVALID","WOULD_CLOSE_POSITIONS","INSUFFICIENT_CASH","RULES_INVALID","TARGET_OUT_OF_BAND","TIER_LIMIT_EXCEEDED","FEATURE_NOT_AVAILABLE","IDEMPOTENCY_KEY_CONFLICT","DAILY_LIMIT_EXCEEDED","READ_ONLY_KEY","OAUTH_WRITE_NOT_GRANTED","TOOL_REMOVED","INTERNAL_ERROR"],"description":"Stable machine-readable code from the closed catalog. Present on every refusal a route produces; absent on `401`, the no-plan `403`, the `403` for a key without `read`, and the `429` for the request budget.","uniqueKey":"error_code","typeLabel":"enum\u003cstring>"},"request_id":{"type":"string","format":"uuid","description":"Present on a `500` (`INTERNAL_ERROR`). The same id is in Allocait's logs next to the real cause; quote it when you report the failure.","uniqueKey":"request_id","typeLabel":"string\u003cuuid>"},"issues":{"type":"array","items":{"oneOf":[{"type":"object","description":"One problem or note found while reading rules text. A file\ncarrying any `error`-level issue is never applied; `POST\n/scenarios/{id}/rules` 400s with `error_code: RULES_INVALID` and\nthe full `issues` list instead. A file with only `warning`-level\nissues still applies; those ride along on the 200 response.\n","required":["level","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.level","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.message","typeLabel":"string"},"class":{"type":"string","description":"The asset class name this issue is about, when it is about one class rather than the whole file.","uniqueKey":"issues.items.[INDEX].oneOf.0.class","typeLabel":"string"}},"uniqueKey":"issues.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","description":"One thing the file's text got wrong (`error`) or one note about it (`warning`, such as a web address in a description).","required":["level","where","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.level","typeLabel":"enum\u003cstring>"},"where":{"oneOf":[{"type":"string","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.0","typeLabel":"string"},{"type":"null","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where","typeLabel":"string | null"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.message","typeLabel":"string"},"line":{"type":"integer","description":"The line of the file the issue is on, when it is known.","uniqueKey":"issues.items.[INDEX].oneOf.1.line","typeLabel":"integer"}},"uniqueKey":"issues.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"object"},"description":"Every error and warning found while reading the rules text, when error_code is RULES_INVALID. From the setup routes (`POST /setup/preview`, `POST /setup/apply`) it is `SetupIssue` rows, on INVALID_INPUT.","uniqueKey":"issues","typeLabel":"object[]"},"later_receipt_id":{"type":"string","format":"uuid","description":"The newer import of the same setup file that blocks this undo. Present on IN_USE from `POST /setup/receipts/{id}/undo`; undo that receipt first.","uniqueKey":"later_receipt_id","typeLabel":"string\u003cuuid>"},"limit_type":{"type":"string","description":"Which cap was hit, e.g. \"portfolios\", \"scenarios\", \"webhook_endpoints\", \"watchlists\", \"asset_classes\", \"input_entries\" or \"input_entries_per_input\". Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"limit_type","typeLabel":"string"},"current_count":{"type":"number","description":"How many of limit_type the caller has right now. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"current_count","typeLabel":"number"},"max_allowed":{"type":"number","description":"The cap for limit_type on this account. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"max_allowed","typeLabel":"number"},"existing_id":{"type":"string","format":"uuid","description":"The record that already has this name. Present only when error_code is ALREADY_EXISTS; change it with that id instead of creating another.","uniqueKey":"existing_id","typeLabel":"string\u003cuuid>"},"duplicate_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"duplicate_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Other records with the same name, created before duplicates were refused. Present only on ALREADY_EXISTS, and only when such records exist.","uniqueKey":"duplicate_ids","typeLabel":"string\u003cuuid>[]"},"would_remove":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string","uniqueKey":"would_remove.additionalProperties.items.[INDEX]","typeLabel":"string"},"uniqueKey":"would_remove.additionalProperties","typeLabel":"string[]"},"description":"What the call would drop, keyed by list field, for example the `items` that a watchlist save would remove. Present only when error_code is CONFIRMATION_REQUIRED; resend with those members in `remove`.","uniqueKey":"would_remove","typeLabel":"object"},"valid_values":{"type":"array","items":{"type":"string","uniqueKey":"valid_values.items.[INDEX]","typeLabel":"string"},"description":"The names or options the field accepts. Present on NOT_FOUND for a name, and on INVALID_INPUT for a CHOICE value.","uniqueKey":"valid_values","typeLabel":"string[]"},"input_id":{"type":"string","format":"uuid","description":"The level input that is not a NUMBER, DECIMAL or PERCENTAGE input. Present on INVALID_INPUT from a monitor create or update (`POST /monitors`, `PATCH /monitors/{id}`, MCP `save_monitor`); point the monitor at a number-type input instead.","uniqueKey":"input_id","typeLabel":"string\u003cuuid>"},"short_count":{"type":"integer","description":"How many shorts the portfolio holds. Present on IN_USE from `PATCH /portfolios/{id}` (MCP `save_portfolio`) that turns Allow shorts off while a short is held; close them first.","uniqueKey":"short_count","typeLabel":"integer"},"symbols":{"type":"array","items":{"type":"string","uniqueKey":"symbols.items.[INDEX]","typeLabel":"string"},"description":"Holdings the call names. On IN_USE from `PATCH /portfolios/{id}`, the shorts still held (up to 20, by symbol). On INVALID_INPUT from the holdings writes, the holdings whose negative `shares` was refused (Allow shorts is off, or the holding is in Options), or whose `moves` other than 1 was refused (the holding is in Options). On WOULD_CLOSE_POSITIONS (MCP only), the holdings a full list left out.","uniqueKey":"symbols","typeLabel":"string[]"},"monitors":{"type":"array","description":"The monitors that use this input as a level. Present on IN_USE from an input update (`PATCH /inputs/{id}`, MCP `save_input`) that would change `data_type` to TEXT or CHOICE; move those monitors to another input first.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"name":{"type":"string","uniqueKey":"monitors.items.[INDEX].name","typeLabel":"string"},"portfolio_id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].portfolio_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"monitors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"monitors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"}}},"exampleType":"generated"}},"exampleType":"generated"},"2d99ab64-4e1f-4183-a315-bcf801276d96":{"description":"Key lacks `read` permission, or API access needs an active plan","content":{"application/json":{"schema":{"type":"object","description":"Uniform error envelope returned by every non-2xx response. `error` is\na human-readable message, safe to show the user. A refusal also\ncarries `error_code`, a stable string from the catalog in the info\nblock's Error codes section, to branch on; the HTTP status follows\nthe code (ADR-134). Only `401`, the no-plan `403`, the `403` for a\nkey without `read` and the `429` for the request budget have none.\nA `500` carries `request_id`. Extra fields by code:\nTIER_LIMIT_EXCEEDED carries `limit_type`, `current_count` and\n`max_allowed`, so a caller can branch on how many it has versus the\ncap without a second call. Its `error` text names no plan. It covers\nthe portfolio and scenario limits and the account caps: 20 webhook endpoints, 50\nwatchlists, 200 symbols on one watchlist and 50 custom symbols on one\nmonitor. Don't retry it. RULES_INVALID (`POST\n/scenarios/{id}/rules`) carries `issues`. ALREADY_EXISTS carries\n`existing_id`, plus `duplicate_ids` where older duplicates exist.\nCONFIRMATION_REQUIRED carries `would_remove`; from `POST /setup/apply` it\ncarries a fresh preview instead (`digest`, `file`, `items` and the rest of\n`SetupPreview`). INVALID_INPUT from the setup routes carries `issues`, and\nIN_USE from `POST /setup/receipts/{id}/undo` carries `later_receipt_id`.\nNOT_FOUND on a name, and\nINVALID_INPUT on a CHOICE value, carry `valid_values`. INVALID_INPUT on a\nmonitor whose level input is not a number type carries `input_id`.\nIN_USE on an input whose type would change while a monitor uses it\ncarries `monitors`. IN_USE on `PATCH /portfolios/{id}` that turns\nAllow shorts off while a short is held carries `short_count` and\n`symbols`. INVALID_INPUT on the holdings writes (`POST\n/positions/{symbol}`, `POST /portfolios/{id}/positions/apply`) that\nrefuses a negative `shares`, a `moves` other than 1 on an Options\nholding, or a `mark` on a holding outside the Options class, carries\n`symbols`, the holdings it refused. (`symbols` also appears on `WOULD_CLOSE_POSITIONS`, MCP\nonly, where it lists the holdings a full list left out.)\n","required":["error"],"example":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"},"properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"error_code":{"type":"string","enum":["INVALID_INPUT","NOT_FOUND","ALREADY_EXISTS","IN_USE","CONFIRMATION_REQUIRED","PRICES_INCOMPLETE","PRICES_INVALID","WOULD_CLOSE_POSITIONS","INSUFFICIENT_CASH","RULES_INVALID","TARGET_OUT_OF_BAND","TIER_LIMIT_EXCEEDED","FEATURE_NOT_AVAILABLE","IDEMPOTENCY_KEY_CONFLICT","DAILY_LIMIT_EXCEEDED","READ_ONLY_KEY","OAUTH_WRITE_NOT_GRANTED","TOOL_REMOVED","INTERNAL_ERROR"],"description":"Stable machine-readable code from the closed catalog. Present on every refusal a route produces; absent on `401`, the no-plan `403`, the `403` for a key without `read`, and the `429` for the request budget.","uniqueKey":"error_code","typeLabel":"enum\u003cstring>"},"request_id":{"type":"string","format":"uuid","description":"Present on a `500` (`INTERNAL_ERROR`). The same id is in Allocait's logs next to the real cause; quote it when you report the failure.","uniqueKey":"request_id","typeLabel":"string\u003cuuid>"},"issues":{"type":"array","items":{"oneOf":[{"type":"object","description":"One problem or note found while reading rules text. A file\ncarrying any `error`-level issue is never applied; `POST\n/scenarios/{id}/rules` 400s with `error_code: RULES_INVALID` and\nthe full `issues` list instead. A file with only `warning`-level\nissues still applies; those ride along on the 200 response.\n","required":["level","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.level","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.message","typeLabel":"string"},"class":{"type":"string","description":"The asset class name this issue is about, when it is about one class rather than the whole file.","uniqueKey":"issues.items.[INDEX].oneOf.0.class","typeLabel":"string"}},"uniqueKey":"issues.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","description":"One thing the file's text got wrong (`error`) or one note about it (`warning`, such as a web address in a description).","required":["level","where","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.level","typeLabel":"enum\u003cstring>"},"where":{"oneOf":[{"type":"string","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.0","typeLabel":"string"},{"type":"null","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where","typeLabel":"string | null"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.message","typeLabel":"string"},"line":{"type":"integer","description":"The line of the file the issue is on, when it is known.","uniqueKey":"issues.items.[INDEX].oneOf.1.line","typeLabel":"integer"}},"uniqueKey":"issues.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"object"},"description":"Every error and warning found while reading the rules text, when error_code is RULES_INVALID. From the setup routes (`POST /setup/preview`, `POST /setup/apply`) it is `SetupIssue` rows, on INVALID_INPUT.","uniqueKey":"issues","typeLabel":"object[]"},"later_receipt_id":{"type":"string","format":"uuid","description":"The newer import of the same setup file that blocks this undo. Present on IN_USE from `POST /setup/receipts/{id}/undo`; undo that receipt first.","uniqueKey":"later_receipt_id","typeLabel":"string\u003cuuid>"},"limit_type":{"type":"string","description":"Which cap was hit, e.g. \"portfolios\", \"scenarios\", \"webhook_endpoints\", \"watchlists\", \"asset_classes\", \"input_entries\" or \"input_entries_per_input\". Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"limit_type","typeLabel":"string"},"current_count":{"type":"number","description":"How many of limit_type the caller has right now. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"current_count","typeLabel":"number"},"max_allowed":{"type":"number","description":"The cap for limit_type on this account. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"max_allowed","typeLabel":"number"},"existing_id":{"type":"string","format":"uuid","description":"The record that already has this name. Present only when error_code is ALREADY_EXISTS; change it with that id instead of creating another.","uniqueKey":"existing_id","typeLabel":"string\u003cuuid>"},"duplicate_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"duplicate_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Other records with the same name, created before duplicates were refused. Present only on ALREADY_EXISTS, and only when such records exist.","uniqueKey":"duplicate_ids","typeLabel":"string\u003cuuid>[]"},"would_remove":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string","uniqueKey":"would_remove.additionalProperties.items.[INDEX]","typeLabel":"string"},"uniqueKey":"would_remove.additionalProperties","typeLabel":"string[]"},"description":"What the call would drop, keyed by list field, for example the `items` that a watchlist save would remove. Present only when error_code is CONFIRMATION_REQUIRED; resend with those members in `remove`.","uniqueKey":"would_remove","typeLabel":"object"},"valid_values":{"type":"array","items":{"type":"string","uniqueKey":"valid_values.items.[INDEX]","typeLabel":"string"},"description":"The names or options the field accepts. Present on NOT_FOUND for a name, and on INVALID_INPUT for a CHOICE value.","uniqueKey":"valid_values","typeLabel":"string[]"},"input_id":{"type":"string","format":"uuid","description":"The level input that is not a NUMBER, DECIMAL or PERCENTAGE input. Present on INVALID_INPUT from a monitor create or update (`POST /monitors`, `PATCH /monitors/{id}`, MCP `save_monitor`); point the monitor at a number-type input instead.","uniqueKey":"input_id","typeLabel":"string\u003cuuid>"},"short_count":{"type":"integer","description":"How many shorts the portfolio holds. Present on IN_USE from `PATCH /portfolios/{id}` (MCP `save_portfolio`) that turns Allow shorts off while a short is held; close them first.","uniqueKey":"short_count","typeLabel":"integer"},"symbols":{"type":"array","items":{"type":"string","uniqueKey":"symbols.items.[INDEX]","typeLabel":"string"},"description":"Holdings the call names. On IN_USE from `PATCH /portfolios/{id}`, the shorts still held (up to 20, by symbol). On INVALID_INPUT from the holdings writes, the holdings whose negative `shares` was refused (Allow shorts is off, or the holding is in Options), or whose `moves` other than 1 was refused (the holding is in Options). On WOULD_CLOSE_POSITIONS (MCP only), the holdings a full list left out.","uniqueKey":"symbols","typeLabel":"string[]"},"monitors":{"type":"array","description":"The monitors that use this input as a level. Present on IN_USE from an input update (`PATCH /inputs/{id}`, MCP `save_input`) that would change `data_type` to TEXT or CHOICE; move those monitors to another input first.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"name":{"type":"string","uniqueKey":"monitors.items.[INDEX].name","typeLabel":"string"},"portfolio_id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].portfolio_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"monitors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"monitors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"}}},"exampleType":"generated"}},"exampleType":"generated"},"2d268209-992b-41e6-a3dd-f4fd01a78eb1":{"description":"Portfolio or scenario not found, or not yours (`NOT_FOUND`)","content":{"application/json":{"schema":{"type":"object","description":"Uniform error envelope returned by every non-2xx response. `error` is\na human-readable message, safe to show the user. A refusal also\ncarries `error_code`, a stable string from the catalog in the info\nblock's Error codes section, to branch on; the HTTP status follows\nthe code (ADR-134). Only `401`, the no-plan `403`, the `403` for a\nkey without `read` and the `429` for the request budget have none.\nA `500` carries `request_id`. Extra fields by code:\nTIER_LIMIT_EXCEEDED carries `limit_type`, `current_count` and\n`max_allowed`, so a caller can branch on how many it has versus the\ncap without a second call. Its `error` text names no plan. It covers\nthe portfolio and scenario limits and the account caps: 20 webhook endpoints, 50\nwatchlists, 200 symbols on one watchlist and 50 custom symbols on one\nmonitor. Don't retry it. RULES_INVALID (`POST\n/scenarios/{id}/rules`) carries `issues`. ALREADY_EXISTS carries\n`existing_id`, plus `duplicate_ids` where older duplicates exist.\nCONFIRMATION_REQUIRED carries `would_remove`; from `POST /setup/apply` it\ncarries a fresh preview instead (`digest`, `file`, `items` and the rest of\n`SetupPreview`). INVALID_INPUT from the setup routes carries `issues`, and\nIN_USE from `POST /setup/receipts/{id}/undo` carries `later_receipt_id`.\nNOT_FOUND on a name, and\nINVALID_INPUT on a CHOICE value, carry `valid_values`. INVALID_INPUT on a\nmonitor whose level input is not a number type carries `input_id`.\nIN_USE on an input whose type would change while a monitor uses it\ncarries `monitors`. IN_USE on `PATCH /portfolios/{id}` that turns\nAllow shorts off while a short is held carries `short_count` and\n`symbols`. INVALID_INPUT on the holdings writes (`POST\n/positions/{symbol}`, `POST /portfolios/{id}/positions/apply`) that\nrefuses a negative `shares`, a `moves` other than 1 on an Options\nholding, or a `mark` on a holding outside the Options class, carries\n`symbols`, the holdings it refused. (`symbols` also appears on `WOULD_CLOSE_POSITIONS`, MCP\nonly, where it lists the holdings a full list left out.)\n","required":["error"],"example":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"},"properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"error_code":{"type":"string","enum":["INVALID_INPUT","NOT_FOUND","ALREADY_EXISTS","IN_USE","CONFIRMATION_REQUIRED","PRICES_INCOMPLETE","PRICES_INVALID","WOULD_CLOSE_POSITIONS","INSUFFICIENT_CASH","RULES_INVALID","TARGET_OUT_OF_BAND","TIER_LIMIT_EXCEEDED","FEATURE_NOT_AVAILABLE","IDEMPOTENCY_KEY_CONFLICT","DAILY_LIMIT_EXCEEDED","READ_ONLY_KEY","OAUTH_WRITE_NOT_GRANTED","TOOL_REMOVED","INTERNAL_ERROR"],"description":"Stable machine-readable code from the closed catalog. Present on every refusal a route produces; absent on `401`, the no-plan `403`, the `403` for a key without `read`, and the `429` for the request budget.","uniqueKey":"error_code","typeLabel":"enum\u003cstring>"},"request_id":{"type":"string","format":"uuid","description":"Present on a `500` (`INTERNAL_ERROR`). The same id is in Allocait's logs next to the real cause; quote it when you report the failure.","uniqueKey":"request_id","typeLabel":"string\u003cuuid>"},"issues":{"type":"array","items":{"oneOf":[{"type":"object","description":"One problem or note found while reading rules text. A file\ncarrying any `error`-level issue is never applied; `POST\n/scenarios/{id}/rules` 400s with `error_code: RULES_INVALID` and\nthe full `issues` list instead. A file with only `warning`-level\nissues still applies; those ride along on the 200 response.\n","required":["level","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.level","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.message","typeLabel":"string"},"class":{"type":"string","description":"The asset class name this issue is about, when it is about one class rather than the whole file.","uniqueKey":"issues.items.[INDEX].oneOf.0.class","typeLabel":"string"}},"uniqueKey":"issues.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","description":"One thing the file's text got wrong (`error`) or one note about it (`warning`, such as a web address in a description).","required":["level","where","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.level","typeLabel":"enum\u003cstring>"},"where":{"oneOf":[{"type":"string","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.0","typeLabel":"string"},{"type":"null","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where","typeLabel":"string | null"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.message","typeLabel":"string"},"line":{"type":"integer","description":"The line of the file the issue is on, when it is known.","uniqueKey":"issues.items.[INDEX].oneOf.1.line","typeLabel":"integer"}},"uniqueKey":"issues.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"object"},"description":"Every error and warning found while reading the rules text, when error_code is RULES_INVALID. From the setup routes (`POST /setup/preview`, `POST /setup/apply`) it is `SetupIssue` rows, on INVALID_INPUT.","uniqueKey":"issues","typeLabel":"object[]"},"later_receipt_id":{"type":"string","format":"uuid","description":"The newer import of the same setup file that blocks this undo. Present on IN_USE from `POST /setup/receipts/{id}/undo`; undo that receipt first.","uniqueKey":"later_receipt_id","typeLabel":"string\u003cuuid>"},"limit_type":{"type":"string","description":"Which cap was hit, e.g. \"portfolios\", \"scenarios\", \"webhook_endpoints\", \"watchlists\", \"asset_classes\", \"input_entries\" or \"input_entries_per_input\". Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"limit_type","typeLabel":"string"},"current_count":{"type":"number","description":"How many of limit_type the caller has right now. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"current_count","typeLabel":"number"},"max_allowed":{"type":"number","description":"The cap for limit_type on this account. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"max_allowed","typeLabel":"number"},"existing_id":{"type":"string","format":"uuid","description":"The record that already has this name. Present only when error_code is ALREADY_EXISTS; change it with that id instead of creating another.","uniqueKey":"existing_id","typeLabel":"string\u003cuuid>"},"duplicate_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"duplicate_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Other records with the same name, created before duplicates were refused. Present only on ALREADY_EXISTS, and only when such records exist.","uniqueKey":"duplicate_ids","typeLabel":"string\u003cuuid>[]"},"would_remove":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string","uniqueKey":"would_remove.additionalProperties.items.[INDEX]","typeLabel":"string"},"uniqueKey":"would_remove.additionalProperties","typeLabel":"string[]"},"description":"What the call would drop, keyed by list field, for example the `items` that a watchlist save would remove. Present only when error_code is CONFIRMATION_REQUIRED; resend with those members in `remove`.","uniqueKey":"would_remove","typeLabel":"object"},"valid_values":{"type":"array","items":{"type":"string","uniqueKey":"valid_values.items.[INDEX]","typeLabel":"string"},"description":"The names or options the field accepts. Present on NOT_FOUND for a name, and on INVALID_INPUT for a CHOICE value.","uniqueKey":"valid_values","typeLabel":"string[]"},"input_id":{"type":"string","format":"uuid","description":"The level input that is not a NUMBER, DECIMAL or PERCENTAGE input. Present on INVALID_INPUT from a monitor create or update (`POST /monitors`, `PATCH /monitors/{id}`, MCP `save_monitor`); point the monitor at a number-type input instead.","uniqueKey":"input_id","typeLabel":"string\u003cuuid>"},"short_count":{"type":"integer","description":"How many shorts the portfolio holds. Present on IN_USE from `PATCH /portfolios/{id}` (MCP `save_portfolio`) that turns Allow shorts off while a short is held; close them first.","uniqueKey":"short_count","typeLabel":"integer"},"symbols":{"type":"array","items":{"type":"string","uniqueKey":"symbols.items.[INDEX]","typeLabel":"string"},"description":"Holdings the call names. On IN_USE from `PATCH /portfolios/{id}`, the shorts still held (up to 20, by symbol). On INVALID_INPUT from the holdings writes, the holdings whose negative `shares` was refused (Allow shorts is off, or the holding is in Options), or whose `moves` other than 1 was refused (the holding is in Options). On WOULD_CLOSE_POSITIONS (MCP only), the holdings a full list left out.","uniqueKey":"symbols","typeLabel":"string[]"},"monitors":{"type":"array","description":"The monitors that use this input as a level. Present on IN_USE from an input update (`PATCH /inputs/{id}`, MCP `save_input`) that would change `data_type` to TEXT or CHOICE; move those monitors to another input first.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"name":{"type":"string","uniqueKey":"monitors.items.[INDEX].name","typeLabel":"string"},"portfolio_id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].portfolio_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"monitors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"monitors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"}}},"exampleType":"generated"}},"exampleType":"generated"},"f6ceffe8-96c4-4179-99be-1e620c2d2e07":{"description":"Rate limit exceeded: maximum 60 requests per minute per account,\nor 10,000 per UTC day (see the info block's Rate limits section).\nThe per-minute refusal carries `Retry-After: 60` and the\n`X-RateLimit-*` headers; the daily refusal carries `Retry-After`\nset to the seconds until 00:00 UTC and no `X-RateLimit-*` headers.\nNeither has an `error_code`. `POST /support-requests` and\n`POST /agent-feedback` also return `429` with `error_code:\nDAILY_LIMIT_EXCEEDED` past 20 filed per rolling 24 hours; that one\ncarries the `X-RateLimit-*` headers and no `Retry-After`.\n","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent only on the request budget's own `429`s, never on a per-route cap (`DAILY_LIMIT_EXCEEDED`) or any other status.","schema":{"type":"integer","example":60}},"X-RateLimit-Limit":{"description":"The per-minute request budget, always `60`. Sent on every response that reaches a route and on the per-minute `429`.","schema":{"type":"integer","example":60}},"X-RateLimit-Remaining":{"description":"Requests left in the current one-minute window, after this one. The daily count is not reported until it is reached.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","description":"Uniform error envelope returned by every non-2xx response. `error` is\na human-readable message, safe to show the user. A refusal also\ncarries `error_code`, a stable string from the catalog in the info\nblock's Error codes section, to branch on; the HTTP status follows\nthe code (ADR-134). Only `401`, the no-plan `403`, the `403` for a\nkey without `read` and the `429` for the request budget have none.\nA `500` carries `request_id`. Extra fields by code:\nTIER_LIMIT_EXCEEDED carries `limit_type`, `current_count` and\n`max_allowed`, so a caller can branch on how many it has versus the\ncap without a second call. Its `error` text names no plan. It covers\nthe portfolio and scenario limits and the account caps: 20 webhook endpoints, 50\nwatchlists, 200 symbols on one watchlist and 50 custom symbols on one\nmonitor. Don't retry it. RULES_INVALID (`POST\n/scenarios/{id}/rules`) carries `issues`. ALREADY_EXISTS carries\n`existing_id`, plus `duplicate_ids` where older duplicates exist.\nCONFIRMATION_REQUIRED carries `would_remove`; from `POST /setup/apply` it\ncarries a fresh preview instead (`digest`, `file`, `items` and the rest of\n`SetupPreview`). INVALID_INPUT from the setup routes carries `issues`, and\nIN_USE from `POST /setup/receipts/{id}/undo` carries `later_receipt_id`.\nNOT_FOUND on a name, and\nINVALID_INPUT on a CHOICE value, carry `valid_values`. INVALID_INPUT on a\nmonitor whose level input is not a number type carries `input_id`.\nIN_USE on an input whose type would change while a monitor uses it\ncarries `monitors`. IN_USE on `PATCH /portfolios/{id}` that turns\nAllow shorts off while a short is held carries `short_count` and\n`symbols`. INVALID_INPUT on the holdings writes (`POST\n/positions/{symbol}`, `POST /portfolios/{id}/positions/apply`) that\nrefuses a negative `shares`, a `moves` other than 1 on an Options\nholding, or a `mark` on a holding outside the Options class, carries\n`symbols`, the holdings it refused. (`symbols` also appears on `WOULD_CLOSE_POSITIONS`, MCP\nonly, where it lists the holdings a full list left out.)\n","required":["error"],"example":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"},"properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"error_code":{"type":"string","enum":["INVALID_INPUT","NOT_FOUND","ALREADY_EXISTS","IN_USE","CONFIRMATION_REQUIRED","PRICES_INCOMPLETE","PRICES_INVALID","WOULD_CLOSE_POSITIONS","INSUFFICIENT_CASH","RULES_INVALID","TARGET_OUT_OF_BAND","TIER_LIMIT_EXCEEDED","FEATURE_NOT_AVAILABLE","IDEMPOTENCY_KEY_CONFLICT","DAILY_LIMIT_EXCEEDED","READ_ONLY_KEY","OAUTH_WRITE_NOT_GRANTED","TOOL_REMOVED","INTERNAL_ERROR"],"description":"Stable machine-readable code from the closed catalog. Present on every refusal a route produces; absent on `401`, the no-plan `403`, the `403` for a key without `read`, and the `429` for the request budget.","uniqueKey":"error_code","typeLabel":"enum\u003cstring>"},"request_id":{"type":"string","format":"uuid","description":"Present on a `500` (`INTERNAL_ERROR`). The same id is in Allocait's logs next to the real cause; quote it when you report the failure.","uniqueKey":"request_id","typeLabel":"string\u003cuuid>"},"issues":{"type":"array","items":{"oneOf":[{"type":"object","description":"One problem or note found while reading rules text. A file\ncarrying any `error`-level issue is never applied; `POST\n/scenarios/{id}/rules` 400s with `error_code: RULES_INVALID` and\nthe full `issues` list instead. A file with only `warning`-level\nissues still applies; those ride along on the 200 response.\n","required":["level","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.level","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.message","typeLabel":"string"},"class":{"type":"string","description":"The asset class name this issue is about, when it is about one class rather than the whole file.","uniqueKey":"issues.items.[INDEX].oneOf.0.class","typeLabel":"string"}},"uniqueKey":"issues.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","description":"One thing the file's text got wrong (`error`) or one note about it (`warning`, such as a web address in a description).","required":["level","where","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.level","typeLabel":"enum\u003cstring>"},"where":{"oneOf":[{"type":"string","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.0","typeLabel":"string"},{"type":"null","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where","typeLabel":"string | null"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.message","typeLabel":"string"},"line":{"type":"integer","description":"The line of the file the issue is on, when it is known.","uniqueKey":"issues.items.[INDEX].oneOf.1.line","typeLabel":"integer"}},"uniqueKey":"issues.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"object"},"description":"Every error and warning found while reading the rules text, when error_code is RULES_INVALID. From the setup routes (`POST /setup/preview`, `POST /setup/apply`) it is `SetupIssue` rows, on INVALID_INPUT.","uniqueKey":"issues","typeLabel":"object[]"},"later_receipt_id":{"type":"string","format":"uuid","description":"The newer import of the same setup file that blocks this undo. Present on IN_USE from `POST /setup/receipts/{id}/undo`; undo that receipt first.","uniqueKey":"later_receipt_id","typeLabel":"string\u003cuuid>"},"limit_type":{"type":"string","description":"Which cap was hit, e.g. \"portfolios\", \"scenarios\", \"webhook_endpoints\", \"watchlists\", \"asset_classes\", \"input_entries\" or \"input_entries_per_input\". Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"limit_type","typeLabel":"string"},"current_count":{"type":"number","description":"How many of limit_type the caller has right now. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"current_count","typeLabel":"number"},"max_allowed":{"type":"number","description":"The cap for limit_type on this account. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"max_allowed","typeLabel":"number"},"existing_id":{"type":"string","format":"uuid","description":"The record that already has this name. Present only when error_code is ALREADY_EXISTS; change it with that id instead of creating another.","uniqueKey":"existing_id","typeLabel":"string\u003cuuid>"},"duplicate_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"duplicate_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Other records with the same name, created before duplicates were refused. Present only on ALREADY_EXISTS, and only when such records exist.","uniqueKey":"duplicate_ids","typeLabel":"string\u003cuuid>[]"},"would_remove":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string","uniqueKey":"would_remove.additionalProperties.items.[INDEX]","typeLabel":"string"},"uniqueKey":"would_remove.additionalProperties","typeLabel":"string[]"},"description":"What the call would drop, keyed by list field, for example the `items` that a watchlist save would remove. Present only when error_code is CONFIRMATION_REQUIRED; resend with those members in `remove`.","uniqueKey":"would_remove","typeLabel":"object"},"valid_values":{"type":"array","items":{"type":"string","uniqueKey":"valid_values.items.[INDEX]","typeLabel":"string"},"description":"The names or options the field accepts. Present on NOT_FOUND for a name, and on INVALID_INPUT for a CHOICE value.","uniqueKey":"valid_values","typeLabel":"string[]"},"input_id":{"type":"string","format":"uuid","description":"The level input that is not a NUMBER, DECIMAL or PERCENTAGE input. Present on INVALID_INPUT from a monitor create or update (`POST /monitors`, `PATCH /monitors/{id}`, MCP `save_monitor`); point the monitor at a number-type input instead.","uniqueKey":"input_id","typeLabel":"string\u003cuuid>"},"short_count":{"type":"integer","description":"How many shorts the portfolio holds. Present on IN_USE from `PATCH /portfolios/{id}` (MCP `save_portfolio`) that turns Allow shorts off while a short is held; close them first.","uniqueKey":"short_count","typeLabel":"integer"},"symbols":{"type":"array","items":{"type":"string","uniqueKey":"symbols.items.[INDEX]","typeLabel":"string"},"description":"Holdings the call names. On IN_USE from `PATCH /portfolios/{id}`, the shorts still held (up to 20, by symbol). On INVALID_INPUT from the holdings writes, the holdings whose negative `shares` was refused (Allow shorts is off, or the holding is in Options), or whose `moves` other than 1 was refused (the holding is in Options). On WOULD_CLOSE_POSITIONS (MCP only), the holdings a full list left out.","uniqueKey":"symbols","typeLabel":"string[]"},"monitors":{"type":"array","description":"The monitors that use this input as a level. Present on IN_USE from an input update (`PATCH /inputs/{id}`, MCP `save_input`) that would change `data_type` to TEXT or CHOICE; move those monitors to another input first.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"name":{"type":"string","uniqueKey":"monitors.items.[INDEX].name","typeLabel":"string"},"portfolio_id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].portfolio_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"monitors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"monitors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"}}},"exampleType":"generated"}},"exampleType":"generated"},"65b4e956-d453-4d82-8cda-af5ba8c2a373":{"description":"Unexpected server error. `error_code` is `INTERNAL_ERROR` and\n`request_id` names this failure: quote it in `POST /agent-feedback`.\nThe body never carries a schema, column or constraint name.\n","content":{"application/json":{"schema":{"type":"object","description":"Uniform error envelope returned by every non-2xx response. `error` is\na human-readable message, safe to show the user. A refusal also\ncarries `error_code`, a stable string from the catalog in the info\nblock's Error codes section, to branch on; the HTTP status follows\nthe code (ADR-134). Only `401`, the no-plan `403`, the `403` for a\nkey without `read` and the `429` for the request budget have none.\nA `500` carries `request_id`. Extra fields by code:\nTIER_LIMIT_EXCEEDED carries `limit_type`, `current_count` and\n`max_allowed`, so a caller can branch on how many it has versus the\ncap without a second call. Its `error` text names no plan. It covers\nthe portfolio and scenario limits and the account caps: 20 webhook endpoints, 50\nwatchlists, 200 symbols on one watchlist and 50 custom symbols on one\nmonitor. Don't retry it. RULES_INVALID (`POST\n/scenarios/{id}/rules`) carries `issues`. ALREADY_EXISTS carries\n`existing_id`, plus `duplicate_ids` where older duplicates exist.\nCONFIRMATION_REQUIRED carries `would_remove`; from `POST /setup/apply` it\ncarries a fresh preview instead (`digest`, `file`, `items` and the rest of\n`SetupPreview`). INVALID_INPUT from the setup routes carries `issues`, and\nIN_USE from `POST /setup/receipts/{id}/undo` carries `later_receipt_id`.\nNOT_FOUND on a name, and\nINVALID_INPUT on a CHOICE value, carry `valid_values`. INVALID_INPUT on a\nmonitor whose level input is not a number type carries `input_id`.\nIN_USE on an input whose type would change while a monitor uses it\ncarries `monitors`. IN_USE on `PATCH /portfolios/{id}` that turns\nAllow shorts off while a short is held carries `short_count` and\n`symbols`. INVALID_INPUT on the holdings writes (`POST\n/positions/{symbol}`, `POST /portfolios/{id}/positions/apply`) that\nrefuses a negative `shares`, a `moves` other than 1 on an Options\nholding, or a `mark` on a holding outside the Options class, carries\n`symbols`, the holdings it refused. (`symbols` also appears on `WOULD_CLOSE_POSITIONS`, MCP\nonly, where it lists the holdings a full list left out.)\n","required":["error"],"example":{"error":"Portfolio not found or access denied","error_code":"NOT_FOUND"},"properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"error_code":{"type":"string","enum":["INVALID_INPUT","NOT_FOUND","ALREADY_EXISTS","IN_USE","CONFIRMATION_REQUIRED","PRICES_INCOMPLETE","PRICES_INVALID","WOULD_CLOSE_POSITIONS","INSUFFICIENT_CASH","RULES_INVALID","TARGET_OUT_OF_BAND","TIER_LIMIT_EXCEEDED","FEATURE_NOT_AVAILABLE","IDEMPOTENCY_KEY_CONFLICT","DAILY_LIMIT_EXCEEDED","READ_ONLY_KEY","OAUTH_WRITE_NOT_GRANTED","TOOL_REMOVED","INTERNAL_ERROR"],"description":"Stable machine-readable code from the closed catalog. Present on every refusal a route produces; absent on `401`, the no-plan `403`, the `403` for a key without `read`, and the `429` for the request budget.","uniqueKey":"error_code","typeLabel":"enum\u003cstring>"},"request_id":{"type":"string","format":"uuid","description":"Present on a `500` (`INTERNAL_ERROR`). The same id is in Allocait's logs next to the real cause; quote it when you report the failure.","uniqueKey":"request_id","typeLabel":"string\u003cuuid>"},"issues":{"type":"array","items":{"oneOf":[{"type":"object","description":"One problem or note found while reading rules text. A file\ncarrying any `error`-level issue is never applied; `POST\n/scenarios/{id}/rules` 400s with `error_code: RULES_INVALID` and\nthe full `issues` list instead. A file with only `warning`-level\nissues still applies; those ride along on the 200 response.\n","required":["level","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.level","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.0.message","typeLabel":"string"},"class":{"type":"string","description":"The asset class name this issue is about, when it is about one class rather than the whole file.","uniqueKey":"issues.items.[INDEX].oneOf.0.class","typeLabel":"string"}},"uniqueKey":"issues.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","description":"One thing the file's text got wrong (`error`) or one note about it (`warning`, such as a web address in a description).","required":["level","where","message"],"properties":{"level":{"type":"string","enum":["error","warning"],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.level","typeLabel":"enum\u003cstring>"},"where":{"oneOf":[{"type":"string","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.0","typeLabel":"string"},{"type":"null","description":"Where in the file, or null for the file as a whole.","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.where","typeLabel":"string | null"},"message":{"type":"string","isRequired":true,"uniqueKey":"issues.items.[INDEX].oneOf.1.message","typeLabel":"string"},"line":{"type":"integer","description":"The line of the file the issue is on, when it is known.","uniqueKey":"issues.items.[INDEX].oneOf.1.line","typeLabel":"integer"}},"uniqueKey":"issues.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"issues.items.[INDEX]","typeLabel":"object"},"description":"Every error and warning found while reading the rules text, when error_code is RULES_INVALID. From the setup routes (`POST /setup/preview`, `POST /setup/apply`) it is `SetupIssue` rows, on INVALID_INPUT.","uniqueKey":"issues","typeLabel":"object[]"},"later_receipt_id":{"type":"string","format":"uuid","description":"The newer import of the same setup file that blocks this undo. Present on IN_USE from `POST /setup/receipts/{id}/undo`; undo that receipt first.","uniqueKey":"later_receipt_id","typeLabel":"string\u003cuuid>"},"limit_type":{"type":"string","description":"Which cap was hit, e.g. \"portfolios\", \"scenarios\", \"webhook_endpoints\", \"watchlists\", \"asset_classes\", \"input_entries\" or \"input_entries_per_input\". Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"limit_type","typeLabel":"string"},"current_count":{"type":"number","description":"How many of limit_type the caller has right now. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"current_count","typeLabel":"number"},"max_allowed":{"type":"number","description":"The cap for limit_type on this account. Present only when error_code is TIER_LIMIT_EXCEEDED.","uniqueKey":"max_allowed","typeLabel":"number"},"existing_id":{"type":"string","format":"uuid","description":"The record that already has this name. Present only when error_code is ALREADY_EXISTS; change it with that id instead of creating another.","uniqueKey":"existing_id","typeLabel":"string\u003cuuid>"},"duplicate_ids":{"type":"array","items":{"type":"string","format":"uuid","uniqueKey":"duplicate_ids.items.[INDEX]","typeLabel":"string\u003cuuid>"},"description":"Other records with the same name, created before duplicates were refused. Present only on ALREADY_EXISTS, and only when such records exist.","uniqueKey":"duplicate_ids","typeLabel":"string\u003cuuid>[]"},"would_remove":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string","uniqueKey":"would_remove.additionalProperties.items.[INDEX]","typeLabel":"string"},"uniqueKey":"would_remove.additionalProperties","typeLabel":"string[]"},"description":"What the call would drop, keyed by list field, for example the `items` that a watchlist save would remove. Present only when error_code is CONFIRMATION_REQUIRED; resend with those members in `remove`.","uniqueKey":"would_remove","typeLabel":"object"},"valid_values":{"type":"array","items":{"type":"string","uniqueKey":"valid_values.items.[INDEX]","typeLabel":"string"},"description":"The names or options the field accepts. Present on NOT_FOUND for a name, and on INVALID_INPUT for a CHOICE value.","uniqueKey":"valid_values","typeLabel":"string[]"},"input_id":{"type":"string","format":"uuid","description":"The level input that is not a NUMBER, DECIMAL or PERCENTAGE input. Present on INVALID_INPUT from a monitor create or update (`POST /monitors`, `PATCH /monitors/{id}`, MCP `save_monitor`); point the monitor at a number-type input instead.","uniqueKey":"input_id","typeLabel":"string\u003cuuid>"},"short_count":{"type":"integer","description":"How many shorts the portfolio holds. Present on IN_USE from `PATCH /portfolios/{id}` (MCP `save_portfolio`) that turns Allow shorts off while a short is held; close them first.","uniqueKey":"short_count","typeLabel":"integer"},"symbols":{"type":"array","items":{"type":"string","uniqueKey":"symbols.items.[INDEX]","typeLabel":"string"},"description":"Holdings the call names. On IN_USE from `PATCH /portfolios/{id}`, the shorts still held (up to 20, by symbol). On INVALID_INPUT from the holdings writes, the holdings whose negative `shares` was refused (Allow shorts is off, or the holding is in Options), or whose `moves` other than 1 was refused (the holding is in Options). On WOULD_CLOSE_POSITIONS (MCP only), the holdings a full list left out.","uniqueKey":"symbols","typeLabel":"string[]"},"monitors":{"type":"array","description":"The monitors that use this input as a level. Present on IN_USE from an input update (`PATCH /inputs/{id}`, MCP `save_input`) that would change `data_type` to TEXT or CHOICE; move those monitors to another input first.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"name":{"type":"string","uniqueKey":"monitors.items.[INDEX].name","typeLabel":"string"},"portfolio_id":{"type":"string","format":"uuid","uniqueKey":"monitors.items.[INDEX].portfolio_id","typeLabel":"string\u003cuuid>"}},"uniqueKey":"monitors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"monitors","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":"Internal error","error_code":"INTERNAL_ERROR","request_id":"5b1e7c52-3f4a-4d0e-9a55-2d5cbe6f0a11"},"examples":{"Example":{"title":"Example","value":{"error":"Internal error","error_code":"INTERNAL_ERROR","request_id":"5b1e7c52-3f4a-4d0e-9a55-2d5cbe6f0a11"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"7fd1832f-5a87-49c5-91d9-dd9065c02713":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Raw API key shown once when created in the Allocait app (Settings > API keys). Send it verbatim in this header; the server stores and compares only its SHA-256 hash. Allocait generates every key: `alc_` followed by 64 lowercase hex characters. Keys issued before 2026-10-10 are 64 hex characters with no prefix and keep working. A key may carry an expiry (90 days or 1 year, or never). A malformed, unknown, revoked or expired key gets `401` with no further detail, and a malformed one is refused before any lookup. Keys cannot be created through this API.","scopes":[],"schemeName":"ApiKeyAuth"}}},"servers":{"13120e45-325e-41e1-99fd-a11d6f409d02":{"url":"https://allocait.app/api/v1","description":"Hosted Allocait API"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"x-api-key","description":"Raw API key shown once when created in the Allocait app (Settings > API keys). Send it verbatim in this header; the server stores and compares only its SHA-256 hash. Allocait generates every key: `alc_` followed by 64 lowercase hex characters. Keys issued before 2026-10-10 are 64 hex characters with no prefix and keep working. A key may carry an expiry (90 days or 1 year, or never). A malformed, unknown, revoked or expired key gets `401` with no further detail, and a malformed one is refused before any lookup. Keys cannot be created through this API.","scopes":[],"schemeName":"ApiKeyAuth"},"schema":{"title":"x-api-key","type":"string","description":"Raw API key shown once when created in the Allocait app (Settings > API keys). Send it verbatim in this header; the server stores and compares only its SHA-256 hash. Allocait generates every key: `alc_` followed by 64 lowercase hex characters. Keys issued before 2026-10-10 are 64 hex characters with no prefix and keep working. A key may carry an expiry (90 days or 1 year, or never). A malformed, unknown, revoked or expired key gets `401` with no further detail, and a malformed one is refused before any lookup. Keys cannot be created through this API.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"ApiKeyAuth","name":"x-api-key"}],"title":"ApiKeyAuth"}]},"originalFileLocation":"openapi.yaml"},"subdomain":"allocait","siteName":"Allocait","title":"Preview rebalance amounts with your prices - Allocait","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-09T05:23:21.125Z","originalFileLocation":"api-reference/checks/preview-rebalance-amounts-with-your-prices.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Returns pro rata amounts that would move out-of-compliance classes toward their aim: the class rule\u0026#x27;s own Target % when set, otherwise the midpoint of its allocation band, using the prices you provide. Rows are ordered largest-dollar-value first. This is arithmetic on the user\u0026#x27;s own rules, not a recommendation. A short (negative shares) or an option (a holding in the Options class) gets no row, and not_rebalanced lists each one once. A class\u0026#x27;s move is the gap on its net value (shorts subtract), spread over its long holdings outside Options only (ADR-153, ADR-145), so one long can carry the whole gap. A class with no priced long holding outside Options gets no row, and appears in unresolved if it stays outside its band. For a class that holds only shorts and options, the reason no_priced_holdings means there is nothing to trade, whatever the prices. A portfolio worth zero or less is not rebalanced: percentages are undefined there, so trades is empty, each resulting_pct is null and total_value is still reported, signed (ADR-153). prices is required and must cover every non-cash position in the portfolio, except a held option with a mark or one past its expiry (ADR-147). Symbols you send that the portfolio does not hold are ignored. Keys are matched to held symbols case-insensitively. If a held symbol is missing from the map, the call fails with a 400 whose body carries missing_symbols. Allocait never fills a symbol you left out from its own market data (ADR-036).\">\u003cmeta data-mint-head name=\"application-name\" content=\"Allocait\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Preview rebalance amounts with your prices - Allocait\">\u003cmeta data-mint-head property=\"og:description\" content=\"Returns pro rata amounts that would move out-of-compliance classes toward their aim: the class rule\u0026#x27;s own Target % when set, otherwise the midpoint of its allocation band, using the prices you provide. Rows are ordered largest-dollar-value first. This is arithmetic on the user\u0026#x27;s own rules, not a recommendation. A short (negative shares) or an option (a holding in the Options class) gets no row, and not_rebalanced lists each one once. A class\u0026#x27;s move is the gap on its net value (shorts subtract), spread over its long holdings outside Options only (ADR-153, ADR-145), so one long can carry the whole gap. A class with no priced long holding outside Options gets no row, and appears in unresolved if it stays outside its band. For a class that holds only shorts and options, the reason no_priced_holdings means there is nothing to trade, whatever the prices. A portfolio worth zero or less is not rebalanced: percentages are undefined there, so trades is empty, each resulting_pct is null and total_value is still reported, signed (ADR-153). prices is required and must cover every non-cash position in the portfolio, except a held option with a mark or one past its expiry (ADR-147). Symbols you send that the portfolio does not hold are ignored. Keys are matched to held symbols case-insensitively. If a held symbol is missing from the map, the call fails with a 400 whose body carries missing_symbols. Allocait never fills a symbol you left out from its own market data (ADR-036).\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Allocait\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://allocait.mintlify.site/_mintlify/api/og/v2?division=Checks\u0026amp;title=Preview+rebalance+amounts+with+your+prices\u0026amp;description=Returns+pro+rata+amounts+that+would+move+out-of-compliance+classes%0Atoward+their+aim%3A+the+class+rule%27s+own+Target+%25+when+set%2C+otherwise%0Athe+midpoint+of+its+alloc\u0026amp;theme=f4ffca4ae92cd96f3d29a15e\u0026amp;signature=95694d13556013e270e4a808f9b6c0e1a775a8bdd87075eaddcf771b7af843b4\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Preview rebalance amounts with your prices - Allocait\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Returns pro rata amounts that would move out-of-compliance classes toward their aim: the class rule\u0026#x27;s own Target % when set, otherwise the midpoint of its allocation band, using the prices you provide. Rows are ordered largest-dollar-value first. This is arithmetic on the user\u0026#x27;s own rules, not a recommendation. A short (negative shares) or an option (a holding in the Options class) gets no row, and not_rebalanced lists each one once. A class\u0026#x27;s move is the gap on its net value (shorts subtract), spread over its long holdings outside Options only (ADR-153, ADR-145), so one long can carry the whole gap. A class with no priced long holding outside Options gets no row, and appears in unresolved if it stays outside its band. For a class that holds only shorts and options, the reason no_priced_holdings means there is nothing to trade, whatever the prices. A portfolio worth zero or less is not rebalanced: percentages are undefined there, so trades is empty, each resulting_pct is null and total_value is still reported, signed (ADR-153). prices is required and must cover every non-cash position in the portfolio, except a held option with a mark or one past its expiry (ADR-147). Symbols you send that the portfolio does not hold are ignored. Keys are matched to held symbols case-insensitively. If a held symbol is missing from the map, the call fails with a 400 whose body carries missing_symbols. Allocait never fills a symbol you left out from its own market data (ADR-036).\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://allocait.mintlify.site/_mintlify/api/og/v2?division=Checks\u0026amp;title=Preview+rebalance+amounts+with+your+prices\u0026amp;description=Returns+pro+rata+amounts+that+would+move+out-of-compliance+classes%0Atoward+their+aim%3A+the+class+rule%27s+own+Target+%25+when+set%2C+otherwise%0Athe+midpoint+of+its+alloc\u0026amp;theme=f4ffca4ae92cd96f3d29a15e\u0026amp;signature=95694d13556013e270e4a808f9b6c0e1a775a8bdd87075eaddcf771b7af843b4\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/allocait/8WDpZ9h0WNasoRjb/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Allocait\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0b0b0b\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/checks/preview-rebalance-amounts-with-your-prices.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.allocait.app/#organization\",\"name\":\"Allocait\",\"url\":\"https://docs.allocait.app\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/allocait/N9X8GrpLUSiZAKIm/logo/light.svg?fit=max\u0026auto=format\u0026n=N9X8GrpLUSiZAKIm\u0026q=85\u0026s=37c68a7ac5dc3550d24f484060530ea6\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.allocait.app#website\",\"name\":\"Allocait\",\"url\":\"https://docs.allocait.app\",\"publisher\":{\"@id\":\"https://docs.allocait.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices#webpage\",\"url\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices\",\"name\":\"Preview rebalance amounts with your prices\",\"description\":\"Returns pro rata amounts that would move out-of-compliance classes toward their aim: the class rule's own Target % when set, otherwise the midpoint of its allocation band, using the prices you provide. Rows are ordered largest-dollar-value first. This is arithmetic on the user's own rules, not a recommendation. A short (negative shares) or an option (a holding in the Options class) gets no row, and not_rebalanced lists each one once. A class's move is the gap on its net value (shorts subtract), spread over its long holdings outside Options only (ADR-153, ADR-145), so one long can carry the whole gap. A class with no priced long holding outside Options gets no row, and appears in unresolved if it stays outside its band. For a class that holds only shorts and options, the reason no_priced_holdings means there is nothing to trade, whatever the prices. A portfolio worth zero or less is not rebalanced: percentages are undefined there, so trades is empty, each resulting_pct is null and total_value is still reported, signed (ADR-153). prices is required and must cover every non-cash position in the portfolio, except a held option with a mark or one past its expiry (ADR-147). Symbols you send that the portfolio does not hold are ignored. Keys are matched to held symbols case-insensitively. If a held symbol is missing from the map, the call fails with a 400 whose body carries missing_symbols. Allocait never fills a symbol you left out from its own market data (ADR-036).\",\"dateModified\":\"2026-11-09T05:23:21.125Z\",\"isPartOf\":{\"@id\":\"https://docs.allocait.app#website\"},\"breadcrumb\":{\"@id\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Endpoints\",\"item\":\"https://docs.allocait.app/api-reference/checks/check-compliance-with-your-prices\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Checks\",\"item\":\"https://docs.allocait.app/api-reference/checks/check-compliance-with-your-prices\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Preview rebalance amounts with your prices\",\"item\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices#apireference\",\"headline\":\"Preview rebalance amounts with your prices\",\"name\":\"Preview rebalance amounts with your prices\",\"description\":\"Returns pro rata amounts that would move out-of-compliance classes toward their aim: the class rule's own Target % when set, otherwise the midpoint of its allocation band, using the prices you provide. Rows are ordered largest-dollar-value first. This is arithmetic on the user's own rules, not a recommendation. A short (negative shares) or an option (a holding in the Options class) gets no row, and not_rebalanced lists each one once. A class's move is the gap on its net value (shorts subtract), spread over its long holdings outside Options only (ADR-153, ADR-145), so one long can carry the whole gap. A class with no priced long holding outside Options gets no row, and appears in unresolved if it stays outside its band. For a class that holds only shorts and options, the reason no_priced_holdings means there is nothing to trade, whatever the prices. A portfolio worth zero or less is not rebalanced: percentages are undefined there, so trades is empty, each resulting_pct is null and total_value is still reported, signed (ADR-153). prices is required and must cover every non-cash position in the portfolio, except a held option with a mark or one past its expiry (ADR-147). Symbols you send that the portfolio does not hold are ignored. Keys are matched to held symbols case-insensitively. If a held symbol is missing from the map, the call fails with a 400 whose body carries missing_symbols. Allocait never fills a symbol you left out from its own market data (ADR-036).\",\"url\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices\",\"mainEntityOfPage\":{\"@id\":\"https://docs.allocait.app/api-reference/checks/preview-rebalance-amounts-with-your-prices#webpage\"},\"dateModified\":\"2026-11-09T05:23:21.125Z\",\"publisher\":{\"@id\":\"https://docs.allocait.app/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.allocait.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Allocait\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Allocait\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/checks/preview-rebalance-amounts-with-your-prices.md","siteName":"Allocait","nav":{"global":null,"tabs":[{"tab":"Get started","pages":[{"title":"Get started","href":""}]},{"tab":"Concepts","pages":[{"title":"Concepts","href":"/concepts/allocation-bands"}]},{"tab":"Claude \u0026 MCP","pages":[{"title":"Claude \u0026 MCP","href":"/claude/overview"}]},{"tab":"ChatGPT \u0026 Codex","pages":[{"title":"ChatGPT \u0026 Codex","href":"/chatgpt/connect"}]},{"tab":"Guides","pages":[{"title":"Guides","href":"/guides/write-your-rules"}]},{"tab":"API reference","groups":[{"group":"Start","pages":[{"title":"API overview","sidebarTitle":"Overview","href":"/api/introduction"},{"title":"Endpoints by task","sidebarTitle":"By task","href":"/api/endpoints-by-task"},{"title":"API quickstart","sidebarTitle":"Quickstart","href":"/api/quickstart"},{"title":"Authentication","sidebarTitle":"Authentication","href":"/api/authentication"}]},{"group":"Conventions","pages":[{"title":"Conventions","sidebarTitle":"Conventions","href":"/api/conventions"},{"title":"Rate limits","sidebarTitle":"Rate limits","href":"/api/rate-limits"},{"title":"Idempotency","sidebarTitle":"Idempotency","href":"/api/idempotency"}]},{"group":"Errors","pages":[{"title":"API errors","sidebarTitle":"Errors","href":"/api/errors"},{"title":"Error codes","sidebarTitle":"Error codes","href":"/api/error-codes"}]},{"group":"Webhooks","pages":[{"title":"Webhook events","sidebarTitle":"Webhook events","href":"/api/webhook-events"},{"title":"Verify deliveries","sidebarTitle":"Verify deliveries","href":"/api/webhook-verification"}]},{"group":"Endpoints","pages":[{"group":"Checks","pages":[{"title":"Check compliance with your prices","deprecated":null,"version":null,"openapi":"/openapi.yaml post /compliance/check","href":"/api-reference/checks/check-compliance-with-your-prices"},{"title":"Pre-flight check of a proposed allocation plan","deprecated":null,"version":null,"openapi":"/openapi.yaml post /validate","href":"/api-reference/checks/pre-flight-check-of-a-proposed-allocation-plan"},{"title":"Check a proposed change against the rules","description":"States which of the user's own rules a proposed change puts outside\nits range or leaves further outside, using prices you supply. It\nreads and writes nothing, decides nothing and needs only `read`, so\na Core account's key can call it. A result inside every range does\nnot say a change is advisable. Allocait cannot approve, stop or\nplace an order.\n\n`trades` is the whole change, 1 to 50 items, applied together and in\nany order: several trades in one symbol net. `side` is the direction\nof the change being asked about: `BUY` adds shares to the holding,\n`SELL` removes shares. Send `shares` (fractions allowed) or\n`notional` (dollars, at the price in `prices`), not both. A `SELL`\nlarger than the shares held is `INVALID_INPUT`, never clamped,\nunless the portfolio has `allow_shorts` on: then a `SELL` can take\na holding below zero and a `BUY` can take a short above it, and\n`shares_after` is signed (negative is a short). A holding in the\nOptions class never goes below zero, and a change worth\n100000000000000 or more cannot be recorded, so it is refused. `CASH`\nis not tradable. A symbol the portfolio does not hold needs\n`asset_class` (a class name, rules text alias or id); a held symbol\nkeeps the class it is recorded under.\n\n`prices` is required and must cover every non-cash holding and every\ntraded symbol, except a held option with a `mark` or one past its\nexpiry, which is priced from the user's own number or at 0 (ADR-147).\nA hole is a `400` with `error_code: PRICES_INCOMPLETE`\nand `missing_symbols`; Allocait never fills a symbol you left out\nfrom its own market data (ADR-036). A held symbol may be priced 0 (a\nworthless option); a price you pass for an unexpired option replaces\nits mark for this call only. A traded symbol priced 0 or less is\n`PRICES_INVALID`. Prices are used for this call only and never\nstored.\n\nA trade in a held option that has expired is not checked, because the\noption counts 0 and a trade cannot change the book. It is\n`INVALID_INPUT` and the message names the trade's index and symbol and\nthe write that closes it (`shares` 0 and `price` 0).\n\n`scenario_id` defaults to the portfolio's active scenario. A\nportfolio with none set needs `scenario_id` (a 400 that says so).\n\n**Reading the result.** `rules` lists only the rules outside their\nrange before or after the change. Rules inside both are counted in\n`rules_judged_count`. `change` describes a rule's distance from its\nrange, never the trade. `newly_or_further_outside_count` answers\n\"did this change add a breach or deepen one\". A bot that must do\nneither checks that it equals 0.\n\n`within_rules` answers a different question: is the whole book\ninside every rule after the change. It is true only when no rule is\noutside its range after the change, `rules_judged_count` is above 0\nand `cash.sufficient` is true. Treat `false` as \"not confirmed\",\nnever as a block Allocait enforces. Treat `true` as saying nothing\nabout any symbol no rule covers; `not_covered` lists those\nsymbols, traded or held.\n\n`exposure_after` says how much of the book gains if prices rise\nonce the whole change is applied: long, short, net and gross as\npercents of `total_value`, at your prices (`shares x price x moves`;\na holding's Moves is the setting the user recorded, 1 unless set). It\nis a reading beside the rules, not part of the verdict, and\n`within_rules` does not read it. Options count at their premium, a\ncall as long and a put as short, and an expired option counts 0\n(ADR-147).\n\nReport `positions_updated_at` with the verdict. The book is what\nAllocait has recorded. Allocait does not read the live account. The symbols in the\nexamples are fictional and their numbers are made up.\n","deprecated":null,"version":null,"openapi":"/openapi.yaml post /trades/check","href":"/api-reference/checks/check-a-proposed-change-against-the-rules"},{"title":"Preview rebalance amounts with your prices","deprecated":null,"version":null,"openapi":"/openapi.yaml post /rebalance/preview","href":"/api-reference/checks/preview-rebalance-amounts-with-your-prices"}]},{"group":"Portfolios","pages":[{"title":"Get portfolio summary","description":"Returns what the user recorded for a portfolio, unpriced: name,\ncurrency, position count, and active scenario. No total value.\nAllocait never returns a value computed from its own stored quote\non this surface (ADR-036). For a priced total, POST\n/portfolio/snapshot with prices.\n","deprecated":null,"version":null,"openapi":"/openapi.yaml get /portfolio/summary","href":"/api-reference/portfolios/get-portfolio-summary"},{"title":"List portfolios","deprecated":null,"version":null,"openapi":"/openapi.yaml get /portfolios","href":"/api-reference/portfolios/list-portfolios"},{"title":"Create a portfolio with an initial cash position","deprecated":null,"version":null,"openapi":"/openapi.yaml post /portfolios","href":"/api-reference/portfolios/create-a-portfolio-with-an-initial-cash-position"},{"title":"Delete a portfolio","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /portfolios/{id}","href":"/api-reference/portfolios/delete-a-portfolio"},{"title":"Change a portfolio's name, description, active scenario or Allow shorts","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /portfolios/{id}","href":"/api-reference/portfolios/change-a-portfolios-name-description-active-scenario-or-allow-shorts"},{"title":"Get a portfolio snapshot (unpriced)","deprecated":null,"version":null,"openapi":"/openapi.yaml get /portfolio/snapshot","href":"/api-reference/portfolios/get-a-portfolio-snapshot-unpriced"},{"title":"Get a portfolio snapshot with your prices","deprecated":null,"version":null,"openapi":"/openapi.yaml post /portfolio/snapshot","href":"/api-reference/portfolios/get-a-portfolio-snapshot-with-your-prices"}]},{"group":"Holdings and cash","pages":[{"title":"List positions","deprecated":null,"version":null,"openapi":"/openapi.yaml get /positions","href":"/api-reference/holdings-and-cash/list-positions"},{"title":"Record one holding's new total shares","deprecated":null,"version":null,"openapi":"/openapi.yaml post /positions/{symbol}","href":"/api-reference/holdings-and-cash/record-one-holdings-new-total-shares"},{"title":"Calculate a target share count for a position","deprecated":null,"version":null,"openapi":"/openapi.yaml post /positions/size","href":"/api-reference/holdings-and-cash/calculate-a-target-share-count-for-a-position"},{"title":"Reconcile a portfolio's holdings to an absolute desired state","deprecated":null,"version":null,"openapi":"/openapi.yaml post /portfolios/{id}/positions/apply","href":"/api-reference/holdings-and-cash/reconcile-a-portfolios-holdings-to-an-absolute-desired-state"},{"title":"Deposit or withdraw cash from a portfolio","deprecated":null,"version":null,"openapi":"/openapi.yaml post /portfolios/{id}/cash-movements","href":"/api-reference/holdings-and-cash/deposit-or-withdraw-cash-from-a-portfolio"}]},{"group":"Watchlists","pages":[{"title":"List watchlists","deprecated":null,"version":null,"openapi":"/openapi.yaml get /watchlists","href":"/api-reference/watchlists/list-watchlists"},{"title":"Create a watchlist","deprecated":null,"version":null,"openapi":"/openapi.yaml post /watchlists","href":"/api-reference/watchlists/create-a-watchlist"},{"title":"Change a watchlist's name and symbols in one call","deprecated":null,"version":null,"openapi":"/openapi.yaml put /watchlists/{id}","href":"/api-reference/watchlists/change-a-watchlists-name-and-symbols-in-one-call"},{"title":"Delete a watchlist","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /watchlists/{id}","href":"/api-reference/watchlists/delete-a-watchlist"},{"title":"Rename a watchlist","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /watchlists/{id}","href":"/api-reference/watchlists/rename-a-watchlist"},{"title":"List items in a watchlist","deprecated":null,"version":null,"openapi":"/openapi.yaml get /watchlists/{id}/items","href":"/api-reference/watchlists/list-items-in-a-watchlist"},{"title":"Add a symbol to a watchlist","deprecated":null,"version":null,"openapi":"/openapi.yaml post /watchlists/{id}/items","href":"/api-reference/watchlists/add-a-symbol-to-a-watchlist"},{"title":"Reorder a watchlist's items","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /watchlists/{id}/items","href":"/api-reference/watchlists/reorder-a-watchlists-items"},{"title":"Remove a symbol from a watchlist","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /watchlists/{id}/items/{item_id}","href":"/api-reference/watchlists/remove-a-symbol-from-a-watchlist"}]},{"group":"Inputs","pages":[{"title":"List input (tracked-value) definitions","deprecated":null,"version":null,"openapi":"/openapi.yaml get /inputs","href":"/api-reference/inputs/list-input-tracked-value-definitions"},{"title":"Create an Input (tracked-value) definition","deprecated":null,"version":null,"openapi":"/openapi.yaml post /inputs","href":"/api-reference/inputs/create-an-input-tracked-value-definition"},{"title":"Change an Input definition and its options in one call","deprecated":null,"version":null,"openapi":"/openapi.yaml put /inputs/{id}","href":"/api-reference/inputs/change-an-input-definition-and-its-options-in-one-call"},{"title":"Delete an Input definition","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /inputs/{id}","href":"/api-reference/inputs/delete-an-input-definition"},{"title":"Update an Input definition","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /inputs/{id}","href":"/api-reference/inputs/update-an-input-definition"},{"title":"List recorded values for one input","deprecated":null,"version":null,"openapi":"/openapi.yaml get /inputs/{id}/entries","href":"/api-reference/inputs/list-recorded-values-for-one-input"},{"title":"List dropdown options for one CHOICE input","deprecated":null,"version":null,"openapi":"/openapi.yaml get /inputs/{id}/options","href":"/api-reference/inputs/list-dropdown-options-for-one-choice-input"},{"title":"Add a dropdown option","deprecated":null,"version":null,"openapi":"/openapi.yaml post /inputs/{id}/options","href":"/api-reference/inputs/add-a-dropdown-option"},{"title":"Remove a dropdown option","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /inputs/{id}/options/{option_id}","href":"/api-reference/inputs/remove-a-dropdown-option"},{"title":"Rename or reorder a dropdown option","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /inputs/{id}/options/{option_id}","href":"/api-reference/inputs/rename-or-reorder-a-dropdown-option"},{"title":"Record (upsert) one or more custom input values","deprecated":null,"version":null,"openapi":"/openapi.yaml post /inputs/entries","href":"/api-reference/inputs/record-upsert-one-or-more-custom-input-values"},{"title":"Delete one or more recorded input values","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /inputs/entries","href":"/api-reference/inputs/delete-one-or-more-recorded-input-values"}]},{"group":"Playbooks","pages":[{"title":"List playbooks","deprecated":null,"version":null,"openapi":"/openapi.yaml get /playbooks","href":"/api-reference/playbooks/list-playbooks"},{"title":"Create a playbook","deprecated":null,"version":null,"openapi":"/openapi.yaml post /playbooks","href":"/api-reference/playbooks/create-a-playbook"},{"title":"Resolve a playbook's symbols and its input values for a date","deprecated":null,"version":null,"openapi":"/openapi.yaml get /playbooks/{id}","href":"/api-reference/playbooks/resolve-a-playbooks-symbols-and-its-input-values-for-a-date"},{"title":"Delete a playbook","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /playbooks/{id}","href":"/api-reference/playbooks/delete-a-playbook"},{"title":"Update a playbook","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /playbooks/{id}","href":"/api-reference/playbooks/update-a-playbook"}]},{"group":"Monitors","pages":[{"title":"List condition monitors and their recorded levels","deprecated":null,"version":null,"openapi":"/openapi.yaml get /monitors","href":"/api-reference/monitors/list-condition-monitors-and-their-recorded-levels"},{"title":"Create a condition monitor","deprecated":null,"version":null,"openapi":"/openapi.yaml post /monitors","href":"/api-reference/monitors/create-a-condition-monitor"},{"title":"Delete a condition monitor","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /monitors/{id}","href":"/api-reference/monitors/delete-a-condition-monitor"},{"title":"Update a condition monitor","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /monitors/{id}","href":"/api-reference/monitors/update-a-condition-monitor"}]},{"group":"Rules","pages":[{"title":"List scenarios","deprecated":null,"version":null,"openapi":"/openapi.yaml get /scenarios","href":"/api-reference/rules/list-scenarios"},{"title":"Create a scenario","deprecated":null,"version":null,"openapi":"/openapi.yaml post /scenarios","href":"/api-reference/rules/create-a-scenario"},{"title":"Delete a scenario","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /scenarios/{id}","href":"/api-reference/rules/delete-a-scenario"},{"title":"Rename a scenario and/or replace its description","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /scenarios/{id}","href":"/api-reference/rules/rename-a-scenario-andor-replace-its-description"},{"title":"List asset classes","deprecated":null,"version":null,"openapi":"/openapi.yaml get /asset-classes","href":"/api-reference/rules/list-asset-classes"},{"title":"Create a custom asset class","deprecated":null,"version":null,"openapi":"/openapi.yaml post /asset-classes","href":"/api-reference/rules/create-a-custom-asset-class"},{"title":"Delete a custom asset class","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /asset-classes/{id}","href":"/api-reference/rules/delete-a-custom-asset-class"},{"title":"Rename an asset class and/or replace its description","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /asset-classes/{id}","href":"/api-reference/rules/rename-an-asset-class-andor-replace-its-description"},{"title":"List position rules (allocation band and position size per asset class)","deprecated":null,"version":null,"openapi":"/openapi.yaml get /position-rules","href":"/api-reference/rules/list-position-rules-allocation-band-and-position-size-per-asset-class"},{"title":"Set one asset class's rule in a scenario","deprecated":null,"version":null,"openapi":"/openapi.yaml post /scenarios/{id}/position-rules","href":"/api-reference/rules/set-one-asset-classs-rule-in-a-scenario"},{"title":"Reconcile a scenario's position rules to an absolute desired state","deprecated":null,"version":null,"openapi":"/openapi.yaml post /scenarios/{id}/position-rules/apply","href":"/api-reference/rules/reconcile-a-scenarios-position-rules-to-an-absolute-desired-state"},{"title":"Get a scenario's rules as rules text","deprecated":null,"version":null,"openapi":"/openapi.yaml get /scenarios/{id}/rules","href":"/api-reference/rules/get-a-scenarios-rules-as-rules-text"},{"title":"Import rules text into a scenario's rules, or preview it with dry_run","deprecated":null,"version":null,"openapi":"/openapi.yaml post /scenarios/{id}/rules","href":"/api-reference/rules/import-rules-text-into-a-scenarios-rules-or-preview-it-with-dry_run"},{"title":"List rules restore points, newest first","deprecated":null,"version":null,"openapi":"/openapi.yaml get /rules/restore-points","href":"/api-reference/rules/list-rules-restore-points-newest-first"},{"title":"Undo an import or an earlier restore","deprecated":null,"version":null,"openapi":"/openapi.yaml post /rules/restore-points/{id}/restore","href":"/api-reference/rules/undo-an-import-or-an-earlier-restore"},{"title":"Get the rules text format spec, ready-to-import examples, and copy/paste AI prompts","deprecated":null,"version":null,"openapi":"/openapi.yaml get /rules/spec","href":"/api-reference/rules/get-the-rules-text-format-spec-ready-to-import-examples-and-copypaste-ai-prompts"}]},{"group":"Actions","pages":[{"title":"List a portfolio's actions","deprecated":null,"version":null,"openapi":"/openapi.yaml get /actions","href":"/api-reference/actions/list-a-portfolios-actions"},{"title":"Delete one or more actions","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /actions","href":"/api-reference/actions/delete-one-or-more-actions"},{"title":"Edit an action's comment","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /actions/{id}","href":"/api-reference/actions/edit-an-actions-comment"}]},{"group":"Support and feedback","pages":[{"title":"List your support requests, newest first","deprecated":null,"version":null,"openapi":"/openapi.yaml get /support-requests","href":"/api-reference/support-and-feedback/list-your-support-requests-newest-first"},{"title":"File a support request","deprecated":null,"version":null,"openapi":"/openapi.yaml post /support-requests","href":"/api-reference/support-and-feedback/file-a-support-request"},{"title":"List your agent feedback, newest first","deprecated":null,"version":null,"openapi":"/openapi.yaml get /agent-feedback","href":"/api-reference/support-and-feedback/list-your-agent-feedback-newest-first"},{"title":"Report feedback about the agent surface itself","deprecated":null,"version":null,"openapi":"/openapi.yaml post /agent-feedback","href":"/api-reference/support-and-feedback/report-feedback-about-the-agent-surface-itself"}]},{"group":"Charts","pages":[{"title":"List saved charts for a portfolio","deprecated":null,"version":null,"openapi":"/openapi.yaml get /charts","href":"/api-reference/charts/list-saved-charts-for-a-portfolio"},{"title":"Create a saved chart","deprecated":null,"version":null,"openapi":"/openapi.yaml post /charts","href":"/api-reference/charts/create-a-saved-chart"},{"title":"Delete a saved chart","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /charts/{id}","href":"/api-reference/charts/delete-a-saved-chart"},{"title":"Update a saved chart","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /charts/{id}","href":"/api-reference/charts/update-a-saved-chart"}]},{"group":"Preferences","pages":[{"title":"Get what the app opens to, and the theme","deprecated":null,"version":null,"openapi":"/openapi.yaml get /preferences","href":"/api-reference/preferences/get-what-the-app-opens-to-and-the-theme"},{"title":"Set which portfolio/watchlist/chart/playbook/monitor the app shows, or the theme","deprecated":null,"version":null,"openapi":"/openapi.yaml post /preferences","href":"/api-reference/preferences/set-which-portfoliowatchlistchartplaybookmonitor-the-app-shows-or-the-theme"}]},{"group":"Webhooks","pages":[{"title":"List webhook endpoints","deprecated":null,"version":null,"openapi":"/openapi.yaml get /webhooks","href":"/api-reference/webhooks/list-webhook-endpoints"},{"title":"Register a webhook endpoint","deprecated":null,"version":null,"openapi":"/openapi.yaml post /webhooks","href":"/api-reference/webhooks/register-a-webhook-endpoint"},{"title":"Delete a webhook endpoint","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /webhooks/{id}","href":"/api-reference/webhooks/delete-a-webhook-endpoint"},{"title":"Update a webhook endpoint","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /webhooks/{id}","href":"/api-reference/webhooks/update-a-webhook-endpoint"}]},{"group":"Setup file","pages":[{"title":"Export your watchlists, Inputs, playbooks, monitors and saved charts as one JSON document","deprecated":null,"version":null,"openapi":"/openapi.yaml get /setup/export","href":"/api-reference/setup-file/export-your-watchlists-inputs-playbooks-monitors-and-saved-charts-as-one-json-document"},{"title":"Preview an ALLOCAIT.md setup file","deprecated":null,"version":null,"openapi":"/openapi.yaml post /setup/preview","href":"/api-reference/setup-file/preview-an-allocaitmd-setup-file"},{"title":"Apply a previewed ALLOCAIT.md setup file","deprecated":null,"version":null,"openapi":"/openapi.yaml post /setup/apply","href":"/api-reference/setup-file/apply-a-previewed-allocaitmd-setup-file"},{"title":"List the account's setup file receipts","deprecated":null,"version":null,"openapi":"/openapi.yaml get /setup/receipts","href":"/api-reference/setup-file/list-the-accounts-setup-file-receipts"},{"title":"Undo an applied setup file, or preview the undo","deprecated":null,"version":null,"openapi":"/openapi.yaml post /setup/receipts/{id}/undo","href":"/api-reference/setup-file/undo-an-applied-setup-file-or-preview-the-undo"}]}]}]},{"tab":"Support \u0026 trust","pages":[{"title":"Support \u0026 trust","href":"/support"}]}]},"basePath":"","title":"Preview rebalance amounts with your prices - Allocait","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-C9Wu0MeN.js","utils-jWgu-6Qf.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DBD8f9qn.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BGuX1ui5.js","snippetPresets-Evy63nQB.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BQHO1lnV.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-B6C8m-t_.js","shallow-BG4cT0fH.js","getApiPlaygroundDisplay-CgEPrE-D.js","CodeSnippet-CU8JyZ9N.js","CodeSnippets-BnxHU32T.js","Page-D6S0Yh6q.js","getPastedJson-CwiYOonh.js","icon-DYDpWmDf.js","MethodPill-C-J-l7_c.js","DuplicateIcon-B6ARwg9w.js","createIcon-Dsv4MtDq.js","DynamicMarkdown-CtasenyM.js","SectionHeading-YNcgYwjB.js","axios-vUo_bRtp.js","Markdown-CwLx6PAg.js","clsx-C3kuh_dz.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CmKHfscc.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-U3mI6Ljh.js"]}