{"openapi":"3.1.1","info":{"title":"Trellia Integration API","version":"1.0.0","description":"Personal, scoped REST API for advisers, fund managers and staff. Create a key in portal Integrations. Keys expire within 90 days and are bound to their issuing role and company. Trellia and InvestSense staff read the complete active portfolio and fund catalogues using ordinary portfolios:read and funds:read scopes. Other roles retain live entitlements and company boundaries. Scope grants never bypass live account or object permissions. Server-to-server HTTPS use; no browser cross-origin credential sharing. Unknown query parameters and duplicate parameters are rejected; only POST operations take a JSON body, and they need an Idempotency-Key. Staff write operations only propose change sets, which the owner reviews and applies in the Staff room. Rate limits are budgets in points per minute: each operation spends 1 (single record), 3 (list or heavy read), 5 (write) or 10 (revert or restore proposal), and a shared global budget applies across all keys. All data responses are private, no-store. Breaking changes use a new major URL version."},"servers":[{"url":"/api/v1"}],"security":[{"bearerAuth":[]}],"paths":{"/me":{"get":{"operationId":"getApiIdentity","summary":"Read the caller's current identity and scopes","description":"Works for personal keys, MCP access grants, service keys and job tokens. Adds the principal kind, display name (never an email), live staff role, isFullStaff, the service principal name or job id where relevant, and when the credential or grant ends.","x-required-scope":"profile:read","parameters":[],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/IdentityProfile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolios":{"get":{"operationId":"listPortfolios","summary":"List portfolios available to your role","description":"Trellia and InvestSense staff read all active portfolios across companies, suites and platforms. Other accounts retain live portfolio entitlements and exact menu access. The key must grant portfolios:read.","x-required-scope":"portfolios:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page; keep all filters unchanged.","schema":{"type":"string","maxLength":2048}},{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"suiteSlug","in":"query","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"platformSlug","in":"query","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"menuSlug","in":"query","description":"Exact platform menu slug; existing portal menu entitlements apply.","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"ids","in":"query","description":"Exact portfolio ids. With codes and code, at most 100 together; returns one page and rejects a cursor.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"codes","in":"query","description":"Exact portfolio codes, case-insensitive.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":120}},"style":"form","explode":false},{"name":"code","in":"query","description":"One exact portfolio code, case-insensitive.","schema":{"type":"string","minLength":1,"maxLength":120}},{"name":"companySlug","in":"query","schema":{"type":"string","maxLength":160}},{"name":"suiteId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"platformId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"nameContains","in":"query","schema":{"type":"string","maxLength":100}},{"name":"growthMin","in":"query","description":"Minimum growth allocation in percent (70 means 70%), an exact decimal.","schema":{"type":"string"}},{"name":"growthMax","in":"query","description":"Maximum growth allocation in percent, an exact decimal.","schema":{"type":"string"}},{"name":"includeInactive","in":"query","description":"Full staff only. Reads inactive portfolios too.","schema":{"type":"string","enum":["true","false"]}},{"name":"includeProspects","in":"query","description":"Omit for the existing behaviour (prospect portfolios included). false hides prospects; true needs full staff.","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","description":"name orders by (name, id) with a keyset cursor.","schema":{"type":"string","enum":["id","name"],"default":"id"}},{"name":"includeTotal","in":"query","description":"Adds totalCount, capped at 10000 (totalCountCapped says when it stopped).","schema":{"type":"string","enum":["true","false"]}},{"name":"include","in":"query","description":"lookthroughFlag adds hasLookthroughHoldings; external adds latestAggregationDate and isExternal; bloombergExport adds the stored Bloomberg portfolio name and drifting flag (full staff only).","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["lookthroughFlag","external","bloombergExport"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioDataPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolios/{portfolioId}":{"get":{"operationId":"getPortfolio","summary":"Read portfolio identity","description":"Trellia and InvestSense staff read all active portfolios across companies, suites and platforms. Other accounts retain live portfolio entitlements and exact menu access. The key must grant portfolios:read.","x-required-scope":"portfolios:read","parameters":[{"name":"portfolioId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"menuSlug","in":"query","description":"Exact platform menu slug; existing portal menu entitlements apply.","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"includeInactive","in":"query","description":"Full staff only. Keeps history on inactive portfolios reachable.","schema":{"type":"string","enum":["true","false"]}},{"name":"include","in":"query","description":"lookthroughFlag adds hasLookthroughHoldings; external adds latestAggregationDate and isExternal; bloombergExport adds the stored Bloomberg portfolio name and drifting flag (full staff only).","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["lookthroughFlag","external","bloombergExport"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioDataItem"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolios/{portfolioId}/holdings":{"get":{"operationId":"getPortfolioHoldings","summary":"Read a page of portfolio holdings","description":"Trellia and InvestSense staff read all active portfolios across companies, suites and platforms. Other accounts retain live portfolio entitlements and exact menu access. The key must grant portfolios:read. Resolves existing white-label holdings inheritance. Weights are exact decimal fractions; 0.05 means 5%.","x-required-scope":"portfolios:read","parameters":[{"name":"portfolioId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page; keep all filters unchanged.","schema":{"type":"string","maxLength":2048}},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for latest available. Pagination pins that snapshot.","schema":{"type":"string","format":"date"}},{"name":"menuSlug","in":"query","description":"Exact platform menu slug; existing portal menu entitlements apply.","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"include","in":"query","description":"classification adds the asset class, sub-asset class (own and strategy-effective), strategy, growth flag and security id; nested adds nestedPortfolioId.","schema":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["classification","nested"]}},"style":"form","explode":false},{"name":"weightGt0","in":"query","description":"true returns positive weights only.","schema":{"type":"string","enum":["true","false"]}},{"name":"expand","in":"query","description":"Flattens nested portfolios to leaf rows at depth 4 with effective weights. limit counts top-level holdings.","schema":{"type":"string","enum":["nested"]}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioHoldingsExtended"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolios/{portfolioId}/performance":{"get":{"operationId":"getPortfolioPerformance","summary":"Read latest available period performance","description":"Trellia and InvestSense staff read all active portfolios across companies, suites and platforms. Other accounts retain live portfolio entitlements and exact menu access. The key must grant portfolios:read. Uses the portal-selected performance series and inherited source. Values are decimal strings in percentage points. Missing data is explicitly unavailable, never zero.","x-required-scope":"portfolios:read","parameters":[{"name":"portfolioId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"menuSlug","in":"query","description":"Exact platform menu slug; existing portal menu entitlements apply.","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"asOf","in":"query","description":"The latest month-end snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioPerformance"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fum":{"get":{"operationId":"getFumSummary","summary":"Read staff FUM KPIs and twelve-month histories","description":"Requires fum:read and live Trellia/InvestSense staff FUM permission. Confidential staff reporting; adviser, fund-manager and restricted staff keys are denied. Reuses dashboard calculations, latest-per-platform snapshots and legacy flow consolidation; not a transaction ledger. Amounts are AUD strings from dashboard numeric calculations.","x-required-scope":"fum:read","parameters":[{"name":"date","in":"query","required":true,"description":"Explicit available reporting date (YYYY-MM-DD). Obtain dates from /fum/dates.","schema":{"type":"string","format":"date"}},{"name":"startDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"clientTypes","in":"query","description":"Comma-separated reporting buckets.","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["betashares","investsense","bespoke"]}},"style":"form","explode":false},{"name":"states","in":"query","description":"Comma-separated reporting states (matched firm office state, then platform state).","schema":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"string","enum":["NSW","VIC","QLD","WA","SA","TAS","ACT","NT"]}},"style":"form","explode":false},{"name":"suiteIds","in":"query","description":"Comma-separated suite IDs.","schema":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FumSummary"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/flows":{"get":{"operationId":"getFumFlows","summary":"Read staff net flows and twelve-month history","description":"Requires fum:read and live Trellia/InvestSense staff FUM permission. Confidential staff reporting; adviser, fund-manager and restricted staff keys are denied. Reuses dashboard calculations, latest-per-platform snapshots and legacy flow consolidation; not a transaction ledger. Amounts are AUD strings from dashboard numeric calculations.","x-required-scope":"fum:read","parameters":[{"name":"date","in":"query","required":true,"description":"Explicit available reporting date (YYYY-MM-DD). Obtain dates from /fum/dates.","schema":{"type":"string","format":"date"}},{"name":"startDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"clientTypes","in":"query","description":"Comma-separated reporting buckets.","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["betashares","investsense","bespoke"]}},"style":"form","explode":false},{"name":"states","in":"query","description":"Comma-separated reporting states (matched firm office state, then platform state).","schema":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"string","enum":["NSW","VIC","QLD","WA","SA","TAS","ACT","NT"]}},"style":"form","explode":false},{"name":"suiteIds","in":"query","description":"Comma-separated suite IDs.","schema":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FumFlows"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fum/rows":{"get":{"operationId":"listFumRows","summary":"Read paged flat staff FUM and flow reporting facts","description":"Requires fum:read and live Trellia/InvestSense staff FUM permission. Confidential staff reporting; adviser, fund-manager and restricted staff keys are denied. Reuses dashboard calculations, latest-per-platform snapshots and legacy flow consolidation; not a transaction ledger. Amounts are AUD strings from dashboard numeric calculations. Page data uses data/totalCount/revision/nextOffset, not cursor pagination. Closing FUM is a snapshot; never sum it across reporting dates.","x-required-scope":"fum:read","parameters":[{"name":"date","in":"query","required":true,"description":"Explicit available reporting date (YYYY-MM-DD). Obtain dates from /fum/dates.","schema":{"type":"string","format":"date"}},{"name":"startDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"clientTypes","in":"query","description":"Comma-separated reporting buckets.","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["betashares","investsense","bespoke"]}},"style":"form","explode":false},{"name":"states","in":"query","description":"Comma-separated reporting states (matched firm office state, then platform state).","schema":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"string","enum":["NSW","VIC","QLD","WA","SA","TAS","ACT","NT"]}},"style":"form","explode":false},{"name":"suiteIds","in":"query","description":"Comma-separated suite IDs.","schema":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"revision","in":"query","description":"Dataset/filter revision from the first page; required after offset zero. Keep all filters fixed. 409 dataset_changed requires restarting the full extract.","schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FumRowsPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fum/breakdown":{"get":{"operationId":"listFumBreakdown","summary":"Read a grouped staff FUM or holdings estimate breakdown","description":"Requires fum:read and live Trellia/InvestSense staff FUM permission. Confidential staff reporting; adviser, fund-manager and restricted staff keys are denied. Reuses dashboard calculations, latest-per-platform snapshots and legacy flow consolidation; not a transaction ledger. Amounts are AUD strings from dashboard numeric calculations. fund_manager/product groups are holdings-derived estimates; unsupported measures are null, not zero.","x-required-scope":"fum:read","parameters":[{"name":"date","in":"query","required":true,"description":"Explicit available reporting date (YYYY-MM-DD). Obtain dates from /fum/dates.","schema":{"type":"string","format":"date"}},{"name":"startDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","description":"Optional inclusive flow range; supply both bounds. Closing FUM remains at date.","schema":{"type":"string","format":"date"}},{"name":"clientTypes","in":"query","description":"Comma-separated reporting buckets.","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["betashares","investsense","bespoke"]}},"style":"form","explode":false},{"name":"states","in":"query","description":"Comma-separated reporting states (matched firm office state, then platform state).","schema":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"string","enum":["NSW","VIC","QLD","WA","SA","TAS","ACT","NT"]}},"style":"form","explode":false},{"name":"suiteIds","in":"query","description":"Comma-separated suite IDs.","schema":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"revision","in":"query","description":"Dataset/filter revision from the first page; required after offset zero. Keep all filters fixed. 409 dataset_changed requires restarting the full extract.","schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}},{"name":"groupBy","in":"query","required":true,"schema":{"type":"string","enum":["dealer","adviser","company","platform","platform_menu","state","suite","firm","firm_owner","trellia_owner","portfolio","fund_manager","product"]}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FumBreakdownPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fum/dates":{"get":{"operationId":"listFumDates","summary":"List available staff FUM reporting dates","description":"Requires fum:read and live Trellia/InvestSense staff FUM permission. Confidential staff reporting; adviser, fund-manager and restricted staff keys are denied. Reuses dashboard calculations, latest-per-platform snapshots and legacy flow consolidation; not a transaction ledger. Amounts are AUD strings from dashboard numeric calculations. Date discovery is bounded and revision-paged.","x-required-scope":"fum:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":1000}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"revision","in":"query","description":"Dataset/filter revision from the first page; required after offset zero. Keep all filters fixed. 409 dataset_changed requires restarting the full extract.","schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FumDatesPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/funds":{"get":{"operationId":"listCompanyFunds","summary":"List funds available to your role","description":"Trellia and InvestSense staff read all funds across companies. Other eligible accounts read funds owned by their current company and direct child companies. Requires funds:read.","x-required-scope":"funds:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page; keep all filters unchanged.","schema":{"type":"string","maxLength":2048}},{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"identifier","in":"query","description":"Exact identifier, case-insensitive.","schema":{"type":"string","minLength":1,"maxLength":120}},{"name":"hasHoldings","in":"query","description":"Only funds that disclose holdings (security-level or fixed interest). Only true is accepted.","schema":{"type":"boolean","enum":[true]}},{"name":"include","in":"query","description":"holdingsSummary adds the maintained holdings summary.","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["holdingsSummary"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceFundPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/funds/{fundId}":{"get":{"operationId":"getCompanyFund","summary":"Read a fund available to your role","description":"Full staff catalogue access or live company ownership is required, plus funds:read.","x-required-scope":"funds:read","parameters":[{"name":"fundId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"include","in":"query","description":"detail (objective, business, manager and research text; Trellia and InvestSense staff with reference:read only, otherwise 403) and classification (sub-asset class, asset class, growth flag).","schema":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["detail","classification"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceFundDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/funds/{fundId}/holdings":{"get":{"operationId":"getCompanyFundHoldings","summary":"Read holdings of a fund available to your role","description":"Full staff catalogue access or live company ownership is required, plus funds:read. Weights are the stored disclosure weights. By default rows are in id order; sort=weight_desc orders by weight (largest first). limit above 100 (to 1000) is for full staff only. include=security adds the linked security's identifiers, country and market value. strategyLatest=true reads the freshest disclosure of the fund or its non-terminated strategy siblings and reports it as disclosingFundId. totalCount is on the first page only. Cost 3.","x-required-scope":"funds:read","parameters":[{"name":"fundId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page; keep all filters unchanged.","schema":{"type":"string","maxLength":2048}},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for latest available. Pagination pins that snapshot.","schema":{"type":"string","format":"date"}},{"name":"include","in":"query","description":"security adds the linked security's identifiers.","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["security"]}},"style":"form","explode":false},{"name":"sort","in":"query","schema":{"type":"string","enum":["weight_desc"]}},{"name":"strategyLatest","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FundHoldingsExtended"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/watchlist/items":{"get":{"operationId":"listOwnWatchlistItems","summary":"Read own watchlist identities without notes","x-required-scope":"watchlist:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page; keep all filters unchanged.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/WatchlistPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/watchlist/items/{investmentId}":{"put":{"operationId":"putOwnPrivateWatchlistItem","summary":"Save an investment to your private watchlist","description":"Idempotent, empty request body. Creates your private list if absent. The list must be private inside the write transaction; shared lists are denied. Existing saves return ALREADY_SAVED.","x-required-scope":"watchlist:write","parameters":[{"name":"investmentId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/WatchlistWrite"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteOwnPrivateWatchlistItem","summary":"Remove an investment from your private watchlist","description":"Idempotent, empty request body. Only the caller's private list can change. Shared lists and items retaining another author's notes are denied. Missing items return NOT_SAVED. Removing an item deletes its attached rationale and owner's notes.","x-required-scope":"watchlist:write","parameters":[{"name":"investmentId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/WatchlistWrite"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate parameter or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Unsupported method. See Allow header.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Allow":{"schema":{"type":"string"}}}},"409":{"description":"Resource conflict, changed FUM dataset revision, or private watchlist requirement.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"412":{"description":"Resource precondition was not met.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The declared request body is larger than 512 KB, or the response is larger than the API returns (2 MB by default; code response_too_large). Narrow the request, lower the limit, or use the Staff room exports.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned. A write with a lost response may be retried idempotently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets":{"get":{"operationId":"listChangeSets","summary":"List your change sets","x-required-scope":"changes:read","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["OPEN","APPLIED","DISCARDED"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"cursor","in":"query","schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeSetPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"createChangeSet","summary":"Open a change set","description":"Holds proposed changes until you apply them in the Staff room (reviewUrl). At most 20 open sets per person.","x-required-scope":"changes:write","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per logical request (8 to 128 of A-Z a-z 0-9 _ . : -). Retrying with the same key and body within 24 hours replays the first response.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}},{"name":"X-Trellia-Client","in":"header","required":false,"description":"mcp or cli. Recorded as the change's surface; it never changes access.","schema":{"type":"string","enum":["mcp","cli","api"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChangeSet"}}}},"responses":{"201":{"description":"Proposed. Nothing is live until applied.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeSet"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}":{"get":{"operationId":"getChangeSet","summary":"Read one of your change sets with its items and previews","x-required-scope":"changes:read","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeSet"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}/items":{"post":{"operationId":"proposeChange","summary":"Propose a create, edit or archive in an open change set","description":"UPDATE data is a partial record merged onto the live record. ARCHIVE moves the record and its link rows to the archive, where it can be restored. The item's preview shows the field-level before and after. Also needs the area's write scope, for example portfolio_updates:write. Any other Staff room action is proposed with entity staff_action and data { action, input }; list the allowed actions, their input schemas and the operation each takes with GET /staff-actions.","x-required-scope":"changes:write","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per logical request (8 to 128 of A-Z a-z 0-9 _ . : -). Retrying with the same key and body within 24 hours replays the first response.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}},{"name":"X-Trellia-Client","in":"header","required":false,"description":"mcp or cli. Recorded as the change's surface; it never changes access.","schema":{"type":"string","enum":["mcp","cli","api"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposeChange"}}}},"responses":{"201":{"description":"Proposed. Nothing is live until applied.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeItem"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}/items/{itemId}":{"delete":{"operationId":"removeProposedChange","summary":"Remove a proposal from an open change set","description":"Deletes one waiting proposal. Removing the last one leaves the change set open and empty, so a replacement can be proposed into it; when nothing follows, close it with POST /change-sets/{changeSetId}/discard.","x-required-scope":"changes:write","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeSet"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}/items/{itemId}/revise":{"post":{"operationId":"reviseChange","summary":"Revise a waiting or rejected change after review feedback","description":"Replaces the change's data (same record and operation) and puts it back to waiting. Read reviewNote on rejected items first. For UPDATE, data is the changed fields.","x-required-scope":"changes:write","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per logical request (8 to 128 of A-Z a-z 0-9 _ . : -). Retrying with the same key and body within 24 hours replays the first response.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}},{"name":"X-Trellia-Client","in":"header","required":false,"description":"mcp or cli. Recorded as the change's surface; it never changes access.","schema":{"type":"string","enum":["mcp","cli","api"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviseChange"}}}},"responses":{"201":{"description":"Proposed. Nothing is live until applied.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeItem"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}/discard":{"post":{"operationId":"discardChangeSet","summary":"Discard an open change set","description":"Withdraws one of your own open change sets: it becomes DISCARDED and can no longer be applied or changed. Use it for a set you emptied or no longer want.","x-required-scope":"changes:write","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per logical request (8 to 128 of A-Z a-z 0-9 _ . : -). Retrying with the same key and body within 24 hours replays the first response.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}},{"name":"X-Trellia-Client","in":"header","required":false,"description":"mcp or cli. Recorded as the change's surface; it never changes access.","schema":{"type":"string","enum":["mcp","cli","api"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Empty"}}}},"responses":{"201":{"description":"Proposed. Nothing is live until applied.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeSet"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}/revert":{"post":{"operationId":"proposeRevert","summary":"Propose undoing an applied change set","description":"Creates a new change set that undoes the applied one, for you to review and apply. Refused if any record changed since, or after the 90-day revert window.","x-required-scope":"changes:write","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per logical request (8 to 128 of A-Z a-z 0-9 _ . : -). Retrying with the same key and body within 24 hours replays the first response.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}},{"name":"X-Trellia-Client","in":"header","required":false,"description":"mcp or cli. Recorded as the change's surface; it never changes access.","schema":{"type":"string","enum":["mcp","cli","api"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposeRevert"}}}},"responses":{"201":{"description":"Proposed. Nothing is live until applied.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeSet"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/change-sets/{changeSetId}/restores":{"post":{"operationId":"proposeRestore","summary":"Propose restoring an archived record with its original ids","x-required-scope":"changes:write","parameters":[{"name":"changeSetId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per logical request (8 to 128 of A-Z a-z 0-9 _ . : -). Retrying with the same key and body within 24 hours replays the first response.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}},{"name":"X-Trellia-Client","in":"header","required":false,"description":"mcp or cli. Recorded as the change's surface; it never changes access.","schema":{"type":"string","enum":["mcp","cli","api"]}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposeRestore"}}}},"responses":{"201":{"description":"Proposed. Nothing is live until applied.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ChangeItem"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/staff-actions":{"get":{"operationId":"listStaffActions","summary":"List the Staff room actions that can be proposed","description":"Each action is proposed as an item with entity staff_action, the listed operation and data { action, input }, where input follows the action's own inputSchema (dates are ISO strings). The action runs as the person who approves it, with the Staff room's own validation. Full Trellia and InvestSense staff only.","x-required-scope":"changes:read","parameters":[],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/StaffActionList"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/archive":{"get":{"operationId":"listArchivedRecords","summary":"List archived records that can be restored","x-required-scope":"changes:read","parameters":[{"name":"entity","in":"query","schema":{"type":"string","pattern":"^[a-z_]{1,64}$"}},{"name":"entityId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ArchivePage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-updates":{"get":{"operationId":"listPortfolioUpdates","summary":"List portfolio updates, including drafts","description":"Without sort: newest id first with an id cursor (the original behaviour). sort=date_desc or updated_asc use an opaque keyset cursor bound to every filter; updated_asc orders by (updatedAt, id) and updatedSince is inclusive, so re-read the boundary and de-duplicate. include=content returns the HTML as stored (limit at most 25). A service principal reads published updates only; published=false is 403.","x-required-scope":"portfolio_updates:read","parameters":[{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"published","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"suiteSlug","in":"query","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"dateFrom","in":"query","schema":{"type":"string","format":"date"}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date"}},{"name":"slug","in":"query","description":"Exact slug.","schema":{"type":"string","minLength":1,"maxLength":160}},{"name":"updatedSince","in":"query","description":"Inclusive; an ISO-8601 timestamp with an offset.","schema":{"type":"string","format":"date-time"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["date_desc","updated_asc"]}},{"name":"include","in":"query","description":"Comma-separated: content, thumbnail.","schema":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["content","thumbnail"]}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page; keep every filter unchanged. Without sort it is the last id.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioUpdateListPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"x-cost":3}},"/portfolio-updates/{portfolioUpdateId}":{"get":{"operationId":"getPortfolioUpdate","summary":"Read a portfolio update in the shape change proposals use","description":"expand=links adds suites, categories, authors (id and name) and portfolios. A service principal cannot read a draft: it is a 404.","x-required-scope":"portfolio_updates:read","parameters":[{"name":"portfolioUpdateId","in":"path","required":true,"schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"expand","in":"query","schema":{"type":"string","enum":["links"]}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioUpdateDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or your Staff room access does not cover this area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"The change set is not open, a record changed since, or a revert conflicts.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"The proposed data is invalid, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or change-set limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable; retry with the same Idempotency-Key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"x-cost":1}},"/imports":{"post":{"operationId":"startImport","summary":"Start a bulk import","description":"Returns a presigned PUT (10 minutes, size and SHA-256 signed) into api-imports/<userId>/<importId>/, or a chunks URL when delivery is chunks, or nothing for server-side kinds. Needs the <kind>:import scope and full staff access.","x-required-scope":"changes:write","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartImport"}}}},"responses":{"201":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/StartedImport"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Not Trellia or InvestSense staff, missing the <kind>:import scope for the kind, or no Staff room access to the area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Already submitted, or a chunk was replayed with different rows.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid input, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Import quota reached (20 a day, 3 in flight).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/imports/{importId}/chunks":{"post":{"operationId":"appendImportChunk","summary":"Push a chunk of JSON rows","description":"Chunks are sent in order from seq 0, at most 2,000 rows and 400 KiB each. Replaying the same chunk is harmless.","x-required-scope":"changes:write","parameters":[{"name":"importId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportChunk"}}}},"responses":{"201":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ImportChunkAck"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Not Trellia or InvestSense staff, missing the <kind>:import scope for the kind, or no Staff room access to the area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Already submitted, or a chunk was replayed with different rows.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid input, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Import quota reached (20 a day, 3 in flight).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/imports/{importId}/submit":{"post":{"operationId":"submitImport","summary":"Queue staging of an import","description":"Returns 202 with a job to poll. The worker waits for the malware scan (fail closed), validates, diffs against live data and attaches one import item to the change set for review.","x-required-scope":"changes:write","parameters":[{"name":"importId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{8,128}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitImport"}}}},"responses":{"202":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/SubmittedImport"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Not Trellia or InvestSense staff, missing the <kind>:import scope for the kind, or no Staff room access to the area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Already submitted, or a chunk was replayed with different rows.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid input, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Import quota reached (20 a day, 3 in flight).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/jobs/{jobId}":{"get":{"operationId":"getJob","summary":"Read the status of one of your jobs","x-required-scope":"changes:read","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ImportJob"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request, body, Idempotency-Key or parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Not Trellia or InvestSense staff, missing the <kind>:import scope for the kind, or no Staff room access to the area.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Already submitted, or a chunk was replayed with different rows.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid input, or the Idempotency-Key was reused for a different request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Import quota reached (20 a day, 3 in flight).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/periods":{"get":{"operationId":"listPerformanceReportPeriods","summary":"The month ends the control panel offers, and the default","x-required-scope":"performance_reports:read","parameters":[],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportPeriods"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/readiness":{"get":{"operationId":"getPerformanceReportReadiness","summary":"The readiness matrix for a month end","description":"One row per covered portfolio by company and suite, with each data point's status (GREEN, AMBER, RED, NOT_APPLICABLE) and what to fix.","x-required-scope":"performance_reports:read","parameters":[{"name":"periodEnd","in":"query","required":true,"description":"A month end (yyyy-MM-dd); GET /performance-reports/periods lists them.","schema":{"type":"string","format":"date"}},{"name":"companyId","in":"query","required":false,"description":"Only this company's portfolios.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportReadiness"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/companies":{"get":{"operationId":"listPerformanceReportCompanies","summary":"Companies with reportable portfolios and their override counts","x-required-scope":"performance_reports:read","parameters":[],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportCompanies"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/companies/{companyId}/settings":{"get":{"operationId":"getPerformanceReportSettings","summary":"A company's settings grid: effective values and their source","x-required-scope":"performance_reports:read","parameters":[{"name":"companyId","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportSettings"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/companies/{companyId}/disclaimers":{"get":{"operationId":"getPerformanceReportDisclaimers","summary":"A company's report disclaimer and per-platform overrides","x-required-scope":"performance_reports:read","parameters":[{"name":"companyId","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportDisclaimers"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/comparators":{"get":{"operationId":"listPerformanceReportComparators","summary":"Portfolios with their current objective, benchmark and peer group","x-required-scope":"performance_reports:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"companyId","in":"query","required":false,"description":"Only this company's portfolios.","schema":{"type":"integer","minimum":1}},{"name":"suiteId","in":"query","required":false,"description":"Only this suite's portfolios.","schema":{"type":"integer","minimum":1}},{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportComparatorPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/comparators/{portfolioId}":{"get":{"operationId":"getPerformanceReportComparatorHistory","summary":"One portfolio's whole comparator history","x-required-scope":"performance_reports:read","parameters":[{"name":"portfolioId","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportComparatorHistory"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/series":{"get":{"operationId":"listPerformanceReportSeries","summary":"Report series with their latest observation date","x-required-scope":"performance_reports:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"kind","in":"query","schema":{"type":"string","enum":["INDEX","MACRO","FUND","PEER_GROUP","DERIVED"]}},{"name":"activeOnly","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportSeriesPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/benchmarks":{"get":{"operationId":"getPerformanceReportBenchmarks","summary":"Attribution benchmarks: per asset class and composite weights","x-required-scope":"performance_reports:read","parameters":[],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportBenchmarks"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/commentary":{"get":{"operationId":"getPerformanceReportCommentary","summary":"The commentary a portfolio's report would show for a month end","description":"The market and portfolio text with where each comes from (override, generated, formulaic, suppressed), the stored generated text and the attribution behind it.","x-required-scope":"performance_reports:read","parameters":[{"name":"portfolioId","in":"query","required":true,"description":"The portfolio.","schema":{"type":"integer","minimum":1}},{"name":"periodEnd","in":"query","required":true,"description":"A month end (yyyy-MM-dd); GET /performance-reports/periods lists them.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportCommentary"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/generated":{"get":{"operationId":"listGeneratedPerformanceReports","summary":"Generated reports for a month end, newest first","x-required-scope":"performance_reports:read","parameters":[{"name":"periodEnd","in":"query","required":true,"description":"A month end (yyyy-MM-dd); GET /performance-reports/periods lists them.","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"status","in":"query","schema":{"type":"string","enum":["PENDING","READY","FAILED"]}},{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/GeneratedPerformanceReportPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/generated/{reportId}":{"get":{"operationId":"getGeneratedPerformanceReport","summary":"A generated report's status and stored file key","x-required-scope":"performance_reports:read","parameters":[{"name":"reportId","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/GeneratedPerformanceReportStatus"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/uploads":{"get":{"operationId":"listPerformanceReportUploads","summary":"Performance data uploads, newest first","x-required-scope":"performance_reports:read","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"status","in":"query","schema":{"type":"string","enum":["VALIDATING","READY_TO_COMMIT","COMMITTED","FAILED","DISCARDED"]}},{"name":"template","in":"query","schema":{"type":"string","enum":["INDEX_LEVELS","INDEX_RETURNS","FUND_MONTHLY_RETURNS","DISCRETE_RETURNS","CPI_ESTIMATE","COMPOSITE_RETURNS"]}},{"name":"search","in":"query","schema":{"type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportUploadPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/performance-reports/feeds":{"get":{"operationId":"listPerformanceReportFeeds","summary":"Scheduled data feeds, whether each is on, and its last run","x-required-scope":"performance_reports:read","parameters":[],"responses":{"200":{"description":"Successful scoped operation.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PerformanceReportFeeds"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid query or path parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired or revoked credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Insufficient scope, or not Trellia or InvestSense staff with Performance reports access.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is too large; filter or page the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit reached.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-holdings":{"get":{"operationId":"listPortfolioHoldings","summary":"Read holdings for up to 25 portfolios in one page","description":"Each portfolio is read at its own latest snapshot on or before asOf, or only at the exact dates in exactDates (no fallback). White-label holdings inheritance is resolved server-side. Weights are exact decimal fractions (0.05 is 5%). Rows are ordered by (portfolioId, holdingId) with a keyset cursor that pins each portfolio's snapshot date. Unclassified rows keep null classification. The platform-cash identifier rewrite is not applied.","x-required-scope":"portfolios:read","x-cost":3,"parameters":[{"name":"portfolioIds","in":"query","description":"Comma-separated portfolio ids, at most 25. An unknown, inactive or not entitled id is absent from the response.","schema":{"type":"array","minItems":1,"maxItems":25,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}},{"name":"exactDates","in":"query","description":"Only snapshots on exactly these dates. Cannot be combined with asOf.","schema":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"string","format":"date"}},"style":"form","explode":false},{"name":"include","in":"query","description":"classification adds assetClass, subAssetClass (the holding's own), effectiveSubAssetClass (strategy-overridden), strategyId, growthAsset and securityId; nested adds nestedPortfolioId (the live active portfolio whose code equals the identifier).","schema":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["classification","nested"]}},"style":"form","explode":false},{"name":"weightGt0","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioHoldingsBulk"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-holdings/dates":{"get":{"operationId":"listPortfolioHoldingDates","summary":"List holding snapshot dates for up to 100 portfolios","description":"Newest first, resolved through white-label holdings inheritance. Registered at cost 3 for any number of ids.","x-required-scope":"portfolios:read","x-cost":3,"parameters":[{"name":"portfolioIds","in":"query","description":"Comma-separated portfolio ids, at most 100. An unknown, inactive or not entitled id is absent from the response.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"before","in":"query","description":"Only dates strictly before this one.","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":366,"default":60}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioHoldingDates"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-saa":{"get":{"operationId":"listPortfolioSaa","summary":"Read strategic asset allocation ranges for up to 100 portfolios","description":"Per asset class, the latest row on or before asOf (today when omitted). White-label inherit_saa is resolved server-side. Bounds are percent; a missing bound is null. Rows are ordered by (portfolioId, assetClassId) with a keyset cursor.","x-required-scope":"portfolios:read","x-cost":3,"parameters":[{"name":"portfolioIds","in":"query","description":"Comma-separated portfolio ids, at most 100. An unknown, inactive or not entitled id is absent from the response.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":500}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioSaa"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-performance":{"get":{"operationId":"listPortfolioPerformance","summary":"Read latest period performance for up to 100 portfolios","description":"Items are as GET /portfolios/{portfolioId}/performance. Values are percentage points as decimal strings. An unknown or not entitled id is absent; missing data is explicitly unavailable, never zero.","x-required-scope":"portfolios:read","x-cost":3,"parameters":[{"name":"ids","in":"query","description":"Portfolio ids, at most 100.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"The latest month-end snapshot on or before this date.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioPerformanceBatch"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolios/{portfolioId}/lookthrough":{"get":{"operationId":"getPortfolioLookthrough","summary":"Look through a portfolio to its underlying securities","description":"Requires portfolios:read. Full staff read every active portfolio; other readers read portfolios they are entitled to, checked live. A portfolio that is unknown or not accessible is a 404. Expands nested portfolios (at most maxDepth levels, root included), looks each fund through to its freshest disclosure (the fund or its non-terminated strategy siblings), and passes direct stocks straight through. Weights are exact decimal fractions (0.05 is 5%). A disclosure stored as percent is converted to a fraction. coverage and unresolved describe the whole portfolio, not the page, and are repeated on every page. A cursor is pinned to the snapshot and to the disclosures used; if either changes between pages the next page is a 409 (dataset_changed). A request too large to answer in time is a 400 (dataset_limit): narrow it. Heavy read, cost 10.","x-required-scope":"portfolios:read","x-cost":10,"parameters":[{"name":"portfolioId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}},{"name":"maxDepth","in":"query","description":"Levels of nested portfolios to expand, the root counting as level 1.","schema":{"type":"integer","minimum":1,"maximum":4,"default":4}},{"name":"groupBy","in":"query","schema":{"type":"string","enum":["leaf","security","sector","country"],"default":"security"}},{"name":"security","in":"query","description":"Keep only constituents whose ISIN or name contains this text (case-insensitive).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}},{"name":"include","in":"query","description":"security adds exchangeCode, cusip, sedol and countryIso to groupBy=security items. groupBy=leaf always carries them.","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["security"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioLookthrough"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-lookthrough":{"get":{"operationId":"getPortfoliosLookthrough","summary":"Look through up to 10 portfolios in one call","description":"Requires portfolios:read, with the same entitlement as GET /portfolios: a requested portfolio the caller cannot read, or that does not exist, is simply absent (never an error). Each portfolio is the GET /portfolios/{portfolioId}/lookthrough result with the same parameters; a white-label portfolio is looked through once per source portfolio (sourcePortfolioId, inherited). Weights are exact decimal fractions (0.05 is 5%). A disclosure stored as percent is converted to a fraction. portfolios lists a summary for each portfolio this page covers; items carry their portfolioId, in portfolio id order then row key, at most limit rows across all portfolios and at most the single endpoint's page cap from any one portfolio (500 for groupBy=security, 1000 for leaf), and at most ceil(limit / that cap) portfolios per page, the one a cursor resumes inside included (limit=5000 covers all 10 security portfolios). The cursor is pinned to these parameters, and inside a portfolio to its snapshot and disclosures (409 dataset_changed if they change). A page that would be larger than the response cap, or that runs short of time, ends early with the portfolios already done and a nextCursor instead of failing; the first portfolio of a page always progresses or fails as the single endpoint does (400 dataset_limit). Heavy read, costed as the single calls it replaces: 10 for each portfolio the page works on, that is each distinct requested portfolio from the cursor's onward (all of them on the first page, the resumed one included), at most ceil(limit / cap), and never less than 10.","x-required-scope":"portfolios:read","x-cost":10,"parameters":[{"name":"portfolioIds","in":"query","description":"Portfolio ids; duplicates are ignored.","schema":{"type":"array","minItems":1,"maxItems":10,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}},{"name":"maxDepth","in":"query","description":"Levels of nested portfolios to expand, the root counting as level 1.","schema":{"type":"integer","minimum":1,"maximum":4,"default":4}},{"name":"groupBy","in":"query","schema":{"type":"string","enum":["leaf","security"],"default":"security"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":5000,"default":1000}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}},{"name":"include","in":"query","description":"security adds exchangeCode, cusip, sedol and countryIso to groupBy=security items. groupBy=leaf always carries them.","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["security"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/BulkPortfolioLookthrough"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/investments/lookthrough":{"get":{"operationId":"getInvestmentsLookthrough","summary":"Read the constituents of up to 100 investments","description":"Requires funds:read. Full staff read the investment catalogue; fund managers read funds owned by their company. Unknown or inaccessible identifiers are absent from the response. Each identifier resolves to its freshest disclosure (itself or a non-terminated strategy sibling); disclosureDate says which. Weights are exact decimal fractions (0.05 is 5%). A disclosure stored as percent is converted to a fraction. groupBy=sector and country are pre-aggregated per identifier, with a null label for constituents without a classification or security link. Heavy read, cost 10.","x-required-scope":"funds:read","x-cost":10,"parameters":[{"name":"identifiers","in":"query","description":"Investment identifiers (APIR codes or tickers), case-insensitive; the 2048 character query limit applies.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":40}},"style":"form","explode":false},{"name":"groupBy","in":"query","schema":{"type":"string","enum":["constituent","sector","country"],"default":"constituent"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/InvestmentLookthrough"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/holdings/holders":{"get":{"operationId":"listHoldingsHolders","summary":"List the portfolios that hold an instrument now","description":"Requires portfolios:read. Full staff read every active portfolio; other readers read portfolios they are entitled to, checked live. A portfolio that is unknown or not accessible is a 404. A portfolio is listed when its latest snapshot on or before today holds a matching investment above zero. A match is the investment whose identifier equals identifier, an investment linked to a security with that ISIN or exchange code, or any investment of a strategyId. CASH and AUD match both. Provide identifier, strategyId or both. An unknown identifier is an empty page. White-label portfolios are listed only for holdings of their own. With include=weight each item adds platformName and weight (summed over the matching top-level holdings); full staff may then page 500 at a time, others 100. Ordered by portfolio code. Heavy read, cost 10.","x-required-scope":"portfolios:read","x-cost":10,"parameters":[{"name":"identifier","in":"query","description":"APIR code, ISIN or ticker; case-insensitive, exact.","schema":{"type":"string","minLength":1,"maxLength":40}},{"name":"strategyId","in":"query","description":"Strategy ids whose investments all match.","schema":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"string","pattern":"^[1-9][0-9]{0,9}$"}},"style":"form","explode":false},{"name":"include","in":"query","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["weight"]}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":50}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/HoldersPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/investments":{"get":{"operationId":"listInvestments","summary":"Look up investments (the holding-detail catalogue)","description":"Every investment, including cash, direct securities and ETFs that have no strategy. Look up by identifier, id or search; duplicates of one identifier are all returned, live before terminated, classified first, newest id first, and the first is the match. Unknown identifiers are absent. Adviser-owned unlisted holdings are never returned. include=classification adds the sub-asset class, asset class, growth flag, effective sub-asset class (the investment's own, else its strategy's) and valuation classification; strategyMembers lists the identifiers of the strategy's funds; holdingsSummary reads the maintained summary; security needs securities:read too. Requires reference:read. The cursor is bound to every filter: reusing it with different filters is a 400.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"identifiers","in":"query","description":"Exact identifiers, case-insensitive. The 2048 character query limit applies.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":120}},"style":"form","explode":false},{"name":"ids","in":"query","description":"Holding-detail ids.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"search","in":"query","description":"Case-insensitive contains match.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"includeTerminated","in":"query","description":"Include terminated investments. Default false.","schema":{"type":"boolean"}},{"name":"subAssetClass","in":"query","description":"Exact sub-asset class name, case-insensitive.","schema":{"type":"string","maxLength":100}},{"name":"include","in":"query","description":"Optional blocks to add to each item.","schema":{"type":"array","minItems":1,"maxItems":6,"items":{"type":"string","enum":["classification","strategy","company","strategyMembers","holdingsSummary","security"]}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceInvestmentPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/investments/fixed-interest":{"get":{"operationId":"listLatestFixedInterest","summary":"Latest fixed-interest snapshot per fund","description":"The newest stored snapshot (credit, region and sector buckets, durations, yield) for each identifier. Values are returned exactly as stored: the portal holds some funds as percent and some as fractions, and scaleDetected says which. Unknown identifiers and funds without a snapshot are absent. Requires reference:read.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"identifiers","in":"query","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":120}},"style":"form","explode":false,"required":true}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceFixedInterestLatest"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/investments/{investmentId}/fixed-interest/history":{"get":{"operationId":"listFixedInterestHistory","summary":"Fixed-interest snapshot history of one investment","description":"Every stored snapshot, oldest first, as stored (see scaleDetected). Requires reference:read. The cursor is bound to every filter: reusing it with different filters is a 400.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"investmentId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"from","in":"query","description":"First snapshot date to return.","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceFixedInterestHistory"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/funds/holding-dates":{"get":{"operationId":"getFundHoldingDates","summary":"Latest holdings date per fund, with strategy siblings","description":"For each requested identifier, the latest holdings snapshot date (security-level or fixed-interest) across the fund and its live strategy siblings, and the sibling identifiers (the fund itself when it has no strategy). Null means no snapshot. Every requested identifier is a key. Requires funds:read.","x-required-scope":"funds:read","x-cost":3,"parameters":[{"name":"identifiers","in":"query","schema":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"string","minLength":1,"maxLength":120}},"style":"form","explode":false,"required":true}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceFundHoldingDates"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/reference/structure":{"get":{"operationId":"getReferenceStructure","summary":"Platforms, suites and the latest holdings dates","description":"Platforms, live suites with their company and active portfolio count, and the latest portfolio and fund holdings dates. Changes rarely: clients may cache it for 10 minutes. Requires reference:read.","x-required-scope":"reference:read","x-cost":1,"parameters":[],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceStructure"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/reference/taxonomy":{"get":{"operationId":"getReferenceTaxonomy","summary":"Asset classes, sub-asset classes and valuation classifications","description":"Requires reference:read.","x-required-scope":"reference:read","x-cost":1,"parameters":[],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceTaxonomy"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/reference/pds":{"get":{"operationId":"listReferencePds","summary":"Product disclosure statement links","description":"The latest PDS per suite and platform pair (latest=true, the default) or every link (latest=false, at most 1000). Only public http or https document links are returned. Several platforms are a comma-separated platformId list. A portfolioCode narrows to that portfolio's suite and platform. Requires reference:read.","x-required-scope":"reference:read","x-cost":1,"parameters":[{"name":"suiteId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"platformId","in":"query","schema":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"portfolioCode","in":"query","schema":{"type":"string","maxLength":40}},{"name":"latest","in":"query","description":"Default true.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferencePds"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/companies":{"get":{"operationId":"listCompanies","summary":"List companies","description":"Name order. No contacts, staff or financials. activePortfolioCount counts active, not deleted portfolios in the company's live suites. includeTotal adds a capped totalCount to the first page. Requires reference:read. The cursor is bound to every filter: reusing it with different filters is a 400.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"search","in":"query","description":"Case-insensitive contains match.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"companyType","in":"query","schema":{"type":"string","enum":["Flagship","Bespoke","FundManager","Distributor"]}},{"name":"hasPortfolios","in":"query","schema":{"type":"boolean"}},{"name":"includeDeleted","in":"query","description":"Include deleted companies. Default false.","schema":{"type":"boolean"}},{"name":"includeTotal","in":"query","description":"Add a capped totalCount to the first page.","schema":{"type":"boolean"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceCompanyPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/suites":{"get":{"operationId":"listSuites","summary":"List live suites","description":"Id order; deleted suites are excluded. Requires reference:read. The cursor is bound to every filter: reusing it with different filters is a 400.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceSuitePage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/platforms":{"get":{"operationId":"listPlatforms","summary":"List platforms","description":"Id order. Requires reference:read. The cursor is bound to every filter: reusing it with different filters is a 400.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferencePlatformPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/strategies":{"get":{"operationId":"listStrategies","summary":"List fund strategies","description":"Name order. childFundCount counts live funds. primaryFund is the live fund with the most holding rows, then the latest holdings date, then the lowest id. Requires reference:read. The cursor is bound to every filter: reusing it with different filters is a 400.","x-required-scope":"reference:read","x-cost":3,"parameters":[{"name":"search","in":"query","description":"Case-insensitive contains match.","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"companyType","in":"query","schema":{"type":"string","enum":["Flagship","Bespoke","FundManager","Distributor"]}},{"name":"assetClass","in":"query","description":"Asset class names, case-insensitive.","schema":{"type":"array","minItems":1,"maxItems":20,"items":{"type":"string","maxLength":100}},"style":"form","explode":false},{"name":"include","in":"query","description":"Optional blocks to add to each item.","schema":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["primaryFund","subAssetClass"]}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceStrategyPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/valuation-dashboard":{"get":{"operationId":"getValuationDashboard","summary":"Valuation dashboard by classification","description":"Each classification's latest row on or before the as-of date (asOfDate is the latest dashboard date on or before asOf). includePrior adds each classification's row on or before the latest dashboard date at least three months earlier (priorDate). All figures are percent. Requires reference:read.","x-required-scope":"reference:read","x-cost":1,"parameters":[{"name":"asOf","in":"query","schema":{"type":"string","format":"date"}},{"name":"includePrior","in":"query","schema":{"type":"boolean"}},{"name":"classification","in":"query","description":"A classification id, or its name (case-insensitive).","schema":{"type":"string","maxLength":100}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceValuationDashboard"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/valuation-dashboard/dates":{"get":{"operationId":"listValuationDashboardDates","summary":"Valuation dashboard dates","description":"Newest first. Requires reference:read.","x-required-scope":"reference:read","x-cost":1,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ReferenceValuationDates"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-fees":{"get":{"operationId":"getPortfolioFees","summary":"Read the latest portfolio fees for up to 100 portfolios","description":"Trellia and InvestSense staff with the live Staff room fee permission only. Not available to service principals. Returns the latest fee row on or before asOf for each live portfolio, resolving white-label fee inheritance server-side (inherited and sourcePortfolioId say so). All fees are decimal fractions (0.0075 is 0.75%). A portfolio that is not in the catalogue, or has no fee row, is absent from items. Requires fees:read.","x-required-scope":"fees:read","x-cost":3,"parameters":[{"name":"portfolioIds","in":"query","description":"Portfolio ids, comma separated (at most 100; the query string is capped at 2048 characters).","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioFees"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/investment-fees":{"get":{"operationId":"getInvestmentFees","summary":"Read the latest PDS fees for investments","description":"Trellia and InvestSense staff with the live Staff room fee permission only. Not available to service principals. Use exactly one of identifiers, ids, or strategyLinked=true (universe mode, paged by limit and cursor). Fees are the newest row on or before asOf, matched on the investment's fund_id or APIR code. All investment fees are percent (0.75 is 0.75%). An unknown identifier, or an investment with no fee row, is omitted, never zero. Adviser-owned unlisted holdings are never returned. include=strategyBenchmark adds the most expensive current member of the investment's strategy and every priced member, so a client can apply its own unit-class exclusion. Requires fees:read.","x-required-scope":"fees:read","x-cost":3,"parameters":[{"name":"identifiers","in":"query","description":"Investment identifiers (APIR, ticker or code), comma separated, case-insensitive.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":120}},"style":"form","explode":false},{"name":"ids","in":"query","description":"Investment (holding-detail) ids, comma separated.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}},{"name":"include","in":"query","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["strategyBenchmark"]}},"style":"form","explode":false},{"name":"strategyLinked","in":"query","description":"Universe mode: every non-terminated, strategy-linked investment that has a fee row, id ordered.","schema":{"type":"boolean","enum":[true]}},{"name":"includeTerminated","in":"query","description":"Universe mode only. Terminated investments are never returned.","schema":{"type":"boolean","enum":[false]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/InvestmentFees"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fee-insights":{"get":{"operationId":"getFeeInsights","summary":"Cheaper same-strategy alternatives and rebate benchmarks","description":"Trellia and InvestSense staff with the live Staff room fee permission only. Not available to service principals. Needs both fees:read and rebates:read; the registered scope is fees:read and a key without rebates:read is refused. Keys are the identifiers trimmed and upper-cased; an identifier with no insight is absent, so a client treats absence as no opportunity. cheaperAlternatives are in percent, rebateBenchmarks in decimal fractions. Computed from live data on each request. Requires fees:read and rebates:read.","x-required-scope":"fees:read","x-cost":3,"parameters":[{"name":"identifiers","in":"query","description":"Investment identifiers, comma separated.","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","minLength":1,"maxLength":120}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FeeInsights"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/rebates":{"get":{"operationId":"getRebates","summary":"Read negotiated rebates and the highest stored rebate","description":"Trellia and InvestSense staff with the live Staff room rebates permission only. Not available to service principals. items holds the latest rebate on or before asOf for each (portfolio, holding-detail) pair among live portfolios. maxima holds, per holding-detail, the highest rebate ever stored across all portfolios and dates (it ignores asOf). Amounts are decimal fractions (0.0010 is 0.10%). The page is a slice of holdingDetailIds ordered by id: when a response is too large, lower limit and retry the same cursor. Provide portfolioIds, or includeMaximum=true for maxima alone. Requires rebates:read, which fees:read does not imply.","x-required-scope":"rebates:read","x-cost":3,"parameters":[{"name":"holdingDetailIds","in":"query","description":"Investment (holding-detail) ids, comma separated.","schema":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"portfolioIds","in":"query","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"asOf","in":"query","description":"Latest snapshot on or before this date; omit for the latest available.","schema":{"type":"string","format":"date"}},{"name":"includeMaximum","in":"query","description":"Include the highest stored rebate per holding-detail.","schema":{"type":"boolean","default":true}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":200}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/RebatesResponse"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/securities":{"get":{"operationId":"listSecurities","summary":"Search and list FactSet securities","description":"Relevance-ranked search (exact ticker or identifier, ordinary equities, then hybrids and debt; the ASX line first among equals), identifier lookups, or an (updatedAt, id) change feed with updatedSince. Keyset paged; totalCount is on page one only and capped at 10000. No holdings are returned.","x-required-scope":"securities:read","x-cost":3,"parameters":[{"name":"search","in":"query","description":"Substring of name, ISIN, CUSIP, SEDOL or exchange code.","schema":{"type":"string","maxLength":100}},{"name":"isin","in":"query","schema":{"type":"string","pattern":"^[A-Za-z0-9]{12}$"}},{"name":"isins","in":"query","schema":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","pattern":"^[A-Za-z0-9]{12}$"}},"style":"form","explode":false},{"name":"ids","in":"query","schema":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"style":"form","explode":false},{"name":"exchangeCode","in":"query","schema":{"type":"string","maxLength":40}},{"name":"updatedSince","in":"query","description":"Inclusive. Orders by (updatedAt, id) ascending.","schema":{"type":"string","format":"date-time"}},{"name":"include","in":"query","description":"marketData returns the latest price, market cap, consensus and fundamentals the retired security_factset_latest view carried.","schema":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["references","latestPrice","marketData"]}},"style":"form","explode":false},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/SecurityPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/securities/{securityId}":{"get":{"operationId":"getSecurity","summary":"Get one FactSet security","description":"include defaults to references and latestPrice.","x-required-scope":"securities:read","x-cost":1,"parameters":[{"name":"securityId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"include","in":"query","schema":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"string","enum":["references","latestPrice"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/Security"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/securities/{securityId}/research":{"get":{"operationId":"getSecurityResearch","summary":"Get FactSet research for a security","description":"Latest fundamentals, consensus, broker estimates and ratings, and target prices, read in one transaction. include defaults to fundamentals, consensus and targetPrices. Buy, hold and sell bucketing and upside stay with the caller.","x-required-scope":"securities:research:read","x-cost":3,"parameters":[{"name":"securityId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"include","in":"query","schema":{"type":"array","minItems":1,"maxItems":5,"items":{"type":"string","enum":["fundamentals","consensus","brokerEstimates","brokerRatings","targetPrices"]}},"style":"form","explode":false},{"name":"ratingsWindowDays","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":90}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/SecurityResearch"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/research-notes":{"get":{"operationId":"listResearchNotes","summary":"List meeting notes and IC minutes","description":"Sanitised notes only: notes without sanitised text are excluded and the raw transcript is never read. Newest first by (date, id), or oldest change first with updatedSince. With no scoping filter only the last 24 months are read (windowFrom says so). totalCount is on page one. fields=date returns only id and date (the last-IC anchor). include=body adds the sanitised transcript (clipped at 200000 characters). The audit row records counts, never text.","x-required-scope":"research:read","x-cost":3,"parameters":[{"name":"type","in":"query","description":"ic (the Investment Committee), or a meeting type name in any case, for example fund_manager. Exact match; fund_manager is only FUND_MANAGER.","schema":{"type":"string","maxLength":60}},{"name":"companyId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"company","in":"query","description":"Company name contains, or the note title contains it.","schema":{"type":"string","maxLength":100}},{"name":"fundIdentifier","in":"query","description":"An investment identifier (APIR code or ticker) the note is related to, directly or through its strategy.","schema":{"type":"string","maxLength":40}},{"name":"titleSearch","in":"query","schema":{"type":"string","maxLength":100}},{"name":"dateFrom","in":"query","schema":{"type":"string","format":"date"}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date"}},{"name":"updatedSince","in":"query","description":"Inclusive. Switches the order to updatedAt ascending, then id; re-read the boundary and de-duplicate.","schema":{"type":"string","format":"date-time"}},{"name":"summaryOnly","in":"query","description":"Return a longer summary (4000 characters) instead of the 600 character default.","schema":{"type":"boolean"}},{"name":"maxChars","in":"query","description":"Clips each returned summary (and body) to this many characters.","schema":{"type":"integer","minimum":1,"maximum":200000}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":25,"default":10}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}},{"name":"fields","in":"query","schema":{"type":"string","enum":["date"]}},{"name":"include","in":"query","schema":{"type":"array","minItems":1,"maxItems":1,"items":{"type":"string","enum":["body"]}},"style":"form","explode":false}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ResearchNotePage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/research-notes/search":{"get":{"operationId":"searchResearchNotes","summary":"Search meeting notes and IC minutes by text","description":"The list filters plus a text match (at least 3 characters) in the summary, sanitised transcript and title. Each item says where it matched and carries a short snippet. Heavy: cost 10.","x-required-scope":"research:read","x-cost":10,"parameters":[{"name":"text","in":"query","required":true,"description":"Text to find, matched case-insensitively and literally.","schema":{"type":"string","minLength":3,"maxLength":100}},{"name":"type","in":"query","description":"ic (the Investment Committee), or a meeting type name in any case, for example fund_manager. Exact match; fund_manager is only FUND_MANAGER.","schema":{"type":"string","maxLength":60}},{"name":"companyId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"company","in":"query","description":"Company name contains, or the note title contains it.","schema":{"type":"string","maxLength":100}},{"name":"fundIdentifier","in":"query","description":"An investment identifier (APIR code or ticker) the note is related to, directly or through its strategy.","schema":{"type":"string","maxLength":40}},{"name":"titleSearch","in":"query","schema":{"type":"string","maxLength":100}},{"name":"dateFrom","in":"query","schema":{"type":"string","format":"date"}},{"name":"dateTo","in":"query","schema":{"type":"string","format":"date"}},{"name":"updatedSince","in":"query","description":"Inclusive. Switches the order to updatedAt ascending, then id; re-read the boundary and de-duplicate.","schema":{"type":"string","format":"date-time"}},{"name":"summaryOnly","in":"query","description":"Return a longer summary (4000 characters) instead of the 600 character default.","schema":{"type":"boolean"}},{"name":"maxChars","in":"query","description":"Clips each returned summary (and body) to this many characters.","schema":{"type":"integer","minimum":1,"maximum":200000}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":25,"default":10}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ResearchNoteSearchPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/research-notes/{noteId}":{"get":{"operationId":"getResearchNote","summary":"Get one meeting note with its sanitised transcript","description":"The transcript is clipped to maxChars (default 400000) so the response stays under the size cap, and transcriptTruncated says so; this endpoint never returns 413.","x-required-scope":"research:read","x-cost":1,"parameters":[{"name":"noteId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"maxChars","in":"query","schema":{"type":"integer","minimum":1,"maximum":500000}},{"name":"summaryOnly","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ResearchNoteDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/research-notes/{noteId}/attachment":{"get":{"operationId":"getResearchNoteAttachment","summary":"Get a presigned download of a meeting attachment","description":"A presigned GET URL valid for 10 minutes. The storage bucket and path are never returned separately.","x-required-scope":"research:files:read","x-cost":3,"parameters":[{"name":"noteId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PresignedFile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/pitch-decks":{"get":{"operationId":"listPitchDecks","summary":"List fund pitch decks","description":"Newest first by (date, id). Keyset paged.","x-required-scope":"research:files:read","x-cost":3,"parameters":[{"name":"fundIdentifier","in":"query","description":"An investment identifier the deck covers.","schema":{"type":"string","maxLength":40}},{"name":"search","in":"query","schema":{"type":"string","maxLength":100}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PitchDeckPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/pitch-decks/{deckId}/file":{"get":{"operationId":"getPitchDeckFile","summary":"Get a presigned download of a pitch deck","description":"A presigned GET URL valid for 10 minutes.","x-required-scope":"research:files:read","x-cost":3,"parameters":[{"name":"deckId","in":"path","required":true,"description":"Positive database identifier encoded as a string.","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PresignedFile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fum/latest":{"get":{"operationId":"getFumLatest","summary":"Latest FUM per portfolio code","description":"Each code's own latest date, summed across advisers (or per adviser with groupAdviser), with month-to-date flows up to that date, tagged with company, suite and platform (one portfolio per code: non-deleted, active, lowest id). The adviser filter applies before summing. Offset plus revision paging: a stale revision is a 409.","x-required-scope":"fum:read","x-cost":3,"parameters":[{"name":"code","in":"query","schema":{"type":"string","maxLength":40}},{"name":"codes","in":"query","schema":{"type":"array","minItems":1,"maxItems":170,"items":{"type":"string","maxLength":40}},"style":"form","explode":false},{"name":"portfolioId","in":"query","schema":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},{"name":"company","in":"query","schema":{"type":"string","maxLength":100}},{"name":"platform","in":"query","schema":{"type":"string","maxLength":100}},{"name":"adviser","in":"query","schema":{"type":"string","maxLength":100}},{"name":"groupAdviser","in":"query","schema":{"type":"boolean"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":500}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"maximum":100000,"default":0}},{"name":"revision","in":"query","schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FumLatestPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/portfolio-update-options":{"get":{"operationId":"getPortfolioUpdateOptions","summary":"List what a portfolio update is written against","description":"Suites with their company and active portfolio count, update categories, and update authors. Authors are id and name only, never an email. Needs portfolio_updates:read and the Staff room portfolio updates permission.","x-required-scope":"portfolio_updates:read","x-cost":3,"parameters":[],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/PortfolioUpdateOptions"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/import-kinds":{"get":{"operationId":"listImportKinds","summary":"Describe the bulk import kinds","description":"The server's import kind registry: each kind's scope, reader, key columns, accepted columns and revert notes, and whether you can start one (the kind's own import scope plus Staff room access). Replaces any client-side copy of the kinds.","x-required-scope":"changes:read","x-cost":1,"parameters":[],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ImportKindList"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/job-tokens":{"post":{"operationId":"issueJobToken","summary":"Issue a job token","description":"Issues a short-lived (60 seconds to 2 hours), read-only token bound to the caller and one Analytics job. The secret is in the response once and is never stored or logged. Only an MCP access grant holding job-tokens:issue can call this; a token can hold only scopes the grant holds, from the job-token allowlist (never a write, import, change or watchlist scope). Requires an Idempotency-Key header and a JSON body (Content-Type: application/json).","x-required-scope":"job-tokens:issue","x-cost":5,"parameters":[],"responses":{"201":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/JobToken"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueJobTokenRequest"}}}}}},"/job-tokens/{jobId}":{"delete":{"operationId":"revokeJobTokens","summary":"Revoke the caller's job tokens for one job","description":"Ends every active job token the caller issued for the job (the job finished, was cancelled or failed). Only the caller's own job tokens are touched. Repeating it returns revoked: 0.","x-required-scope":"job-tokens:issue","x-cost":5,"parameters":[{"name":"jobId","in":"path","required":true,"description":"The Analytics job id the token is bound to.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/RevokedJobTokens"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/files":{"post":{"operationId":"createFile","summary":"Create an upload (Files API)","description":"Records a PENDING file and returns a presigned PUT (10 minutes) that accepts exactly the declared size, content type and SHA-256. PUT the bytes with putHeaders, then call POST /files/{fileId}/complete. The file is visible only to its owner and expires (default 7 days, at most 30). A job token uploads as its requesting user and only for its own job. purpose=portfolio_update_image needs portfolio_updates:write and is not available to job tokens. Requires an Idempotency-Key header and a JSON body (Content-Type: application/json).","x-required-scope":"files:upload","x-cost":5,"parameters":[],"responses":{"201":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/CreatedFile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFileRequest"}}}}},"get":{"operationId":"listFiles","summary":"List your files","description":"The caller's own files, newest first (keyset cursor on createdAt and id). Never another person's. A job token sees only its own job's files. Default status is PENDING and READY; expired and deleted files are not listed.","x-required-scope":"files:read","x-cost":3,"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["PENDING","READY","REJECTED"]}},{"name":"kind","in":"query","schema":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,47}$"}},{"name":"purpose","in":"query","schema":{"type":"string","enum":["generated_file","portfolio_update_image"]}},{"name":"jobId","in":"query","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FilePage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/files/{fileId}/complete":{"post":{"operationId":"completeFile","summary":"Complete an upload","description":"Verifies the uploaded object (size, SHA-256, malware scan) and makes the file READY. A mismatch or an unclean scan returns 200 with status REJECTED and a rejectionReason, and the object is deleted. 409 means the upload or the scan is not finished: retry shortly. 503 file_storage_unavailable means storage refused to read the object: contact support with the request ID. Send an empty JSON object as the body. Requires an Idempotency-Key header and a JSON body (Content-Type: application/json).","x-required-scope":"files:upload","x-cost":5,"parameters":[{"name":"fileId","in":"path","required":true,"description":"The file id returned when the file was created.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/CompletedFile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyObject"}}}}}},"/files/{fileId}":{"get":{"operationId":"getFile","summary":"Get a file's status","description":"Status and metadata of one of the caller's files. The storage key is never returned.","x-required-scope":"files:read","x-cost":1,"parameters":[{"name":"fileId","in":"path","required":true,"description":"The file id returned when the file was created.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ApiFile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"operationId":"deleteFile","summary":"Delete a file","description":"Soft deletes the caller's own file and removes its object. Repeating it returns the deleted file.","x-required-scope":"files:upload","x-cost":5,"parameters":[{"name":"fileId","in":"path","required":true,"description":"The file id returned when the file was created.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ApiFile"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/files/{fileId}/download":{"get":{"operationId":"downloadFile","summary":"Get a download link for a file","description":"A presigned GET (15 minutes) for a READY, unexpired file, as an attachment. Records a downloaded event.","x-required-scope":"files:read","x-cost":3,"parameters":[{"name":"fileId","in":"path","required":true,"description":"The file id returned when the file was created.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,40}$"}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/FileDownload"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/mirror/portfolio-holding-membership":{"get":{"operationId":"mirrorPortfolioHoldingMembership","summary":"Current top-level holding membership of every portfolio (worker mirror)","description":"Service principals holding mirror:read only. Each live portfolio's latest snapshot on or before asOf, positive weights only (decimal_fraction), one row per investment; white-label portfolios take their source's snapshot while the link inherits holdings. Keyset (portfolioId, holdingDetailId); asOf is pinned across pages.","x-required-scope":"mirror:read","x-cost":3,"parameters":[{"name":"asOf","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":500}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/MirrorPortfolioMembershipPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/mirror/fund-holding-membership":{"get":{"operationId":"mirrorFundHoldingMembership","summary":"Funds with disclosed holdings (worker mirror)","description":"Service principals holding mirror:read only. Each fund's latest disclosure date and the constituent count on it. Keyset by fund id.","x-required-scope":"mirror:read","x-cost":3,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":500}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/MirrorFundMembershipPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/mirror/holdings-snapshots":{"get":{"operationId":"mirrorHoldingsSnapshots","summary":"Bulk holdings snapshots across portfolios (worker mirror)","description":"Service principals holding mirror:read only. Every holding row on or after sinceDate for every live portfolio (or up to 25 portfolioIds), with white-label inheritance resolved per date. Weights are decimal_fraction. Keyset (portfolioId, date, holdingId).","x-required-scope":"mirror:read","x-cost":3,"parameters":[{"name":"sinceDate","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"portfolioIds","in":"query","schema":{"type":"array","minItems":1,"maxItems":25,"items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":500}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/MirrorHoldingSnapshotPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/mirror/investments":{"get":{"operationId":"mirrorInvestments","summary":"The investment universe with classification (worker mirror)","description":"Service principals holding mirror:read only. Every investment except adviser-private holdings, with Bloomberg ticker, security, strategy and the fund's own and effective (strategy-overridden) sub-asset class. Keyset by id.","x-required-scope":"mirror:read","x-cost":3,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/MirrorInvestmentPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/brain/client-names":{"get":{"operationId":"brainClientNames","summary":"Client names for redaction","description":"Service principal brain-sensing only (scope client-names:read); any other caller is refused and a security event is logged. Names only: distinct, trimmed names of clients and households, with one-character and initials-only names excluded and no adviser filter. Keyset by client id; the client re-reads at most hourly and treats an incomplete walk as unknown. 503 service_unavailable unless the request is served by the API service as its own database login, whose column grant is the control on client data.","x-required-scope":"client-names:read","x-cost":3,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"cursor","in":"query","description":"Opaque nextCursor from the preceding page. Keep every filter unchanged; a cursor reused with different filters is a 400.","schema":{"type":"string","maxLength":2048}}],"responses":{"200":{"description":"Successful scoped operation.","headers":{"X-Request-ID":{"description":"Server-generated request identifier.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"UTC Unix seconds at window reset.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ClientNamesPage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid identifier, cursor, query, duplicate or unknown parameter, or unexpected request body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Missing, invalid, expired, revoked or invalidated credential.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"403":{"description":"Missing scope, role or resource operation denied (never says which).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"}}}},"404":{"description":"Unknown or inaccessible resource (same response for both).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Resource conflict, or a changed snapshot revision.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"The response is larger than the API returns (2 MB by default; code response_too_large). Lower the limit or narrow the request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded. Retry after Retry-After seconds.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"503":{"description":"Data, security, rate limiting or durable audit unavailable; no data is returned.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Opaque personal API key","description":"Authorization: Bearer trl_<secret>. Keys are displayed once, hashed at rest, individually revocable and expire within 90 days."}},"schemas":{"FumReportingMeta":{"type":"object","required":["asOf","flowPeriod","currency","amountBasis","snapshotBasis","flowBasis"],"properties":{"asOf":{"type":"string","format":"date"},"flowPeriod":{"type":"object","required":["startDate","endDate"],"properties":{"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"}}},"currency":{"type":"string","const":"AUD"},"amountBasis":{"type":"string","const":"dashboard_calculated"},"snapshotBasis":{"type":"string","const":"latest_date_per_platform"},"flowBasis":{"type":"string","const":"period_sum_with_legacy_month_end_consolidation"}}},"FumHistoryRow":{"type":"object","required":["date","investsense","betashares","bespoke","total"],"properties":{"date":{"type":"string","format":"date"},"investsense":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"betashares":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"bespoke":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"total":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."}}},"FumSummary":{"type":"object","required":["meta","totalFum","netFlow","firmCount","clientCount","adviserCount","investorCount","fumHistory","flowHistory"],"properties":{"meta":{"$ref":"#/components/schemas/FumReportingMeta"},"totalFum":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"netFlow":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"firmCount":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"clientCount":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"adviserCount":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"investorCount":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"fumHistory":{"type":"array","maxItems":12,"items":{"$ref":"#/components/schemas/FumHistoryRow"}},"flowHistory":{"type":"array","maxItems":12,"items":{"$ref":"#/components/schemas/FumHistoryRow"}}}},"FumFlows":{"type":"object","required":["meta","netFlow","history"],"properties":{"meta":{"$ref":"#/components/schemas/FumReportingMeta"},"netFlow":{"type":"object","required":["value","percentageChange"],"properties":{"value":{"type":"string"},"percentageChange":{"type":["number","null"],"description":"Relative percentage change: 5 means a 5% change. Null when a like-for-like comparison is unavailable."}}},"history":{"type":"array","maxItems":12,"items":{"$ref":"#/components/schemas/FumHistoryRow"}}}},"FumRow":{"type":"object","required":["id","sourceDate","portfolioId","portfolioName","suiteId","suiteName","companyId","companyName","reportingCompanyId","reportingCompanyName","platformName","platformMenuId","platformMenuName","platformMenuSlug","state","platformState","dealer","adviser","portfolioCode","clientType","closingFum","inflow","outflow","netFlow","numberOfAccounts"],"properties":{"id":{"type":"string"},"sourceDate":{"type":"string","format":"date"},"portfolioId":{"type":["string","null"]},"portfolioName":{"type":["string","null"]},"suiteId":{"type":["string","null"]},"suiteName":{"type":["string","null"]},"companyId":{"type":["string","null"]},"companyName":{"type":["string","null"]},"reportingCompanyId":{"type":["string","null"]},"reportingCompanyName":{"type":["string","null"]},"platformName":{"type":["string","null"]},"platformMenuId":{"type":["string","null"]},"platformMenuName":{"type":["string","null"]},"platformMenuSlug":{"type":["string","null"]},"state":{"type":["string","null"]},"platformState":{"type":["string","null"]},"dealer":{"type":["string","null"]},"adviser":{"type":["string","null"]},"portfolioCode":{"type":"string"},"clientType":{"type":"string","enum":["investsense","betashares","bespoke"]},"closingFum":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"inflow":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"outflow":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"netFlow":{"type":"string","description":"AUD amount from the dashboard calculation, serialized as a decimal string. This does not recover precision already rounded by dashboard numeric calculations."},"numberOfAccounts":{"type":"integer","minimum":0}}},"FumBreakdownRow":{"type":"object","required":["id","dealer","adviser","company","companyType","platform","platformMenu","state","suite","suiteId","firm","firmOwner","trelliaOwner","portfolioCode","portfolioName","fundManager","holdingIdentifier","holdingName","closingFum","netFlow","estimatedFum","numberOfAccounts","portfolioCount"],"properties":{"id":{"type":"string"},"dealer":{"type":["string","null"]},"adviser":{"type":["string","null"]},"company":{"type":["string","null"]},"companyType":{"type":["string","null"]},"platform":{"type":["string","null"]},"platformMenu":{"type":["string","null"]},"state":{"type":["string","null"]},"suite":{"type":["string","null"]},"suiteId":{"type":["string","null"]},"firm":{"type":["string","null"]},"firmOwner":{"type":["string","null"]},"trelliaOwner":{"type":["string","null"]},"portfolioCode":{"type":["string","null"]},"portfolioName":{"type":["string","null"]},"fundManager":{"type":["string","null"]},"holdingIdentifier":{"type":["string","null"]},"holdingName":{"type":["string","null"]},"closingFum":{"type":["string","null"]},"netFlow":{"type":["string","null"]},"estimatedFum":{"type":["string","null"]},"numberOfAccounts":{"type":["integer","null"],"minimum":0},"portfolioCount":{"type":"integer","minimum":0}}},"FumRowsPage":{"type":"object","required":["data","totalCount","revision","nextOffset","meta"],"properties":{"data":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/FumRow"}},"totalCount":{"type":"integer","minimum":0},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"},"nextOffset":{"type":["integer","null"],"minimum":0},"meta":{"$ref":"#/components/schemas/FumReportingMeta"}}},"FumBreakdownPage":{"type":"object","required":["data","totalCount","revision","nextOffset","meta"],"properties":{"data":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/FumBreakdownRow"}},"totalCount":{"type":"integer","minimum":0},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"},"nextOffset":{"type":["integer","null"],"minimum":0},"meta":{"$ref":"#/components/schemas/FumReportingMeta"}}},"FumDate":{"type":"object","required":["date"],"properties":{"date":{"type":"string","format":"date"}}},"FumDatesPage":{"type":"object","required":["data","totalCount","revision","nextOffset"],"properties":{"data":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/FumDate"}},"totalCount":{"type":"integer","minimum":0},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"},"nextOffset":{"type":["integer","null"],"minimum":0}}},"Problem":{"type":"object","required":["type","title","status","detail","code","requestId"],"properties":{"type":{"type":"string","const":"about:blank"},"title":{"type":"string"},"status":{"type":"integer","minimum":400,"maximum":599},"detail":{"type":"string"},"code":{"type":"string"},"requestId":{"type":"string","format":"uuid"}}},"Meta":{"type":"object","required":["requestId","apiVersion"],"properties":{"requestId":{"type":"string","format":"uuid"},"apiVersion":{"type":"string","const":"1"}}},"Profile":{"type":"object","required":["userId","role","companyId","scopes"],"properties":{"userId":{"type":"string"},"role":{"type":"string","enum":["adviser","fund_manager","staff"]},"companyId":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}}}},"PortfolioIdentity":{"type":"object","required":["id","code","name","suiteName","suiteSlug","platformName","platformSlug"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"string"},"name":{"type":"string"},"suiteName":{"type":"string"},"suiteSlug":{"type":"string"},"platformName":{"type":"string"},"platformSlug":{"type":"string"}}},"Portfolio":{"type":"object","required":["id","code","name","suiteName","suiteSlug","platformName","platformSlug","inceptionDate","active"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"string"},"name":{"type":"string"},"suiteName":{"type":"string"},"suiteSlug":{"type":"string"},"platformName":{"type":"string"},"platformSlug":{"type":"string"},"inceptionDate":{"type":"string","format":"date"},"active":{"type":"boolean"}}},"PortfolioPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/PortfolioIdentity"}},"nextCursor":{"type":["string","null"]}}},"PortfolioHolding":{"type":"object","required":["id","investmentId","identifier","name","weight"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"investmentId":{"type":["string","null"]},"identifier":{"type":["string","null"]},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."}}},"PortfolioHoldings":{"type":"object","required":["portfolioId","asOfDate","weightUnit","inherited","items","nextCursor"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"weightUnit":{"type":"string","const":"decimal_fraction"},"inherited":{"type":"boolean"},"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/PortfolioHolding"}},"nextCursor":{"type":["string","null"]}}},"PortfolioPerformance":{"type":"object","required":["portfolioId","asOfDate","status","valueUnit","provenance","aggregations"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["available","unavailable"]},"valueUnit":{"type":"string","const":"percent","description":"5.2 means 5.2%, not 520%."},"provenance":{"type":"object","required":["inherited","source","periodBasis"],"properties":{"inherited":{"type":"boolean"},"source":{"type":"string","const":"selected_performance_series"},"periodBasis":{"type":"string","const":"selected_series_portfolio"}}},"aggregations":{"type":"array","items":{"type":"object","required":["period","value"],"properties":{"period":{"type":"string","enum":["ONE_MONTH","THREE_MONTHS","SIX_MONTHS","ONE_YEAR","TWO_YEARS","THREE_YEARS","FIVE_YEARS","SEVEN_YEARS","TEN_YEARS","SINCE_INCEPTION","SINCE_INVESTSENSE_INCEPTION"]},"value":{"type":["string","null"],"description":"Exact decimal percentage, or null when unavailable."}}}}}},"Fund":{"type":"object","required":["id","identifier","name","terminated","strategy","company"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"terminated":{"type":"boolean"},"strategy":{"type":["object","null"],"required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}},"company":{"type":["object","null"],"required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}}}},"FundPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/Fund"}},"nextCursor":{"type":["string","null"]}}},"FundHolding":{"type":"object","required":["id","identifier","name","weight","currency"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."},"currency":{"type":"string"}}},"FundHoldings":{"type":"object","required":["fundId","asOfDate","weightUnit","items","nextCursor"],"properties":{"fundId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"weightUnit":{"type":"string","const":"decimal_fraction"},"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/FundHolding"}},"nextCursor":{"type":["string","null"]}}},"WatchlistItem":{"type":"object","required":["id","investmentId","identifier","name","kind","availability","assetClassName","subAssetClassName","addedAt"],"properties":{"id":{"type":"string"},"investmentId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"kind":{"type":"string","enum":["STOCK","ETF","MANAGED_FUND","OTHER"]},"availability":{"type":"string","enum":["AVAILABLE","NO_LONGER_AVAILABLE","UNSUPPORTED"]},"assetClassName":{"type":["string","null"]},"subAssetClassName":{"type":["string","null"]},"addedAt":{"type":"string","format":"date-time"}}},"WatchlistPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/WatchlistItem"}},"nextCursor":{"type":["string","null"]}}},"WatchlistWrite":{"type":"object","required":["status","investmentId"],"properties":{"investmentId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"status":{"type":"string","enum":["ADDED","ALREADY_SAVED","REMOVED","NOT_SAVED"]}}},"Empty":{"type":"object","additionalProperties":false},"CreateChangeSet":{"type":"object","additionalProperties":false,"required":["title","changeNote"],"properties":{"title":{"type":"string","minLength":3,"maxLength":200},"changeNote":{"type":"string","minLength":3,"maxLength":2000,"description":"Why these changes are being made. Recorded against every change."}}},"ProposeChange":{"type":"object","additionalProperties":false,"required":["entity","operation"],"properties":{"entity":{"type":"string","enum":["portfolio_update","staff_action"]},"operation":{"type":"string","enum":["CREATE","UPDATE","ARCHIVE"]},"targetId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$","description":"Required for UPDATE and ARCHIVE."},"data":{"type":"object","description":"Full record for CREATE, changed fields for UPDATE. For entity staff_action: { action, input }.","properties":{"title":{"type":"string","maxLength":300},"date":{"type":"string","format":"date"},"excerpt":{"type":"string","maxLength":5000},"content":{"type":"string","description":"HTML body.","maxLength":500000},"thumbnail":{"type":"string","format":"uri"},"pdf":{"type":["string","null"]},"showToInvestors":{"type":"boolean"},"sendToEveryoneWithAccess":{"type":"boolean"},"updateType":{"type":"string"},"betasharesSection":{"type":["string","null"]},"published":{"type":"boolean","description":"Publishing notifies advisers, and only happens when you apply the change set."},"suiteIds":{"type":"array","items":{"type":"integer"}},"categoryIds":{"type":"array","items":{"type":"integer"}},"authorIds":{"type":"array","items":{"type":"string"}},"portfolioIds":{"type":"array","items":{"type":"integer"},"minItems":1}}}}},"ReviseChange":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"type":"object","properties":{"title":{"type":"string","maxLength":300},"date":{"type":"string","format":"date"},"excerpt":{"type":"string","maxLength":5000},"content":{"type":"string","description":"HTML body.","maxLength":500000},"thumbnail":{"type":"string","format":"uri"},"pdf":{"type":["string","null"]},"showToInvestors":{"type":"boolean"},"sendToEveryoneWithAccess":{"type":"boolean"},"updateType":{"type":"string"},"betasharesSection":{"type":["string","null"]},"published":{"type":"boolean","description":"Publishing notifies advisers, and only happens when you apply the change set."},"suiteIds":{"type":"array","items":{"type":"integer"}},"categoryIds":{"type":"array","items":{"type":"integer"}},"authorIds":{"type":"array","items":{"type":"string"}},"portfolioIds":{"type":"array","items":{"type":"integer"},"minItems":1}}}}},"ProposeRevert":{"type":"object","additionalProperties":false,"required":["changeNote"],"properties":{"changeNote":{"type":"string","minLength":3,"maxLength":2000}}},"ProposeRestore":{"type":"object","additionalProperties":false,"required":["bundleId"],"properties":{"bundleId":{"type":"string","pattern":"^[a-z0-9]{20,40}$"}}},"ChangeItem":{"type":"object","properties":{"id":{"type":"string"},"seq":{"type":"integer"},"entity":{"type":"string"},"operation":{"type":"string","enum":["CREATE","UPDATE","ARCHIVE","RESTORE","REVERT"]},"targetId":{"type":["string","null"]},"status":{"type":"string","enum":["PENDING","APPLIED","STALE","REJECTED"]},"data":{"type":"object"},"preview":{"type":"object","description":"summary, fields (before/after) or rows, conflicts."},"result":{"type":["object","null"]},"reviewNote":{"type":["string","null"],"description":"Why a reviewer rejected this change. Act on it, then revise."},"reviewedAt":{"type":["string","null"],"format":"date-time"}}},"ChangeSet":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"changeNote":{"type":"string"},"status":{"type":"string","enum":["OPEN","APPLIED","DISCARDED"]},"surface":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"appliedAt":{"type":["string","null"],"format":"date-time"},"revertUntil":{"type":["string","null"],"format":"date-time"},"revertsChangeSetId":{"type":["string","null"]},"revertedByChangeSetId":{"type":["string","null"]},"itemCount":{"type":"integer"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"seq":{"type":"integer"},"entity":{"type":"string"},"operation":{"type":"string","enum":["CREATE","UPDATE","ARCHIVE","RESTORE","REVERT"]},"targetId":{"type":["string","null"]},"status":{"type":"string","enum":["PENDING","APPLIED","STALE","REJECTED"]},"data":{"type":"object"},"preview":{"type":"object","description":"summary, fields (before/after) or rows, conflicts."},"result":{"type":["object","null"]},"reviewNote":{"type":["string","null"],"description":"Why a reviewer rejected this change. Act on it, then revise."},"reviewedAt":{"type":["string","null"],"format":"date-time"}}}},"reviewUrl":{"type":"string","format":"uri","description":"Pending Changes page in the Staff room where the set is reviewed and applied."},"reviewNote":{"type":["string","null"],"description":"Reviewer feedback on the whole set."},"counts":{"type":["object","null"],"properties":{"waiting":{"type":"integer"},"applied":{"type":"integer"},"rejected":{"type":"integer"},"stale":{"type":"integer"}}},"nextStep":{"type":["string","null"],"description":"Plain-language next action for the proposer or their agent."}}},"ChangeSetPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ChangeSet"}},"nextCursor":{"type":["string","null"]}}},"StaffActionList":{"type":"object","required":["actions","excluded"],"properties":{"actions":{"type":"array","items":{"type":"object","required":["id","label","kind","operation","inputSchema"],"properties":{"id":{"type":"string","description":"Send as data.action."},"label":{"type":"string"},"kind":{"type":"string","enum":["create","update","delete","action"]},"operation":{"type":"string","enum":["CREATE","UPDATE","ARCHIVE"],"description":"The operation to propose this action with."},"tables":{"type":"array","items":{"type":"string"}},"irreversibleSideEffects":{"type":"array","items":{"type":"string"},"description":"Effects an undo of the data cannot recall, such as emails."},"inputSchema":{"type":"object","description":"JSON Schema of data.input."}}}},"excluded":{"type":"array","description":"Staff room procedures that are never available here.","items":{"type":"object","properties":{"pattern":{"type":"string"},"reason":{"type":"string"}}}}}},"ArchivePage":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"bundleId":{"type":"string"},"entity":{"type":["string","null"]},"entityId":{"type":["string","null"]},"archivedAt":{"type":"string","format":"date-time"},"archivedById":{"type":["string","null"]},"changeSetId":{"type":["string","null"]},"rowCount":{"type":"integer"},"record":{"type":"object"}}}}}},"PortfolioUpdate":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string","maxLength":300},"date":{"type":"string","format":"date"},"excerpt":{"type":"string","maxLength":5000},"content":{"type":"string","description":"HTML body.","maxLength":500000},"thumbnail":{"type":"string","format":"uri"},"pdf":{"type":["string","null"]},"showToInvestors":{"type":"boolean"},"sendToEveryoneWithAccess":{"type":"boolean"},"updateType":{"type":"string"},"betasharesSection":{"type":["string","null"]},"published":{"type":"boolean","description":"Publishing notifies advisers, and only happens when you apply the change set."},"suiteIds":{"type":"array","items":{"type":"integer"}},"categoryIds":{"type":"array","items":{"type":"integer"}},"authorIds":{"type":"array","items":{"type":"string"}},"portfolioIds":{"type":"array","items":{"type":"integer"},"minItems":1}}},"PortfolioUpdatePage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"date":{"type":["string","null"],"format":"date"},"published":{"type":"boolean"}}}},"nextCursor":{"type":["string","null"]}}},"StartImport":{"type":"object","additionalProperties":false,"required":["kind"],"properties":{"kind":{"type":"string","description":"holdings, fum, fund_holdings, table_rows, and the other kinds."},"delivery":{"type":"string","enum":["file","chunks"]},"filename":{"type":"string","maxLength":255},"sizeBytes":{"type":"integer","minimum":1},"sha256":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"},"mode":{"type":"string","enum":["upsert","replace_groups"],"default":"upsert"},"stageValidOnly":{"type":"boolean","default":false},"dryRun":{"type":"boolean","default":false,"description":"Only for kind fund_holdings_copy. Reports what the copy would write, creates no import, change set or queue entry and is not counted against the imports quota. The response is { jobId, status: SUCCEEDED, dryRun: true }; GET /jobs/{id} returns counts and perTarget."},"input":{"type":"object","additionalProperties":true}}},"StartedImport":{"type":"object","required":["importId","kind","source","expiresAt"],"properties":{"importId":{"type":"string"},"kind":{"type":"string"},"source":{"type":"string","enum":["file","chunks","server"]},"upload":{"type":["object","null"],"properties":{"url":{"type":"string"},"method":{"type":"string","enum":["PUT"]},"expiresInSeconds":{"type":"integer"},"headers":{"type":"object","additionalProperties":{"type":"string"}}}},"chunks":{"type":["object","null"],"additionalProperties":true},"expiresAt":{"type":"string","format":"date-time"}}},"ImportChunk":{"type":"object","additionalProperties":false,"required":["seq","rows"],"properties":{"seq":{"type":"integer","minimum":0},"rows":{"type":"array","maxItems":2000,"items":{"type":"object","additionalProperties":true}}}},"ImportChunkAck":{"type":"object","required":["seq","chunkCount","totalRows"],"properties":{"seq":{"type":"integer"},"chunkCount":{"type":"integer"},"totalRows":{"type":"integer"}}},"SubmitImport":{"type":"object","additionalProperties":false,"required":["changeNote"],"properties":{"changeSetId":{"type":"string","pattern":"^[a-z0-9]{20,40}$"},"changeNote":{"type":"string","minLength":3,"maxLength":2000}}},"SubmittedImport":{"type":"object","required":["jobId","importId","status"],"properties":{"jobId":{"type":"string"},"importId":{"type":"string"},"status":{"type":"string","enum":["QUEUED"]}}},"ImportJob":{"type":"object","required":["id","type","status","progress"],"properties":{"id":{"type":"string"},"type":{"type":"string"},"status":{"type":"string","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]},"progress":{"type":"integer","minimum":0,"maximum":100},"phase":{"type":["string","null"]},"counts":{"type":["object","null"],"additionalProperties":true},"perTarget":{"type":"array","description":"Dry runs of fund_holdings_copy only: one entry per target fund.","items":{"type":"object","properties":{"identifier":{"type":"string"},"dates":{"type":"array","items":{"type":"string","format":"date"}},"dateCount":{"type":"integer","minimum":0},"rowCount":{"type":"integer","minimum":0},"skippedReason":{"type":["string","null"],"enum":["fund_not_found","same_as_source","no_source_rows",null]}}}},"errors":{"type":["array","null"],"items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}},"validationReportUrl":{"type":["string","null"],"description":"10 minute link to the validation report CSV."},"importId":{"type":["string","null"]},"changeSetId":{"type":["string","null"]},"changeItemId":{"type":["string","null"]},"startedAt":{"type":["string","null"],"format":"date-time"},"finishedAt":{"type":["string","null"],"format":"date-time"}}},"PerformanceReportPeriods":{"type":"object","required":["defaultPeriodEnd","periods"],"properties":{"defaultPeriodEnd":{"type":"string","format":"date"},"periods":{"type":"array","items":{"type":"object","required":["periodEnd","label","isQuarterEnd"],"properties":{"periodEnd":{"type":"string","format":"date"},"label":{"type":"string"},"isQuarterEnd":{"type":"boolean"}},"additionalProperties":true}}},"additionalProperties":true},"PerformanceReportReadiness":{"type":"object","required":["periodEnd","isQuarterEnd","generatedAt","companies"],"properties":{"periodEnd":{"type":"string","format":"date"},"isQuarterEnd":{"type":"boolean"},"generatedAt":{"type":"string","format":"date-time"},"companies":{"type":"array","items":{"type":"object","required":["companyId","companyName","summary","suites"],"properties":{"companyId":{"type":"integer","minimum":1},"companyName":{"type":"string"},"summary":{"type":"object","additionalProperties":true},"suites":{"type":"array","items":{"type":"object","required":["suiteId","suiteName","summary","portfolios"],"properties":{"suiteId":{"type":"integer","minimum":1},"suiteName":{"type":"string"},"summary":{"type":"object","additionalProperties":true},"portfolios":{"type":"array","items":{"type":"object","required":["portfolioId","code","name","isIncluded","periodMonths","overall","cells"],"properties":{"portfolioId":{"type":"integer","minimum":1},"code":{"type":"string"},"name":{"type":"string"},"isIncluded":{"type":"boolean"},"isShownToAdvisers":{"type":"boolean"},"template":{"type":"string"},"cadence":{"type":"string"},"periodMonths":{"anyOf":[{"type":"integer","enum":[1,3]},{"type":"null"}]},"overall":{"type":"string"},"cells":{"type":"object","description":"By data point: status, detail and the fix (null when GREEN or NOT_APPLICABLE).","additionalProperties":true},"returnsPreliminaryFrom":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true}}},"additionalProperties":true},"PerformanceReportCompanies":{"type":"array","items":{"type":"object","required":["companyId","name","suiteCount","portfolioCount","overrideCount"],"properties":{"companyId":{"type":"integer","minimum":1},"name":{"type":"string"},"suiteCount":{"type":"integer","minimum":0},"portfolioCount":{"type":"integer","minimum":0},"overrideCount":{"type":"integer","minimum":0}},"additionalProperties":true}},"PerformanceReportSettings":{"type":"object","description":"The company first, then each suite followed by its portfolios.","required":["companyId","rows"],"properties":{"companyId":{"type":"integer","minimum":1},"rows":{"type":"array","items":{"type":"object","required":["scope","label","values","ownValues"],"properties":{"scope":{"type":"object","required":["kind","id"],"properties":{"kind":{"type":"string","enum":["COMPANY","SUITE","PORTFOLIO"]},"id":{"type":"integer","minimum":1}},"additionalProperties":true},"label":{"type":"string"},"code":{"anyOf":[{"type":"string"},{"type":"null"}]},"values":{"type":"object","description":"Every setting's effective value, its source (COMPANY, SUITE, PORTFOLIO, DEFAULT, UNSET) and the scope that set it.","additionalProperties":true},"ownValues":{"type":"object","description":"Only the values this scope sets itself; propose staff.performanceReports.settings.update to change them.","additionalProperties":true}},"additionalProperties":true}}},"additionalProperties":true},"PerformanceReportDisclaimers":{"type":"object","required":["companyDisclaimer","disclaimers","platformOptions"],"properties":{"companyDisclaimer":{"anyOf":[{"type":"string"},{"type":"null"}]},"disclaimers":{"type":"array","items":{"type":"object","required":["id","platformId","platformName","body"],"properties":{"id":{"type":"integer","minimum":1},"platformId":{"type":"integer","minimum":1},"platformName":{"type":"string"},"body":{"type":"string"}},"additionalProperties":true}},"platformOptions":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer","minimum":1},"name":{"type":"string"}},"additionalProperties":true}}},"additionalProperties":true},"PerformanceReportComparatorRow":{"type":"object","required":["portfolioId","code","name","objective","benchmark","peerGroup"],"properties":{"portfolioId":{"type":"integer","minimum":1},"code":{"type":"string"},"name":{"type":"string"},"companyName":{"type":"string"},"suiteName":{"type":"string"},"inceptionDate":{"type":"string","format":"date"},"objective":{"anyOf":[{"type":"object","required":["seriesId","seriesKey","displayName","effectiveFrom"],"properties":{"seriesId":{"type":"integer","minimum":1},"seriesKey":{"type":"string"},"displayName":{"type":"string"},"effectiveFrom":{"type":"string","format":"date"}},"additionalProperties":true},{"type":"null"}]},"benchmark":{"anyOf":[{"type":"object","required":["seriesId","seriesKey","displayName","effectiveFrom"],"properties":{"seriesId":{"type":"integer","minimum":1},"seriesKey":{"type":"string"},"displayName":{"type":"string"},"effectiveFrom":{"type":"string","format":"date"}},"additionalProperties":true},{"type":"null"}]},"peerGroup":{"anyOf":[{"type":"object","required":["seriesId","seriesKey","displayName","effectiveFrom"],"properties":{"seriesId":{"type":"integer","minimum":1},"seriesKey":{"type":"string"},"displayName":{"type":"string"},"effectiveFrom":{"type":"string","format":"date"}},"additionalProperties":true},{"type":"null"}]}},"additionalProperties":true},"PerformanceReportComparatorPage":{"type":"object","required":["items","totalCount"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PerformanceReportComparatorRow"}},"totalCount":{"type":"integer","minimum":0}}},"PerformanceReportComparatorHistory":{"type":"object","required":["portfolio","rows","automatic"],"properties":{"portfolio":{"type":"object","required":["id","code","name","inceptionDate"],"properties":{"id":{"type":"integer","minimum":1},"code":{"type":"string"},"name":{"type":"string"},"inceptionDate":{"type":"string","format":"date"}},"additionalProperties":true},"rows":{"type":"array","items":{"type":"object","required":["id","role","seriesId","effectiveFrom","effectiveTo"],"properties":{"id":{"type":"integer","minimum":1},"role":{"type":"string","enum":["OBJECTIVE","BENCHMARK","PEER_GROUP"]},"seriesId":{"type":"integer","minimum":1},"seriesKey":{"type":"string"},"label":{"anyOf":[{"type":"string"},{"type":"null"}]},"effectiveFrom":{"type":"string","format":"date"},"effectiveTo":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]}},"additionalProperties":true}},"automatic":{"type":"array","items":{"type":"object"}}},"additionalProperties":true},"PerformanceReportSeries":{"type":"object","required":["id","key","name","kind","isActive","latestObservationDate"],"properties":{"id":{"type":"integer","minimum":1},"key":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["INDEX","MACRO","FUND","PEER_GROUP","DERIVED"]},"isActive":{"type":"boolean"},"latestObservationDate":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}]},"marketIndexGroup":{"anyOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":true},"PerformanceReportSeriesPage":{"type":"object","required":["items","totalCount"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PerformanceReportSeries"}},"totalCount":{"type":"integer","minimum":0}}},"PerformanceReportBenchmarks":{"type":"object","required":["assetClasses","composites","assetClassOptions"],"properties":{"assetClasses":{"type":"array","items":{"type":"object","required":["assetClassId","assetClassName","mode"],"properties":{"assetClassId":{"type":"integer","minimum":1},"assetClassName":{"type":"string"},"mode":{"type":"string"},"seriesId":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]}},"additionalProperties":true}},"composites":{"type":"array","items":{"type":"object","required":["seriesId","seriesKey","weights"],"properties":{"seriesId":{"type":"integer","minimum":1},"seriesKey":{"type":"string"},"weights":{"type":"array","items":{"type":"object","required":["assetClassId","weightPercent"],"properties":{"assetClassId":{"type":"integer","minimum":1},"weightPercent":{"type":"number","description":"Percent, 0 to 100."}},"additionalProperties":true}}},"additionalProperties":true}},"assetClassOptions":{"type":"array","items":{"type":"object"}}},"additionalProperties":true},"PerformanceReportCommentary":{"type":"object","required":["portfolioId","periodEnd","market","portfolio","canRegenerate"],"properties":{"portfolioId":{"type":"integer","minimum":1},"periodEnd":{"type":"string","format":"date"},"market":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"portfolio":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"formulaicDraft":{"anyOf":[{"type":"string"},{"type":"null"}]},"unavailableReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"generation":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"attribution":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"canRegenerate":{"type":"boolean"}},"additionalProperties":true},"GeneratedPerformanceReport":{"type":"object","required":["id","portfolioId","periodEnd","periodMonths","status"],"properties":{"id":{"type":"integer","minimum":1},"portfolioId":{"type":"integer","minimum":1},"portfolioCode":{"type":"string"},"portfolioName":{"type":"string"},"periodEnd":{"type":"string","format":"date"},"periodMonths":{"type":"integer","enum":[1,3]},"template":{"type":"string"},"status":{"type":"string","enum":["PENDING","READY","FAILED"]},"hasPreliminaryData":{"type":"boolean"},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"additionalProperties":true},"GeneratedPerformanceReportPage":{"type":"object","required":["items","totalCount"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedPerformanceReport"}},"totalCount":{"type":"integer","minimum":0}}},"GeneratedPerformanceReportStatus":{"type":"object","required":["reportId","status"],"properties":{"reportId":{"type":"integer","minimum":1},"status":{"type":"string","enum":["PENDING","READY","FAILED"]},"s3Key":{"anyOf":[{"type":"string","description":"Storage key of the PDF; opened through the Staff room."},{"type":"null"}]},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":true},"PerformanceReportUpload":{"type":"object","required":["id","template","status","createdAt"],"properties":{"id":{"type":"integer","minimum":1},"template":{"type":"string","enum":["INDEX_LEVELS","INDEX_RETURNS","FUND_MONTHLY_RETURNS","DISCRETE_RETURNS","CPI_ESTIMATE","COMPOSITE_RETURNS"]},"fileName":{"type":"string"},"status":{"type":"string","enum":["VALIDATING","READY_TO_COMMIT","COMMITTED","FAILED","DISCARDED"]},"rowCount":{"type":"integer","minimum":0},"errorCount":{"type":"integer","minimum":0},"feedKey":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"committedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"additionalProperties":true},"PerformanceReportUploadPage":{"type":"object","required":["items","totalCount"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PerformanceReportUpload"}},"totalCount":{"type":"integer","minimum":0}}},"PerformanceReportFeeds":{"type":"array","items":{"type":"object","required":["key","label","enabled","lastRun"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"enabled":{"type":"boolean"},"lastRun":{"anyOf":[{"type":"object","additionalProperties":true},{"type":"null"}]}},"additionalProperties":true}},"PortfolioDataItem":{"type":"object","required":["id","code","name","suiteName","suiteSlug","platformName","platformSlug","inceptionDate","active","companyId","companyName","companySlug","companyColour","suiteId","platformId","isProspect","growthAllocation","objective","customSortOrder","factsheet","bloombergTicker","portfolioType","investsenseInceptionDate","latestHoldingsDate"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"string"},"name":{"type":"string"},"suiteName":{"type":"string"},"suiteSlug":{"type":"string"},"platformName":{"type":"string"},"platformSlug":{"type":"string"},"inceptionDate":{"type":"string","format":"date"},"active":{"type":"boolean"},"companyId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"companyName":{"type":["string","null"]},"companySlug":{"type":["string","null"]},"companyColour":{"type":["string","null"]},"suiteId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"platformId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"isProspect":{"type":"boolean"},"growthAllocation":{"type":["string","null"],"description":"Percent as a decimal string; 70 means 70%."},"objective":{"type":["object","null"],"required":["id","name","cpi"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"cpi":{"type":["string","null"],"description":"The objective's stored CPI figure, unchanged."}}},"customSortOrder":{"type":"integer"},"factsheet":{"type":["object","null"],"required":["id","name","type"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"type":{"type":["string","null"]}}},"bloombergTicker":{"type":["string","null"],"description":"The portfolio's own Bloomberg directs ticker."},"bloombergPortfolioName":{"type":["string","null"],"description":"Only with include=bloombergExport (full staff): the stored Bloomberg export portfolio name."},"bloombergPortfolioTypeDrifting":{"type":["boolean","null"],"description":"Only with include=bloombergExport (full staff): true for drifting exports, false for fixed-weight exports; null when unconfigured."},"portfolioType":{"type":["string","null"]},"investsenseInceptionDate":{"type":["string","null"],"format":"date"},"latestHoldingsDate":{"type":["string","null"],"format":"date","description":"Latest holdings snapshot date, resolved through white-label holdings inheritance."},"hasLookthroughHoldings":{"type":"boolean","description":"Only with include=lookthroughFlag: the latest snapshot holds a positive-weight holding that discloses its own holdings."},"latestAggregationDate":{"type":["string","null"],"format":"date","description":"Only with include=external: latest month-end with a published value in the standard periods."},"isExternal":{"type":"boolean","description":"Only with include=external: true for prospect portfolios."}}},"PortfolioDataPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/PortfolioDataItem"}},"nextCursor":{"type":["string","null"]},"totalCount":{"type":"integer","minimum":0},"totalCountCapped":{"type":"boolean"}}},"PortfolioDataHolding":{"type":"object","required":["portfolioId","asOfDate","inherited","sourcePortfolioId","holdingId","holdingDetailId","investmentId","identifier","name","weight","isTerminated"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":"string","format":"date"},"inherited":{"type":"boolean"},"sourcePortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"holdingId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"investmentId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":["string","null"]},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal fraction; 0.05 means 5%."},"isTerminated":{"type":["boolean","null"]},"assetClass":{"type":["object","null"],"required":["id","name","sortOrder"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"sortOrder":{"type":"integer"}}},"subAssetClass":{"type":["object","null"],"required":["id","code","name","valuationClassificationId"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"integer"},"name":{"type":"string"},"valuationClassificationId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"}},"description":"The holding detail's own sub-asset class."},"effectiveSubAssetClass":{"type":["object","null"],"required":["id","code","name","valuationClassificationId"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"integer"},"name":{"type":"string"},"valuationClassificationId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"}},"description":"Strategy-overridden: the strategy's sub-asset class when it has one, else the holding detail's own. The asset class follows it."},"strategyId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"growthAsset":{"type":["boolean","null"]},"securityId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"nestedPortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"}}},"PortfolioHoldingsBulk":{"type":"object","required":["items","nextCursor","weightUnit","snapshots"],"properties":{"items":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/PortfolioDataHolding"}},"nextCursor":{"type":["string","null"]},"weightUnit":{"type":"string","const":"decimal_fraction"},"snapshots":{"type":"array","description":"One entry per authorised requested portfolio, including those with no holdings. Unauthorised ids are absent.","items":{"type":"object","required":["portfolioId","asOfDate","asOfDates","inherited","sourcePortfolioId"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"asOfDates":{"type":"array","items":{"type":"string","format":"date"}},"inherited":{"type":"boolean"},"sourcePortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"}}}}}},"PortfolioHoldingRowExtended":{"type":"object","required":["id","holdingId","holdingDetailId","investmentId","identifier","name","weight","isTerminated"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$","description":"Legacy alias of holdingId."},"holdingId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"investmentId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":["string","null"]},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal fraction; 0.05 means 5%."},"isTerminated":{"type":["boolean","null"]},"assetClass":{"type":["object","null"],"required":["id","name","sortOrder"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"sortOrder":{"type":"integer"}}},"subAssetClass":{"type":["object","null"],"required":["id","code","name","valuationClassificationId"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"integer"},"name":{"type":"string"},"valuationClassificationId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"}},"description":"The holding detail's own sub-asset class."},"effectiveSubAssetClass":{"type":["object","null"],"required":["id","code","name","valuationClassificationId"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"integer"},"name":{"type":"string"},"valuationClassificationId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"}},"description":"Strategy-overridden: the strategy's sub-asset class when it has one, else the holding detail's own. The asset class follows it."},"strategyId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"growthAsset":{"type":["boolean","null"]},"securityId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"nestedPortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":"string","format":"date","description":"With expand=nested: the date this row was read on."},"depth":{"type":"integer","minimum":0,"maximum":4},"nestedPath":{"type":"array","items":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}}}},"PortfolioHoldingsExtended":{"type":"object","required":["portfolioId","asOfDate","weightUnit","inherited","items","nextCursor"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"weightUnit":{"type":"string","const":"decimal_fraction"},"inherited":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioHoldingRowExtended"}},"nextCursor":{"type":["string","null"]}}},"PortfolioHoldingDates":{"type":"object","required":["items"],"properties":{"items":{"type":"array","maxItems":100,"items":{"type":"object","required":["portfolioId","inherited","sourcePortfolioId","dates"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"inherited":{"type":"boolean"},"sourcePortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"dates":{"type":"array","items":{"type":"string","format":"date"}}}}}}},"PortfolioSaaRow":{"type":"object","required":["portfolioId","inherited","sourcePortfolioId","assetClassId","assetClass","sortOrder","saaDate","minimum","target","maximum"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"inherited":{"type":"boolean"},"sourcePortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"assetClassId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"assetClass":{"type":"string"},"sortOrder":{"type":"integer"},"saaDate":{"type":"string","format":"date"},"minimum":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"target":{"type":"string","description":"Exact decimal value encoded as a string."},"maximum":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}},"PortfolioSaa":{"type":"object","required":["items","nextCursor","valueUnit"],"properties":{"items":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/PortfolioSaaRow"}},"nextCursor":{"type":["string","null"]},"valueUnit":{"type":"string","const":"percent","description":"Bounds and target are percent: 5 means 5%."}}},"PortfolioPerformanceItem":{"type":"object","required":["portfolioId","asOfDate","status","valueUnit","provenance","aggregations"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["available","unavailable"]},"valueUnit":{"type":"string","const":"percent","description":"5.2 means 5.2%, not 520%."},"provenance":{"type":"object","required":["inherited","source","periodBasis"],"properties":{"inherited":{"type":"boolean"},"source":{"type":"string","const":"selected_performance_series"},"periodBasis":{"type":"string","const":"selected_series_portfolio"}}},"aggregations":{"type":"array","items":{"type":"object","required":["period","value"],"properties":{"period":{"type":"string"},"value":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}}}}},"PortfolioPerformanceBatch":{"type":"object","required":["items"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/PortfolioPerformanceItem"}}}},"LookthroughSecurityItem":{"type":"object","required":["securityId","isin","name","sector","country","weight","via"],"properties":{"securityId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"isin":{"type":["string","null"]},"name":{"type":["string","null"]},"sector":{"type":["string","null"]},"country":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."},"via":{"type":"array","description":"Identifiers of the held investments that contribute this security.","items":{"type":"string"}},"exchangeCode":{"type":["string","null"]},"cusip":{"type":["string","null"]},"sedol":{"type":["string","null"]},"countryIso":{"type":["string","null"]}}},"LookthroughSectorItem":{"type":"object","required":["sector","weight"],"properties":{"sector":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."}}},"LookthroughCountryItem":{"type":"object","required":["country","weight"],"properties":{"country":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."}}},"LookthroughLeafItem":{"type":"object","required":["securityId","identifier","isin","exchangeCode","cusip","sedol","name","countryIso","origin","subAssetClassId","sourceFundIdentifier","sourceFundName","weight"],"properties":{"securityId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":["string","null"]},"isin":{"type":["string","null"]},"exchangeCode":{"type":["string","null"]},"cusip":{"type":["string","null"]},"sedol":{"type":["string","null"]},"name":{"type":["string","null"]},"countryIso":{"type":["string","null"]},"origin":{"type":"string","enum":["direct","fund","other"]},"subAssetClassId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"sourceFundIdentifier":{"type":["string","null"]},"sourceFundName":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."}}},"LookthroughCoverage":{"type":"object","required":["securityMapped","fundUnmapped","unresolved"],"properties":{"securityMapped":{"type":"string","description":"Exact decimal value encoded as a string."},"fundUnmapped":{"type":"string","description":"Exact decimal value encoded as a string."},"unresolved":{"type":"string","description":"Exact decimal value encoded as a string."}}},"LookthroughUnresolvedHolding":{"type":"object","required":["identifier","name","weight"],"properties":{"identifier":{"type":"string"},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."}}},"PortfolioLookthrough":{"type":"object","required":["items","nextCursor","portfolioId","asOfDate","weightUnit","groupBy","coverage","unresolved","unresolvedCount","fundDisclosureDates"],"properties":{"items":{"type":"array","maxItems":1000,"items":{"oneOf":[{"$ref":"#/components/schemas/LookthroughSecurityItem"},{"$ref":"#/components/schemas/LookthroughSectorItem"},{"$ref":"#/components/schemas/LookthroughCountryItem"},{"$ref":"#/components/schemas/LookthroughLeafItem"}]}},"nextCursor":{"type":["string","null"]},"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"weightUnit":{"type":"string","const":"decimal_fraction"},"groupBy":{"type":"string","enum":["leaf","security","sector","country"]},"coverage":{"$ref":"#/components/schemas/LookthroughCoverage"},"unresolved":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/LookthroughUnresolvedHolding"}},"unresolvedCount":{"type":"integer","minimum":0},"fundDisclosureDates":{"type":"object","description":"Disclosure date used for each looked-through fund, keyed by the held fund's identifier. How stale is too stale is the caller's rule.","additionalProperties":{"type":"string","format":"date"}}}},"BulkPortfolioLookthroughSummary":{"type":"object","required":["portfolioId","asOfDate","weightUnit","coverage","unresolved","unresolvedCount","fundDisclosureDates","inherited","sourcePortfolioId","holdingsRevision"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":["string","null"],"format":"date"},"weightUnit":{"type":"string","const":"decimal_fraction"},"coverage":{"$ref":"#/components/schemas/LookthroughCoverage"},"unresolved":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/LookthroughUnresolvedHolding"}},"unresolvedCount":{"type":"integer","minimum":0},"fundDisclosureDates":{"type":"object","additionalProperties":{"type":"string","format":"date"}},"inherited":{"type":"boolean","description":"True when the holdings come from a white-label source portfolio."},"sourcePortfolioId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$","description":"The white-label source portfolio whose holdings were looked through; null unless inherited."},"holdingsRevision":{"type":["string","null"],"description":"The single look-through's revision for this portfolio and parameters; null without a holdings snapshot."}}},"BulkPortfolioLookthroughItem":{"type":"object","description":"A LookthroughSecurityItem (groupBy=security) or LookthroughLeafItem (groupBy=leaf) with its portfolioId.","required":["portfolioId"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"}},"additionalProperties":true},"BulkPortfolioLookthrough":{"type":"object","required":["portfolios","items","nextCursor"],"properties":{"portfolios":{"type":"array","maxItems":10,"items":{"$ref":"#/components/schemas/BulkPortfolioLookthroughSummary"}},"items":{"type":"array","maxItems":5000,"items":{"$ref":"#/components/schemas/BulkPortfolioLookthroughItem"}},"nextCursor":{"type":["string","null"]}}},"InvestmentConstituentItem":{"type":"object","required":["identifier","securityId","isin","name","sector","country","weight","disclosureDate"],"properties":{"identifier":{"type":"string"},"securityId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"isin":{"type":["string","null"]},"name":{"type":["string","null"]},"sector":{"type":["string","null"]},"country":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."},"disclosureDate":{"type":"string","format":"date"}}},"InvestmentSectorItem":{"type":"object","required":["identifier","sector","weight","disclosureDate"],"properties":{"identifier":{"type":"string"},"sector":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."},"disclosureDate":{"type":"string","format":"date"}}},"InvestmentCountryItem":{"type":"object","required":["identifier","country","weight","disclosureDate"],"properties":{"identifier":{"type":"string"},"country":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."},"disclosureDate":{"type":"string","format":"date"}}},"InvestmentLookthrough":{"type":"object","required":["items","nextCursor","weightUnit","groupBy"],"properties":{"items":{"type":"array","maxItems":1000,"items":{"oneOf":[{"$ref":"#/components/schemas/InvestmentConstituentItem"},{"$ref":"#/components/schemas/InvestmentSectorItem"},{"$ref":"#/components/schemas/InvestmentCountryItem"}]}},"nextCursor":{"type":["string","null"]},"weightUnit":{"type":"string","const":"decimal_fraction"},"groupBy":{"type":"string","enum":["constituent","sector","country"]}}},"FundHoldingExtended":{"type":"object","required":["id","identifier","name","weight","currency"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."},"currency":{"type":"string"},"securityId":{"type":["string","null"],"pattern":"^[1-9][0-9]{0,18}$"},"isin":{"type":["string","null"]},"exchangeCode":{"type":["string","null"]},"cusip":{"type":["string","null"]},"sedol":{"type":["string","null"]},"countryIso":{"type":["string","null"]},"marketValue":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"securityDescription":{"type":["string","null"]}}},"FundHoldingsExtended":{"type":"object","required":["items","nextCursor","fundId","fundName","asOfDate","weightUnit"],"properties":{"items":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/FundHoldingExtended"}},"nextCursor":{"type":["string","null"]},"fundId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"fundName":{"type":["string","null"]},"asOfDate":{"type":["string","null"],"format":"date"},"weightUnit":{"type":"string","const":"decimal_fraction"},"totalCount":{"type":"integer","minimum":0,"description":"Rows in the disclosure; first page only."},"disclosingFundId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$","description":"With strategyLatest=true, the share class whose disclosure is returned."}}},"HolderItem":{"type":"object","required":["id","code","name","asOfDate"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"string"},"name":{"type":"string"},"asOfDate":{"type":"string","format":"date"},"platformName":{"type":["string","null"]},"weight":{"type":"string","description":"Exact decimal value encoded as a string."}}},"HoldersPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/HolderItem"}},"nextCursor":{"type":["string","null"]}}},"ReferenceHoldingsSummary":{"type":"object","required":["kind","equityRows","fixedInterestRows","latestEquityDate","latestFixedInterestDate","constituentCount","selected"],"properties":{"kind":{"type":"string","enum":["equity","fixed_interest","mixed","none"]},"equityRows":{"type":"integer","minimum":0},"fixedInterestRows":{"type":"integer","minimum":0},"latestEquityDate":{"type":["string","null"],"format":"date"},"latestFixedInterestDate":{"type":["string","null"],"format":"date"},"constituentCount":{"type":"integer","minimum":0,"description":"Distinct securities in the latest security-level snapshot."},"selected":{"type":["string","null"],"enum":["equity","fixed_interest",null],"description":"The disclosure with the later date; security-level on a tie."}}},"ReferenceInvestment":{"type":"object","required":["id","investmentId","identifier","name","isTerminated","securityId","strategyId","bloombergTicker"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$","description":"The holding-detail id."},"investmentId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"isTerminated":{"type":"boolean"},"securityId":{"type":["string","null"]},"strategyId":{"type":["string","null"]},"bloombergTicker":{"type":["string","null"]},"subAssetClassId":{"type":["string","null"]},"subAssetClass":{"type":["string","null"]},"assetClassId":{"type":["string","null"]},"assetClass":{"type":["string","null"]},"growthAsset":{"type":["boolean","null"]},"effectiveSubAssetClassId":{"type":["string","null"]},"effectiveSubAssetClass":{"type":["string","null"]},"valuationClassificationId":{"type":["string","null"]},"strategy":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]},"memberIdentifiers":{"type":"array","items":{"type":"string"}}}},"company":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}},"holdingsSummary":{"$ref":"#/components/schemas/ReferenceHoldingsSummary"},"security":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"isin":{"type":"string"},"cusip":{"type":["string","null"]},"sedol":{"type":["string","null"]},"exchangeCode":{"type":["string","null"]},"name":{"type":["string","null"]}}}}},"ReferenceInvestmentPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceInvestment"}},"nextCursor":{"type":["string","null"]}}},"ReferenceFixedInterestSnapshot":{"type":"object","required":["id","identifier","asOfDate","credit","region","sector"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":["string","null"]},"identifier":{"type":"string"},"fundName":{"type":["string","null"]},"asOfDate":{"type":"string","format":"date"},"effectiveDuration":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"modifiedDuration":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"creditDuration":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"effectiveMaturity":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"yieldToMaturity":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"credit":{"type":"object","properties":{"aaa":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"aa":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"a":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"bbb":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"bb":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"b":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"belowB":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"notRated":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"cash":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}},"region":{"type":"object","properties":{"australia":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"northAmerica":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"europeExUk":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"uk":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"asia":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"em":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"other":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"cash":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}},"sector":{"type":"object","properties":{"globalSovereign":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"australianSovereign":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"investmentGradeCorporate":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"subInvestmentGradeCorporate":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"securitised":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"hybrids":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"emergingMarketDebt":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"otherSectors":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"cash":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}},"scaleDetected":{"type":"object","properties":{"credit":{"type":"string","enum":["percent","fraction","empty"]},"region":{"type":"string","enum":["percent","fraction","empty"]},"sector":{"type":"string","enum":["percent","fraction","empty"]},"yieldToMaturity":{"type":["string","null"],"enum":["percent","fraction",null]}}}}},"ReferenceFixedInterestLatest":{"type":"object","required":["items","scale"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceFixedInterestSnapshot"}},"scale":{"type":"object","properties":{"values":{"type":"string","enum":["as_stored"]},"exposureGroups":{"type":"string"},"yieldToMaturity":{"type":"string"},"durations":{"type":"string","enum":["years"]}}}}},"ReferenceFixedInterestHistory":{"type":"object","required":["investmentId","identifier","items","nextCursor","scale"],"properties":{"investmentId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceFixedInterestSnapshot"}},"nextCursor":{"type":["string","null"]},"scale":{"type":"object","properties":{"values":{"type":"string","enum":["as_stored"]},"exposureGroups":{"type":"string"},"yieldToMaturity":{"type":"string"},"durations":{"type":"string","enum":["years"]}}}}},"ReferenceFund":{"type":"object","required":["id","holdingDetailId","identifier","name","terminated","strategy","company","bloombergTicker","securityId","latestHoldingsDate"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"terminated":{"type":"boolean"},"strategy":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}},"company":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}},"bloombergTicker":{"type":["string","null"]},"securityId":{"type":["string","null"]},"latestHoldingsDate":{"type":["string","null"],"format":"date","description":"Later of the security-level and fixed-interest snapshot dates; null when the fund discloses nothing."},"holdingsSummary":{"$ref":"#/components/schemas/ReferenceHoldingsSummary"}}},"ReferenceFundPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceFund"}},"nextCursor":{"type":["string","null"]}}},"ReferenceFundDetail":{"type":"object","required":["id","holdingDetailId","identifier","name","terminated","strategy","company","bloombergTicker","securityId","latestHoldingsDate"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"terminated":{"type":"boolean"},"strategy":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}},"company":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}},"bloombergTicker":{"type":["string","null"]},"securityId":{"type":["string","null"]},"latestHoldingsDate":{"type":["string","null"],"format":"date","description":"Later of the security-level and fixed-interest snapshot dates; null when the fund discloses nothing."},"holdingsSummary":{"$ref":"#/components/schemas/ReferenceHoldingsSummary"},"detail":{"type":["object","null"],"description":"Full staff with reference:read only.","properties":{"objective":{"type":["string","null"]},"business":{"type":["string","null"]},"portfolioManager":{"type":["string","null"]},"investsenseSummary":{"type":["string","null"]},"fundStrengths":{"type":["string","null"]},"fundWeaknesses":{"type":["string","null"]},"fundType":{"type":["string","null"]},"suggestedTimeframe":{"type":["string","null"]},"targetReturn":{"type":["string","null"]},"wholesaleOnly":{"type":["boolean","null"]},"distributionFrequency":{"type":["string","null"]}}},"classification":{"type":"object","properties":{"subAssetClass":{"type":["string","null"]},"subAssetClassCode":{"type":["integer","null"]},"assetClass":{"type":["string","null"]},"growthAsset":{"type":["boolean","null"]}}}}},"ReferenceFundHoldingDates":{"type":"object","required":["dates","siblings"],"properties":{"dates":{"type":"object","additionalProperties":{"type":["string","null"],"format":"date"}},"siblings":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"ReferenceStructure":{"type":"object","required":["platforms","suites","latestHoldingDates"],"properties":{"platforms":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"slug":{"type":"string"}}}},"suites":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"slug":{"type":"string"},"companyId":{"type":["string","null"]},"companyName":{"type":["string","null"]},"portfolioCount":{"type":"integer","minimum":0}}}},"latestHoldingDates":{"type":"object","properties":{"portfolio":{"type":["string","null"],"format":"date"},"fund":{"type":["string","null"],"format":"date"}}}}},"ReferenceTaxonomy":{"type":"object","required":["assetClasses","subAssetClasses","valuationClassifications"],"properties":{"assetClasses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"sortOrder":{"type":"integer"},"growthAsset":{"type":"boolean"},"proxyEtf":{"type":["object","null"],"properties":{"investmentId":{"type":["string","null"]},"identifier":{"type":["string","null"]},"name":{"type":["string","null"]},"code":{"type":["string","null"]}}}}}},"subAssetClasses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"integer"},"name":{"type":"string"},"assetClassId":{"type":["string","null"]},"growthAsset":{"type":["boolean","null"]},"valuationClassificationId":{"type":["string","null"]},"indexName":{"type":["string","null"]},"proxyEtf":{"type":["object","null"],"properties":{"investmentId":{"type":["string","null"]},"identifier":{"type":["string","null"]},"name":{"type":["string","null"]},"code":{"type":["string","null"]}}}}}},"valuationClassifications":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}}}},"ReferencePds":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"suiteId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"platformId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"effectiveDate":{"type":"string","format":"date"},"url":{"type":"string","format":"uri"}}}}}},"ReferenceCompany":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]},"slug":{"type":"string"},"companyType":{"type":"string","enum":["Flagship","Bespoke","FundManager","Distributor"]},"website":{"type":["string","null"]},"mainColour":{"type":["string","null"]},"isDeleted":{"type":"boolean"},"activePortfolioCount":{"type":"integer","minimum":0}}},"ReferenceCompanyPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceCompany"}},"nextCursor":{"type":["string","null"]},"totalCount":{"type":"integer","minimum":0},"totalCountCapped":{"type":"boolean"}}},"ReferenceSuite":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"slug":{"type":"string"}}},"ReferenceSuitePage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceSuite"}},"nextCursor":{"type":["string","null"]}}},"ReferencePlatform":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"slug":{"type":"string"}}},"ReferencePlatformPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferencePlatform"}},"nextCursor":{"type":["string","null"]}}},"ReferenceStrategy":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"},"company":{"type":"object","properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]},"type":{"type":"string","enum":["Flagship","Bespoke","FundManager","Distributor"]}}},"assetClass":{"type":["string","null"]},"subAssetClass":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"integer"},"name":{"type":"string"}}},"childFundCount":{"type":"integer","minimum":0},"bloombergFundName":{"type":["string","null"]},"primaryFund":{"type":["object","null"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"latestHoldingsDate":{"type":["string","null"],"format":"date"}}}}},"ReferenceStrategyPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ReferenceStrategy"}},"nextCursor":{"type":["string","null"]}}},"ReferenceValuationDashboard":{"type":"object","required":["asOfDate","priorDate","items","valueUnit"],"properties":{"asOfDate":{"type":["string","null"],"format":"date"},"priorDate":{"type":["string","null"],"format":"date"},"items":{"type":"array","items":{"type":"object","properties":{"classificationId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"classification":{"type":"string"},"date":{"type":"string","format":"date"},"expectedReturn":{"type":"string","description":"Percent, exact decimal."},"potentialLossEstimate":{"type":"string","description":"Percent, exact decimal."},"volatility":{"type":"string","description":"Percent, exact decimal."},"prior":{"type":["object","null"],"properties":{"date":{"type":"string","format":"date"},"expectedReturn":{"type":"string","description":"Percent, exact decimal."},"potentialLossEstimate":{"type":"string","description":"Percent, exact decimal."},"volatility":{"type":"string","description":"Percent, exact decimal."}}}}}},"valueUnit":{"type":"string","enum":["percent"]}}},"ReferenceValuationDates":{"type":"object","required":["dates"],"properties":{"dates":{"type":"array","items":{"type":"string","format":"date"}}}},"PortfolioFeeItem":{"type":"object","required":["portfolioId","inherited","sourcePortfolioId","effectiveDate","investmentManagementFee","responsibleEntityFee","modelManagerPlusReFee","underlyingManagerFee","interestRetainedOnCashFee","modelPerformanceFee","underlyingManagerPerformanceFee","modelTransactionFee","underlyingTransactionFee"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"inherited":{"type":"boolean"},"sourcePortfolioId":{"anyOf":[{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},{"type":"null"}],"description":"The portfolio the fees were read from, only when inherited."},"effectiveDate":{"type":"string","format":"date"},"investmentManagementFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"responsibleEntityFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"modelManagerPlusReFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"underlyingManagerFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"interestRetainedOnCashFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"modelPerformanceFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"underlyingManagerPerformanceFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"modelTransactionFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"underlyingTransactionFee":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}},"PortfolioFees":{"type":"object","required":["items","feeUnit"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/PortfolioFeeItem"}},"feeUnit":{"type":"string","enum":["decimal_fraction"]}}},"StrategyMerBenchmark":{"type":"object","required":["identifier","name","mer","members"],"properties":{"identifier":{"type":"string"},"name":{"type":["string","null"]},"mer":{"type":"string","description":"Percent, exact decimal string."},"members":{"type":"array","items":{"type":"object","required":["identifier","name","mer"],"properties":{"identifier":{"type":"string"},"name":{"type":["string","null"]},"mer":{"type":"string","description":"Percent, exact decimal string."}}}}}},"InvestmentFeeItem":{"type":"object","required":["investmentId","holdingDetailId","identifier","effectiveDate","imfcPds","performanceFeeCosts","netTotalTO","buySpread","sellSpread","feeUnit","strategyId"],"properties":{"investmentId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"effectiveDate":{"type":["string","null"],"format":"date"},"imfcPds":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"performanceFeeCosts":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"netTotalTO":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"buySpread":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"sellSpread":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"feeUnit":{"type":"string","enum":["percent"]},"strategyId":{"anyOf":[{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},{"type":"null"}]},"strategyMerBenchmark":{"anyOf":[{"$ref":"#/components/schemas/StrategyMerBenchmark"},{"type":"null"}],"description":"Only with include=strategyBenchmark."}}},"InvestmentFees":{"type":"object","required":["items","nextCursor","feeUnit"],"properties":{"items":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/InvestmentFeeItem"}},"nextCursor":{"type":["string","null"],"description":"Universe mode only; null otherwise and on the last page."},"feeUnit":{"type":"string","enum":["percent"]}}},"CheaperAlternative":{"type":"object","required":["ownIdentifier","ownName","altIdentifier","altName","strategyName","own","alt","deltaPct"],"properties":{"ownIdentifier":{"type":"string"},"ownName":{"type":["string","null"]},"altIdentifier":{"type":"string"},"altName":{"type":["string","null"]},"strategyName":{"type":"string"},"own":{"type":"object","required":["merPct","performanceFeePct","transactionCostPct","allInPct","feeDate"],"properties":{"merPct":{"type":"string"},"performanceFeePct":{"type":"string"},"transactionCostPct":{"type":"string"},"allInPct":{"type":"string","description":"MER plus performance fee plus net transactional and operational cost. Missing components count as 0. Spreads are excluded."},"feeDate":{"type":["string","null"],"format":"date"}}},"alt":{"type":"object","required":["merPct","performanceFeePct","transactionCostPct","allInPct","feeDate"],"properties":{"merPct":{"type":"string"},"performanceFeePct":{"type":"string"},"transactionCostPct":{"type":"string"},"allInPct":{"type":"string","description":"MER plus performance fee plus net transactional and operational cost. Missing components count as 0. Spreads are excluded."},"feeDate":{"type":["string","null"],"format":"date"}}},"deltaPct":{"type":"string","description":"Saving in percentage points, above 0.05. Own all-in minus the cheaper sibling's."}}},"RebateBenchmark":{"type":"object","required":["maxRebate","topPortfolioNames"],"properties":{"maxRebate":{"type":"string","description":"Decimal fraction."},"topPortfolioNames":{"type":"array","maxItems":3,"items":{"type":"string"}}}},"FeeInsights":{"type":"object","required":["cheaperAlternatives","rebateBenchmarks","units"],"properties":{"cheaperAlternatives":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CheaperAlternative"}},"rebateBenchmarks":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/RebateBenchmark"}},"units":{"type":"object","required":["cheaperAlternatives","rebateBenchmarks"],"properties":{"cheaperAlternatives":{"type":"string","enum":["percent"]},"rebateBenchmarks":{"type":"string","enum":["decimal_fraction"]}}}}},"RebateItem":{"type":"object","required":["portfolioId","holdingDetailId","amount","date"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"amount":{"type":"string","description":"Decimal fraction."},"date":{"type":"string","format":"date"}}},"RebateMaximum":{"type":"object","required":["holdingDetailId","amount"],"properties":{"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"amount":{"type":"string","description":"Decimal fraction."}}},"RebatesResponse":{"type":"object","required":["items","maxima","nextCursor","amountUnit"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RebateItem"}},"maxima":{"type":"array","items":{"$ref":"#/components/schemas/RebateMaximum"}},"nextCursor":{"type":["string","null"]},"amountUnit":{"type":"string","enum":["decimal_fraction"]}}},"SecurityReferences":{"type":"object","required":["name","url","country","countryIso","region","factsetEconomy","factsetSector","factsetIndustry"],"properties":{"name":{"type":["string","null"]},"url":{"type":["string","null"]},"country":{"type":["string","null"]},"countryIso":{"type":["string","null"]},"region":{"type":["string","null"]},"factsetEconomy":{"type":["string","null"]},"factsetSector":{"type":["string","null"]},"factsetIndustry":{"type":["string","null"]}}},"SecurityLatestPrice":{"type":"object","required":["date","closePrice","marketCap"],"properties":{"date":{"type":"string","format":"date"},"closePrice":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"marketCap":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}},"SecurityConsensus":{"type":"object","required":["date","metrics"],"properties":{"date":{"type":"string","format":"date"},"metrics":{"type":"object","required":["eps","dps","bps","fcfps","roe","roic","ebitda","net_debt"],"properties":{"eps":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"dps":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"bps":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"fcfps":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"roe":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"roic":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"ebitda":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."},"net_debt":{"type":"array","minItems":5,"maxItems":5,"items":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"description":"Five fiscal-year estimates; index 0 is the first forecast year (1FY). Null when missing, never zero."}}}}},"SecurityFundamentals":{"type":"object","required":["date","values"],"properties":{"date":{"type":"string","format":"date"},"values":{"type":"object","description":"eps, dps, bps, fcps, roe, roic, enterprise_value, ebit, ebitda, total_debt, net_debt, long_term_debt, assets, equity, dividend_pct_franked as exact decimal strings; null when missing.","additionalProperties":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."}}}},"SecurityMarketData":{"type":"object","required":["priceDate","closePrice","marketCap","marketCapDate","factsetEconomyId","factsetEconomy","factsetIndustryId","factsetIndustry","countryRegion","consensus","fundamentals"],"properties":{"priceDate":{"type":["string","null"],"format":"date"},"closePrice":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"marketCap":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"marketCapDate":{"type":["string","null"],"format":"date"},"factsetEconomyId":{"type":["string","null"]},"factsetEconomy":{"type":["string","null"]},"factsetIndustryId":{"type":["string","null"]},"factsetIndustry":{"type":["string","null"]},"countryRegion":{"type":["string","null"]},"consensus":{"oneOf":[{"$ref":"#/components/schemas/SecurityConsensus"},{"type":"null"}]},"fundamentals":{"oneOf":[{"$ref":"#/components/schemas/SecurityFundamentals"},{"type":"null"}]}}},"Security":{"type":"object","required":["id","name","isin","cusip","sedol","exchangeCode","ticker","sector","industry","country","countryIso","updatedAt"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]},"isin":{"type":"string"},"cusip":{"type":["string","null"]},"sedol":{"type":["string","null"]},"exchangeCode":{"type":["string","null"]},"ticker":{"type":["string","null"],"description":"exchangeCode before its first '-' (CBA-AU gives CBA)."},"sector":{"type":["string","null"]},"industry":{"type":["string","null"]},"country":{"type":["string","null"]},"countryIso":{"type":["string","null"]},"updatedAt":{"type":"string","format":"date-time"},"references":{"oneOf":[{"$ref":"#/components/schemas/SecurityReferences"},{"type":"null"}]},"latestPrice":{"oneOf":[{"$ref":"#/components/schemas/SecurityLatestPrice"},{"type":"null"}]},"marketData":{"$ref":"#/components/schemas/SecurityMarketData"}}},"SecurityPage":{"type":"object","required":["items","nextCursor","totalCount","totalCountCapped"],"properties":{"items":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/Security"}},"nextCursor":{"type":["string","null"]},"totalCount":{"type":["integer","null"],"minimum":0},"totalCountCapped":{"type":"boolean"}}},"BrokerEstimate":{"type":"object","required":["date","targetPrice","broker","analyst"],"properties":{"date":{"type":"string","format":"date"},"targetPrice":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"broker":{"type":["string","null"]},"analyst":{"type":["string","null"]}}},"BrokerRating":{"type":"object","required":["date","rating","broker","analyst"],"properties":{"date":{"type":"string","format":"date"},"rating":{"type":["string","null"]},"broker":{"type":["string","null"]},"analyst":{"type":["string","null"]}}},"TargetPrices":{"type":"object","required":["date","medianTargetPrice","meanTargetPrice","latestPrice","latestPriceDate"],"properties":{"date":{"type":"string","format":"date"},"medianTargetPrice":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"meanTargetPrice":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"latestPrice":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"latestPriceDate":{"type":["string","null"],"format":"date"}}},"SecurityResearch":{"type":"object","required":["securityId","isin","securityName","exchangeCode","ratingsWindowDays"],"properties":{"securityId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"isin":{"type":"string"},"securityName":{"type":["string","null"]},"exchangeCode":{"type":["string","null"]},"ratingsWindowDays":{"type":"integer","minimum":0},"fundamentals":{"oneOf":[{"$ref":"#/components/schemas/SecurityFundamentals"},{"type":"null"}]},"consensus":{"oneOf":[{"$ref":"#/components/schemas/SecurityConsensus"},{"type":"null"}]},"brokerEstimates":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/BrokerEstimate"}},"brokerRatings":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/BrokerRating"}},"recentRatings":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/BrokerRating"}},"targetPrices":{"oneOf":[{"$ref":"#/components/schemas/TargetPrices"},{"type":"null"}]}}},"ResearchNote":{"type":"object","required":["id","date","title","type","location","companyId","companyName","summary","summaryChars","summaryTruncated","hasAttachment","attachmentName","updatedAt"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"date":{"type":"string","format":"date"},"title":{"type":"string"},"type":{"type":"string"},"location":{"type":"string"},"companyId":{"oneOf":[{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},{"type":"null"}]},"companyName":{"type":["string","null"]},"summary":{"type":["string","null"]},"summaryChars":{"type":"integer","minimum":0},"summaryTruncated":{"type":"boolean"},"hasAttachment":{"type":"boolean"},"attachmentName":{"type":["string","null"]},"updatedAt":{"type":"string","format":"date-time"},"body":{"type":["string","null"]},"bodyTruncated":{"type":"boolean"}}},"ResearchNoteDate":{"type":"object","required":["id","date"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"date":{"type":"string","format":"date"}}},"ResearchNoteMatch":{"type":"object","required":["in","snippet","transcriptMatchCount"],"properties":{"in":{"type":"string","enum":["summary","transcript","title"]},"snippet":{"type":["string","null"]},"transcriptMatchCount":{"type":"integer","minimum":0}}},"ResearchNoteSearchItem":{"allOf":[{"$ref":"#/components/schemas/ResearchNote"},{"type":"object","required":["match"],"properties":{"match":{"$ref":"#/components/schemas/ResearchNoteMatch"}}}]},"ResearchNotePage":{"type":"object","required":["items","nextCursor","totalCount","windowFrom"],"properties":{"items":{"type":"array","maxItems":25,"items":{"oneOf":[{"$ref":"#/components/schemas/ResearchNote"},{"$ref":"#/components/schemas/ResearchNoteDate"}]}},"nextCursor":{"type":["string","null"]},"totalCount":{"type":["integer","null"],"minimum":0},"windowFrom":{"type":["string","null"],"format":"date"}}},"ResearchNoteSearchPage":{"type":"object","required":["items","nextCursor","totalCount","windowFrom"],"properties":{"items":{"type":"array","maxItems":25,"items":{"$ref":"#/components/schemas/ResearchNoteSearchItem"}},"nextCursor":{"type":["string","null"]},"totalCount":{"type":["integer","null"],"minimum":0},"windowFrom":{"type":["string","null"],"format":"date"}}},"ResearchNoteDetail":{"type":"object","required":["id","date","title","type","location","companyId","summary","hasAttachment","attachmentName","transcript","transcriptChars","transcriptTruncated"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"date":{"type":"string","format":"date"},"title":{"type":"string"},"type":{"type":"string"},"location":{"type":"string"},"companyId":{"oneOf":[{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},{"type":"null"}]},"summary":{"type":["string","null"]},"hasAttachment":{"type":"boolean"},"attachmentName":{"type":["string","null"]},"transcript":{"type":["string","null"],"description":"Sanitised transcript, clipped to maxChars; null with summaryOnly."},"transcriptChars":{"type":"integer","minimum":0},"transcriptTruncated":{"type":"boolean"}}},"PresignedFile":{"type":"object","required":["url","fileName","contentType","sizeBytes"],"properties":{"url":{"type":"string","format":"uri"},"fileName":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":["integer","null"],"minimum":0}}},"PitchDeck":{"type":"object","required":["id","date","asOfDate","fileName","strategies","companies"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"date":{"type":"string","format":"date"},"asOfDate":{"type":["string","null"],"format":"date"},"fileName":{"type":["string","null"]},"strategies":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"companies":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":["string","null"]}}}}}},"PitchDeckPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/PitchDeck"}},"nextCursor":{"type":["string","null"]}}},"FumLatestRow":{"type":"object","required":["portfolioCode","asOf","closingFum","accounts","adviserCount","inflowMtd","outflowMtd","netFlowMtd","companyName","suiteName","platformName"],"properties":{"portfolioCode":{"type":"string"},"asOf":{"type":"string","format":"date"},"closingFum":{"type":"string","description":"AUD, exact decimal string."},"accounts":{"type":"integer","minimum":0},"adviserCount":{"type":"integer","minimum":0},"inflowMtd":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"outflowMtd":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"netFlowMtd":{"type":["string","null"],"description":"Exact decimal value encoded as a string; null when missing, never zero."},"companyName":{"type":["string","null"]},"suiteName":{"type":["string","null"]},"platformName":{"type":["string","null"]},"adviser":{"type":["string","null"]}}},"FumLatestPage":{"type":"object","required":["data","totalCount","revision","nextOffset"],"properties":{"data":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/FumLatestRow"}},"totalCount":{"type":"integer","minimum":0},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"},"nextOffset":{"type":["integer","null"],"minimum":0}}},"IdentityProfile":{"type":"object","required":["userId","role","companyId","scopes","principalType","displayName","staffRole","isFullStaff"],"properties":{"userId":{"type":"string","description":"The user id, or service:<name> for a service principal (never a user row)."},"role":{"type":"string","enum":["adviser","fund_manager","staff"]},"companyId":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"principalType":{"type":"string","enum":["key","oauth","service","job"]},"displayName":{"type":"string","description":"A person's name, or the principal's name. Never an email."},"staffRole":{"type":["string","null"],"description":"Live staff sub-role; null for a service principal."},"isFullStaff":{"type":"boolean","description":"A person who is Trellia or InvestSense staff. Always false for a service principal."},"servicePrincipalName":{"type":"string"},"jobId":{"type":"string"},"grantExpiresAt":{"type":"string","format":"date-time","description":"MCP grants only: when the current access grant ends."},"expiresAt":{"type":"string","format":"date-time","description":"Keys, service keys and job tokens: when the credential ends."}}},"PortfolioUpdateOptions":{"type":"object","required":["suites","categories","authors"],"properties":{"suites":{"type":"array","maxItems":1000,"items":{"type":"object","required":["id","slug","name","companyId","companyName","portfolioCount"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"slug":{"type":"string"},"name":{"type":"string"},"companyId":{"type":["string","null"]},"companyName":{"type":["string","null"]},"portfolioCount":{"type":"integer","minimum":0}}}},"categories":{"type":"array","maxItems":500,"items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"authors":{"type":"array","maxItems":500,"items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}}}},"PortfolioUpdateListPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/PortfolioUpdateListItem"}},"nextCursor":{"type":["string","null"]}}},"PortfolioUpdateListItem":{"type":"object","required":["id","slug","title","date","published","excerpt","updateType","showToInvestors","suites","categories","portfolioCount","imageCount","updatedAt"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"slug":{"type":"string"},"title":{"type":"string"},"date":{"type":["string","null"],"format":"date"},"published":{"type":"boolean"},"excerpt":{"type":["string","null"]},"updateType":{"type":"string"},"showToInvestors":{"type":"boolean"},"suites":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"categories":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"portfolioCount":{"type":"integer","minimum":0},"imageCount":{"type":"integer","minimum":0,"description":"Number of img tags in the HTML body."},"updatedAt":{"type":"string","format":"date-time"},"thumbnail":{"type":["string","null"],"description":"Only with include=thumbnail."},"content":{"type":["string","null"],"description":"HTML as stored (at most 500000 characters). Only with include=content."}}},"PortfolioUpdateDetail":{"type":"object","required":["id","slug","title","published"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"slug":{"type":"string"},"title":{"type":"string"},"date":{"type":["string","null"],"format":"date"},"excerpt":{"type":["string","null"]},"content":{"type":["string","null"]},"thumbnail":{"type":["string","null"]},"pdf":{"type":["string","null"]},"showToInvestors":{"type":"boolean"},"sendToEveryoneWithAccess":{"type":"boolean"},"updateType":{"type":"string"},"betasharesSection":{"type":["string","null"]},"published":{"type":"boolean"},"suiteIds":{"type":"array","items":{"type":"integer"}},"categoryIds":{"type":"array","items":{"type":"integer"}},"authorIds":{"type":"array","items":{"type":"string"}},"portfolioIds":{"type":"array","items":{"type":"integer"}},"updatedAt":{"type":["string","null"],"format":"date-time"},"links":{"type":"object","description":"Only with expand=links.","required":["suites","categories","authors","portfolios"],"properties":{"suites":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"categories":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"authors":{"type":"array","items":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"name":{"type":"string"}}}},"portfolios":{"type":"array","maxItems":2000,"items":{"type":"object","required":["id","code","name","suiteId","platformName"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"code":{"type":"string"},"name":{"type":"string"},"suiteId":{"type":["string","null"]},"platformName":{"type":["string","null"]}}}}}}}},"ImportKindList":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object","required":["kind","scope","label","description","reader","mode","keyColumns","replaceGroupColumns","columns","acceptsAllColumns","revertNotes","startable"],"properties":{"kind":{"type":"string"},"scope":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"reader":{"type":"string","enum":["tabular","performance_wide","server"]},"mode":{"type":"string","enum":["upsert","replace_groups"]},"keyColumns":{"type":"array","items":{"type":"string"}},"replaceGroupColumns":{"type":["array","null"],"items":{"type":"string"}},"columns":{"type":"array","items":{"type":"object","required":["column","inputs","required","reference"],"properties":{"column":{"type":"string"},"inputs":{"type":"array","items":{"type":"string"}},"required":{"type":"boolean"},"reference":{"type":["string","null"]}}}},"acceptsAllColumns":{"type":"boolean"},"revertNotes":{"type":"string"},"startable":{"type":"boolean"},"tables":{"type":"array","description":"Only for table_rows.","items":{"type":"object","required":["table","keyColumns"],"properties":{"table":{"type":"string"},"keyColumns":{"type":"array","items":{"type":"string"}}}}}}}}}},"EmptyObject":{"type":"object","additionalProperties":false},"IssueJobTokenRequest":{"type":"object","additionalProperties":false,"required":["jobId","jobKind","scopes","ttlSeconds"],"properties":{"jobId":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"},"jobKind":{"type":"string","enum":["ic_prep","fm_prep","book_analysis","due_diligence","esg_report","bbu","quarterly_figures"]},"scopes":{"type":"array","minItems":1,"items":{"type":"string","enum":["profile:read","portfolios:read","funds:read","fum:read","reference:read","fees:read","rebates:read","securities:read","securities:research:read","research:read","research:files:read","portfolio_updates:read","files:read","files:upload"]}},"ttlSeconds":{"type":"integer","minimum":60,"maximum":7200}}},"JobToken":{"type":"object","required":["jobId","jobKind","token","tokenPrefix","scopes","expiresAt"],"properties":{"jobId":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"},"jobKind":{"type":"string","enum":["ic_prep","fm_prep","book_analysis","due_diligence","esg_report","bbu","quarterly_figures"]},"token":{"type":"string","description":"The secret (trj_...). Returned once; send it as the Bearer token for this job only."},"tokenPrefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":"string","format":"date-time"}}},"RevokedJobTokens":{"type":"object","required":["jobId","revoked"],"properties":{"jobId":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"},"revoked":{"type":"integer","minimum":0}}},"CreateFileRequest":{"type":"object","additionalProperties":false,"required":["purpose","kind","fileName","contentType","sizeBytes","sha256"],"properties":{"purpose":{"type":"string","enum":["generated_file","portfolio_update_image"]},"kind":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,47}$"},"fileName":{"type":"string","maxLength":200},"contentType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":1,"maximum":104857600},"sha256":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"},"jobId":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"},"expiresInSeconds":{"type":"integer","minimum":900,"maximum":2592000}}},"ApiFile":{"type":"object","required":["id","purpose","kind","status","fileName","contentType","sizeBytes","sha256","hostedUrl","width","height","jobId","createdAt","completedAt","expiresAt"],"properties":{"id":{"type":"string"},"purpose":{"type":"string","enum":["generated_file","portfolio_update_image"]},"kind":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,47}$"},"status":{"type":"string","enum":["PENDING","READY","REJECTED","DELETED"]},"fileName":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"hostedUrl":{"type":["string","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"jobId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}},"CreatedFile":{"type":"object","required":["id","purpose","kind","status","fileName","contentType","sizeBytes","sha256","hostedUrl","width","height","jobId","createdAt","completedAt","expiresAt","putMethod","putUrl","putHeaders","putUrlExpiresAt"],"properties":{"id":{"type":"string"},"purpose":{"type":"string","enum":["generated_file","portfolio_update_image"]},"kind":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,47}$"},"status":{"type":"string","enum":["PENDING","READY","REJECTED","DELETED"]},"fileName":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"hostedUrl":{"type":["string","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"jobId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"putMethod":{"type":"string","enum":["PUT"]},"putUrl":{"type":"string"},"putHeaders":{"type":"object","additionalProperties":{"type":"string"},"description":"Send exactly these headers with the PUT."},"putUrlExpiresAt":{"type":"string","format":"date-time"}}},"CompletedFile":{"type":"object","required":["id","purpose","kind","status","fileName","contentType","sizeBytes","sha256","hostedUrl","width","height","jobId","createdAt","completedAt","expiresAt","rejectionReason"],"properties":{"id":{"type":"string"},"purpose":{"type":"string","enum":["generated_file","portfolio_update_image"]},"kind":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,47}$"},"status":{"type":"string","enum":["PENDING","READY","REJECTED","DELETED"]},"fileName":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"hostedUrl":{"type":["string","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"jobId":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"rejectionReason":{"type":["string","null"],"enum":["size_mismatch","hash_mismatch","malware_scan","invalid_image",null]}}},"FilePage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiFile"}},"nextCursor":{"type":["string","null"]}}},"FileDownload":{"type":"object","required":["url","urlExpiresAt","fileName","contentType","sizeBytes"],"properties":{"url":{"type":"string"},"urlExpiresAt":{"type":"string","format":"date-time"},"fileName":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer"}}},"MirrorPortfolioMembershipItem":{"type":"object","required":["portfolioId","portfolioCode","holdingDetailId","identifier","asOfDate","weight"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"portfolioCode":{"type":"string"},"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"asOfDate":{"type":"string","format":"date"},"weight":{"type":"string","description":"Decimal fraction, exact string."}}},"MirrorPortfolioMembershipPage":{"type":"object","required":["items","nextCursor","asOf","weightUnit"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MirrorPortfolioMembershipItem"}},"nextCursor":{"type":["string","null"]},"asOf":{"type":"string","format":"date"},"weightUnit":{"type":"string","enum":["decimal_fraction"]}}},"MirrorFundMembershipItem":{"type":"object","required":["fundId","holdingDetailId","identifier","latestHoldingsDate","constituentCount"],"properties":{"fundId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"latestHoldingsDate":{"type":"string","format":"date"},"constituentCount":{"type":"integer","minimum":0}}},"MirrorFundMembershipPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MirrorFundMembershipItem"}},"nextCursor":{"type":["string","null"]}}},"MirrorHoldingSnapshotItem":{"type":"object","required":["portfolioId","asOfDate","inherited","sourcePortfolioId","holdingId","holdingDetailId","investmentId","identifier","name","weight","isTerminated"],"properties":{"portfolioId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"asOfDate":{"type":"string","format":"date"},"inherited":{"type":"boolean"},"sourcePortfolioId":{"type":["string","null"]},"holdingId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"holdingDetailId":{"type":["string","null"]},"investmentId":{"type":["string","null"]},"identifier":{"type":["string","null"]},"name":{"type":["string","null"]},"weight":{"type":"string","description":"Decimal fraction, exact string."},"isTerminated":{"type":["boolean","null"]}}},"MirrorHoldingSnapshotPage":{"type":"object","required":["items","nextCursor","weightUnit"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MirrorHoldingSnapshotItem"}},"nextCursor":{"type":["string","null"]},"weightUnit":{"type":"string","enum":["decimal_fraction"]}}},"MirrorInvestmentItem":{"type":"object","required":["id","investmentId","identifier","name","isTerminated","securityId","strategyId","bloombergTicker","subAssetClassId","subAssetClass","assetClassId","assetClass","growthAsset","effectiveSubAssetClassId","effectiveSubAssetClass","valuationClassificationId"],"properties":{"id":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"investmentId":{"type":"string","pattern":"^[1-9][0-9]{0,18}$"},"identifier":{"type":"string"},"name":{"type":["string","null"]},"isTerminated":{"type":"boolean"},"securityId":{"type":["string","null"]},"strategyId":{"type":["string","null"]},"bloombergTicker":{"type":["string","null"]},"subAssetClassId":{"type":["string","null"]},"subAssetClass":{"type":["string","null"]},"assetClassId":{"type":["string","null"]},"assetClass":{"type":["string","null"]},"growthAsset":{"type":["boolean","null"]},"effectiveSubAssetClassId":{"type":["string","null"]},"effectiveSubAssetClass":{"type":["string","null"]},"valuationClassificationId":{"type":["string","null"]}}},"MirrorInvestmentPage":{"type":"object","required":["items","nextCursor"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MirrorInvestmentItem"}},"nextCursor":{"type":["string","null"]}}},"ClientNameItem":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"ClientNamesPage":{"type":"object","required":["items","nextCursor","asOf"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ClientNameItem"}},"nextCursor":{"type":["string","null"]},"asOf":{"type":"string","format":"date-time"}}}}}}